Compare commits

...

271 Commits

Author SHA1 Message Date
Kubernetes Publisher 2da25b2322 Merge pull request #132269 from dims/update-to-latest-github.com/modern-go/reflect2
Update to latest github.com/modern-go/reflect2

Kubernetes-commit: d55b119d34883bbad2a3436dcb6c62339d963031
2025-06-12 21:02:18 +00:00
Kubernetes Publisher 110ba5998e Merge pull request #132251 from ardaguclu/kubectl-interactive-delete-fix
kubectl delete: update interactive delete to break on new line

Kubernetes-commit: dac3c09bd16643dbac5e976e85d81825dd226ac0
2025-06-12 16:46:28 +00:00
Davanum Srinivas 716737e46a Update to latest github.com/modern-go/reflect2
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 3908550c0dc189cfa9de38a84bee508fa0659463
2025-06-12 11:20:39 -04:00
Arda Güçlü 8a11631ed9 kubectl delete: Update interactive delete to break on new line
Kubernetes-commit: fb611f4c93e6d8d8eb920f4436af748432402f50
2025-06-12 11:27:51 +03:00
Kubernetes Publisher 330f86df8e Merge pull request #132209 from dims/update-github.com/spf13/cobra-v1.9.1eksctl
update github.com/spf13/cobra v1.9.1

Kubernetes-commit: dc19f0b6b9cd14ece6b1929cb4e7ea2c9d322b95
2025-06-10 20:54:36 +00:00
Kubernetes Publisher 55101ca654 Merge pull request #131500 from HaraldNordgren/sort_configmaps
kubectl: sort configmap data alphabetically and simplify display format

Kubernetes-commit: 447efd4c0f45f13d262423265a8a960666ed3778
2025-06-10 20:54:34 +00:00
Harald Nordgren ab62ac8cf1 Revert "improve display format"
This reverts commit 28e7acf0f93f5c9edb43ab09cd181e8847409215.

Kubernetes-commit: f8b701243503fc10a037f86e77ce4df5741a07c6
2025-06-10 16:56:58 +02:00
Davanum Srinivas af5ade99d8 update github.com/spf13/cobra v1.9.1
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 449320a54a2dac04f953d5f6401d875ea9b7e8de
2025-06-10 10:50:54 -04:00
Kubernetes Publisher 4d27286e9c Merge pull request #132103 from nojnhuh/typed-ring-buffer
Replace queue.FIFOs with k8s.io/utils/buffer.Ring

Kubernetes-commit: 5090812df4fb6cf09a9181635d90c2e154eab8cc
2025-06-06 21:12:11 +00:00
Kubernetes Publisher 9130183f39 Merge pull request #132110 from jpbetz/gengo-bump
Bump gengo/v2 to latest, pick up related validation-gen fixes

Kubernetes-commit: 4fff091ce7c8b22e6a511231e400adb865a7b300
2025-06-05 21:39:08 +00:00
Joe Betz e808dbbf1f Bump gengo/v2 to latest
Kubernetes-commit: ac5cb23000f57b7b034fa98e5cc4f6e8fb6e8a9c
2025-06-04 22:39:08 -04:00
Jon Huhn 579a7a5a35 Update k8s.io/utils for new generic ring buffer
Kubernetes-commit: 8cdbbf5cdaef7e37cfd432e9044aa52f4d42adcd
2025-06-04 12:09:53 -05:00
Itamar Holder 0b4adb247f [KEP-2400] kubectl top: add a --show-swap option (#129458)
* top, refactor: turn package-exposed variables to unexpose struct fields

Signed-off-by: Itamar Holder <iholder@redhat.com>

* kubectl top node: add the --show-swap option

Example output:
> kubectl top node --show-swap
NAME     CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)   SWAP(bytes)   SWAP(%)
node01   500m         8%       2836Mi          60%         0Mi           0%
node02   260m         5%       2206Mi          47%         512Mi         50%

Signed-off-by: Itamar Holder <iholder@redhat.com>

* kubectl top pod: add the --show-swap option

Example output:
> kubectl top pod -n kube-system --show-swap
NAME                                      CPU(cores)   MEMORY(bytes)   SWAP(bytes)
coredns-58d5bc5cdb-5nbk4                  2m           19Mi            0Mi
coredns-58d5bc5cdb-jsh26                  3m           37Mi            0Mi
etcd-node01                               51m          143Mi           0Mi
kube-apiserver-node01                     98m          824Mi           0Mi
kube-controller-manager-node01            20m          135Mi           0Mi
kube-proxy-ffgs2                          1m           24Mi            0Mi
kube-proxy-fhvwx                          1m           39Mi            0Mi
kube-scheduler-node01                     13m          69Mi            0Mi
metrics-server-8598789fdb-d2kcj           5m           26Mi            0Mi

Signed-off-by: Itamar Holder <iholder@redhat.com>

* kubectl top node --show-swap: add unit tests

Signed-off-by: Itamar Holder <iholder@redhat.com>

* kubectl top pod --show-swap: Add unit tests

Signed-off-by: Itamar Holder <iholder@redhat.com>

* Explicitly mark swap as unavailable when necessary

Signed-off-by: Itamar Holder <iholder@redhat.com>

---------

Signed-off-by: Itamar Holder <iholder@redhat.com>

Kubernetes-commit: 8d3fb9ee0a51b6a6ea135d991391c35806422c19
2025-06-04 17:10:38 +03:00
Kubernetes Publisher 49afb3c466 Merge pull request #132055 from soltysh/default_prefs_tests
kuberc: add tests for DefaultGetPreferences

Kubernetes-commit: e9b3d62c9aa2c25d745fdf56a7ce5b29ff72973d
2025-06-03 20:43:23 +00:00
Maciej Szulik 17c0dde6b1 kuberc: add tests for DefaultGetPreferences
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 68efb079aabd3295ff4ee5cc56c89ff266e9224d
2025-06-02 16:47:02 +02:00
Kubernetes Publisher bc4c094b08 Merge pull request #131984 from soltysh/update_sigcli_security
Update security contacts for sig-cli owned repos

Kubernetes-commit: cefa8311bca466462734d9c1a24e549e7f94ba19
2025-05-28 18:35:03 +00:00
Kubernetes Publisher 800afb48a7 Merge pull request #131951 from dims/drop-usages-of-deprecated-otelgrpc-methods
Drop usages of deprecated otelgrpc methods (update to v0.60.0)

Kubernetes-commit: d9c1b4ec9b3df7f09dc23a0cc2b3daf2506d3688
2025-05-27 18:46:20 +00:00
Maciej Szulik 2375a3a9f6 Update security contacts for sig-cli owned repos
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 4e3634bbbfb2e416d991075a2a99ab92b0e3da19
2025-05-27 16:51:51 +02:00
Kubernetes Publisher 18f24e791d Merge pull request #131964 from skitt/kubectl-pkg-errors
kubectl: drop dependency on github.com/pkg/errors

Kubernetes-commit: 4c2a741aacc6eea0ae1b0b345034434f9473f52b
2025-05-26 23:12:30 +00:00
Kubernetes Publisher 9c13527bac Merge pull request #131962 from superbrothers/kubectl-explain-revert-output-shorthand
Revert shorthand for kubectl explain --output

Kubernetes-commit: b2dfba4151b859c31a27fe31f8703f9b2b758270
2025-05-26 18:33:18 +00:00
Kubernetes Publisher 17bb82b84d Merge pull request #131818 from soltysh/kuberc_beta
Promote kuberc to beta

Kubernetes-commit: fe5b9896ae8601b044a4e47901a844c93070df3b
2025-05-26 14:50:31 +00:00
Stephen Kitt abe43f6e92 kubectl: drop dependency on github.com/pkg/errors
The package is unmaintained, and kubectl doesn't rely on the
functionality it provides on top of Golang errors (stack traces).

Signed-off-by: Stephen Kitt <skitt@redhat.com>

Kubernetes-commit: 54b2fad0330032ae1bbac990f93a3644aa8a12af
2025-05-26 10:44:46 +02:00
Kazuki Suda bb9c5182ea Revert shorthand for kubectl explain --output
Kubernetes-commit: df2857e7777f18c482359cfb43a72a3cdfd89646
2025-05-26 12:16:24 +09:00
Davanum Srinivas 4ee16d2b51 Drop usages of deprecated otelgrpc methods
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 7c0f968ab256486b524ea37014ccf580b12c73e4
2025-05-23 19:40:36 -07:00
Maciej Szulik 46d6f63709 kuberc: make update and update-vendor
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 76f95271a5d563ea31edbcd8f0e8eebf67cb3634
2025-05-15 14:15:20 +02:00
Maciej Szulik 8500d2979d kuberc: introduce fuzzing for kuberc types
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: c29accaf5819bd4b05409cecb9bbb3ba065d840b
2025-05-16 13:45:37 +02:00
Arda Güçlü ca5a831a47 Promote kuberc to beta
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: b0370c483af1bdbc1e2664f53445411c585c4559
2025-05-06 12:52:20 +03:00
Maciej Szulik b011cffff8 kuberc: pick the first known version when decoding + tests
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 1f355e5b44141be55da269a9183d53bbccd16c95
2025-05-15 16:24:43 +02:00
Maciej Szulik cb7efba696 kuberc: align internal and v1alpha1 go-types with v1beta1
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 0341b27c5d0dfb1d10818c9976f54af22971bedc
2025-05-21 13:32:37 +02:00
Maciej Szulik 2be4847754 kuberc: add v1beta1 types
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 39195f9a463cce6b3ce4e3d9f648c2915407596d
2025-05-15 14:14:59 +02:00
Kubernetes Publisher 6096dfa3cf Merge pull request #131741 from soltysh/deprecate_preferences
Deprecate kubeconfig's preference field in favor of kuberc

Kubernetes-commit: c40db09a0a2bf8df02be93d7da1912cfa7cbe333
2025-05-20 16:37:25 +00:00
Kubernetes Publisher 279ddf3abe Merge pull request #131838 from dims/bump-google.golang.org/grpc-to-google-v1.72.1
Bump google.golang.org/grpc to google v1.72.1

Kubernetes-commit: 444e2b4eb079727d7cdd81ad25041502656370b8
2025-05-20 16:37:21 +00:00
Omer Aplatony 5ff92a69e3 Kubectl: check version skew (#127365)
Signed-off-by: Omer Aplatony <omerap12@gmail.com>

Kubernetes-commit: 35307319740a3a52cf4632c24b7f99d675537bdf
2025-05-19 20:19:14 +03:00
Davanum Srinivas 777f5e3cd1 Bump google.golang.org/grpc v1.72.1
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 9b3830fba234bc4a4f09a1ad4417e4d18b74d6dc
2025-05-18 12:52:05 -04:00
Kubernetes Publisher 4afda566a9 Merge pull request #128419 from liggitt/etcd-3.6
etcd 3.6 client update

Kubernetes-commit: 09ca440a450e9103a8f835f598c09237dba6ecbb
2025-05-16 04:42:29 +00:00
Jordan Liggitt c37ca76b9c bump etcd client to 3.6
hack/pin-dependency.sh go.etcd.io/etcd/api/v3 v3.6.0
hack/pin-dependency.sh go.etcd.io/etcd/client/pkg/v3 v3.6.0
hack/pin-dependency.sh go.etcd.io/etcd/client/v3 v3.6.0
hack/pin-dependency.sh go.etcd.io/etcd/pkg/v3 v3.6.0
hack/pin-dependency.sh go.etcd.io/etcd/server/v3 v3.6.0

hack/pin-dependency.sh github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0

hack/update-vendor.sh

Kubernetes-commit: cf0bbf1171e918d5d7ba1d3c83b5f347fc8333b0
2025-05-15 21:19:11 -04:00
Maciej Szulik 47f13bd18b Deprecate kubeconfig's preference field in favor of kuberc
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 8cf5e8db78deb186ef362f64ab779c09e9520156
2025-05-13 13:39:13 +02:00
Kubernetes Publisher 88bb12ba04 Merge pull request #131672 from soltysh/kubectl_featuregate_cleanup
Kubectl FeatureGate cleanups

Kubernetes-commit: 8812a3dc3ed1cbd3c7dc38b8027e014672cf1fb1
2025-05-08 13:21:14 -07:00
Maciej Szulik 52ec1da081 Add comment describing the feature gate with a link to KEP
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 9e3a1b0a9081ab49bbc44c415525dce862eb6a12
2025-05-08 14:43:24 +02:00
Maciej Szulik 307936eb9d Swap KUBECTL_COMMAND_HEADERS to use the proper feature gate mechanism
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: e3f3da5e795960508089aed08fe7fd9bec0a6db2
2025-05-08 14:09:17 +02:00
Maciej Szulik 90ee929b88 Drop KUBECTL_ENABLE_CMD_SHADOW featgure gat entirely
https://kep.k8s.io/3638 has been promoted to stable back in 1.32 so now
is the right time to drop this feature gate entirely.

Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: d1b5f268b48eda4bb8acdeef52407c27add9e076
2025-05-08 14:05:19 +02:00
Kubernetes Publisher 105c831190 Merge pull request #131668 from soltysh/command_creation_logging
Manually read verbosity before kubectl command construction

Kubernetes-commit: 4e30b51ebcdc24a65a0a5edfde0b9706c95d43d0
2025-05-08 20:24:14 +00:00
Maciej Szulik d35aa2c630 Manually read verbosity before kubectl command construction
kubectl command construction is slowly getting more functionality which
sometimes requires to log certain actions. Currently we parse the
verbosity only when actually running the command, so all of construction
code is not able to use -v=5. This commit adds the manual parsing and
loglevel setting berore we even start creating the kubectl command.

Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 69682b75e508462e01f865a156f2171233b653d1
2025-05-08 13:29:11 +02:00
Kubernetes Publisher f4a8c5b53e Merge pull request #131620 from ardaguclu/drop-custom-profile-feature
Drop KUBECTL_DEBUG_CUSTOM_PROFILE feature gate entirely

Kubernetes-commit: 8b00a96b51e82075be9770282c9c82507d8abf38
2025-05-07 16:19:08 +00:00
Arda Güçlü 5bcd2add11 Drop KUBECTL_DEBUG_CUSTOM_PROFILE feature gate entirely
Kubernetes-commit: 94d043b149b845a4f02f12a3d318df278194d377
2025-05-06 13:00:14 +03:00
Kubernetes Publisher bb3c0d9f3a Merge pull request #131586 from ardaguclu/kuberc-completion
Continue alias creation when __completion is used to enable completion

Kubernetes-commit: 893486dfd16ff8c628c6f33bb2bea869ad86115f
2025-05-05 08:19:24 +00:00
Kubernetes Publisher 3323e167c5 Merge pull request #131595 from aojea/utils_fake_clock
update k8s.io/utils to bring fakeClock.Waiters()

Kubernetes-commit: e3e1f80c0110c847acf4381b1790c1c667395010
2025-05-03 04:20:15 +00:00
Antonio Ojea 3013d81bdf update k8s.io/utils to bring fakeClock.Waiters()
Change-Id: I7e25338df225c2c27457403fbc2f158d08638f87

Kubernetes-commit: c2c003a71fc52fa79c2fff0109afad58573d0216
2025-05-02 11:21:11 +00:00
Kubernetes Publisher 38e8d36c38 Merge pull request #130989 from liggitt/creationTimestamp-omitzero
Omit null creationTimestamp

Kubernetes-commit: 01899a7c86337b05a16a4155c9351cf947beaee9
2025-05-03 00:24:11 +00:00
Arda Güçlü b0f5f0c0aa Continue alias creation when __completion is used to enable completion
Kubernetes-commit: f6d0498017fc71c72891ad9455c4391aa63c6e71
2025-05-02 13:23:22 +03:00
Harald Nordgren 65d852d39c improve display format
Kubernetes-commit: 28e7acf0f93f5c9edb43ab09cd181e8847409215
2025-04-27 20:35:38 +02:00
Harald Nordgren 7ec7bb7cc1 kubectl: sort configmaps alphabetically to avoid random order
Kubernetes-commit: f30c23a7831a25266a56b9b2990fa1ca19b48ad5
2025-04-27 15:36:09 +02:00
Jordan Liggitt 722397942b Drop null creationTimestamp from test fixtures
Kubernetes-commit: 6bb6c9934294d8265197c9dfc4c9dd3adaca147a
2025-03-24 09:37:26 -04:00
Jordan Liggitt 0cdb311ed6 bump cbor to add omitzero support
Kubernetes-commit: bc6051717137cef288b82305588e675de4a32c0d
2025-03-25 12:27:43 -04:00
Jordan Liggitt 4d172bd365 bump structured-merge-diff to add omitzero support
Kubernetes-commit: 06b0784062f68566daa8eed83c475b738dcf620c
2025-03-24 16:34:01 -04:00
Kubernetes Publisher 285ed6ce48 Merge pull request #131491 from tchap/kubectl-service-describe-trafficdistribution
kubectl describe service: Add Traffic Distribution

Kubernetes-commit: a19c0ad5533d1503825f22a3725de07cb81fced1
2025-04-28 12:05:03 +00:00
Ondra Kupka 4627533853 kubectl describe service: Add Traffic Distribution
Kubernetes-commit: ad40bc88568bdb19fdba0b960755bd014b2ae5e5
2025-04-26 18:02:19 +02:00
Rodrey ae92d5f0bd Add more test cases to TestDescribeSecret test (#131422)
* Converted to parameterised tests.

* Added test case for sorting with casing.

* Formatted code.

* Added test case for keys that contain numbers.

Kubernetes-commit: 74e84dbf5a339a3830ddd172fe8767ca0952cbb8
2025-04-24 20:10:05 +00:00
Kubernetes Publisher 3a0b77ee9b Merge pull request #131097 from ardaguclu/increase-cp-timeout
Increase kubectl cp command timeout to 30 seconds

Kubernetes-commit: 8237bc5035c7cdec4df561f56e9e68a4c26024f0
2025-04-24 00:26:44 +00:00
Kubernetes Publisher 9301b2a1f6 Merge pull request #130995 from xigang/utils
bump k8s.io/utils for improvements

Kubernetes-commit: 43a7d3be12425cc80ca6ad3599809a19728c5566
2025-04-24 00:26:43 +00:00
Kubernetes Publisher d40094d4e4 Merge pull request #130987 from arthurbdiniz/kubectl-diff-testing-language-env
Set LANGUAGE env variable in TestDiffProgram for consistent locale be…

Kubernetes-commit: da7f3cef166af40644ed9265d7a6a9d7a7e842d3
2025-04-24 00:26:42 +00:00
Taha Farahani 46f95a7c68 Unhandled panic crash on rollout_history printer.PrintObj (#130503)
* Change: Handling nil runtime.Object

Signed-off-by: Taha Farahani <tahacodes@proton.me>

* Change: Return only if there is error in rollout_history

Signed-off-by: Taha Farahani <tahacodes@proton.me>

* Change: Return the unknown revision error directly in rollout_history.go

Signed-off-by: Taha Farahani <tahacodes@proton.me>

* Change: Remove unintended newline

Signed-off-by: Taha Farahani <tahacodes@proton.me>

* Change: Using go idiomatic way for checking if historyInfo[o.Revision] exists

Signed-off-by: Taha Farahani <tahacodes@proton.me>

* Change: Remove 'error:' from returned error message in rollout_history.go

Signed-off-by: Taha Farahani <tahacodes@proton.me>

* Change: Check for printer.PrintObj returned err

Signed-off-by: Taha Farahani <tahacodes@proton.me>

* Change: Add TestRolloutHistoryErrors test

Signed-off-by: Taha Farahani <tahacodes@proton.me>

* Change: Simple typo fix on Complete() function description

Signed-off-by: Taha Farahani <tahacodes@proton.me>

* Change: Checking for error on o.Complete in TestRolloutHistoryErrors

Signed-off-by: Taha Farahani <tahacodes@proton.me>

---------

Signed-off-by: Taha Farahani <tahacodes@proton.me>

Kubernetes-commit: 609e4a9ba044e64a6244e053d2b1b7c545a2d2ed
2025-04-24 00:01:14 +03:30
Kubernetes Publisher b2ed890887 Merge pull request #130309 from HaraldNordgren/sort_secrets
kubectl: sort secrets alphabetically to avoid random order

Kubernetes-commit: 0130ac1422cf7e4af9d1ffd6c5fae24fe3eb320b
2025-04-24 00:26:40 +00:00
Kubernetes Publisher 265eadfda5 Merge pull request #127183 from mochizuki875/add_attach_warning
Add warning message for attach

Kubernetes-commit: d63a52a007da693cb40d2cfaef4f738cee104ab1
2025-04-24 00:26:39 +00:00
Harald Nordgren 6c0aa1995f pr fix
Kubernetes-commit: 4e3026fdb81667fd5a9fe928736b6e4d67b225e5
2025-04-14 15:59:45 +02:00
Kubernetes Publisher 72b3a7e9b0 Merge pull request #131204 from dims/move-to-released-version-of-prometheus/client_golang-v1.22.0-from-rc.0
Move to released version of prometheus/client_golang v1.22.0 from rc.0

Kubernetes-commit: 92af6ab6926f192a3d4543a1d6fa39f20edad3ea
2025-04-08 23:34:14 +00:00
Davanum Srinivas 2e566591a6 Move to released version of prometheus/client_golang v1.22.0 from rc.0
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 2ef4a8426c2c1b6e3495de08c4686382a752f8f7
2025-04-08 08:35:18 -04:00
Kubernetes Publisher fec9d5b3d5 Merge pull request #131103 from ahrtr/etcd_sdk_20250328
Bump etcd 3.5.21 sdk

Kubernetes-commit: f4d1686120d2367dd4c00df53e93dad51c414435
2025-04-01 11:49:33 +00:00
Benjamin Wang dc53668bca bump etcd 3.5.21 sdk
Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>

Kubernetes-commit: f3b80a858225178e3f7a3ae07bd1b9894e7b3456
2025-03-28 14:30:47 +00:00
Arda Güçlü 399c585899 Increase kubectl cp command timeout to 30 seconds
Kubernetes-commit: 9c228e81d2481150878ca3a431f0ec9a8f150b3f
2025-03-28 12:39:01 +03:00
xigang ece3c8c1d0 bump k8s.io/utils
Kubernetes-commit: fe14689f221a968806b771b226581efb834654cd
2025-03-22 10:14:01 +08:00
Arthur Diniz 5b96de1a99 Set LANGUAGE env variable in TestDiffProgram for consistent locale behavior
Signed-off-by: Arthur Diniz <arthurbdiniz@gmail.com>

Kubernetes-commit: bad6c7e4cc5aef010c2fe2abfcbe51a138a04700
2025-03-21 17:28:41 +00:00
Kubernetes Publisher 5366de04e1 Merge pull request #129872 from seans3/websocket-https-proxy
WebSocket HTTPS Proxy support

Kubernetes-commit: 6f13ba03dac1865174b4edf2b43f6a0f453a8ac7
2025-03-21 09:25:21 +00:00
Kubernetes Publisher 7577f36fbc Merge pull request #130880 from tallclair/ippr-allocatable
[FG:InPlacePodVerticalScaling] Add back `AllocatedResources` and use it for scheduling

Kubernetes-commit: e87e840413aeb3e8ed899965480b3d86b49e4819
2025-03-20 06:23:20 +00:00
Tim Allclair f38b1de6c2 Consider AllocatableResources when computing pod requests
Kubernetes-commit: c2927727107cc8123c2688ea571f464650df6b2b
2025-03-17 21:23:32 -07:00
Kubernetes Publisher 0d5516dcdc Merge pull request #130033 from ardaguclu/completion-use-restclientgetter
Add completion in kubectl debug

Kubernetes-commit: 990b02bf3952a14249fe74add831a5bb02576995
2025-03-19 18:17:17 +00:00
Keita Mochizuki 5cbdedb625 kubectl debug: Display a warning message that the debug container's capabilities may not work with a non-root user (#127696)
* Add warning message about capabilities of debug container

* fix1

* fix2

* fix3

Kubernetes-commit: 07a275437f304456b2a32159ec6550a71d020a64
2025-03-19 10:15:57 +00:00
Kubernetes Publisher 6203603c4a Merge pull request #130906 from serathius/streaming-validation
Update kube-openapi and integrate streaming tags validation

Kubernetes-commit: 32b1819423de505da855cf7544e871a04e63d6ed
2025-03-19 06:29:44 +00:00
Marek Siarkowicz f97d1f5267 Update kube-openapi and integrate streaming tags validation
Kubernetes-commit: 75a4d136abac241f728407515e3d0d8305594675
2025-03-18 21:26:22 +01:00
Kubernetes Publisher 90ba96e4f3 Merge pull request #130733 from natasha41575/pod-resize-conditions
[FG:InPlacePodVerticalScaling] Move pod resize status to pod conditions

Kubernetes-commit: 473ec01548c81fc356308448dd47923d0f234612
2025-03-18 02:15:39 +00:00
Natasha Sarkar ed22800c0c Move pod resize status to pod conditions
Kubernetes-commit: a15520fbeaf458e2fc0f2be6e1ae0f9572369495
2025-03-17 22:01:05 +00:00
Kubernetes Publisher 920f676703 Merge pull request #130862 from icylord/kubectl
kubectl: Remove duplicate selector calculation logic and add missing test cases for the 'describe DaemonSet'

Kubernetes-commit: e950e517ed2547d4b870b7719fdda096373513ab
2025-03-17 22:16:12 +00:00
icylord 88b66ece35 kubectl: Remove duplicate selector calculation logic and add missing test cases for the 'describe DaemonSet' functionality
Kubernetes-commit: 3e48d143fa9d31bd690165109c79b413c67d5966
2025-03-15 17:07:44 +08:00
Kubernetes Publisher 5e1a193aef Merge pull request #130747 from soltysh/exec_context
kubectl: expose context parameter in DefaultRemoteExecutor

Kubernetes-commit: 6c3332e87071083afa234354516e720198840322
2025-03-12 22:16:32 +00:00
Maciej Szulik e4ccb76c1a kubectl: expose context parameter in DefaultRemoteExecutor
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 78e58b8c49fdcddba8cf939e5327440791c73a91
2025-03-12 15:51:13 +01:00
Kubernetes Publisher 277c37ab57 Merge pull request #130555 from thockin/k_k_randfill
Use randfill in k/k

Kubernetes-commit: 0f2bde7745f3b4eadcf317bc5056dfeb96859bd3
2025-03-09 14:32:21 +00:00
Tim Hockin 2bbe460b18 Vendor randfill
Kubernetes-commit: 0ce4268b1fe4f78d77249e329b0349b9d2dd2c65
2025-03-03 23:46:48 -08:00
Kubernetes Publisher f630fabade Merge pull request #130569 from dims/update-to-latest-cadvisor-v0.52.0
Update to latest cadvisor @ v0.52.1 and new opencontainer/cgroups and drops opencontainers/runc

Kubernetes-commit: 0eaee48ecb8669dc65bfdf9a3583326ab88fc39d
2025-03-08 02:29:24 +00:00
Davanum Srinivas a108757aa8 update to v1.22.0-rc.0
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 97a54dc4b04b7d2938d11c5ae9a6233348e854ef
2025-03-07 13:45:34 -05:00
Davanum Srinivas 8c173253d9 update to latest cadvisor @ v0.52.0
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 5ecddb65715af7e2afc4f3cbb1abe393bfb4346a
2025-03-04 14:29:08 -05:00
Kubernetes Publisher deef152435 Merge pull request #130349 from jpbetz/validation-gen-pr1
KEP-5073: Declarative Validation: Add validation generator

Kubernetes-commit: a5dda5d879cdae6562134ca7881ddf7f672f595d
2025-03-03 23:05:27 +00:00
Joe Betz cfdaf20447 Bump gengo/v2 to latest
Co-authored-by: Tim Hockin <thockin@google.com>
Co-authored-by: Aaron Prindle <aprindle@google.com>
Co-authored-by: Yongrui Lin <yongrlin@google.com>
# Conflicts:
#	vendor/modules.txt

Kubernetes-commit: 7f5e1baeeea7382e45cfba7676b69459fbce8b12
2025-03-03 09:49:50 -05:00
Kubernetes Publisher 8883001c90 Merge pull request #128919 from dashpole/update_otel
Update go.opentelemetry.io dependencies to v1.33.0/v0.58.0

Kubernetes-commit: eea2f78e61fe91bb8fcd3c4a357ea3a10d1389db
2025-03-02 00:57:26 +00:00
David Ashpole 24bba46b9d update go.opentelemetry.io dependencies to v1.33.0/v0.58.0
Kubernetes-commit: 29c219dcebe30be99d6917623f8d8707a47194c1
2025-03-01 19:17:16 +00:00
Kubernetes Publisher cab51f793f Merge pull request #130474 from dims/bump-x/crypto-and-x/oauth2
Bump x/oauth2 and x/crypto

Kubernetes-commit: 01ed8ed4ff0a0cbea99370c7a268019829d19e82
2025-02-28 21:00:52 +00:00
Kubernetes Publisher a9d88dcafc Merge pull request #129688 from cpanato/update-main-go124
[go] Bump images, dependencies and versions to go 1.24.0

Kubernetes-commit: b8c95e1954ef222988c0dfe5b45d5cc96c09bcb8
2025-02-27 21:03:20 +00:00
Davanum Srinivas 561b18e2ed Bump x/oauth2 and x/crypto
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 0fede7b8a2fb4c7f120876c9ef1e826f8ef28da2
2025-02-27 10:59:37 -05:00
cpanato 594231109f bump go.mod to set min go1.24
Signed-off-by: cpanato <ctadeu@gmail.com>

Kubernetes-commit: 88300c406b9199ed017e1bada29951fc18e66ae1
2025-02-25 13:21:52 +01:00
Kubernetes Publisher 1fe7110fa9 Merge pull request #130187 from mansikulkarni96/129084
fix:  Sweep and fix stat, lstat, evalsymlink usage for go1.23 on Windows

Kubernetes-commit: ef54ac803b712137871c1a1f8d635d50e69ffa6c
2025-02-23 00:42:24 +00:00
Harald Nordgren 3a69c59961 kubectl: sort secrets alphabetically to avoid random order
Kubernetes-commit: 7d6f86594fc0a7d09710c643de63b24cdcb98e65
2025-02-20 13:28:55 +01:00
Arda Güçlü 246e544fc4 Add completion in kubectl debug
Kubernetes-commit: 533a1211d30b42c4cb485468562e7712dc7f83c7
2025-02-07 13:44:21 +03:00
Jordan Liggitt ef54a58dd7 Drop winsymlink go 1.23 workaround
(cherry picked from commit 3990b6324d0427eaf9ff970da2be02711567ef5f)

Kubernetes-commit: 1f642c79c3192994e76bbe8e7360fd661cd21ab4
2025-02-06 12:45:52 -05:00
Kubernetes Publisher 71aa003817 Merge pull request #130298 from thockin/max_of_of
Fix dup word in API doc

Kubernetes-commit: f67b34612977b6efa7b8e7f37ef058ccef722373
2025-02-21 00:31:06 +00:00
Tim Hockin 4ccb6a52b9 Fix dup word in API doc
Kubernetes-commit: ec66befdcb2c2cf906e5321378ffd8edcccaeae6
2025-02-19 16:51:11 -08:00
Kubernetes Publisher 480491c908 Merge pull request #130249 from seans3/bump-websockets-version
Update gorilla/websockets library from 1.5.0 to latest 1.5.3

Kubernetes-commit: 728dc0d8c7a4d68157b2106330b65abcd5faac87
2025-02-19 04:47:21 +00:00
Kubernetes Publisher f6d73c948b Merge pull request #130238 from soltysh/subresource_stable
Update kubetl subresource to stable

Kubernetes-commit: 717d9f13f355539f2e8b58331e050e3155973db6
2025-02-19 04:47:20 +00:00
Sean Sullivan f1e93ac324 Update gorilla/websockets library from 1.5.0 to latest 1.5.3
Kubernetes-commit: 3100bbab2f7f013b08910f28d8a3debc28a57ea9
2025-02-19 00:26:21 +00:00
Maciej Szulik 7f2f474232 Update kubetl subresource to stable
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: de984ec9b92bcf6ff17060b1cdecdd8fd948bcbb
2025-02-18 14:28:59 +01:00
Arda Güçlü 2e38fc2204 Introduce kuberc as new flag to customize defaulting and define aliases in kubectl (#125230)
Kubernetes-commit: c7a90b670c40a315bea3667921302675008bc39c
2025-02-12 00:39:09 +00:00
Kubernetes Publisher 2fd8e3617a Merge pull request #128367 from vivzbansal/sidecar-2
[FG:InPlacePodVerticalScaling] Implement resize for sidecar containers

Kubernetes-commit: 0634e21fb525743e68d677c53753b43a8b7471bc
2025-02-06 01:32:49 +00:00
Sean Sullivan 313e838cfa Websocket HTTPS proxy support
Kubernetes-commit: f73945aae56b51078318199ff2f0ecae91bc489e
2025-01-29 03:56:55 +00:00
vivzbansal 79fb20cb8b Resolved latest review comments
Kubernetes-commit: 5889da1bbc7a3e515bf6e3d5ca35d600020ff046
2024-12-17 07:56:13 +00:00
Kubernetes Publisher 316ed014ab Merge pull request #129784 from soltysh/refactor_explain
Refactors explain command to split flags from options

Kubernetes-commit: f6f06806cc43ed9f7eb2f68368c90a8239884118
2025-01-24 09:08:18 +00:00
Maciej Szulik d74f0e1af1 Switch from using a function to just pure map in create token
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 87139335b0e6ce5f5bc08d860a870fb9f16392b2
2025-01-23 13:10:06 +01:00
Maciej Szulik 1ab40ed1c8 Finish extracting ExplainFlags structure
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 3030b1dc6a445929c20dc911196746c2d8af2bac
2025-01-23 13:09:19 +01:00
mochizuki875 81562142de Add warning message for attach
Kubernetes-commit: 97dd6dc284682d76fe7e0bc51df851473deee24f
2024-09-06 02:31:14 +00:00
PuneetPunamiya bcafb59748 Refactors explain command to split flags from options
Signed-off-by: Puneet Punamiya ppunamiy@redhat.com
Signed-off-by: Maciej Szulik <soltysh@gmail.com>

Kubernetes-commit: 91afef615ad918cfc364bf5e6d12a96785f2acaf
2022-10-20 12:48:15 +05:30
Kubernetes Publisher 8af785f4be Merge pull request #128971 from aojea/servicecidr_ga
KEP-1880 Multiple Service CIDRs: Graduate to GA

Kubernetes-commit: 45d0fddaf1f24f7b559eb936308ce2aeb9871850
2025-01-22 21:59:57 +00:00
Antonio Ojea 064a840924 describe servicecidr and ipaddress v1
Kubernetes-commit: e3b39758215f152fe59e94b86d1c6db3320103f5
2024-11-26 03:35:16 +00:00
Kubernetes Publisher 7346aee2d4 Merge pull request #129633 from skitt/revert-go-difflib-go-spew
Revert to go-difflib and go-spew releases

Kubernetes-commit: 6d570c923f66a1f214d0c3ba3eddd9a0cd0fae68
2025-01-15 21:23:05 +00:00
Stephen Kitt d384e79d1a Revert to go-difflib and go-spew releases
The last dependency pulling in the tips of go-difflib and go-spew has
reverted to the last release of both projects, so k/k can revert to
the releases too. As can be seen from the contents of vendor, this
doesn't result in any actual change in the code.

Signed-off-by: Stephen Kitt <skitt@redhat.com>

Kubernetes-commit: 3986472b3c7202716f92e586ccfaa4b4fe573dc5
2025-01-15 09:07:27 +01:00
Kubernetes Publisher 7d49790b11 Merge pull request #129622 from dims/update-to-latest-kustomize-v5.6.0
Update to latest kustomize v5.6.0 to drop `github.com/asaskevich/govalidator`

Kubernetes-commit: 42811635adc4840a6769d7a9f7fd47be8df99c43
2025-01-15 01:11:12 +00:00
Davanum Srinivas 7f667b45ca Update to latest kustomize/v5.6.0
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 0d8a8fe3065d6bbff623eeb70dc86b6085fd4c3c
2025-01-14 13:10:47 -05:00
Kubernetes Publisher cee2a595e4 Merge pull request #129349 from dims/bump-x/net-to-v0.33.0
Bump x/net to v0.33.0

Kubernetes-commit: b7ef173c59065f9a5f68eb514ef0483c6f3887ae
2025-01-06 21:18:31 +00:00
gshaibi 3e68cbc2c4 [kubectl] Enhance describe output for projected volume sources to indicate optional Secret/ConfigMap (#129457)
* kubectl: enhance output for projected volume sources to indicate optional secrets

* .

Kubernetes-commit: 4114a9b4e45a4df96f0383d87b2649640a6ffbf1
2025-01-06 15:50:16 +02:00
Kubernetes Publisher 6990be915a Merge pull request #128872 from alvaroaleman/generics
Use generic btree in watchcache

Kubernetes-commit: 8f8c94a04d00e59d286fe4387197bc62c6a4f374
2025-01-03 17:17:34 +00:00
Alvaro Aleman 1613733931 Update github.com/google/btree
Kubernetes-commit: a97ed3c98bcd2c520260aa04c516a24e975e7d69
2025-01-02 19:44:07 -05:00
lixiv be364695f5 Add tests for kubectl qos (#129388)
* Add tests for kubectl qos

* Update staging/src/k8s.io/kubectl/pkg/util/qos/qos_test.go

Co-authored-by: Arda Güçlü <aguclu@redhat.com>

---------

Co-authored-by: Arda Güçlü <aguclu@redhat.com>

Kubernetes-commit: 215d0b094b686ae0ad83a8f2d3078e5860a979ba
2024-12-30 09:06:10 +00:00
Davanum Srinivas ddd9a046e7 Bump x/net to v0.33.0
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 0b6e3718340fa7e3846cf9b7d5a0f7a684a6fa5a
2024-12-20 14:30:57 -05:00
Kubernetes Publisher a8a00dbee1 Merge pull request #128950 from googs1025/feature/kubectl/autoscalev2
feature(kubectl): use autoscalingv2 in kubectl autoscale

Kubernetes-commit: fc53d1b297e8b393855b06b993f1e712a24883b7
2024-12-18 18:38:55 +00:00
Omer Aplatony 120105a0a9 kubectl: add test coverage for cordon command (#129202)
* kubectl: add test coverage for cordon command

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

* using cmp.Diff

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

---------

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

Kubernetes-commit: 3ec97a445f036a38bfec6291dee661954138bac9
2024-12-17 06:34:43 +00:00
Kubernetes Publisher 088003e485 Merge pull request #129213 from Jefftree/k-openapi
Bump kube-openapi

Kubernetes-commit: 13eb074ddd231d127709f0410185eeca68a69c8a
2024-12-14 02:45:48 +00:00
Jefftree 816d854fc8 bump kube-openapi
Kubernetes-commit: 3269f4bb94c58dfe577621c42f88ea06fbdd79a7
2024-12-13 20:50:49 +00:00
Kubernetes Publisher 1a5fd321ec Merge pull request #129195 from dims/update-x/crypto/ssh-dependency
Update x/crypto/ssh dependency to v0.31.0

Kubernetes-commit: b21ab179c74a270cd276d2dbb5f4b55730838096
2024-12-13 10:46:53 +00:00
Davanum Srinivas 575c21a9f0 Update x/crypto/ssh dependency
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 80735180ab2c61232dcc4646e693ddcaeaf96ca3
2024-12-12 20:46:15 -05:00
Kubernetes Publisher 94246703f3 Merge pull request #129054 from pohly/remove-import-name
remove import doc comments

Kubernetes-commit: e8615e27125518f0ed0ba06244b7ecee21451bb0
2024-12-12 10:41:15 +00:00
Kubernetes Publisher 74629f681a Merge pull request #129106 from rotsix/patch-1
docs: `-l/--selector` example for set-based requirements

Kubernetes-commit: d1b702b0b83b7c4ea8d06b2dbd9d33e337117b9d
2024-12-12 10:41:13 +00:00
Kubernetes Publisher 86048014d6 Merge pull request #128909 from ardaguclu/kubectl-set-generic
Use generic sets rather than deprecated sets.String

Kubernetes-commit: 5bfdd18f0b3a1820e2ca0242ef8668532c175fb7
2024-12-12 06:49:47 +00:00
Omer Aplatony 56c9d286fe kubectl: fix wait --for=create to work correctly with label selectors (#128662)
* kubectl: fix wait --for=create to work correctly with label selectors

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

* Add unit test

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

* add integration test

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

* Increase wait time to 40 seconds

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

---------

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

Kubernetes-commit: 0cc926220067cd814cecd8f3d0c3b9235e6a68db
2024-12-12 06:49:46 +00:00
alingse 92bb3cdeda fix: fix miss makezero bug (#125132)
* fix: fix miss makezero bug

Signed-off-by: alingse <alingse@foxmail.com>

* add testcase for new verb

* Update create_role_test.go

---------

Signed-off-by: alingse <alingse@foxmail.com>

Kubernetes-commit: 5b06498cb24ee68dbc2815a1d9fa505da3452d98
2024-12-12 10:56:37 +08:00
Kubernetes Publisher beeec3d7a0 Merge pull request #129103 from liggitt/drop-winreadlinkvolume
Drop use of winreadlinkvolume godebug option

Kubernetes-commit: bfe431b53e600c9a36c46eef0f6ecfcf37265d60
2024-12-06 20:00:07 +00:00
Victor Franzi 40fde549ca docs: `-l/--selector` example for set-based requirements
add an example of set-based requirement when using `-l/--selector` as it's a (less known) filtering capability: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#list-and-watch-filtering

Kubernetes-commit: 8f48a82e6ed9fd19601ad8c32a5f1b55b4299fb0
2024-12-06 12:03:48 +01:00
Jordan Liggitt ee2ac712ef Drop use of winreadlinkvolume godebug option
Kubernetes-commit: 3046fe23d4fe4ba86713ffd61bf0e07156b2b7c3
2024-12-06 02:40:53 -05:00
Kubernetes Publisher e26c49a5f9 Merge pull request #129083 from liggitt/go1.23windows
Revert to go1.22 windows filesystem stdlib behavior

Kubernetes-commit: 6fc64a261c1dca857a5a7fd1bc87fae38dbe1c8a
2024-12-04 23:19:21 +00:00
Jordan Liggitt 9f75b795dc Revert to go1.22 windows filesystem stdlib behavior
Kubernetes-commit: 3878a3a6de64660e356a35f70471c27a09698090
2024-12-04 09:52:56 -05:00
Patrick Ohly 348f12d905 remove import doc comments
The "// import <path>" comment has been superseded by Go modules.
We don't have to remove them, but doing so has some advantages:

- They are used inconsistently, which is confusing.
- We can then also remove the (currently broken) hack/update-vanity-imports.sh.
- Last but not least, it would be a first step towards avoiding the k8s.io domain.

This commit was generated with
   sed -i -e 's;^package \(.*\) // import.*;package \1;' $(git grep -l '^package.*// import' | grep -v 'vendor/')

Everything was included, except for
   package labels // import k8s.io/kubernetes/pkg/util/labels
because that package is marked as "read-only".

Kubernetes-commit: 8a908e0c0bd96a3455edf7e3b5f5af90564e65b0
2024-12-02 14:43:58 +01:00
Arda Güçlü 61dc2ecb38 Use generic Contains rather than deprecated ContainsString
Kubernetes-commit: 8312c3ec242faf30f3967e59465ca5a764a4ee85
2024-11-25 11:30:04 +03:00
googs1025 e2968fb8ad feature(kubectl): use autoscalingv2 in kubectl autoscale
Kubernetes-commit: a87dd67a3c89612828d613cd71828a906b4d7c3c
2024-11-23 21:43:29 +08:00
Arda Güçlü 608a0553d7 Use generic sets rather than deprecated sets.String
Kubernetes-commit: c3f15fd707a092e6cb7d96b84b81ada1f118d759
2024-11-21 13:22:39 +03:00
Kubernetes Publisher 169a952417 Merge pull request #128559 from lauralorenz/crashloopbackoff-refactorimagepullbackoff-e2enodecriproxytest
E2E Node tests for image pull backoff and crashloopbackoff behavior

Kubernetes-commit: 5ee686b6cfd1431dbde77873f64d9c2a90610745
2024-11-13 20:25:58 +00:00
Kubernetes Publisher d0bc9691f3 Merge pull request #128761 from ah8ad3/revert-126533
Revert PR #126533 and add a test case for broken case

Kubernetes-commit: af7581e8ec6839c0eb7405cdd95af3285434cdcb
2024-11-13 06:05:42 +00:00
Laura Lorenz 133d258d8e Use a better util
Signed-off-by: Laura Lorenz <lauralorenz@google.com>

Kubernetes-commit: 8e7b2af712a79db423b7bfdf2a7bf35f75542c13
2024-11-12 23:26:04 +00:00
Laura Lorenz 1811ebafa9 Clearer image pull test and utils
Signed-off-by: Laura Lorenz <lauralorenz@google.com>

Kubernetes-commit: 285d433dea79e6838cdd0648c36a2a82fd398179
2024-11-12 22:48:17 +00:00
ah8ad3 7ff7f80add Revert PR #126533 and add a test case for the case where there is yaml
structed texts in the description.
We should find a way to both relign line breaks and not break these kind
of texts.

Signed-off-by: ah8ad3 <ah8ad3@gmail.com>

Kubernetes-commit: 7580e6ac00b00cf6e7ba375a3730e0dccbf40463
2024-11-12 14:23:03 +03:30
Kubernetes Publisher 6e4fe32a45 Merge pull request #128407 from ndixita/pod-level-resources
[PodLevelResources] Pod Level Resources Feature Alpha

Kubernetes-commit: c25f5eefe4efda4c0d9561d06942cd3de3dfe2e4
2024-11-08 16:13:12 +00:00
ndixita 9a565d149e QOS changes for Pod Level resources
Kubernetes-commit: 26f11c458620751733250b35d1f60c9ed2a96e57
2024-10-30 01:24:36 +00:00
ndixita 1f9df3421a Adding support for pod level resources in kubectl
1. Add support for pod level resources in kubectl
2. Reuse the existing method to describe container resources and generalize it to describe both pod and container level resources

Kubernetes-commit: 502e0f55c43291af800e8633760d461343bd39b3
2024-10-24 21:13:54 +00:00
Omer Aplatony 2bb31e1a0f Replace PollImmediate with PollUntilContextTimeout (#128147)
* Replace PollImmediate with PollUntilContextTimeout

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

* Add context to RetryErrorCondition function

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

* lint: fix error comparison in scale package

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

* Fix RetryErrorCondition function signature

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

* revert to if err statement

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

---------

Signed-off-by: Omer Aplatony <omerap12@gmail.com>

Kubernetes-commit: 9d816f1587c918e7acae6d9195d33606aec998b1
2024-11-07 16:57:29 +02:00
Kubernetes Publisher 2cccb2df6a Merge pull request #124952 from AxeZhan/maxContainerRestarts
[Sidecar Containers] Pods comparison by maxContainerRestarts should account for sidecar containers

Kubernetes-commit: 9a9331afd60a4db3ffd8dc9bd38b788948308175
2024-11-08 16:13:08 +00:00
Kubernetes Publisher 4ced6667a4 Merge pull request #128593 from jpbetz/bump-cel-123
Introduce CEL two variable comprehensions

Kubernetes-commit: dc01fa9d2b6632dc932eb760573659608add1b8f
2024-11-07 04:01:54 +00:00
Joe Betz b7988e1775 hack/pin-dependency.sh github.com/google/cel-go v0.22.0
Kubernetes-commit: b0180a9a376caee4a12cbf549b3187d21cbdc07d
2024-11-05 19:21:09 -05:00
Kubernetes Publisher 2ebf801b89 Merge pull request #128296 from AnishShah/kubectl-resize
[FG:InPlacePodVerticalScaling] Remove restrictions on subresource flag in kubectl commands

Kubernetes-commit: f451aec23787c2b48489eea2377cd13dfa15bded
2024-11-06 11:56:50 +00:00
Anish Shah b22c40d47c kubectl: remove subresource restrictions from all commands
Removing this restrictions will allow us to use these commands with the
new resize subresource.

Kubernetes-commit: e1ca63489f2b788f893ab37a27242ce319e1eaf6
2024-10-31 16:00:52 -07:00
Kubernetes Publisher 4b9836ac7a Merge pull request #128377 from tallclair/allocated-status-2
[FG:InPlacePodVerticalScaling] Implement AllocatedResources status changes for Beta

Kubernetes-commit: f81a68f4888c9da87f856d17516fb810518a67c0
2024-11-06 03:55:35 +00:00
Kubernetes Publisher 913dcdf388 Merge pull request #128580 from jpbetz/bump-kube-openapi
Bump kube-openapi to latest

Kubernetes-commit: 9a2a7537f035969a68e432b4cc276dbce8ce1735
2024-11-06 00:01:11 +00:00
Kubernetes Publisher e91a2f1400 Merge pull request #126533 from ah8ad3/kubectl-explain-wrap
Realign line breaks in kubectl explain wrap method

Kubernetes-commit: 602c70b65d49e0687026064edb8601087da00bd2
2024-11-05 19:56:24 +00:00
Kubernetes Publisher 2fceb953a8 Merge pull request #128352 from omerap12/fix-empty-remote-port
port-forward: fixed error handling for empty remote port

Kubernetes-commit: 033b275d109a662119ac745262ef7a9b4607a0a8
2024-11-05 15:49:36 +00:00
Joe Betz dc24746c3a hack/pin-dependency.sh k8s.io/kube-openapi 32ad38e42d3faf1ce94eb29f4ea6d763339b258e
Kubernetes-commit: f2157ff73e3c9b7c2a36bf371e388e8976d93975
2024-11-05 10:18:57 -05:00
Kubernetes Publisher 6989e5df8d Merge pull request #128396 from ritazh/deprecate-EnforceMountableSecretsAnnotation
deprecate EnforceMountableSecretsAnnotation in 1.32

Kubernetes-commit: bc79d3ba87b8b3c4b7c68f26cdfcaa35654d96ac
2024-11-05 07:56:14 +00:00
Rita Zhang 739aca7b89 deprecate EnforceMountableSecretsAnnotation in 1.32
Signed-off-by: Rita Zhang <rita.z.zhang@gmail.com>

Kubernetes-commit: e7cdc595551954d6b87a859296eb09fddd01f3c9
2024-10-28 08:01:33 -07:00
Kubernetes Publisher 7ec5989b2d Merge pull request #128507 from dims/use-k8s.io/utils/lru-instead-of-github.com/golang/groupcache/lru
Use k8s.io/utils/lru instead of github.com/golang/groupcache/lru

Kubernetes-commit: 7a4d755644e83dfade7bbc4c240c204a9e54d9c0
2024-11-05 00:02:15 +00:00
Davanum Srinivas c5abf9ddc7 Use k8s.io/utils/lru instead of github.com/golang/groupcache/lru
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 2b0592ee77d0a0bb3017df042066ecb8c83d2fb3
2024-11-01 22:19:11 -04:00
Kubernetes Publisher a886863a93 Merge pull request #128494 from dims/drop-go-colortext-and-its-usage
Drop go-colortext and its usage

Kubernetes-commit: 6ae2d359ad2eed549f467016465d04fa4b222b7a
2024-11-04 15:50:43 +00:00
Kubernetes Publisher 4532c53760 Merge pull request #128470 from omerap12/autoscale-unit
kubectl: add test coverage for autoscale command

Kubernetes-commit: f4d05aad776f6439de578497bb5076b512f907ad
2024-11-04 11:50:30 +00:00
Kubernetes Publisher 3cd67e0222 Merge pull request #128481 from carlory/dependencies-ginkgo-gomega
dependencies: ginkgo v2.21.0, gomega v1.35.1

Kubernetes-commit: 88a997ac01cd8a386df9318d81b89257307f53fb
2024-11-01 20:01:53 +00:00
Davanum Srinivas 69f03b081e Drop go-colortext and its usage
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: d450b6e653a8dcf11f28822eadea379734b3f53d
2024-11-01 09:55:42 -04:00
carlory b67296a41b dependencies: ginkgo v2.21.0, gomega v1.35.1
Kubernetes-commit: 80b1a297865500891bd823005ace761becae5dbf
2024-11-01 11:35:24 +08:00
Kubernetes Publisher 3553001de4 Merge pull request #128416 from jpbetz/reset-filter
Add optional ResetFieldsFilterStrategy interface for storage

Kubernetes-commit: b831df733e5cf244331f61fffb0ba86787b27236
2024-11-01 05:41:11 +00:00
Joe Betz c7e911a6b5 hack/pin-dependency.sh sigs.k8s.io/structured-merge-diff/v4 v4.4.2
Kubernetes-commit: 6fe51403665f1b6e820226004817b92e3118cabc
2024-10-31 21:19:15 -04:00
Omer Aplatony bb485d40d9 kubectl: add test coverage for autoscale command
Signed-off-by: Omer Aplatony <omerap12@gmail.com>

Kubernetes-commit: 6cb17d85a550ce8237f8542a9e59fdd03973c7d6
2024-10-31 14:26:15 +02:00
Omer Aplatony dc6975b78c port-forward: fixed error handling for empty remote port
Signed-off-by: Omer Aplatony <omerap12@gmail.com>

Kubernetes-commit: c01a8a51af10811e182be896795168bbd561c7e9
2024-10-26 14:24:09 +03:00
Tim Allclair af49e676b2 Stop using status.AllocatedResources to aggregate resources
Kubernetes-commit: 81df1958196e04f04d038e5ec9e2025989a30b29
2024-10-25 21:18:19 -07:00
Kubernetes Publisher a499023358 Merge pull request #125314 from enj/enj/i/proto_for_core
Use protobuf for core clients

Kubernetes-commit: 7b7a7968d4c90c4430b1009546e13ce78bcde134
2024-10-24 18:55:48 +00:00
Monis Khan 1014b1d5f2 Fix tests that assume core clients use JSON
Signed-off-by: Monis Khan <mok@microsoft.com>

Kubernetes-commit: 6595fa40268bc8e7f46dcc28267e5e8b0b1ae493
2024-08-19 10:38:16 -04:00
Kubernetes Publisher 816c382177 Merge pull request #122818 from y1hao/fix-typo
Fix error in i18n package usage examples

Kubernetes-commit: e6659b60f88575d4c1037d0de41292aa3aba010f
2024-10-23 02:53:32 +00:00
Arda Güçlü 4c8c153513 Wire context to logs command and add interrupt handler (#127503)
* Wire context to logs command and add interrupt handler

* Move conditional outside of interrupt handler

Kubernetes-commit: 5826868586d501060a6151d04c511236b11a26d4
2024-10-22 21:49:06 +03:00
Arda Güçlü 484ede079f KEP-4292: Add e2e test for custom profile in kubectl debug (#127187)
* Remove KUBECTL_DEBUG_CUSTOM_PROFILE env var

* Add e2e test for custom profile in kubectl debug

* Keep feature flag until 1.33

* Update comment

* Simplify tests by relying on test framework functionality

* Rename import alias to better to pass verify-import-alias

Kubernetes-commit: 1caf9a150b794a7c4a17e63a54b902ec0b0be570
2024-10-22 21:48:59 +03:00
Kubernetes Publisher 73f8c2980c Merge pull request #128165 from liggitt/prune-self-require
Drop self-referencing replace directives

Kubernetes-commit: a8fc7ae761c19ab436cf513c9eed877f08961cf7
2024-10-18 05:25:58 +00:00
Jordan Liggitt 87fbd1d830 Drop self-referencing replace directives
Kubernetes-commit: 3be1109829d4b0921972bb8b5f66a4d179ff6255
2024-10-17 15:51:15 -04:00
Kubernetes Publisher f829c4b789 Merge pull request #128064 from dims/update-to-last-versions-of-some-very-infrequently-updated-repos
Update to last versions of some very infrequently updated repos

Kubernetes-commit: 07e73682b9a5259cacac978346ed4567588e4165
2024-10-16 06:55:24 +00:00
Kubernetes Publisher 1b29da9296 Merge pull request #128081 from soltysh/strict_spacing
Fix spacing in --validate flag description

Kubernetes-commit: 99cc395e2b9870ab9813e7ea4c0940225e30d05d
2024-10-15 12:24:28 +01:00
Maciej Szulik 80dc149179 Fix spacing in --validate flag description
Kubernetes-commit: 7b0660ec9f572c7b8c964c5447aa9169684f9a2b
2024-10-15 11:16:33 +02:00
Davanum Srinivas 84e8e731c9 Update to last versions of some very infrequently updated repos
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 7f8210e33f8cd626d1fb86cd7d12d077ec3047d5
2024-10-14 17:23:16 -04:00
Kubernetes Publisher c1f9faf7c3 Merge pull request #128051 from googs1025/kubectl/fix/resourcebuilder
bug(kubectl): return resource builder error in scale cmd

Kubernetes-commit: 9a0b07d38cb95d0d55044e591839c131a9258e2f
2024-10-14 18:47:38 +00:00
googs1025 c90e4a0fd8 bug(kubectl): return resource builder error in scale cmd
Kubernetes-commit: 8d084809296a845f01a0a1177bb0bf825f498d84
2024-10-14 18:25:13 +08:00
Kubernetes Publisher 86e0d9e48c Merge pull request #127881 from omerap12/drain-package-PollUntilContextTimeout
Update waitForDelete to use PollUntilContextTimeout

Kubernetes-commit: 5b1a4caedae0ca28adc2b22837789d6828b74d19
2024-10-14 06:41:57 +00:00
Kubernetes Publisher 3aac470db0 Merge pull request #127998 from skitt/golang-x-oct-2024
October 2024 golang.org/x bump

Kubernetes-commit: 8cbb11519c54c120e2dc120a4799e53abbfea4a4
2024-10-11 15:32:13 +00:00
Kubernetes Publisher 1d2b08a308 Merge pull request #127985 from dims/update-moby-runc-dependencies-oct-10
Update moby/runc dependencies

Kubernetes-commit: 6e5e8f374e834fa8dab341bde5c522704ed55ba6
2024-10-11 15:32:11 +00:00
Stephen Kitt 55b0096f22 October 2024 golang.org/x bump
Nothing major here, but nothing liable to cause pain to downstreams
either.

* https://github.com/golang/crypto/compare/v0.26.0...v0.28.0 (there’s
  a SHA3 fix there but it’s only relevant for 32-bit platforms)
* https://github.com/golang/net/compare/v0.28.0...v0.30.0 (mostly
  http2; route address parsing fix on Darwin)
* https://github.com/golang/oauth2/compare/v0.21.0...v0.23.0 (Google
  license fix)
* https://github.com/golang/sys/compare/v0.23.0...v0.26.0 (faster
  getrandom() on Linux through the vDSO; improved RISC-V support)
* https://github.com/golang/term/compare/v0.23.0...v0.25.0
* https://github.com/golang/time/compare/v0.3.0...v0.7.0 (0-limit
  handling fix in x/time/rate; Google license fix)
* https://github.com/golang/tools/compare/v0.24.0...v0.26.0

This doesn’t include golang.org/x/exp; that doesn’t have any relevant
changes. There’s an apidiff fix but we always pull in the latest
apidiff anyway.

Signed-off-by: Stephen Kitt <skitt@redhat.com>

Kubernetes-commit: 6c5a528727c30803d4426b29c06ae5d350619877
2024-10-11 10:22:13 +02:00
Davanum Srinivas fb82836788 Update moby/runc dependencies
Signed-off-by: Davanum Srinivas <davanum@gmail.com>

Kubernetes-commit: 521f2d106b9c5744ce57a8ec03124bcdadbca986
2024-10-10 11:58:22 -04:00
Kubernetes Publisher 9e16ef8eda Merge pull request #127942 from liggitt/json123
sigs.k8s.io/json go 1.23 bump

Kubernetes-commit: fc318e3ba4cb1db822d7f802993059846f64179d
2024-10-10 22:55:53 +00:00
Jordan Liggitt fa1f5fc526 Update sigs.k8s.io/json to go1.23
Kubernetes-commit: 8eff759b6ac7c3bb0c6a8823c751f5a578d6f721
2024-10-10 11:00:11 -04:00
Kubernetes Publisher a0488cfbe5 Merge pull request #127869 from ak20102763/explain_o_shorthand
Added shorthand for kubectl explain --output

Kubernetes-commit: 1f9d2577da68290c0466c1404bbff6100e1e303a
2024-10-10 10:42:41 +00:00
Kubernetes Publisher 184746c687 Merge pull request #127965 from koba1t/dependencies/update_kustomize_v5.5.0
Update kubectl kustomize to v5.5.0

Kubernetes-commit: e7bc45269d53da81d276efdde06dcbbeb4c286cc
2024-10-10 02:43:59 +00:00
Kubernetes Publisher 7ed2361d8a Merge pull request #127901 from skitt/k8s-sigs-yaml
Use sigs.k8s.io/yaml instead of gopkg.in/yaml

Kubernetes-commit: dd87bc064631354885193fc1a97d0e7b603e77b4
2024-10-09 23:29:02 +00:00
koba1t 983dddad9d Update kubectl kustomize to kyaml/v0.18.1, cmd/config/v0.15.0, api/v0.18.0, kustomize/v5.5.0
Kubernetes-commit: e7daa708520502cb375945af117b9e647acf5014
2024-10-09 23:32:45 +09:00
Kubernetes Publisher 2bb291358c Merge pull request #125118 from jsoref/from-to
Order ScalingReplicaSet message from->to

Kubernetes-commit: a1df68a31f535d4d4d55090e89805d8e574c3aa9
2024-10-09 10:46:02 +00:00
Kubernetes Publisher 7c89fa5dca Merge pull request #126932 from zhifei92/kubectl-describe-ep
Fix the bug where "kubectl describe svc' endpoints"behaves unexpectedly.

Kubernetes-commit: c270e562525a84e496cdbbb1ab7ced31bd2eeaca
2024-10-09 10:46:01 +00:00
Stephen Kitt 0f462824c7 Use sigs.k8s.io/yaml instead of gopkg.in/yaml
Since we have a Kubernetes-specific fork of go-yaml, use that
consistently throughout the project. This doesn't eliminate the
dependencies on gopkg.in/yaml, which are still used indirectly; but it
ensures that the whole project benefits from fixes or changes to
sigs.k8s.io/yaml.

Signed-off-by: Stephen Kitt <skitt@redhat.com>

Kubernetes-commit: f1fa4086b329376861272708d81da7988e8c4ad0
2024-10-07 14:27:52 +02:00
Omer Aplatony c329ccff7c Update waitForDelete to use PollUntilContextTimeout
Signed-off-by: Omer Aplatony <omerap12@gmail.com>

Kubernetes-commit: bba055067e6283f94ee05cedeb33dacafe4a1094
2024-10-05 22:07:37 +03:00
Akash 4106fc8791 Added shorthand for explain --output
Removed short flag example

Kubernetes-commit: 923a41370dc85062241fa149edda1307a16910e2
2024-10-05 03:19:57 +05:30
zhifei92 f3a7f811d0 fix: kubeclt describe service endpoints shows endpoints that are not ready
Kubernetes-commit: 64e2066e5c823eaa958fcbdd6024d0253688f36c
2024-08-27 12:42:37 +08:00
Kubernetes Publisher 5f5894cd61 Merge pull request #127634 from deads2k/apply-subresource
add --subresource to kubectl apply

Kubernetes-commit: bb6bfba47510c699cbbd1e910f37caca4c634359
2024-10-03 02:38:35 +00:00
Kubernetes Publisher 867c9194ad Merge pull request #127685 from mmorel-35/testifylint/expected-actual@k8s.io/kubectl
fix: enable expected-actual rule from testifylint in module `k8s.io/kubectl`

Kubernetes-commit: 1b4024948878fd8aab19deff48ae8b7102f0d34a
2024-09-29 09:22:35 +00:00
Kubernetes Publisher 4315ad9aaa Merge pull request #126764 from liggitt/mergo
reimplement merge to drop mergo dependency

Kubernetes-commit: ee74baec6e05afde972f1a8705d4f8efe066f120
2024-09-28 09:22:50 +00:00
Matthieu MOREL 36d3a02b4d fix: enable expected-actual rule from testifylint in module `k8s.io/kubectl`
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>

Kubernetes-commit: 223ea3445c2ced92630732ca765dee56bccae8ed
2024-09-27 07:47:42 +02:00
David Eads d6ad8b12b7 add --subresource to kubectl apply
Kubernetes-commit: 55ba8b2cbb375aaedcd01dd5d4dd0f81ef0415bf
2024-09-25 17:23:09 -04:00
Jordan Liggitt 4d5b682af1 Update vendor
Kubernetes-commit: 745ae75a15cad2f1c5da5518c00f2eb366ffb786
2024-08-17 21:42:00 -04:00
Kubernetes Publisher 5d2e9155d4 Merge pull request #127646 from mmorel-35/testifylint/formatter@k8s.io/kubectl
fix: enable formatter rule from testifylint in module `k8s.io/kubectl`

Kubernetes-commit: 4b33029691adceaa83bbd8e9879b5a6b455634e1
2024-09-26 13:12:30 +00:00
ah8ad3 e4a11c9548 realign line breaks in kubectl exaplin wrap method
Kubernetes-commit: 008f17419a0decbb82985a74a730a8b60ed07e5d
2024-08-04 10:02:17 +03:30
Matthieu MOREL c0e80201dc fix: enable formatter rule from testifylint in module `k8s.io/kubectl`
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>

Kubernetes-commit: 3e558fe604d9f209a9758e30866226aefda39f8a
2024-07-14 07:58:03 +00:00
Kubernetes Publisher 6c52e7fa5d Merge pull request #127512 from bergerhoffer/adding-interactive-delete
Adding example for interactive delete

Kubernetes-commit: 257d6f3f5bf75ff0ce6c53c104a0ab9df1ed5059
2024-09-23 09:07:30 +00:00
Kubernetes Publisher bbfe64c1ac Merge pull request #127534 from mmorel-35/testifylint/contains@k8s.io/kubectl
fix: enable contains rule from testifylint in module `k8s.io/kubectl`

Kubernetes-commit: 25aa9cd074072307a1168259c92cfefb1eafc27a
2024-09-23 09:07:29 +00:00
Kubernetes Publisher f92e952318 Merge pull request #126799 from kiashok/update-cadvisor-hcsshim
Update cadvisor and hcsshim versions

Kubernetes-commit: 4c2e23904794a289be22b2c9bce3303edfa0f622
2024-09-23 05:15:52 +00:00
Matthieu MOREL cfb4ff091f fix: enable contains rule from testifylint in module `k8s.io/kubectl`
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>

Kubernetes-commit: 1e7bd5541ea20b41d961f1bb88d9cc958a69ff66
2024-09-22 11:56:01 +02:00
Andrea Hoffer a0d920bb63 Adding example for interactive delete
Kubernetes-commit: 8e7593e18ab1788dc15e7f7db669301adcd42b2e
2024-09-20 14:54:52 -04:00
Kirtana Ashok 20877bc489 Update cadvisor and hcsshim versions
Signed-off-by: Kirtana Ashok <kiashok@microsoft.com>

Kubernetes-commit: 3fba9930b72f78b53fb83b0d533a426080c0f92e
2024-09-05 08:35:53 -07:00
Kubernetes Publisher 5e52c27b4e Merge pull request #127422 from srivastav-abhishek/go-vet-fix
Go vet fixes for gotip

Kubernetes-commit: f2700895a4315014c56bfe1db7fb1562a61a8b50
2024-09-20 17:20:59 +00:00
Keita Mochizuki 90452b2e92 kubectl debug: warning message about legacy profile (#127230)
* Add warning message for legacy profile

* fix1

* fix2

Kubernetes-commit: dd4943c831dbc43fb8d410ccdbc27e3c807131fa
2024-09-20 00:28:38 +09:00
Kubernetes Publisher 650e81b1f2 Merge pull request #126588 from jingyuanliang/master
kubectl/describe: use function calls to build field selector

Kubernetes-commit: 5302055b0780990b878ec24f1907842417336372
2024-09-19 17:19:18 +00:00
Kubernetes Publisher 262825a8a6 Merge pull request #126907 from alegueri/update-example-logs-all-pods
[UPDATE] updating logs examples to contain --all-pods flag

Kubernetes-commit: c53cad79ab4c379908a2e7c9ac8457d4240f0661
2024-09-14 00:13:49 +00:00
Kubernetes Publisher fee9d648a7 Merge pull request #127327 from ryanwinterms/wait_doc
Document the "create" option to the "kubectl wait" command

Kubernetes-commit: 88df7e307b755ea1a0c3223a85d881d9703f2cf7
2024-09-13 16:19:16 +00:00
Ryan Winter 1945b46b05 document the "create" option to the "kubeclt wait" command.
Signed-off-by: Ryan Winter <ryanwinter@outlook.com>

Kubernetes-commit: a3615ce5a38e9ea09339d4b45b843a84e2bf391d
2024-09-12 09:21:37 -07:00
Abhishek Kr Srivastav 36d480f43c Fix Go vet errors for master golang
Co-authored-by: Rajalakshmi-Girish <rajalakshmi.girish1@ibm.com>
Co-authored-by: Abhishek Kr Srivastav <Abhishek.kr.srivastav@ibm.com>

Kubernetes-commit: 95860cff1c418ea6f5494e4a6168e7acd1c390ec
2024-09-12 18:15:22 +05:30
Kubernetes Publisher 3aa701d129 Merge pull request #127271 from liggitt/go1.23
Update go.mod for go 1.23

Kubernetes-commit: c775fb2238e1ed48f62f02898bbb3ecee993e044
2024-09-12 05:56:52 +00:00
Jordan Liggitt 111ebd712e Update k8s.io/gengo/v2
Kubernetes-commit: e7957232cfcfaad1da50252653dea94ac22dc681
2024-09-11 15:38:38 -04:00
Jordan Liggitt 11efae9ae4 Pin godebug default to go1.23
Kubernetes-commit: 102a9dbab1764e8793d0237b25143fa49cd96831
2024-09-10 12:22:40 -04:00
Jordan Liggitt 9ca6564d24 Update go.mod to go 1.23
Kubernetes-commit: 65ef53139012dee36c08f558604dea48af170e11
2024-09-10 12:07:06 -04:00
Kubernetes Publisher e13117fcac Merge pull request #125960 from pohly/dep-logging
dependencies: logr v1.4.2, zap v1.27.0

Kubernetes-commit: a8d4eb60097863210b89063003e537253cf091a8
2024-09-06 20:18:03 +00:00
Kubernetes Publisher 57edd7ccc7 Merge pull request #127011 from jpbetz/format-only-imports
gengo performance: Speed up update-codegen.sh by switching to FormatOnly in gengo

Kubernetes-commit: 95956671d8da7783a726133709b8085f56dda052
2024-09-04 04:24:45 +00:00
Joe Betz 7640fec64e Bump gengo/v2 to pick up FormatOnly setting for imports
Co-authored-by: Tim Hockin <thockin@google.com>

Kubernetes-commit: d5555af62bf25ba9ff0b979fe048b992596cf2cc
2024-09-03 11:32:09 -04:00
Kubernetes Publisher b2a7d2626d Merge pull request #126995 from googs1025/fix/top_cmd
kubectl(top): modify the percentage display of the top command

Kubernetes-commit: e95441591235032994666ff91cfcd77a13d8c7b2
2024-09-02 16:11:16 +00:00
alegueri 9a0e211708 Update logs.go
Kubernetes-commit: ab01874a0658407e1121235591c75f2d6bae0108
2024-08-29 23:52:36 -07:00
googs1025 dca3776905 kubectl(top): modify the percentage display of the top command
Kubernetes-commit: 4209f515eee198dd9192e466cb67a157a2a3d835
2024-08-29 20:44:14 +08:00
Kubernetes Publisher 14f6a11dd8 Merge pull request #126787 from Jefftree/update-kube-openapi
Bump k8s.io/kube-openapi and k8s.io/gengo

Kubernetes-commit: f1a922c8e6f951381450ee3c2922ca018f14a82e
2024-08-28 00:24:41 +00:00
Jefftree b0a9adb1c6 re-vendor k8s.io/kube-openapi
Kubernetes-commit: ea2bdb6334ec1a2821a96163d83480d5fdb1861b
2024-08-27 01:58:39 +00:00
Jefftree 9035822a02 re-vendor k8s.io/gengo/v2
Kubernetes-commit: 6dc87bf173642ff5c8183eb2717377e787e713a9
2024-08-27 01:56:06 +00:00
Kubernetes Publisher c3d194bcd2 Merge pull request #126822 from micahhausler/additional-verbs
Include additional verbs to can-i

Kubernetes-commit: 43968d23073c66c6f82b7aef69dc2d72a2ef7fe2
2024-08-26 18:42:11 +01:00
Alessandra Guerinoni b06b2ef141 [UPDATE] updating logs examples to contain --all-pods flag
Kubernetes-commit: 8bb6e0282ea1ccefe6fd465c7718c560facc888a
2024-08-25 20:10:07 -07:00
Micah Hausler e1b9b58b72 Include additional verbs to can-i
Kubernetes-commit: 08ea67334e1cd664c9f3c34be9a51c0f216183aa
2024-08-20 13:21:55 -05:00
Kubernetes Publisher c4be63c54b Merge pull request #126838 from zou2699/fix-126836
fix: use the getContext() method for evicting pods

Kubernetes-commit: b60e01f881aa8a74b44d0ac1000e4f67f854273b
2024-08-21 20:18:20 +00:00
tux bd15ba4612 fix: use the getContext() method for evicting pods
Kubernetes-commit: cc244e8d1d9d57818816e8e35651b78b0c6f9709
2024-08-21 14:08:57 +08:00
Kubernetes Publisher 4a18df8277 Merge pull request #126652 from ardaguclu/add-timeout-cp-dest-check
Add timeout cancellation to kubectl cp destination path check

Kubernetes-commit: c999f9d828009f0a535237aca74ce2e5f6a8088c
2024-08-16 18:56:52 +00:00
Arda Güçlü 2c705c6f91 Increate timeout to 10sec and shortcut when ctx deadline is exceeded
Kubernetes-commit: ca2c9c64b489d14352e9b6f4c827506a5653a569
2024-08-16 16:13:01 +03:00
Kubernetes Publisher 823a551020 Merge pull request #126715 from tklauser/use-go-stdlib-slices
Use Go standard library slices package instead of k8s.io/utils/strings/slices

Kubernetes-commit: 1dd3c64502dfd07137f311fed63408af9c0c2513
2024-08-16 02:54:15 +00:00
Tobias Klauser d80cbcdb4d Use Go standard library slices package instead of k8s.io/utils/strings/slices
The package was introduced in Go 1.21 and is already in use in the k8s
code base.

Kubernetes-commit: 23dcd2604883c7ba91d72f5a9d84706650260c55
2024-08-15 14:43:53 +02:00
Kubernetes Publisher cf5c214b25 Merge pull request #126706 from carlory/kubectl-describe-image-volume
show image volume when kubectl describe a pod with image volume

Kubernetes-commit: ab26ad095029eb46ca2e938ac3a16cb6f164e657
2024-08-15 15:26:13 +00:00
carlory c63fb82d09 Fix print volume when kubelet describe a pod with image volume
Kubernetes-commit: bd32f542e9bba4a1eca31818cbd79db9801ab2e5
2024-08-15 18:00:13 +08:00
Benjamin Elder ee337ad2d6 kuebctl cp: discard output from test command
we only care about the exit code

see https://github.com/kubernetes/kubernetes/issues/126669

Kubernetes-commit: 78ae67a90042aa6ed5e91fc5730c10f26ba8d7f6
2024-08-14 16:58:02 -07:00
Kubernetes Publisher 03a826a301 Merge pull request #126545 from yangjunmyfm192085/updatepersistentVolumeClaimRetentionPolicy
Update incorrect description of persistentVolumeClaimRetentionPolicy

Kubernetes-commit: 6a478b4306ea9ae3b8f86bd1ef71072d9a03be22
2024-08-14 07:03:07 +00:00
Arda Güçlü 4fe61440d3 Add timeout cancellation to kubectl cp destination path check
Kubernetes-commit: d981b19ad30c3396e8a4d197bedc346e68e0270b
2024-08-13 11:02:04 +03:00
Kubernetes Publisher 3f1b31120b Merge pull request #126638 from soltysh/fix_wait
wait: don't lowercase condition in --for argument

Kubernetes-commit: 099a88370d017dacf16e67306ebcdec8394fae83
2024-08-12 17:23:00 +00:00
Maciej Szulik 8f2f49349b wait: don't lowercase condition in --for argument
Kubernetes-commit: fad6c424ac9b69229e02f9d9058c8131005f86e2
2024-08-12 16:30:20 +02:00
Jingyuan Liang 619e8f9f0d kubectl/describe: use function calls to build field selector
Instead of using string concatenation.

Signed-off-by: Jingyuan Liang <jingyuanliang@google.com>

Kubernetes-commit: a2dc34cb17c2eb9981b80cd9a550559f3a74ce23
2024-08-08 00:53:04 +00:00
杨军10092085 acdf12bd01 Updated incorrect description of persistentVolumeClaimRetentionPolicy
Kubernetes-commit: 56bbae4807989cd43eff17cf9fa93f7b54c087bd
2024-08-05 21:30:25 +08:00
Kubernetes Publisher 2e31adb070 Merge pull request #126145 from carlory/kep-3751-api
[KEP-3751] Promote VolumeAttributesClass to beta

Kubernetes-commit: c2fdeca4ab81336daf20c91b810c9685918c3d58
2024-07-24 01:56:00 +00:00
carlory 05a8bf872e Promote VolumeAttributesClass to beta
Kubernetes-commit: 0260c7d023551f85621049ca604a4fd5110ba0a9
2024-07-17 15:55:06 +08:00
Patrick Ohly 78100b683e dependencies: logr v1.4.2, zap v1.27.0
No particular reason for updating besides staying up-to-date.

Kubernetes-commit: 861ed2d2feeca187a32dcf793c9e3d5ab21bfdfc
2024-07-08 17:51:59 +02:00
Josh Soref 209732ca71 chore: Order ScalingReplicaSet message from->to
* change format of event
* include `from 0` for new replicas
* update describe tests to reflect current output

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

Kubernetes-commit: 502c05ed019573e8ed43c412f739882eec0f5f7c
2024-05-24 12:18:06 -04:00
AxeZhan 4657409ea3 consider sidecar containers in maxContainerRestarts
Kubernetes-commit: 7533123eb5e7c6ecd59d00d236235581f7f1157b
2024-05-19 23:50:25 +08:00
Yihao Wang 9a6ad3e08e Fix typo in i18n usage examples
Kubernetes-commit: e9c30951051b66bb5050d0d5bf622d4ef7a4481c
2024-01-17 13:12:21 +13:00
162 changed files with 8787 additions and 945 deletions

View File

@ -10,7 +10,7 @@
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
# INSTRUCTIONS AT https://kubernetes.io/security/
ardaguclu
eddiezane
KnVerey
natasha41575
mpuckett159
soltysh

2
doc.go
View File

@ -14,4 +14,4 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package kubectl // import "k8s.io/kubectl"
package kubectl

105
go.mod
View File

@ -2,98 +2,93 @@
module k8s.io/kubectl
go 1.22.0
go 1.24.0
godebug default=go1.24
require (
github.com/MakeNowJust/heredoc v1.0.0
github.com/chai2010/gettext-go v1.0.2
github.com/daviddengcn/go-colortext v1.0.0
github.com/distribution/reference v0.5.0
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d
github.com/distribution/reference v0.6.0
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f
github.com/fatih/camelcase v1.0.0
github.com/go-openapi/jsonreference v0.20.2
github.com/google/gnostic-models v0.6.8
github.com/google/go-cmp v0.6.0
github.com/jonboulle/clockwork v0.2.2
github.com/google/gnostic-models v0.6.9
github.com/google/go-cmp v0.7.0
github.com/jonboulle/clockwork v0.5.0
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
github.com/lithammer/dedent v1.1.0
github.com/mitchellh/go-wordwrap v1.0.1
github.com/moby/term v0.5.0
github.com/onsi/ginkgo/v2 v2.19.0
github.com/onsi/gomega v1.33.1
github.com/pkg/errors v0.9.1
github.com/onsi/ginkgo/v2 v2.21.0
github.com/onsi/gomega v1.35.1
github.com/russross/blackfriday/v2 v2.1.0
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
golang.org/x/sys v0.21.0
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0
golang.org/x/sys v0.31.0
gopkg.in/evanphx/json-patch.v4 v4.12.0
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.0.0-20240720022854-7d5e5eaf3aef
k8s.io/apimachinery v0.0.0-20240720202316-95b78024e3fe
k8s.io/cli-runtime v0.0.0-20240713190550-094be534f684
k8s.io/client-go v0.0.0-20240720223250-82af755eff54
k8s.io/component-base v0.0.0-20240715183844-6f32dbe8ef25
k8s.io/component-helpers v0.0.0-20240713184356-f77f7fa6cffb
k8s.io/api v0.0.0-20250612195650-7efafe3627c8
k8s.io/apimachinery v0.0.0-20250612195403-e0270fe44c97
k8s.io/cli-runtime v0.0.0-20250612204029-ea98d716c955
k8s.io/client-go v0.0.0-20250612200049-4e82e684120e
k8s.io/component-base v0.0.0-20250612201519-d0c00e6471f7
k8s.io/component-helpers v0.0.0-20250612201654-2b90e129ba7a
k8s.io/klog/v2 v2.130.1
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340
k8s.io/metrics v0.0.0-20240713190411-b5dc5cba9c19
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd
sigs.k8s.io/kustomize/kustomize/v5 v5.4.2
sigs.k8s.io/kustomize/kyaml v0.17.1
sigs.k8s.io/structured-merge-diff/v4 v4.4.1
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff
k8s.io/metrics v0.0.0-20250612203843-e8073a5e5ba0
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3
sigs.k8s.io/kustomize/kustomize/v5 v5.6.0
sigs.k8s.io/kustomize/kyaml v0.19.0
sigs.k8s.io/randfill v1.0.0
sigs.k8s.io/structured-merge-diff/v4 v4.7.0
sigs.k8s.io/yaml v1.4.0
)
require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/moby/spdystream v0.4.0 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/term v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/protobuf v1.34.2 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.27.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/term v0.30.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.9.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/kustomize/api v0.17.2 // indirect
sigs.k8s.io/kustomize/api v0.19.0 // indirect
)
replace k8s.io/code-generator => k8s.io/code-generator v0.0.0-20240720023521-ec3cc888df4c

267
go.sum
View File

@ -1,106 +1,68 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
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/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/daviddengcn/go-colortext v1.0.0 h1:ANqDyC0ys6qCSvuEK7l3g5RaehL/Xck9EX8ATG8oKsE=
github.com/daviddengcn/go-colortext v1.0.0/go.mod h1:zDqEI5NVUop5QPpVJUxE9UO10hRnmkD5G4Pmri9+m4c=
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4=
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc=
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
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-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
github.com/golangplus/bytes v1.0.0/go.mod h1:AdRaCFwmc/00ZzELMWb01soso6W1R/++O1XL80yAn+A=
github.com/golangplus/fmt v1.0.0/go.mod h1:zpM0OfbMCjPtd2qkTD/jX2MgiFCqklhSUFyDW44gVQE=
github.com/golangplus/testing v1.0.0 h1:+ZeeiKZENNOMkTTELoSySazi+XaEhVO0mb+eanrSEUQ=
github.com/golangplus/testing v1.0.0/go.mod h1:ZDreixUV3YzhoVraIDyOzHrr76p6NUh6k/pPg/Q3gYA=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@ -122,146 +84,109 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8=
github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
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/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/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/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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
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/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@ -269,43 +194,41 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20240720022854-7d5e5eaf3aef h1:srEy4lds3ddDhT+cxFy68Uvt3GVRTo3fwnw+Us/Nqqs=
k8s.io/api v0.0.0-20240720022854-7d5e5eaf3aef/go.mod h1:SvpyE6bmVBf1ly5BaD4y6yym4ZpHrV2pa8tTRjcglaA=
k8s.io/apimachinery v0.0.0-20240720202316-95b78024e3fe h1:V9MwpYUwbKlfLKVrhpVuKWiat/LBIhm1pGB9/xdHm5Q=
k8s.io/apimachinery v0.0.0-20240720202316-95b78024e3fe/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
k8s.io/cli-runtime v0.0.0-20240713190550-094be534f684 h1:WxhNQHxCpKjsVLa9IB05GmGlEsjYIOpfarRJGl+EtLY=
k8s.io/cli-runtime v0.0.0-20240713190550-094be534f684/go.mod h1:00xlk94/AwccyFVMnGbbX7sWiRNDXLHtSqQ/U4Sozvs=
k8s.io/client-go v0.0.0-20240720223250-82af755eff54 h1:BQ6OUPmYQm6GUJsPJrV4ouPTusfkZvo08u7uxXZEK4A=
k8s.io/client-go v0.0.0-20240720223250-82af755eff54/go.mod h1:GaT6DD2rtHnEnFV8iJ38Y8SemkQQI9E00pYBv8+d0Xc=
k8s.io/component-base v0.0.0-20240715183844-6f32dbe8ef25 h1:9SIVS17h6glmGM2G4ILkpQRUYc/zZ7y15gD2uaby0rM=
k8s.io/component-base v0.0.0-20240715183844-6f32dbe8ef25/go.mod h1:YYWVx/ele54LQcShCdQpmsIqiHgZ+KjWY7WGMzTjKGk=
k8s.io/component-helpers v0.0.0-20240713184356-f77f7fa6cffb h1:klgEnJlSj867TrU7c2RBXdxuNdBklpwZxOJHHsKP5x8=
k8s.io/component-helpers v0.0.0-20240713184356-f77f7fa6cffb/go.mod h1:T/wlkd8Q5SQXhqWJt2x1HD2GTAQ9eysgwNbWLMOEipA=
k8s.io/api v0.0.0-20250612195650-7efafe3627c8 h1:K1AnJQBQTKLy2C/up2YSFuuQ+OBucYGcDCBO2cafjlQ=
k8s.io/api v0.0.0-20250612195650-7efafe3627c8/go.mod h1:+9QbMyXTXctHAXg3fdhJbuZgyzhYgprCn43M5NqoJzw=
k8s.io/apimachinery v0.0.0-20250612195403-e0270fe44c97 h1:h2og30eGCCk1GOEZK6+LNhhlydDcWY3wJaWDIs05xR8=
k8s.io/apimachinery v0.0.0-20250612195403-e0270fe44c97/go.mod h1:EZ7eIfFAwky7ktmG4Pu9XWxBxFG++4dxPDOM0GL3abw=
k8s.io/cli-runtime v0.0.0-20250612204029-ea98d716c955 h1:/vNS33lahptlYENPecDoe4fD8SOE+aGTxP5wozvK7zw=
k8s.io/cli-runtime v0.0.0-20250612204029-ea98d716c955/go.mod h1:Exo7hMRapEHo/QMSGxd1tqaGuZBQpgGZt7Sintr5L/M=
k8s.io/client-go v0.0.0-20250612200049-4e82e684120e h1:xoSxEgTvcAD7YG46B6RN1yZx5KhF0YKNe4SSoY+qSQA=
k8s.io/client-go v0.0.0-20250612200049-4e82e684120e/go.mod h1:hktzpPyrdfB1WrXOvdnDayNSrngzEwWjiwTGqq6Zjns=
k8s.io/component-base v0.0.0-20250612201519-d0c00e6471f7 h1:PmR3IJeL8qbnqdH70lmCLxZjHFr+Cbz5v6VY6ZFlMsI=
k8s.io/component-base v0.0.0-20250612201519-d0c00e6471f7/go.mod h1:eMJvxKozNu3AbHhH6mWUJbzNhElacCbAilLeMjxIW5k=
k8s.io/component-helpers v0.0.0-20250612201654-2b90e129ba7a h1:AccUaO5Y8Z/rRivu4l0eqZbocGbxHGqiuo19dc0vcPw=
k8s.io/component-helpers v0.0.0-20250612201654-2b90e129ba7a/go.mod h1:5Grn35PpLsSHt+WUrQbXI2QN85eBCWnH5nx4fGBbYYU=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
k8s.io/metrics v0.0.0-20240713190411-b5dc5cba9c19 h1:qOfe7taXie9iPv+ESDV73iIk43W3PMn56JCSkR7j+Zg=
k8s.io/metrics v0.0.0-20240713190411-b5dc5cba9c19/go.mod h1:L15kLoNeqDBxOGA/dFTp7vwwNnEauBmZ63xhBolNoag=
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g=
sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0=
sigs.k8s.io/kustomize/kustomize/v5 v5.4.2 h1:9Zl5Gqg3XMdBEvkR54pVLCBj7FVO7W+VPNDDEzD6AyE=
sigs.k8s.io/kustomize/kustomize/v5 v5.4.2/go.mod h1:5ypfJVYlPb2MKKeoGknVLxvHemDlQT+szI4+KOhnD6k=
sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ=
sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
k8s.io/metrics v0.0.0-20250612203843-e8073a5e5ba0 h1:Eo70T+FEfbC83+3nBRAqcUNQf/YnGlkCYj+c1q+lldY=
k8s.io/metrics v0.0.0-20250612203843-e8073a5e5ba0/go.mod h1:wyXjSOSPspEM73pO1WXNVAafLtPfWHMnRPgVrX57niY=
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ=
sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o=
sigs.k8s.io/kustomize/kustomize/v5 v5.6.0 h1:MWtRRDWCwQEeW2rnJTqJMuV6Agy56P53SkbVoJpN7wA=
sigs.k8s.io/kustomize/kustomize/v5 v5.6.0/go.mod h1:XuuZiQF7WdcvZzEYyNww9A0p3LazCKeJmCjeycN8e1I=
sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA=
sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY=
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
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/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@ -123,11 +123,11 @@ func NewCmdAPIResources(restClientGetter genericclioptions.RESTClientGetter, ioS
// Validate checks to the APIResourceOptions to see if there is sufficient information run the command
func (o *APIResourceOptions) Validate() error {
supportedOutputTypes := sets.NewString("", "wide", "name")
supportedOutputTypes := sets.New[string]("", "wide", "name")
if !supportedOutputTypes.Has(o.Output) {
return fmt.Errorf("--output %v is not available", o.Output)
}
supportedSortTypes := sets.NewString("", "name", "kind")
supportedSortTypes := sets.New[string]("", "name", "kind")
if len(o.SortBy) > 0 {
if !supportedSortTypes.Has(o.SortBy) {
return fmt.Errorf("--sort-by accepts only name or kind")
@ -193,11 +193,11 @@ func (o *APIResourceOptions) RunAPIResources() error {
continue
}
// filter to resources that support the specified verbs
if len(o.Verbs) > 0 && !sets.NewString(resource.Verbs...).HasAll(o.Verbs...) {
if len(o.Verbs) > 0 && !sets.New[string](resource.Verbs...).HasAll(o.Verbs...) {
continue
}
// filter to resources that belong to the specified categories
if len(o.Categories) > 0 && !sets.NewString(resource.Categories...).HasAll(o.Categories...) {
if len(o.Categories) > 0 && !sets.New[string](resource.Categories...).HasAll(o.Categories...) {
continue
}
resources = append(resources, groupResource{

View File

@ -71,6 +71,7 @@ type ApplyFlags struct {
All bool
Overwrite bool
OpenAPIPatch bool
Subresource string
PruneAllowlist []string
@ -97,6 +98,7 @@ type ApplyOptions struct {
All bool
Overwrite bool
OpenAPIPatch bool
Subresource string
ValidationDirective string
Validator validation.Schema
@ -235,6 +237,7 @@ func (flags *ApplyFlags) AddFlags(cmd *cobra.Command) {
cmdutil.AddPruningFlags(cmd, &flags.Prune, &flags.PruneAllowlist, &flags.All, &flags.ApplySetRef)
cmd.Flags().BoolVar(&flags.Overwrite, "overwrite", flags.Overwrite, "Automatically resolve conflicts between the modified and live configuration by using values from the modified configuration")
cmd.Flags().BoolVar(&flags.OpenAPIPatch, "openapi-patch", flags.OpenAPIPatch, "If true, use openapi to calculate diff when the openapi presents and the resource can be found in the openapi spec. Otherwise, fall back to use baked-in types.")
cmdutil.AddSubresourceFlags(cmd, &flags.Subresource, "If specified, apply will operate on the subresource of the requested object. Only allowed when using --server-side.")
}
// ToOptions converts from CLI inputs to runtime inputs
@ -356,6 +359,7 @@ func (flags *ApplyFlags) ToOptions(f cmdutil.Factory, cmd *cobra.Command, baseNa
All: flags.All,
Overwrite: flags.Overwrite,
OpenAPIPatch: flags.OpenAPIPatch,
Subresource: flags.Subresource,
Recorder: recorder,
Namespace: namespace,
@ -438,6 +442,9 @@ func (o *ApplyOptions) Validate() error {
}
}
}
if len(o.Subresource) > 0 && !o.ServerSideApply {
return fmt.Errorf("--subresource can only be specified for --server-side")
}
return nil
}
@ -577,13 +584,15 @@ func (o *ApplyOptions) applyOneObject(info *resource.Info) error {
options := metav1.PatchOptions{
Force: &o.ForceConflicts,
}
obj, err := helper.Patch(
info.Namespace,
info.Name,
types.ApplyPatchType,
data,
&options,
)
obj, err := helper.
WithSubresource(o.Subresource).
Patch(
info.Namespace,
info.Name,
types.ApplyPatchType,
data,
&options,
)
if err != nil {
if isIncompatibleServerError(err) {
err = fmt.Errorf("Server-side apply not available on the server: (%v)", err)

View File

@ -25,6 +25,7 @@ import (
"net/http"
"os"
"path/filepath"
"slices"
"strings"
"testing"
"time"
@ -60,7 +61,6 @@ import (
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/openapi"
"k8s.io/utils/ptr"
"k8s.io/utils/strings/slices"
"sigs.k8s.io/yaml"
)
@ -2605,7 +2605,6 @@ metadata:
applyset.kubernetes.io/additional-namespaces: ""
applyset.kubernetes.io/contains-group-kinds: ReplicationController
applyset.kubernetes.io/tooling: kubectl/v0.0.0-master+$Format:%H$
creationTimestamp: null
labels:
applyset.kubernetes.io/id: applyset-0eFHV8ySqp7XoShsGvyWFQD3s96yqwHmzc4e0HR1dsY-v1
name: my-set
@ -2639,7 +2638,6 @@ metadata:
applyset.kubernetes.io/additional-namespaces: ""
applyset.kubernetes.io/contains-group-kinds: ReplicationController,Service
applyset.kubernetes.io/tooling: kubectl/v0.0.0-master+$Format:%H$
creationTimestamp: null
labels:
applyset.kubernetes.io/id: applyset-0eFHV8ySqp7XoShsGvyWFQD3s96yqwHmzc4e0HR1dsY-v1
name: my-set
@ -2674,7 +2672,6 @@ metadata:
applyset.kubernetes.io/additional-namespaces: ""
applyset.kubernetes.io/contains-group-kinds: ReplicationController,Service
applyset.kubernetes.io/tooling: kubectl/v0.0.0-master+$Format:%H$
creationTimestamp: null
labels:
applyset.kubernetes.io/id: applyset-0eFHV8ySqp7XoShsGvyWFQD3s96yqwHmzc4e0HR1dsY-v1
name: my-set
@ -2709,7 +2706,6 @@ metadata:
applyset.kubernetes.io/additional-namespaces: ""
applyset.kubernetes.io/contains-group-kinds: Service
applyset.kubernetes.io/tooling: kubectl/v0.0.0-master+$Format:%H$
creationTimestamp: null
labels:
applyset.kubernetes.io/id: applyset-0eFHV8ySqp7XoShsGvyWFQD3s96yqwHmzc4e0HR1dsY-v1
name: my-set
@ -2872,7 +2868,6 @@ metadata:
applyset.kubernetes.io/additional-namespaces: test
applyset.kubernetes.io/contains-group-kinds: ReplicationController
applyset.kubernetes.io/tooling: kubectl/v0.0.0-master+$Format:%H$
creationTimestamp: null
labels:
applyset.kubernetes.io/id: applyset-rhp1a-HVAVT_dFgyEygyA1BEB82HPp2o10UiFTpqtAs-v1
name: my-set
@ -3090,7 +3085,6 @@ metadata:
applyset.kubernetes.io/additional-namespaces: ""
applyset.kubernetes.io/contains-group-resources: replicationcontrollers
applyset.kubernetes.io/tooling: kubectl/v0.0.0-master+$Format:%H$
creationTimestamp: null
labels:
applyset.kubernetes.io/id: applyset-0eFHV8ySqp7XoShsGvyWFQD3s96yqwHmzc4e0HR1dsY-v1
name: my-set

View File

@ -17,13 +17,12 @@ limitations under the License.
package apply
import (
"context"
"encoding/json"
"fmt"
"io"
"time"
"github.com/pkg/errors"
"github.com/jonboulle/clockwork"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
@ -60,7 +59,7 @@ const (
// patchRetryBackOffPeriod is the period to back off when apply patch results in error.
var patchRetryBackOffPeriod = 1 * time.Second
var createPatchErrFormat = "creating patch with:\noriginal:\n%s\nmodified:\n%s\ncurrent:\n%s\nfor:"
var createPatchErrFormat = "creating patch with:\noriginal:\n%s\nmodified:\n%s\ncurrent:\n%s\nfor: %w"
// Patcher defines options to patch OpenAPI objects.
type Patcher struct {
@ -119,13 +118,13 @@ func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, namespace, na
// Serialize the current configuration of the object from the server.
current, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
if err != nil {
return nil, nil, errors.Wrapf(err, "serializing current configuration from:\n%v\nfor:", obj)
return nil, nil, fmt.Errorf("serializing current configuration from:\n%v\nfor: %w", obj, err)
}
// Retrieve the original configuration of the object from the annotation.
original, err := util.GetOriginalConfiguration(obj)
if err != nil {
return nil, nil, errors.Wrapf(err, "retrieving original configuration from:\n%v\nfor:", obj)
return nil, nil, fmt.Errorf("retrieving original configuration from:\n%v\nfor: %w", obj, err)
}
var patchType types.PatchType
@ -177,17 +176,17 @@ func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, namespace, na
patchType = types.StrategicMergePatchType
patch, err = p.buildStrategicMergeFromBuiltins(versionedObj, original, modified, current)
if err != nil {
return nil, nil, errors.Wrapf(err, createPatchErrFormat, original, modified, current)
return nil, nil, fmt.Errorf(createPatchErrFormat, original, modified, current, err)
}
} else {
if !runtime.IsNotRegisteredError(err) {
return nil, nil, errors.Wrapf(err, "getting instance of versioned object for %v:", p.Mapping.GroupVersionKind)
return nil, nil, fmt.Errorf("getting instance of versioned object for %v: %w", p.Mapping.GroupVersionKind, err)
}
patchType = types.MergePatchType
patch, err = p.buildMergePatch(original, modified, current)
if err != nil {
return nil, nil, errors.Wrapf(err, createPatchErrFormat, original, modified, current)
return nil, nil, fmt.Errorf(createPatchErrFormat, original, modified, current, err)
}
}
}
@ -199,7 +198,7 @@ func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, namespace, na
if p.ResourceVersion != nil {
patch, err = addResourceVersion(patch, *p.ResourceVersion)
if err != nil {
return nil, nil, errors.Wrap(err, "Failed to insert resourceVersion in patch")
return nil, nil, fmt.Errorf("failed to insert resourceVersion in patch: %w", err)
}
}
@ -387,7 +386,7 @@ func (p *Patcher) deleteAndCreate(original runtime.Object, modified []byte, name
return modified, nil, err
}
// TODO: use wait
if err := wait.PollImmediate(1*time.Second, p.Timeout, func() (bool, error) {
if err := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, p.Timeout, true, func(ctx context.Context) (bool, error) {
if _, err := p.Helper.Get(namespace, name); !apierrors.IsNotFound(err) {
return false, err
}

View File

@ -206,7 +206,7 @@ func (o *AttachOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
o.GetPodTimeout, err = cmdutil.GetPodRunningTimeoutFlag(cmd)
if err != nil {
return cmdutil.UsageErrorf(cmd, err.Error())
return cmdutil.UsageErrorf(cmd, "%s", err.Error())
}
o.Builder = f.NewBuilder
@ -307,6 +307,7 @@ func (o *AttachOptions) Run() error {
}
if !o.Quiet {
_, _ = fmt.Fprintln(o.ErrOut, "All commands and output from this session will be recorded in container logs, including credentials and sensitive information passed through the command prompt.")
fmt.Fprintln(o.ErrOut, "If you don't see a command prompt, try pressing enter.")
}
if err := t.Safe(o.AttachFunc(o, containerToAttach, t.Raw, sizeQueue)); err != nil {

View File

@ -242,6 +242,7 @@ func TestAttach(t *testing.T) {
pod *corev1.Pod
remoteAttachErr bool
expectedErr string
expectedErrOut []string
}{
{
name: "pod attach",
@ -251,6 +252,10 @@ func TestAttach(t *testing.T) {
attachPath: "/api/" + version + "/namespaces/test/pods/foo/attach",
pod: attachPod(),
container: "bar",
expectedErrOut: []string{
"All commands and output from this session will be recorded in container logs, including credentials and sensitive information passed through the command prompt.",
"If you don't see a command prompt, try pressing enter.",
},
},
{
name: "pod attach error",
@ -305,10 +310,11 @@ func TestAttach(t *testing.T) {
if test.remoteAttachErr {
remoteAttach.err = fmt.Errorf("attach error")
}
streams, _, _, errOut := genericiooptions.NewTestIOStreams()
options := &AttachOptions{
StreamOptions: exec.StreamOptions{
ContainerName: test.container,
IOStreams: genericiooptions.NewTestIOStreamsDiscard(),
IOStreams: streams,
},
Attach: remoteAttach,
GetPodTimeout: 1000,
@ -349,6 +355,14 @@ func TestAttach(t *testing.T) {
if remoteAttach.url.Query().Get("container") != "bar" {
t.Errorf("%s: Did not have query parameters: %s", test.name, remoteAttach.url.Query())
}
if test.expectedErrOut != nil {
for _, expect := range test.expectedErrOut {
if !strings.Contains(errOut.String(), expect) {
t.Errorf("%s: expected message %s not found, got: %s", test.name, expect, strings.ReplaceAll(errOut.String(), "\n", ""))
return
}
}
}
})
}
}

View File

@ -105,10 +105,10 @@ var (
# List all allowed actions in namespace "foo"
kubectl auth can-i --list --namespace=foo`)
resourceVerbs = sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection", "use", "bind", "impersonate", "*", "approve")
nonResourceURLVerbs = sets.NewString("get", "put", "post", "head", "options", "delete", "patch", "*")
resourceVerbs = sets.New[string]("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection", "use", "bind", "impersonate", "*", "approve", "sign", "escalate", "attest")
nonResourceURLVerbs = sets.New[string]("get", "put", "post", "head", "options", "delete", "patch", "*")
// holds all the server-supported resources that cannot be discovered by clients. i.e. users and groups for the impersonate verb
nonStandardResourceNames = sets.NewString("users", "groups")
nonStandardResourceNames = sets.New[string]("users", "groups")
)
// NewCmdCanI returns an initialized Command for 'auth can-i' sub command

View File

@ -161,7 +161,7 @@ func TestRunAccessCheck(t *testing.T) {
test.serverErr
}),
}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}, ContentType: runtime.ContentTypeJSON}}
if err := test.o.Complete(tf, test.args); err != nil {
t.Errorf("%s: %v", test.name, err)
@ -196,6 +196,7 @@ func TestRunAccessList(t *testing.T) {
" [/version] [] [get]\n"
tf := cmdtesting.NewTestFactory().WithNamespace("test")
tf.ClientConfigVal.ContentType = runtime.ContentTypeJSON
defer tf.Cleanup()
ns := scheme.Codecs.WithoutConversion()

View File

@ -250,7 +250,7 @@ func printTableSelfSubjectAccessReview(obj runtime.Object, out io.Writer) error
}
if len(ui.Extra) > 0 {
for _, k := range sets.StringKeySet(ui.Extra).List() {
for _, k := range sets.List(sets.KeySet(ui.Extra)) {
v := ui.Extra[k]
_, err := fmt.Fprintf(w, "Extra: %s\t%v\n", k, v)
if err != nil {

View File

@ -75,9 +75,7 @@ func TestWhoAmIRun(t *testing.T) {
`{
"kind": "SelfSubjectReview",
"apiVersion": "authentication.k8s.io/v1",
"metadata": {
"creationTimestamp": null
},
"metadata": {},
"status": {
"userInfo": {
"username": "jane.doe",
@ -131,9 +129,7 @@ func TestWhoAmIRun(t *testing.T) {
`{
"kind": "SelfSubjectReview",
"apiVersion": "authentication.k8s.io/v1beta1",
"metadata": {
"creationTimestamp": null
},
"metadata": {},
"status": {
"userInfo": {
"username": "jane.doe",
@ -186,9 +182,7 @@ func TestWhoAmIRun(t *testing.T) {
`{
"kind": "SelfSubjectReview",
"apiVersion": "authentication.k8s.io/v1",
"metadata": {
"creationTimestamp": null
},
"metadata": {},
"status": {
"userInfo": {
"username": "jane.doe",

View File

@ -24,13 +24,17 @@ import (
"k8s.io/klog/v2"
autoscalingv1 "k8s.io/api/autoscaling/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericiooptions"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/cli-runtime/pkg/resource"
autoscalingv1client "k8s.io/client-go/kubernetes/typed/autoscaling/v1"
autoscalingv2client "k8s.io/client-go/kubernetes/typed/autoscaling/v2"
"k8s.io/client-go/scale"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme"
@ -43,6 +47,7 @@ import (
var (
autoscaleLong = templates.LongDesc(i18n.T(`
Creates an autoscaler that automatically chooses and sets the number of pods that run in a Kubernetes cluster.
The command will attempt to use the autoscaling/v2 API first, in case of an error, it will fall back to autoscaling/v1 API.
Looks up a deployment, replica set, stateful set, or replication controller by name and creates an autoscaler that uses the given resource as a reference.
An autoscaler can automatically increase or decrease number of pods deployed within the system as needed.`))
@ -78,7 +83,8 @@ type AutoscaleOptions struct {
builder *resource.Builder
fieldManager string
HPAClient autoscalingv1client.HorizontalPodAutoscalersGetter
HPAClientV1 autoscalingv1client.HorizontalPodAutoscalersGetter
HPAClientV2 autoscalingv2client.HorizontalPodAutoscalersGetter
scaleKindResolver scale.ScaleKindResolver
genericiooptions.IOStreams
@ -157,7 +163,8 @@ func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
if err != nil {
return err
}
o.HPAClient = kubeClient.AutoscalingV1()
o.HPAClientV2 = kubeClient.AutoscalingV2()
o.HPAClientV1 = kubeClient.AutoscalingV1()
o.namespace, o.enforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
@ -186,7 +193,6 @@ func (o *AutoscaleOptions) Validate() error {
return nil
}
// Run performs the execution
func (o *AutoscaleOptions) Run() error {
r := o.builder.
Unstructured().
@ -212,44 +218,19 @@ func (o *AutoscaleOptions) Run() error {
return fmt.Errorf("cannot autoscale a %v: %v", mapping.GroupVersionKind.Kind, err)
}
hpa := o.createHorizontalPodAutoscaler(info.Name, mapping)
if err := o.Recorder.Record(hpa); err != nil {
klog.V(4).Infof("error recording current command: %v", err)
}
if o.dryRunStrategy == cmdutil.DryRunClient {
count++
printer, err := o.ToPrinter("created")
if err != nil {
// handles the creation of HorizontalPodAutoscaler objects for both v2 and v1 APIs.
// If v2 API fails, try to create and handle HorizontalPodAutoscaler using v1 API
hpaV2 := o.createHorizontalPodAutoscalerV2(info.Name, mapping)
if err := o.handleHPA(hpaV2); err != nil {
klog.V(1).Infof("Encountered an error with the v2 HorizontalPodAutoscaler: %v. "+
"Falling back to try the v1 HorizontalPodAutoscaler", err)
hpaV1 := o.createHorizontalPodAutoscalerV1(info.Name, mapping)
if err := o.handleHPA(hpaV1); err != nil {
return err
}
return printer.PrintObj(hpa, o.Out)
}
if err := util.CreateOrUpdateAnnotation(o.createAnnotation, hpa, scheme.DefaultJSONEncoder()); err != nil {
return err
}
createOptions := metav1.CreateOptions{}
if o.fieldManager != "" {
createOptions.FieldManager = o.fieldManager
}
if o.dryRunStrategy == cmdutil.DryRunServer {
createOptions.DryRun = []string{metav1.DryRunAll}
}
actualHPA, err := o.HPAClient.HorizontalPodAutoscalers(o.namespace).Create(context.TODO(), hpa, createOptions)
if err != nil {
return err
}
count++
printer, err := o.ToPrinter("autoscaled")
if err != nil {
return err
}
return printer.PrintObj(actualHPA, o.Out)
return nil
})
if err != nil {
return err
@ -260,7 +241,96 @@ func (o *AutoscaleOptions) Run() error {
return nil
}
func (o *AutoscaleOptions) createHorizontalPodAutoscaler(refName string, mapping *meta.RESTMapping) *autoscalingv1.HorizontalPodAutoscaler {
// handleHPA handles the creation and management of a single HPA object.
func (o *AutoscaleOptions) handleHPA(hpa runtime.Object) error {
if err := o.Recorder.Record(hpa); err != nil {
return fmt.Errorf("error recording current command: %w", err)
}
if o.dryRunStrategy == cmdutil.DryRunClient {
printer, err := o.ToPrinter("created")
if err != nil {
return err
}
return printer.PrintObj(hpa, o.Out)
}
if err := util.CreateOrUpdateAnnotation(o.createAnnotation, hpa, scheme.DefaultJSONEncoder()); err != nil {
return err
}
createOptions := metav1.CreateOptions{}
if o.fieldManager != "" {
createOptions.FieldManager = o.fieldManager
}
if o.dryRunStrategy == cmdutil.DryRunServer {
createOptions.DryRun = []string{metav1.DryRunAll}
}
var actualHPA runtime.Object
var err error
switch typedHPA := hpa.(type) {
case *autoscalingv2.HorizontalPodAutoscaler:
actualHPA, err = o.HPAClientV2.HorizontalPodAutoscalers(o.namespace).Create(context.TODO(), typedHPA, createOptions)
case *autoscalingv1.HorizontalPodAutoscaler:
actualHPA, err = o.HPAClientV1.HorizontalPodAutoscalers(o.namespace).Create(context.TODO(), typedHPA, createOptions)
default:
return fmt.Errorf("unsupported HorizontalPodAutoscaler type %T", hpa)
}
if err != nil {
return err
}
printer, err := o.ToPrinter("autoscaled")
if err != nil {
return err
}
return printer.PrintObj(actualHPA, o.Out)
}
func (o *AutoscaleOptions) createHorizontalPodAutoscalerV2(refName string, mapping *meta.RESTMapping) *autoscalingv2.HorizontalPodAutoscaler {
name := o.Name
if len(name) == 0 {
name = refName
}
scaler := autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
APIVersion: mapping.GroupVersionKind.GroupVersion().String(),
Kind: mapping.GroupVersionKind.Kind,
Name: refName,
},
MaxReplicas: o.Max,
},
}
if o.Min > 0 {
scaler.Spec.MinReplicas = &o.Min
}
if o.CPUPercent >= 0 {
scaler.Spec.Metrics = []autoscalingv2.MetricSpec{
{
Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricSource{
Name: corev1.ResourceCPU,
Target: autoscalingv2.MetricTarget{
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: &o.CPUPercent,
},
},
},
}
}
return &scaler
}
func (o *AutoscaleOptions) createHorizontalPodAutoscalerV1(refName string, mapping *meta.RESTMapping) *autoscalingv1.HorizontalPodAutoscaler {
name := o.Name
if len(name) == 0 {
name = refName

View File

@ -0,0 +1,572 @@
/*
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 autoscale
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
autoscalingv1 "k8s.io/api/autoscaling/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/utils/ptr"
)
type validateTestCase struct {
name string
options *AutoscaleOptions
expectedError error
}
func TestAutoscaleValidate(t *testing.T) {
tests := []validateTestCase{
{
name: "valid options",
options: &AutoscaleOptions{
Max: 10,
Min: 1,
},
expectedError: nil,
},
{
name: "max less than 1",
options: &AutoscaleOptions{
Max: 0,
Min: 1,
},
expectedError: fmt.Errorf("--max=MAXPODS is required and must be at least 1, max: 0"),
},
{
name: "min greater than max",
options: &AutoscaleOptions{
Max: 1,
Min: 2,
},
expectedError: fmt.Errorf("--max=MAXPODS must be larger or equal to --min=MINPODS, max: 1, min: 2"),
},
{
name: "zero min replicas",
options: &AutoscaleOptions{
Max: 5,
Min: 0,
},
expectedError: nil,
},
{
name: "negative min replicas",
options: &AutoscaleOptions{
Max: 5,
Min: -2,
},
expectedError: nil,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
errorGot := tc.options.Validate()
assert.Equal(t, tc.expectedError, errorGot)
})
}
}
type createHorizontalPodAutoscalerTestCase struct {
name string
options *AutoscaleOptions
refName string
mapping *meta.RESTMapping
expectedHPAV2 *autoscalingv2.HorizontalPodAutoscaler
expectedHPAV1 *autoscalingv1.HorizontalPodAutoscaler
}
func TestCreateHorizontalPodAutoscalerV2(t *testing.T) {
tests := []createHorizontalPodAutoscalerTestCase{
{
name: "create with all options",
options: &AutoscaleOptions{
Name: "custom-name",
Max: 10,
Min: 2,
CPUPercent: 80,
},
refName: "deployment-1",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
},
},
expectedHPAV2: &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "custom-name",
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "deployment-1",
},
MinReplicas: ptr.To(int32(2)),
MaxReplicas: int32(10),
Metrics: []autoscalingv2.MetricSpec{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricSpec
{
Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricSource{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#ResourceMetricSource
Name: corev1.ResourceCPU,
Target: autoscalingv2.MetricTarget{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricTarget
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: ptr.To(int32(80)),
},
},
},
},
},
},
},
{
name: "create without min replicas",
options: &AutoscaleOptions{
Name: "custom-name-2",
Max: 10,
Min: -1,
CPUPercent: 80,
},
refName: "deployment-2",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
},
},
expectedHPAV2: &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "custom-name-2",
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "deployment-2",
},
MinReplicas: nil,
MaxReplicas: int32(10),
Metrics: []autoscalingv2.MetricSpec{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricSpec
{
Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricSource{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#ResourceMetricSource
Name: corev1.ResourceCPU,
Target: autoscalingv2.MetricTarget{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricTarget
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: ptr.To(int32(80)),
},
},
},
},
},
},
},
{
name: "create without max replicas",
options: &AutoscaleOptions{
Name: "custom-name-3",
Max: -1,
Min: 2,
CPUPercent: 80,
},
refName: "deployment-3",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
},
},
expectedHPAV2: &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "custom-name-3",
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "deployment-3",
},
MinReplicas: ptr.To(int32(2)),
MaxReplicas: int32(-1),
Metrics: []autoscalingv2.MetricSpec{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricSpec
{
Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricSource{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#ResourceMetricSource
Name: corev1.ResourceCPU,
Target: autoscalingv2.MetricTarget{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricTarget
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: ptr.To(int32(80)),
},
},
},
},
},
},
},
{
name: "create without cpu utilization",
options: &AutoscaleOptions{
Name: "custom-name-4",
Max: 10,
Min: 2,
CPUPercent: -1,
},
refName: "deployment-4",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
},
},
expectedHPAV2: &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "custom-name-4",
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "deployment-4",
},
MinReplicas: ptr.To(int32(2)),
MaxReplicas: int32(10),
},
},
},
{
name: "create with replicaset reference",
options: &AutoscaleOptions{
Name: "replicaset-hpa",
Max: 5,
Min: 1,
CPUPercent: 70,
},
refName: "frontend",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "ReplicaSet",
},
},
expectedHPAV2: &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "replicaset-hpa",
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "ReplicaSet",
Name: "frontend",
},
MinReplicas: ptr.To(int32(1)),
MaxReplicas: int32(5),
Metrics: []autoscalingv2.MetricSpec{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricSpec
{
Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricSource{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#ResourceMetricSource
Name: corev1.ResourceCPU,
Target: autoscalingv2.MetricTarget{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricTarget
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: ptr.To(int32(70)),
},
},
},
},
},
},
},
{
name: "create with statefulset reference",
options: &AutoscaleOptions{
Name: "statefulset-hpa",
Max: 8,
Min: 2,
CPUPercent: 60,
},
refName: "web",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "StatefulSet",
},
},
expectedHPAV2: &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "statefulset-hpa",
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "StatefulSet",
Name: "web",
},
MinReplicas: ptr.To(int32(2)),
MaxReplicas: int32(8),
Metrics: []autoscalingv2.MetricSpec{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricSpec
{
Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricSource{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#ResourceMetricSource
Name: corev1.ResourceCPU,
Target: autoscalingv2.MetricTarget{
// Reference: https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricTarget
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: ptr.To(int32(60)),
},
},
},
},
},
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
hpa := tc.options.createHorizontalPodAutoscalerV2(tc.refName, tc.mapping)
assert.Equal(t, tc.expectedHPAV2, hpa)
})
}
}
func TestCreateHorizontalPodAutoscalerV1(t *testing.T) {
tests := []createHorizontalPodAutoscalerTestCase{
{
name: "create with all options",
options: &AutoscaleOptions{
Name: "custom-name",
Max: 10,
Min: 2,
CPUPercent: 80,
},
refName: "deployment-1",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
},
},
expectedHPAV1: &autoscalingv1.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "custom-name",
},
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "deployment-1",
},
MinReplicas: ptr.To(int32(2)),
MaxReplicas: int32(10),
TargetCPUUtilizationPercentage: ptr.To(int32(80)),
},
},
},
{
name: "create without min replicas",
options: &AutoscaleOptions{
Name: "custom-name-2",
Max: 10,
Min: -1,
CPUPercent: 80,
},
refName: "deployment-2",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
},
},
expectedHPAV1: &autoscalingv1.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "custom-name-2",
},
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "deployment-2",
},
MinReplicas: nil,
MaxReplicas: int32(10),
TargetCPUUtilizationPercentage: ptr.To(int32(80)),
},
},
},
{
name: "create without max replicas",
options: &AutoscaleOptions{
Name: "custom-name-3",
Max: -1,
Min: 2,
CPUPercent: 80,
},
refName: "deployment-3",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
},
},
expectedHPAV1: &autoscalingv1.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "custom-name-3",
},
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "deployment-3",
},
MinReplicas: ptr.To(int32(2)),
MaxReplicas: int32(-1),
TargetCPUUtilizationPercentage: ptr.To(int32(80)),
},
},
},
{
name: "create without cpu utilization",
options: &AutoscaleOptions{
Name: "custom-name-4",
Max: 10,
Min: 2,
CPUPercent: -1,
},
refName: "deployment-4",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
},
},
expectedHPAV1: &autoscalingv1.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "custom-name-4",
},
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "deployment-4",
},
MinReplicas: ptr.To(int32(2)),
MaxReplicas: int32(10),
},
},
},
{
name: "create with replicaset reference",
options: &AutoscaleOptions{
Name: "replicaset-hpa",
Max: 5,
Min: 1,
CPUPercent: 70,
},
refName: "frontend",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "ReplicaSet",
},
},
expectedHPAV1: &autoscalingv1.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "replicaset-hpa",
},
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "ReplicaSet",
Name: "frontend",
},
MinReplicas: ptr.To(int32(1)),
MaxReplicas: int32(5),
TargetCPUUtilizationPercentage: ptr.To(int32(70)),
},
},
},
{
name: "create with statefulset reference",
options: &AutoscaleOptions{
Name: "statefulset-hpa",
Max: 8,
Min: 2,
CPUPercent: 60,
},
refName: "web",
mapping: &meta.RESTMapping{
GroupVersionKind: schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "StatefulSet",
},
},
expectedHPAV1: &autoscalingv1.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Name: "statefulset-hpa",
},
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "StatefulSet",
Name: "web",
},
MinReplicas: ptr.To(int32(2)),
MaxReplicas: int32(8),
TargetCPUUtilizationPercentage: ptr.To(int32(60)),
},
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
hpa := tc.options.createHorizontalPodAutoscalerV1(tc.refName, tc.mapping)
assert.Equal(t, tc.expectedHPAV1, hpa)
})
}
}

View File

@ -33,7 +33,6 @@ import (
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
ct "github.com/daviddengcn/go-colortext"
"github.com/spf13/cobra"
)
@ -156,12 +155,8 @@ func (o *ClusterInfoOptions) Run() error {
}
func printService(out io.Writer, name, link string) {
ct.ChangeColor(ct.Green, false, ct.None, false)
fmt.Fprint(out, name)
ct.ResetColor()
fmt.Fprint(out, " is running at ")
ct.ChangeColor(ct.Yellow, false, ct.None, false)
fmt.Fprint(out, link)
ct.ResetColor()
fmt.Fprintln(out, "")
}

View File

@ -73,6 +73,7 @@ import (
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/cmd/version"
"k8s.io/kubectl/pkg/cmd/wait"
"k8s.io/kubectl/pkg/kuberc"
utilcomp "k8s.io/kubectl/pkg/util/completion"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
@ -82,8 +83,6 @@ import (
"k8s.io/kubectl/pkg/cmd/kustomize"
)
const kubectlCmdHeaders = "KUBECTL_COMMAND_HEADERS"
type KubectlOptions struct {
PluginHandler PluginHandler
Arguments []string
@ -142,25 +141,23 @@ func NewDefaultKubectlCommandWithArgs(o KubectlOptions) *cobra.Command {
}
}
} else if err == nil {
if !cmdutil.CmdPluginAsSubcommand.IsDisabled() {
// Command exists(e.g. kubectl create), but it is not certain that
// subcommand also exists (e.g. kubectl create networkpolicy)
// we also have to eliminate kubectl create -f
if IsSubcommandPluginAllowed(foundCmd.Name()) && len(foundArgs) >= 1 && !strings.HasPrefix(foundArgs[0], "-") {
subcommand := foundArgs[0]
builtinSubcmdExist := false
for _, subcmd := range foundCmd.Commands() {
if subcmd.Name() == subcommand {
builtinSubcmdExist = true
break
}
// Command exists(e.g. kubectl create), but it is not certain that
// subcommand also exists (e.g. kubectl create networkpolicy)
// we also have to eliminate kubectl create -f
if IsSubcommandPluginAllowed(foundCmd.Name()) && len(foundArgs) >= 1 && !strings.HasPrefix(foundArgs[0], "-") {
subcommand := foundArgs[0]
builtinSubcmdExist := false
for _, subcmd := range foundCmd.Commands() {
if subcmd.Name() == subcommand {
builtinSubcmdExist = true
break
}
}
if !builtinSubcmdExist {
if err := HandlePluginCommand(o.PluginHandler, cmdPathPieces, len(cmdPathPieces)-len(foundArgs)+1); err != nil {
fmt.Fprintf(o.IOStreams.ErrOut, "Error: %v\n", err)
os.Exit(1)
}
if !builtinSubcmdExist {
if err := HandlePluginCommand(o.PluginHandler, cmdPathPieces, len(cmdPathPieces)-len(foundArgs)+1); err != nil {
fmt.Fprintf(o.IOStreams.ErrOut, "Error: %v\n", err)
os.Exit(1)
}
}
}
@ -361,6 +358,11 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
flags.BoolVar(&warningsAsErrors, "warnings-as-errors", warningsAsErrors, "Treat warnings received from the server as errors and exit with a non-zero exit code")
pref := kuberc.NewPreferences()
if !cmdutil.KubeRC.IsDisabled() {
pref.AddFlags(flags)
}
kubeConfigFlags := o.ConfigFlags
if kubeConfigFlags == nil {
kubeConfigFlags = defaultConfigFlags().WithWarningPrinter(o.IOStreams)
@ -383,6 +385,8 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
// Avoid import cycle by setting ValidArgsFunction here instead of in NewCmdGet()
getCmd := get.NewCmdGet("kubectl", f, o.IOStreams)
getCmd.ValidArgsFunction = utilcomp.ResourceTypeAndNameCompletionFunc(f)
debugCmd := debug.NewCmdDebug(f, o.IOStreams)
debugCmd.ValidArgsFunction = utilcomp.ResourceTypeAndNameCompletionFunc(f)
groups := templates.CommandGroups{
{
@ -434,7 +438,7 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
proxyCmd,
cp.NewCmdCp(f, o.IOStreams),
auth.NewCmdAuth(f, o.IOStreams),
debug.NewCmdDebug(f, o.IOStreams),
debugCmd,
events.NewCmdEvents(f, o.IOStreams),
},
},
@ -490,6 +494,15 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
// Stop warning about normalization of flags. That makes it possible to
// add the klog flags later.
cmds.SetGlobalNormalizationFunc(cliflag.WordSepNormalizeFunc)
if !cmdutil.KubeRC.IsDisabled() {
_, err := pref.Apply(cmds, o.Arguments, o.IOStreams.ErrOut)
if err != nil {
fmt.Fprintf(o.IOStreams.ErrOut, "error occurred while applying preferences %v\n", err)
os.Exit(1)
}
}
return cmds
}
@ -507,12 +520,9 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
//
// https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/859-kubectl-headers
func addCmdHeaderHooks(cmds *cobra.Command, kubeConfigFlags *genericclioptions.ConfigFlags) {
// If the feature gate env var is set to "false", then do no add kubectl command headers.
if value, exists := os.LookupEnv(kubectlCmdHeaders); exists {
if value == "false" || value == "0" {
klog.V(5).Infoln("kubectl command headers turned off")
return
}
if cmdutil.CmdHeaders.IsDisabled() {
klog.V(5).Infoln("kubectl command headers turned off")
return
}
klog.V(5).Infoln("kubectl command headers turned on")
crt := &genericclioptions.CommandHeaderRoundTripper{}
@ -566,3 +576,29 @@ func registerCompletionFuncForGlobalFlags(cmd *cobra.Command, f cmdutil.Factory)
return utilcomp.ListUsersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
}))
}
// GetLogVerbosity parses the provided command-line arguments to determine
// the verbosity level for logging. Returns string representing the verbosity
// level, or 0 if no verbosity flag is specified.
func GetLogVerbosity(args []string) string {
for i, arg := range args {
if arg == "--" {
// flags after "--" does not represent any flag of
// the command. We should short cut the iteration in here.
break
}
if arg == "--v" || arg == "-v" {
if i+1 < len(args) {
return args[i+1]
}
} else if strings.Contains(arg, "--v=") || strings.Contains(arg, "-v=") {
parg := strings.Split(arg, "=")
if len(parg) > 1 && parg[1] != "" {
return parg[1]
}
}
}
return "0"
}

View File

@ -29,6 +29,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericiooptions"
"k8s.io/kubectl/pkg/cmd/plugin"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
)
func TestNormalizationFuncGlobalExistence(t *testing.T) {
@ -381,10 +382,6 @@ func TestKubectlCommandHeadersHooks(t *testing.T) {
envVar: "false",
addsHooks: false,
},
"zero env var value; hooks NOT added": {
envVar: "0",
addsHooks: false,
},
}
for name, testCase := range tests {
@ -394,7 +391,7 @@ func TestKubectlCommandHeadersHooks(t *testing.T) {
if kubeConfigFlags.WrapConfigFn != nil {
t.Fatal("expected initial nil WrapConfigFn")
}
t.Setenv(kubectlCmdHeaders, testCase.envVar)
t.Setenv(string(cmdutil.CmdHeaders), testCase.envVar)
addCmdHeaderHooks(cmds, kubeConfigFlags)
// Valdidate whether the hooks were added.
if testCase.addsHooks && kubeConfigFlags.WrapConfigFn == nil {

View File

@ -69,7 +69,6 @@ func Example_view() {
// name: federal-context
// current-context: federal-context
// kind: Config
// preferences: {}
// users:
// - name: red-user
// user:

View File

@ -89,7 +89,7 @@ func NewCmdConfigGetContexts(streams genericiooptions.IOStreams, configAccess cl
// Complete assigns GetContextsOptions from the args.
func (o *GetContextsOptions) Complete(cmd *cobra.Command, args []string) error {
supportedOutputTypes := sets.NewString("", "name")
supportedOutputTypes := sets.New[string]("", "name")
if !supportedOutputTypes.Has(o.outputFormat) {
return fmt.Errorf("--output %v is not available in kubectl config get-contexts; resetting to default output format", o.outputFormat)
}

View File

@ -55,7 +55,7 @@ func newNavigationSteps(path string) (*navigationSteps, error) {
if err != nil {
return nil, err
}
nextPart := findNameStep(individualParts[currPartIndex:], sets.StringKeySet(mapValueOptions))
nextPart := findNameStep(individualParts[currPartIndex:], sets.KeySet(mapValueOptions))
steps = append(steps, navigationStep{nextPart, mapValueType})
currPartIndex += len(strings.Split(nextPart, "."))
@ -98,7 +98,7 @@ func (s *navigationSteps) moreStepsRemaining() bool {
// findNameStep takes the list of parts and a set of valid tags that can be used after the name. It then walks the list of parts
// until it find a valid "next" tag or until it reaches the end of the parts and then builds the name back up out of the individual parts
func findNameStep(parts []string, typeOptions sets.String) string {
func findNameStep(parts []string, typeOptions sets.Set[string]) string {
if len(parts) == 0 {
return ""
}
@ -136,7 +136,7 @@ func getPotentialTypeValues(typeValue reflect.Type) (map[string]reflect.Type, er
return ret, nil
}
func findKnownValue(parts []string, valueOptions sets.String) int {
func findKnownValue(parts []string, valueOptions sets.Set[string]) int {
for i := range parts {
if valueOptions.Has(parts[i]) {
return i

View File

@ -85,7 +85,6 @@ contexts:
name: my-cluster
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
@ -165,7 +164,6 @@ contexts:
name: my-cluster
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
@ -247,7 +245,6 @@ contexts:
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
@ -272,7 +269,6 @@ contexts:
name: my-cluster
current-context: my-cluster
kind: Config
preferences: {}
users:
- name: mu-cluster
user:

View File

@ -18,12 +18,13 @@ package cp
import (
"archive/tar"
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
"strings"
"time"
"github.com/spf13/cobra"
@ -267,8 +268,8 @@ func (o *CopyOptions) checkDestinationIsDir(dest fileSpec) error {
options := &exec.ExecOptions{
StreamOptions: exec.StreamOptions{
IOStreams: genericiooptions.IOStreams{
Out: bytes.NewBuffer([]byte{}),
ErrOut: bytes.NewBuffer([]byte{}),
Out: io.Discard,
ErrOut: io.Discard,
},
Namespace: dest.PodNamespace,
@ -279,7 +280,21 @@ func (o *CopyOptions) checkDestinationIsDir(dest fileSpec) error {
Executor: &exec.DefaultRemoteExecutor{},
}
return o.execute(options)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
done := make(chan error)
go func() {
done <- o.execute(options)
}()
select {
case <-ctx.Done():
return ctx.Err()
case err := <-done:
return err
}
}
func (o *CopyOptions) copyToPod(src, dest fileSpec, options *exec.ExecOptions) error {
@ -295,6 +310,10 @@ func (o *CopyOptions) copyToPod(src, dest fileSpec, options *exec.ExecOptions) e
// If no error, dest.File was found to be a directory.
// Copy specified src into it
destFile = destFile.Join(srcFile.Base())
} else if errors.Is(err, context.DeadlineExceeded) {
// we haven't decided destination is directory or not because context timeout is exceeded.
// That's why, we should shortcut the process in here.
return err
}
go func(src localPath, dest remotePath, writer io.WriteCloser) {

View File

@ -988,6 +988,6 @@ func cmpFileData(t *testing.T, filePath, data string) {
type testWriter testing.T
func (t *testWriter) Write(p []byte) (n int, err error) {
t.Logf(string(p))
t.Log(string(p))
return len(p), nil
}

View File

@ -116,7 +116,7 @@ var (
func AddSpecialVerb(verb string, gr schema.GroupResource) {
resources, ok := specialVerbs[verb]
if !ok {
resources = make([]schema.GroupResource, 1)
resources = make([]schema.GroupResource, 0, 1)
}
resources = append(resources, gr)
specialVerbs[verb] = resources
@ -425,7 +425,7 @@ func generateResourcePolicyRules(mapper meta.RESTMapper, verbs []string, resourc
// Create separate rule for each of the api group.
rules := []rbacv1.PolicyRule{}
for _, g := range sets.StringKeySet(groupResourceMapping).List() {
for _, g := range sets.List(sets.KeySet(groupResourceMapping)) {
rule := rbacv1.PolicyRule{}
rule.Verbs = verbs
rule.Resources = groupResourceMapping[g]

View File

@ -684,14 +684,17 @@ func TestAddSpecialVerb(t *testing.T) {
testCases := map[string]struct {
verb string
resource schema.GroupResource
isNew bool
}{
"existing verb": {
verb: "use",
resource: schema.GroupResource{Group: "my.custom.io", Resource: "one"},
isNew: false,
},
"new verb": {
verb: "new",
resource: schema.GroupResource{Group: "my.custom.io", Resource: "two"},
isNew: true,
},
}
@ -703,6 +706,16 @@ func TestAddSpecialVerb(t *testing.T) {
t.Errorf("missing expected verb: %s", tc.verb)
}
if tc.isNew {
if len(resources) != 1 {
t.Errorf("new verb should only contain one resource resources:%#v", resources)
}
if !reflect.DeepEqual(tc.resource, resources[0]) {
t.Errorf("miss expected resource:%#v", tc.resource)
}
return
}
for _, res := range resources {
if reflect.DeepEqual(tc.resource, res) {
return

View File

@ -18,6 +18,7 @@ package create
import (
"context"
"errors"
"fmt"
"strconv"
"strings"
@ -399,12 +400,12 @@ func parsePorts(portString string) (int32, intstr.IntOrString, error) {
var targetPort intstr.IntOrString
if portNum, err := strconv.Atoi(portStringSlice[1]); err != nil {
if errs := validation.IsValidPortName(portStringSlice[1]); len(errs) != 0 {
return 0, intstr.FromInt32(0), fmt.Errorf(strings.Join(errs, ","))
return 0, intstr.FromInt32(0), errors.New(strings.Join(errs, ","))
}
targetPort = intstr.FromString(portStringSlice[1])
} else {
if errs := validation.IsValidPortNum(portNum); len(errs) != 0 {
return 0, intstr.FromInt32(0), fmt.Errorf(strings.Join(errs, ","))
return 0, intstr.FromInt32(0), errors.New(strings.Join(errs, ","))
}
targetPort = intstr.FromInt32(int32(portNum))
}

View File

@ -98,14 +98,10 @@ var (
`)
)
func boundObjectKindToAPIVersions() map[string]string {
kinds := map[string]string{
"Pod": "v1",
"Secret": "v1",
"Node": "v1",
}
return kinds
var boundObjectKinds = map[string]string{
"Pod": "v1",
"Secret": "v1",
"Node": "v1",
}
func NewTokenOpts(ioStreams genericiooptions.IOStreams) *TokenOptions {
@ -149,7 +145,7 @@ func NewCmdCreateToken(f cmdutil.Factory, ioStreams genericiooptions.IOStreams)
cmd.Flags().DurationVar(&o.Duration, "duration", o.Duration, "Requested lifetime of the issued token. If not set or if set to 0, the lifetime will be determined by the server automatically. The server may return a token with a longer or shorter lifetime.")
cmd.Flags().StringVar(&o.BoundObjectKind, "bound-object-kind", o.BoundObjectKind, "Kind of an object to bind the token to. "+
"Supported kinds are "+strings.Join(sets.StringKeySet(boundObjectKindToAPIVersions()).List(), ", ")+". "+
"Supported kinds are "+strings.Join(sets.List(sets.KeySet(boundObjectKinds)), ", ")+". "+
"If set, --bound-object-name must be provided.")
cmd.Flags().StringVar(&o.BoundObjectName, "bound-object-name", o.BoundObjectName, "Name of an object to bind the token to. "+
"The token will expire when the object is deleted. "+
@ -226,8 +222,8 @@ func (o *TokenOptions) Validate() error {
return fmt.Errorf("--bound-object-uid can only be set if --bound-object-kind is provided")
}
} else {
if _, ok := boundObjectKindToAPIVersions()[o.BoundObjectKind]; !ok {
return fmt.Errorf("supported --bound-object-kind values are %s", strings.Join(sets.StringKeySet(boundObjectKindToAPIVersions()).List(), ", "))
if _, ok := boundObjectKinds[o.BoundObjectKind]; !ok {
return fmt.Errorf("supported --bound-object-kind values are %s", strings.Join(sets.List(sets.KeySet(boundObjectKinds)), ", "))
}
if len(o.BoundObjectName) == 0 {
return fmt.Errorf("--bound-object-name is required if --bound-object-kind is provided")
@ -250,7 +246,7 @@ func (o *TokenOptions) Run() error {
if len(o.BoundObjectKind) > 0 {
request.Spec.BoundObjectRef = &authenticationv1.BoundObjectReference{
Kind: o.BoundObjectKind,
APIVersion: boundObjectKindToAPIVersions()[o.BoundObjectKind],
APIVersion: boundObjectKinds[o.BoundObjectKind],
Name: o.BoundObjectName,
UID: types.UID(o.BoundObjectUID),
}

View File

@ -99,8 +99,7 @@ func TestCreateToken(t *testing.T) {
serverResponseToken: "abc",
expectStdout: `apiVersion: authentication.k8s.io/v1
kind: TokenRequest
metadata:
creationTimestamp: null
metadata: {}
spec:
audiences: null
boundObjectRef: null

View File

@ -75,6 +75,9 @@ var (
debugging utilities without restarting the pod.
* Node: Create a new pod that runs in the node's host namespaces and can access
the node's filesystem.
Note: When a non-root user is configured for the entire target Pod, some capabilities granted
by debug profile may not work.
`))
debugExample = templates.Examples(i18n.T(`
@ -212,9 +215,7 @@ func (o *DebugOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.TargetContainer, "target", "", i18n.T("When using an ephemeral container, target processes in this container name."))
cmd.Flags().BoolVarP(&o.TTY, "tty", "t", o.TTY, i18n.T("Allocate a TTY for the debugging container."))
cmd.Flags().StringVar(&o.Profile, "profile", ProfileLegacy, i18n.T(`Options are "legacy", "general", "baseline", "netadmin", "restricted" or "sysadmin".`))
if !cmdutil.DebugCustomProfile.IsDisabled() {
cmd.Flags().StringVar(&o.CustomProfileFile, "custom", o.CustomProfileFile, i18n.T("Path to a JSON or YAML file containing a partial container spec to customize built-in debug profiles."))
}
cmd.Flags().StringVar(&o.CustomProfileFile, "custom", o.CustomProfileFile, i18n.T("Path to a JSON or YAML file containing a partial container spec to customize built-in debug profiles."))
}
// Complete finishes run-time initialization of debug.DebugOptions.
@ -399,6 +400,11 @@ func (o *DebugOptions) Validate() error {
}
}
// Warning for legacy profile
if o.Profile == ProfileLegacy {
fmt.Fprintln(o.ErrOut, `--profile=legacy is deprecated and will be removed in the future. It is recommended to explicitly specify a profile, for example "--profile=general".`)
}
return nil
}
@ -492,6 +498,8 @@ func (o *DebugOptions) debugByEphemeralContainer(ctx context.Context, pod *corev
}
klog.V(2).Infof("new ephemeral container: %#v", debugContainer)
o.displayWarning((*corev1.Container)(&debugContainer.EphemeralContainerCommon), pod)
debugJS, err := json.Marshal(debugPod)
if err != nil {
return nil, "", fmt.Errorf("error creating JSON for debug container: %v", err)
@ -608,6 +616,16 @@ func (o *DebugOptions) debugByCopy(ctx context.Context, pod *corev1.Pod) (*corev
if err != nil {
return nil, "", err
}
var debugContainer *corev1.Container
for i := range copied.Spec.Containers {
if copied.Spec.Containers[i].Name == dc {
debugContainer = &copied.Spec.Containers[i]
break
}
}
o.displayWarning(debugContainer, copied)
created, err := o.podClient.Pods(copied.Namespace).Create(ctx, copied, metav1.CreateOptions{})
if err != nil {
return nil, "", err
@ -621,6 +639,32 @@ func (o *DebugOptions) debugByCopy(ctx context.Context, pod *corev1.Pod) (*corev
return created, dc, nil
}
// Display warning message if some capabilities are set by profile and non-root user is specified in .Spec.SecurityContext.RunAsUser.(#1650)
func (o *DebugOptions) displayWarning(container *corev1.Container, pod *corev1.Pod) {
if container == nil {
return
}
if pod.Spec.SecurityContext.RunAsUser == nil || *pod.Spec.SecurityContext.RunAsUser == 0 {
return
}
if container.SecurityContext == nil {
return
}
if container.SecurityContext.RunAsUser != nil && *container.SecurityContext.RunAsUser == 0 {
return
}
if (container.SecurityContext.Privileged == nil || !*container.SecurityContext.Privileged) &&
(container.SecurityContext.Capabilities == nil || len(container.SecurityContext.Capabilities.Add) == 0) {
return
}
_, _ = fmt.Fprintln(o.ErrOut, `Warning: Non-root user is configured for the entire target Pod, and some capabilities granted by debug profile may not work. Please consider using "--custom" with a custom profile that specifies "securityContext.runAsUser: 0".`)
}
// generateDebugContainer returns a debugging pod and an EphemeralContainer suitable for use as a debug container
// in the given pod.
func (o *DebugOptions) generateDebugContainer(pod *corev1.Pod) (*corev1.Pod, *corev1.EphemeralContainer, error) {
@ -942,12 +986,12 @@ func (o *DebugOptions) handleAttachPod(ctx context.Context, restClientGetter gen
}
if status.State.Terminated != nil {
klog.V(1).Info("Ephemeral container terminated, falling back to logs")
return logOpts(restClientGetter, pod, opts)
return logOpts(ctx, restClientGetter, pod, opts)
}
if err := opts.Run(); err != nil {
fmt.Fprintf(opts.ErrOut, "warning: couldn't attach to pod/%s, falling back to streaming logs: %v\n", podName, err)
return logOpts(restClientGetter, pod, opts)
return logOpts(ctx, restClientGetter, pod, opts)
}
return nil
}
@ -965,7 +1009,7 @@ func getContainerStatusByName(pod *corev1.Pod, containerName string) *corev1.Con
}
// logOpts logs output from opts to the pods log.
func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *corev1.Pod, opts *attach.AttachOptions) error {
func logOpts(ctx context.Context, restClientGetter genericclioptions.RESTClientGetter, pod *corev1.Pod, opts *attach.AttachOptions) error {
ctrName, err := opts.GetContainerName(pod)
if err != nil {
return err
@ -976,7 +1020,7 @@ func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *corev1.Po
return err
}
for _, request := range requests {
if err := logs.DefaultConsumeRequest(request, opts.Out); err != nil {
if err := logs.DefaultConsumeRequest(ctx, request, opts.Out); err != nil {
return err
}
}

View File

@ -103,7 +103,10 @@ var (
kubectl delete pod foo --force
# Delete all pods
kubectl delete pods --all`))
kubectl delete pods --all
# Delete all pods only if the user confirms the deletion
kubectl delete pods --all --interactive`))
)
type DeleteOptions struct {
@ -521,7 +524,7 @@ func (o *DeleteOptions) PrintObj(info *resource.Info) {
}
func (o *DeleteOptions) confirmation(infos []*resource.Info) bool {
fmt.Fprintf(o.Out, i18n.T("You are about to delete the following %d resource(s):\n"), len(infos))
fmt.Fprintf(o.Out, i18n.T("You are about to delete the following %d resource(s):\n"), len(infos)) //nolint:errcheck
for _, info := range infos {
groupKind := info.Mapping.GroupVersionKind
kindString := fmt.Sprintf("%s.%s", strings.ToLower(groupKind.Kind), groupKind.Group)
@ -529,11 +532,11 @@ func (o *DeleteOptions) confirmation(infos []*resource.Info) bool {
kindString = strings.ToLower(groupKind.Kind)
}
fmt.Fprintf(o.Out, "%s/%s\n", kindString, info.Name)
fmt.Fprintf(o.Out, "%s/%s\n", kindString, info.Name) //nolint:errcheck
}
fmt.Fprintf(o.Out, i18n.T("Do you want to continue?")+" (y/n): ")
fmt.Fprint(o.Out, i18n.T("Do you want to continue?")+" (y/N): ") //nolint:errcheck
var input string
_, err := fmt.Fscan(o.In, &input)
_, err := fmt.Fscanln(o.In, &input)
if err != nil {
return false
}

View File

@ -375,7 +375,7 @@ func TestDeleteObjectWithInteractive(t *testing.T) {
}
cmd.Run(cmd, []string{})
if buf.String() != "You are about to delete the following 1 resource(s):\nreplicationcontroller/redis-master\nDo you want to continue? (y/n): replicationcontroller/redis-master\n" {
if buf.String() != "You are about to delete the following 1 resource(s):\nreplicationcontroller/redis-master\nDo you want to continue? (y/N): replicationcontroller/redis-master\n" {
t.Errorf("unexpected output: %s", buf.String())
}
@ -396,7 +396,7 @@ func TestDeleteObjectWithInteractive(t *testing.T) {
}
cmd.Run(cmd, []string{})
if buf.String() != "You are about to delete the following 1 resource(s):\nreplicationcontroller/redis-master\nDo you want to continue? (y/n): deletion is cancelled\n" {
if buf.String() != "You are about to delete the following 1 resource(s):\nreplicationcontroller/redis-master\nDo you want to continue? (y/N): deletion is cancelled\n" {
t.Errorf("unexpected output: %s", buf.String())
}
if buf.String() == ": replicationcontroller/redis-master\n" {

View File

@ -193,7 +193,7 @@ func (o *DescribeOptions) Run() error {
allErrs = append(allErrs, err)
}
errs := sets.NewString()
errs := sets.New[string]()
first := true
for _, info := range infos {
mapping := info.ResourceMapping()

View File

@ -161,7 +161,7 @@ func NewCmdDiff(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Co
// command it means changes were found.
// Thus, it should return status code greater than 1.
cmd.SetFlagErrorFunc(func(command *cobra.Command, err error) error {
cmdutil.CheckDiffErr(cmdutil.UsageErrorf(cmd, err.Error()))
cmdutil.CheckDiffErr(cmdutil.UsageErrorf(cmd, "%s", err.Error()))
return nil
})

View File

@ -64,6 +64,7 @@ func TestDiffProgram(t *testing.T) {
externalDiffCommands := [3]string{"diff", "diff -ruN", "diff --report-identical-files"}
t.Setenv("LANG", "C")
t.Setenv("LANGUAGE", "en_US")
for i, c := range externalDiffCommands {
t.Setenv("KUBECTL_EXTERNAL_DIFF", c)

View File

@ -243,7 +243,7 @@ func (o *DrainCmdOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
var err error
if len(args) == 0 && !cmd.Flags().Changed("selector") {
return cmdutil.UsageErrorf(cmd, fmt.Sprintf("USAGE: %s [flags]", cmd.Use))
return cmdutil.UsageErrorf(cmd, "USAGE: %s [flags]", cmd.Use)
}
if len(args) > 0 && len(o.drainer.Selector) > 0 {
return cmdutil.UsageErrorf(cmd, "error: cannot specify both a node name and a --selector option")
@ -326,7 +326,7 @@ func (o *DrainCmdOptions) RunDrain() error {
return err
}
drainedNodes := sets.NewString()
drainedNodes := sets.New[string]()
var fatal []error
remainingNodes := []string{}

View File

@ -103,6 +103,6 @@ func NewCmdEdit(f cmdutil.Factory, ioStreams genericiooptions.IOStreams) *cobra.
"Defaults to the line ending native to your platform.")
cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl-edit")
cmdutil.AddApplyAnnotationVarFlags(cmd, &o.ApplyAnnotation)
cmdutil.AddSubresourceFlags(cmd, &o.Subresource, "If specified, edit will operate on the subresource of the requested object.", editor.SupportedSubresources...)
cmdutil.AddSubresourceFlags(cmd, &o.Subresource, "If specified, edit will operate on the subresource of the requested object.")
return cmd
}

View File

@ -30,8 +30,6 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/spf13/cobra"
yaml "gopkg.in/yaml.v2"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/cli-runtime/pkg/genericiooptions"
@ -41,6 +39,7 @@ import (
"k8s.io/kubectl/pkg/cmd/create"
cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
yaml "sigs.k8s.io/yaml/goyaml.v2"
)
type EditTestCase struct {
@ -173,7 +172,7 @@ func TestEdit(t *testing.T) {
t.Setenv("KUBE_EDITOR", "testdata/test_editor.sh")
t.Setenv("KUBE_EDITOR_CALLBACK", server.URL+"/callback")
testcases := sets.NewString()
testcases := sets.New[string]()
filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
@ -195,7 +194,7 @@ func TestEdit(t *testing.T) {
t.Fatalf("Error locating edit testcases")
}
for _, testcaseName := range testcases.List() {
for _, testcaseName := range testcases.UnsortedList() {
t.Run(testcaseName, func(t *testing.T) {
i = 0
name = testcaseName

View File

@ -25,7 +25,7 @@ import (
"os"
"strings"
yaml "gopkg.in/yaml.v2"
yaml "sigs.k8s.io/yaml/goyaml.v2"
)
type EditTestCase struct {

View File

@ -3,7 +3,7 @@
"kind": "Service",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"kind\":\"Service\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"svc1\",\"creationTimestamp\":null,\"labels\":{\"app\":\"svc1\"}},\"spec\":{\"ports\":[{\"name\":\"80\",\"protocol\":\"TCP\",\"port\":80,\"targetPort\":80}],\"selector\":{\"app\":\"svc1\"},\"type\":\"ClusterIP\"},\"status\":{\"loadBalancer\":{}}}\n"
"kubectl.kubernetes.io/last-applied-configuration": "{\"kind\":\"Service\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"svc1\",\"labels\":{\"app\":\"svc1\"}},\"spec\":{\"ports\":[{\"name\":\"80\",\"protocol\":\"TCP\",\"port\":80,\"targetPort\":80}],\"selector\":{\"app\":\"svc1\"},\"type\":\"ClusterIP\"},\"status\":{\"loadBalancer\":{}}}\n"
},
"creationTimestamp": "2017-02-27T19:40:53Z",
"labels": {

View File

@ -7,7 +7,7 @@ kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: "2017-02-27T19:40:53Z"
labels:
app: svc1

View File

@ -7,7 +7,7 @@ kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: "2017-02-27T19:40:53Z"
labels:
app: svc1

View File

@ -33,7 +33,6 @@
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"app": "nginx"
}

View File

@ -29,7 +29,6 @@ spec:
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:

View File

@ -29,7 +29,6 @@ spec:
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:

View File

@ -33,7 +33,6 @@
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"app": "nginx"
}

View File

@ -3,7 +3,7 @@
"kind": "Service",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"kind\":\"Service\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"svc1\",\"creationTimestamp\":null,\"labels\":{\"app\":\"svc1\"}},\"spec\":{\"ports\":[{\"name\":\"80\",\"protocol\":\"TCP\",\"port\":80,\"targetPort\":80}],\"selector\":{\"app\":\"svc1\"},\"type\":\"ClusterIP\"},\"status\":{\"loadBalancer\":{}}}\n"
"kubectl.kubernetes.io/last-applied-configuration": "{\"kind\":\"Service\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"svc1\",\"labels\":{\"app\":\"svc1\"}},\"spec\":{\"ports\":[{\"name\":\"80\",\"protocol\":\"TCP\",\"port\":80,\"targetPort\":80}],\"selector\":{\"app\":\"svc1\"},\"type\":\"ClusterIP\"},\"status\":{\"loadBalancer\":{}}}\n"
},
"creationTimestamp": "2017-02-27T19:40:53Z",
"labels": {

View File

@ -7,7 +7,7 @@ kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: "2017-02-27T19:40:53Z"
labels:
app: svc1

View File

@ -7,7 +7,7 @@ kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: "2017-02-27T19:40:53Z"
labels:
app: svc1

View File

@ -3,7 +3,7 @@
"kind": "Service",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"kind\":\"Service\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"svc1\",\"creationTimestamp\":null,\"labels\":{\"app\":\"svc1\"}},\"spec\":{\"ports\":[{\"name\":\"80\",\"protocol\":\"TCP\",\"port\":80,\"targetPort\":80}],\"selector\":{\"app\":\"svc1\"},\"type\":\"ClusterIP\"},\"status\":{\"loadBalancer\":{}}}\n"
"kubectl.kubernetes.io/last-applied-configuration": "{\"kind\":\"Service\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"svc1\",\"labels\":{\"app\":\"svc1\"}},\"spec\":{\"ports\":[{\"name\":\"80\",\"protocol\":\"TCP\",\"port\":80,\"targetPort\":80}],\"selector\":{\"app\":\"svc1\"},\"type\":\"ClusterIP\"},\"status\":{\"loadBalancer\":{}}}\n"
},
"creationTimestamp": "2017-02-27T19:40:53Z",
"labels": {

View File

@ -7,7 +7,7 @@ kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: "2017-02-27T19:40:53Z"
labels:
app: svc1

View File

@ -7,7 +7,7 @@ kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: "2017-02-27T19:40:53Z"
labels:
app: svc1

View File

@ -18,11 +18,12 @@ package events
import (
"bytes"
"testing"
"time"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"testing"
"time"
)
func TestPrintObj(t *testing.T) {
@ -50,7 +51,7 @@ func TestPrintObj(t *testing.T) {
},
Type: corev1.EventTypeNormal,
Reason: "ScalingReplicaSet",
Message: "Scaled up replica set bar-002 to 1",
Message: "Scaled up replica set bar-002 from 0 to 1",
ReportingController: "deployment-controller",
EventTime: metav1.NewMicroTime(time.Now().Add(-20 * time.Minute)),
Series: &corev1.EventSeries{
@ -59,7 +60,7 @@ func TestPrintObj(t *testing.T) {
},
},
expected: `LAST SEEN TYPE REASON OBJECT MESSAGE
12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
`,
},
{
@ -83,7 +84,7 @@ func TestPrintObj(t *testing.T) {
},
Type: corev1.EventTypeNormal,
Reason: "ScalingReplicaSet",
Message: "Scaled up replica set bar-002 to 1",
Message: "Scaled up replica set bar-002 from 0 to 1",
ReportingController: "deployment-controller",
EventTime: metav1.NewMicroTime(time.Now().Add(-20 * time.Minute)),
Series: &corev1.EventSeries{
@ -105,7 +106,7 @@ func TestPrintObj(t *testing.T) {
},
Type: corev1.EventTypeNormal,
Reason: "ScalingReplicaSet",
Message: "Scaled up replica set bar-002 to 1",
Message: "Scaled up replica set bar-002 from 0 to 1",
ReportingController: "deployment-controller",
EventTime: metav1.NewMicroTime(time.Now().Add(-15 * time.Minute)),
Series: &corev1.EventSeries{
@ -116,8 +117,8 @@ func TestPrintObj(t *testing.T) {
},
},
expected: `NAMESPACE LAST SEEN TYPE REASON OBJECT MESSAGE
foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
bar 11m (x3 over 15m) Normal ScalingReplicaSet Deployment/bar2 Scaled up replica set bar-002 to 1
foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
bar 11m (x3 over 15m) Normal ScalingReplicaSet Deployment/bar2 Scaled up replica set bar-002 from 0 to 1
`,
},
{
@ -139,7 +140,7 @@ bar 11m (x3 over 15m) Normal ScalingReplicaSet Deployment/bar2 Scaled up replica
},
Type: corev1.EventTypeNormal,
Reason: "ScalingReplicaSet",
Message: "Scaled up replica set bar-002 to 1",
Message: "Scaled up replica set bar-002 from 0 to 1",
ReportingController: "deployment-controller",
EventTime: metav1.NewMicroTime(time.Now().Add(-20 * time.Minute)),
Series: &corev1.EventSeries{
@ -147,7 +148,7 @@ bar 11m (x3 over 15m) Normal ScalingReplicaSet Deployment/bar2 Scaled up replica
LastObservedTime: metav1.NewMicroTime(time.Now().Add(-12 * time.Minute)),
},
},
expected: "12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1\n",
expected: "12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1\n",
},
{
printer: EventPrinter{
@ -168,7 +169,7 @@ bar 11m (x3 over 15m) Normal ScalingReplicaSet Deployment/bar2 Scaled up replica
},
Type: corev1.EventTypeNormal,
Reason: "ScalingReplicaSet",
Message: "Scaled up replica set bar-002 to 1",
Message: "Scaled up replica set bar-002 from 0 to 1",
ReportingController: "deployment-controller",
EventTime: metav1.NewMicroTime(time.Now().Add(-20 * time.Minute)),
Series: &corev1.EventSeries{
@ -177,7 +178,7 @@ bar 11m (x3 over 15m) Normal ScalingReplicaSet Deployment/bar2 Scaled up replica
},
},
expected: `NAMESPACE LAST SEEN TYPE REASON OBJECT MESSAGE
foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
`,
},
{
@ -199,7 +200,7 @@ foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica
},
Type: corev1.EventTypeNormal,
Reason: "ScalingReplicaSet",
Message: "Scaled up replica set bar-002 to 1",
Message: "Scaled up replica set bar-002 from 0 to 1",
ReportingController: "deployment-controller",
EventTime: metav1.NewMicroTime(time.Now().Add(-20 * time.Minute)),
Series: &corev1.EventSeries{
@ -207,7 +208,7 @@ foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica
LastObservedTime: metav1.NewMicroTime(time.Now().Add(-12 * time.Minute)),
},
},
expected: `foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
expected: `foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
`,
},
{

View File

@ -188,7 +188,7 @@ func (flags *EventsFlags) ToOptions() (*EventsOptions, error) {
}
if len(o.FilterTypes) > 0 {
o.FilterTypes = sets.NewString(o.FilterTypes...).List()
o.FilterTypes = sets.List(sets.New[string](o.FilterTypes...))
}
var printer printers.ResourcePrinter

View File

@ -50,7 +50,7 @@ func getFakeEvents() *corev1.EventList {
},
Type: corev1.EventTypeNormal,
Reason: "ScalingReplicaSet",
Message: "Scaled up replica set bar-002 to 1",
Message: "Scaled up replica set bar-002 from 0 to 1",
ReportingController: "deployment-controller",
EventTime: metav1.NewMicroTime(time.Now().Add(-30 * time.Minute)),
Series: &corev1.EventSeries{
@ -72,7 +72,7 @@ func getFakeEvents() *corev1.EventList {
},
Type: corev1.EventTypeWarning,
Reason: "ScalingReplicaSet",
Message: "Scaled up replica set bar-002 to 1",
Message: "Scaled up replica set bar-002 from 0 to 1",
ReportingController: "deployment-controller",
EventTime: metav1.NewMicroTime(time.Now().Add(-28 * time.Minute)),
Series: &corev1.EventSeries{
@ -94,7 +94,7 @@ func getFakeEvents() *corev1.EventList {
},
Type: corev1.EventTypeNormal,
Reason: "ScalingReplicaSet",
Message: "Scaled up replica set bar-002 to 1",
Message: "Scaled up replica set bar-002 from 0 to 1",
ReportingController: "deployment-controller",
EventTime: metav1.NewMicroTime(time.Now().Add(-25 * time.Minute)),
Series: &corev1.EventSeries{
@ -135,9 +135,9 @@ func TestEventIsSorted(t *testing.T) {
}
expected := `NAMESPACE LAST SEEN TYPE REASON OBJECT MESSAGE
foo 20m (x3 over 30m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
foo 18m (x3 over 28m) Warning ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
otherfoo 15m (x3 over 25m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
foo 20m (x3 over 30m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
foo 18m (x3 over 28m) Warning ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
otherfoo 15m (x3 over 25m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected\n%v\ngot\n%v", e, a)
@ -172,9 +172,9 @@ func TestEventNoHeaders(t *testing.T) {
t.Fatal(err)
}
expected := `foo 20m (x3 over 30m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
foo 18m (x3 over 28m) Warning ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
otherfoo 15m (x3 over 25m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
expected := `foo 20m (x3 over 30m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
foo 18m (x3 over 28m) Warning ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
otherfoo 15m (x3 over 25m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected\n%v\ngot\n%v", e, a)
@ -211,7 +211,7 @@ func TestEventFiltered(t *testing.T) {
}
expected := `NAMESPACE LAST SEEN TYPE REASON OBJECT MESSAGE
foo 18m (x3 over 28m) Warning ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1
foo 18m (x3 over 28m) Warning ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 from 0 to 1
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected\n%v\ngot\n%v", e, a)

View File

@ -114,18 +114,26 @@ func NewCmdExec(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Co
// RemoteExecutor defines the interface accepted by the Exec command - provided for test stubbing
type RemoteExecutor interface {
// Execute supports executing remote command in a pod.
Execute(url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error
// ExecuteWithContext, in contrast to Execute, supports stopping the remote command via context cancellation.
ExecuteWithContext(ctx context.Context, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error
}
// DefaultRemoteExecutor is the standard implementation of remote command execution
type DefaultRemoteExecutor struct{}
func (*DefaultRemoteExecutor) Execute(url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error {
func (d *DefaultRemoteExecutor) Execute(url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error {
return d.ExecuteWithContext(context.Background(), url, config, stdin, stdout, stderr, tty, terminalSizeQueue)
}
func (*DefaultRemoteExecutor) ExecuteWithContext(ctx context.Context, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error {
exec, err := createExecutor(url, config)
if err != nil {
return err
}
return exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{
return exec.StreamWithContext(ctx, remotecommand.StreamOptions{
Stdin: stdin,
Stdout: stdout,
Stderr: stderr,
@ -216,7 +224,7 @@ func (p *ExecOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, argsIn []s
p.GetPodTimeout, err = cmdutil.GetPodRunningTimeoutFlag(cmd)
if err != nil {
return cmdutil.UsageErrorf(cmd, err.Error())
return cmdutil.UsageErrorf(cmd, "%s", err.Error())
}
p.Builder = f.NewBuilder

View File

@ -18,6 +18,7 @@ package exec
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
@ -45,6 +46,10 @@ type fakeRemoteExecutor struct {
}
func (f *fakeRemoteExecutor) Execute(url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error {
return f.ExecuteWithContext(context.Background(), url, config, stdin, stdout, stderr, tty, terminalSizeQueue)
}
func (f *fakeRemoteExecutor) ExecuteWithContext(ctx context.Context, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error {
f.url = url
return f.execErr
}

View File

@ -56,83 +56,113 @@ var (
# Get the documentation of a specific field of a resource
kubectl explain pods.spec.containers
# Get the documentation of resources in different format
kubectl explain deployment --output=plaintext-openapiv2`))
)
const (
plaintextTemplateName = "plaintext"
plaintextOpenAPIV2TemplateName = "plaintext-openapiv2"
)
type ExplainOptions struct {
genericiooptions.IOStreams
CmdParent string
APIVersion string
Recursive bool
args []string
Mapper meta.RESTMapper
openAPIGetter openapi.OpenAPIResourcesGetter
// Name of the template to use with the openapiv3 template renderer.
// ExplainFlags directly reflect the information that CLI is gathering via flags.
// They will be converted to Options, which reflect the runtime requirements for
// the command.
type ExplainFlags struct {
APIVersion string
OutputFormat string
Recursive bool
// Client capable of fetching openapi documents from the user's cluster
OpenAPIV3Client openapiclient.Client
genericiooptions.IOStreams
}
func NewExplainOptions(parent string, streams genericiooptions.IOStreams) *ExplainOptions {
return &ExplainOptions{
IOStreams: streams,
CmdParent: parent,
// NewExplainFlags returns a default ExplainFlags
func NewExplainFlags(streams genericiooptions.IOStreams) *ExplainFlags {
return &ExplainFlags{
OutputFormat: plaintextTemplateName,
IOStreams: streams,
}
}
// AddFlags registers flags for a cli
func (flags *ExplainFlags) AddFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(&flags.Recursive, "recursive", flags.Recursive, "Print the fields of fields (Currently only 1 level deep)")
cmd.Flags().StringVar(&flags.APIVersion, "api-version", flags.APIVersion, "Get different explanations for particular API version (API group/version)")
cmd.Flags().StringVarP(&flags.OutputFormat, "output", "o", plaintextTemplateName, "Format in which to render the schema (plaintext, plaintext-openapiv2)")
}
// ToOptions converts from CLI inputs to runtime input
func (flags *ExplainFlags) ToOptions(f cmdutil.Factory, parent string, args []string) (*ExplainOptions, error) {
mapper, err := f.ToRESTMapper()
if err != nil {
return nil, err
}
// Only openapi v3 needs the discovery client.
openAPIV3Client, err := f.OpenAPIV3Client()
if err != nil {
return nil, err
}
o := &ExplainOptions{
IOStreams: flags.IOStreams,
Recursive: flags.Recursive,
APIVersion: flags.APIVersion,
OutputFormat: flags.OutputFormat,
CmdParent: parent,
args: args,
Mapper: mapper,
openAPIGetter: f,
OpenAPIV3Client: openAPIV3Client,
}
return o, nil
}
// NewCmdExplain returns a cobra command for swagger docs
func NewCmdExplain(parent string, f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command {
o := NewExplainOptions(parent, streams)
flags := NewExplainFlags(streams)
cmd := &cobra.Command{
Use: "explain TYPE [--recursive=FALSE|TRUE] [--api-version=api-version-group] [--output=plaintext|plaintext-openapiv2]",
Use: "explain TYPE [--recursive=FALSE|TRUE] [--api-version=api-version-group] [-o|--output=plaintext|plaintext-openapiv2]",
DisableFlagsInUseLine: true,
Short: i18n.T("Get documentation for a resource"),
Long: explainLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
Example: explainExamples,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))
o, err := flags.ToOptions(f, parent, args)
cmdutil.CheckErr(err)
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.Run())
},
}
cmd.Flags().BoolVar(&o.Recursive, "recursive", o.Recursive, "When true, print the name of all the fields recursively. Otherwise, print the available fields with their description.")
cmd.Flags().StringVar(&o.APIVersion, "api-version", o.APIVersion, "Use given api-version (group/version) of the resource.")
// Only enable --output as a valid flag if the feature is enabled
cmd.Flags().StringVar(&o.OutputFormat, "output", plaintextTemplateName, "Format in which to render the schema. Valid values are: (plaintext, plaintext-openapiv2).")
flags.AddFlags(cmd)
return cmd
}
func (o *ExplainOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
var err error
o.Mapper, err = f.ToRESTMapper()
if err != nil {
return err
}
type ExplainOptions struct {
genericiooptions.IOStreams
// Only openapi v3 needs the discovery client.
o.OpenAPIV3Client, err = f.OpenAPIV3Client()
if err != nil {
return err
}
Recursive bool
APIVersion string
// Name of the template to use with the openapiv3 template renderer.
OutputFormat string
// Lazy-load the OpenAPI V2 Resources, so they're not loaded when using OpenAPI V3.
o.openAPIGetter = f
o.args = args
return nil
CmdParent string
args []string
Mapper meta.RESTMapper
openAPIGetter openapi.OpenAPIResourcesGetter
// Client capable of fetching openapi documents from the user's cluster
OpenAPIV3Client openapiclient.Client
}
func (o *ExplainOptions) Validate() error {

View File

@ -57,9 +57,9 @@ func TestExplainInvalidArgs(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
opts := explain.NewExplainOptions("kubectl", genericiooptions.NewTestIOStreamsDiscard())
cmd := explain.NewCmdExplain("kubectl", tf, genericiooptions.NewTestIOStreamsDiscard())
err := opts.Complete(tf, cmd, []string{})
flags := explain.NewExplainFlags(genericiooptions.NewTestIOStreamsDiscard())
opts, err := flags.ToOptions(tf, "kubectl", []string{})
if err != nil {
t.Fatalf("unexpected error %v", err)
}
@ -69,7 +69,7 @@ func TestExplainInvalidArgs(t *testing.T) {
t.Error("unexpected non-error")
}
err = opts.Complete(tf, cmd, []string{"resource1", "resource2"})
opts, err = flags.ToOptions(tf, "kubectl", []string{"resource1", "resource2"})
if err != nil {
t.Fatalf("unexpected error %v", err)
}
@ -84,9 +84,9 @@ func TestExplainNotExistResource(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
opts := explain.NewExplainOptions("kubectl", genericiooptions.NewTestIOStreamsDiscard())
cmd := explain.NewCmdExplain("kubectl", tf, genericiooptions.NewTestIOStreamsDiscard())
err := opts.Complete(tf, cmd, []string{"foo"})
flags := explain.NewExplainFlags(genericiooptions.NewTestIOStreamsDiscard())
opts, err := flags.ToOptions(tf, "kubectl", []string{"foo"})
if err != nil {
t.Fatalf("unexpected error %v", err)
}

View File

@ -694,7 +694,6 @@ func TestExposeOverride(t *testing.T) {
expected: `apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
svc: test
name: foo
@ -717,7 +716,6 @@ status:
expected: `apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
svc: test
name: foo
@ -745,7 +743,6 @@ status:
expected: `apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
svc: test
name: foo
@ -773,7 +770,6 @@ status:
expected: `apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
svc: test
name: foo

View File

@ -19,6 +19,7 @@ package get
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"reflect"
@ -161,7 +162,7 @@ func (s *CustomColumnsPrinter) PrintObj(obj runtime.Object, out io.Writer) error
// we need an actual value in order to retrieve the package path for an object.
// using reflect.Indirect indiscriminately is valid here, as all runtime.Objects are supposed to be pointers.
if printers.InternalObjectPreventer.IsForbidden(reflect.Indirect(reflect.ValueOf(obj)).Type().PkgPath()) {
return fmt.Errorf(printers.InternalObjectPrinterErr)
return errors.New(printers.InternalObjectPrinterErr)
}
if _, found := out.(*tabwriter.Writer); !found {
@ -210,7 +211,7 @@ func (s *CustomColumnsPrinter) printOneObject(obj runtime.Object, parsers []*jso
switch u := obj.(type) {
case *metav1.WatchEvent:
if printers.InternalObjectPreventer.IsForbidden(reflect.Indirect(reflect.ValueOf(u.Object.Object)).Type().PkgPath()) {
return fmt.Errorf(printers.InternalObjectPrinterErr)
return errors.New(printers.InternalObjectPrinterErr)
}
unstructuredObject, err := runtime.DefaultUnstructuredConverter.ToUnstructured(u.Object.Object)
if err != nil {

View File

@ -47,7 +47,6 @@ import (
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/interrupt"
"k8s.io/kubectl/pkg/util/slice"
"k8s.io/kubectl/pkg/util/templates"
"k8s.io/utils/ptr"
)
@ -145,8 +144,6 @@ const (
useServerPrintColumns = "server-print"
)
var supportedSubresources = []string{"status", "scale"}
// NewGetOptions returns a GetOptions with default chunk size 500.
func NewGetOptions(parent string, streams genericiooptions.IOStreams) *GetOptions {
return &GetOptions{
@ -192,7 +189,7 @@ func NewCmdGet(parent string, f cmdutil.Factory, streams genericiooptions.IOStre
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "identifying the resource to get from a server.")
cmdutil.AddChunkSizeFlag(cmd, &o.ChunkSize)
cmdutil.AddLabelSelectorFlagVar(cmd, &o.LabelSelector)
cmdutil.AddSubresourceFlags(cmd, &o.Subresource, "If specified, gets the subresource of the requested object.", supportedSubresources...)
cmdutil.AddSubresourceFlags(cmd, &o.Subresource, "If specified, gets the subresource of the requested object.")
return cmd
}
@ -290,7 +287,7 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
usageString = fmt.Sprintf("%s\nUse \"%s explain <resource>\" for a detailed description of that resource (e.g. %[2]s explain pods).", usageString, fullCmdName)
}
return cmdutil.UsageErrorf(cmd, usageString)
return cmdutil.UsageErrorf(cmd, "%s", usageString)
}
}
@ -319,9 +316,6 @@ func (o *GetOptions) Validate() error {
if o.OutputWatchEvents && !(o.Watch || o.WatchOnly) {
return fmt.Errorf("--output-watch-events option can only be used with --watch or --watch-only")
}
if len(o.Subresource) > 0 && !slice.ContainsString(supportedSubresources, o.Subresource, nil) {
return fmt.Errorf("invalid subresource value: %q. Must be one of %v", o.Subresource, supportedSubresources)
}
return nil
}
@ -492,7 +486,7 @@ func (o *GetOptions) Run(f cmdutil.Factory, args []string) error {
}
allErrs := []error{}
errs := sets.NewString()
errs := sets.New[string]()
infos, err := r.Infos()
if err != nil {
allErrs = append(allErrs, err)

View File

@ -1438,7 +1438,6 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": null,
"name": "foo",
"namespace": "test",
"resourceVersion": "10"
@ -1457,7 +1456,6 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": null,
"name": "bar",
"namespace": "test",
"resourceVersion": "11"
@ -1476,7 +1474,6 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"creationTimestamp": null,
"name": "baz",
"namespace": "test",
"resourceVersion": "12"
@ -2367,10 +2364,10 @@ DELETED test pod/foo 0/0 0 <unknown> <none>
},
{
format: "json",
expected: `{"type":"ADDED","object":{"apiVersion":"v1","kind":"Pod","metadata":{"creationTimestamp":null,"name":"bar","namespace":"test","resourceVersion":"9"},"spec":{"containers":null,"dnsPolicy":"ClusterFirst","enableServiceLinks":true,"restartPolicy":"Always","securityContext":{},"terminationGracePeriodSeconds":30},"status":{}}}
{"type":"ADDED","object":{"apiVersion":"v1","kind":"Pod","metadata":{"creationTimestamp":null,"name":"foo","namespace":"test","resourceVersion":"10"},"spec":{"containers":null,"dnsPolicy":"ClusterFirst","enableServiceLinks":true,"restartPolicy":"Always","securityContext":{},"terminationGracePeriodSeconds":30},"status":{}}}
{"type":"MODIFIED","object":{"apiVersion":"v1","kind":"Pod","metadata":{"creationTimestamp":null,"name":"foo","namespace":"test","resourceVersion":"11"},"spec":{"containers":null,"dnsPolicy":"ClusterFirst","enableServiceLinks":true,"restartPolicy":"Always","securityContext":{},"terminationGracePeriodSeconds":30},"status":{}}}
{"type":"DELETED","object":{"apiVersion":"v1","kind":"Pod","metadata":{"creationTimestamp":null,"name":"foo","namespace":"test","resourceVersion":"12"},"spec":{"containers":null,"dnsPolicy":"ClusterFirst","enableServiceLinks":true,"restartPolicy":"Always","securityContext":{},"terminationGracePeriodSeconds":30},"status":{}}}
expected: `{"type":"ADDED","object":{"apiVersion":"v1","kind":"Pod","metadata":{"name":"bar","namespace":"test","resourceVersion":"9"},"spec":{"containers":null,"dnsPolicy":"ClusterFirst","enableServiceLinks":true,"restartPolicy":"Always","securityContext":{},"terminationGracePeriodSeconds":30},"status":{}}}
{"type":"ADDED","object":{"apiVersion":"v1","kind":"Pod","metadata":{"name":"foo","namespace":"test","resourceVersion":"10"},"spec":{"containers":null,"dnsPolicy":"ClusterFirst","enableServiceLinks":true,"restartPolicy":"Always","securityContext":{},"terminationGracePeriodSeconds":30},"status":{}}}
{"type":"MODIFIED","object":{"apiVersion":"v1","kind":"Pod","metadata":{"name":"foo","namespace":"test","resourceVersion":"11"},"spec":{"containers":null,"dnsPolicy":"ClusterFirst","enableServiceLinks":true,"restartPolicy":"Always","securityContext":{},"terminationGracePeriodSeconds":30},"status":{}}}
{"type":"DELETED","object":{"apiVersion":"v1","kind":"Pod","metadata":{"name":"foo","namespace":"test","resourceVersion":"12"},"spec":{"containers":null,"dnsPolicy":"ClusterFirst","enableServiceLinks":true,"restartPolicy":"Always","securityContext":{},"terminationGracePeriodSeconds":30},"status":{}}}
`,
},
{
@ -2379,7 +2376,6 @@ DELETED test pod/foo 0/0 0 <unknown> <none>
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: bar
namespace: test
resourceVersion: "9"
@ -2397,7 +2393,6 @@ object:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: foo
namespace: test
resourceVersion: "10"
@ -2415,7 +2410,6 @@ object:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: foo
namespace: test
resourceVersion: "11"
@ -2433,7 +2427,6 @@ object:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: foo
namespace: test
resourceVersion: "12"

View File

@ -41,6 +41,7 @@ import (
"k8s.io/kubectl/pkg/util"
"k8s.io/kubectl/pkg/util/completion"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/interrupt"
"k8s.io/kubectl/pkg/util/templates"
)
@ -57,15 +58,33 @@ var (
# Return snapshot logs from pod nginx with only one container
kubectl logs nginx
# Return snapshot logs from pod nginx, prefixing each line with the source pod and container name
kubectl logs nginx --prefix
# Return snapshot logs from pod nginx, limiting output to 500 bytes
kubectl logs nginx --limit-bytes=500
# Return snapshot logs from pod nginx, waiting up to 20 seconds for it to start running.
kubectl logs nginx --pod-running-timeout=20s
# Return snapshot logs from pod nginx with multi containers
kubectl logs nginx --all-containers=true
# Return snapshot logs from all pods in the deployment nginx
kubectl logs deployment/nginx --all-pods=true
# Return snapshot logs from all containers in pods defined by label app=nginx
kubectl logs -l app=nginx --all-containers=true
# Return snapshot logs from all pods defined by label app=nginx, limiting concurrent log requests to 10 pods
kubectl logs -l app=nginx --max-log-requests=10
# Return snapshot of previous terminated ruby container logs from pod web-1
kubectl logs -p -c ruby web-1
# Begin streaming the logs from pod nginx, continuing even if errors occur
kubectl logs nginx -f --ignore-errors=true
# Begin streaming the logs of the ruby container in pod web-1
kubectl logs -f -c ruby web-1
@ -77,6 +96,9 @@ var (
# Show all logs from pod nginx written in the last hour
kubectl logs --since=1h nginx
# Show all logs with timestamps from pod nginx starting from August 30, 2024, at 06:00:00 UTC
kubectl logs nginx --since-time=2024-08-30T06:00:00Z --timestamps=true
# Show logs from a kubelet with an expired serving certificate
kubectl logs --insecure-skip-tls-verify-backend nginx
@ -103,7 +125,7 @@ type LogsOptions struct {
Options runtime.Object
Resources []string
ConsumeRequestFn func(rest.ResponseWrapper, io.Writer) error
ConsumeRequestFn func(context.Context, rest.ResponseWrapper, io.Writer) error
// PodLogOptions
SinceTime string
@ -354,14 +376,21 @@ func (o LogsOptions) RunLogs() error {
len(requests), o.MaxFollowConcurrency,
)
}
return o.parallelConsumeRequest(requests)
}
return o.sequentialConsumeRequest(requests)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
intr := interrupt.New(nil, cancel)
return intr.Run(func() error {
if o.Follow && len(requests) > 1 {
return o.parallelConsumeRequest(ctx, requests)
}
return o.sequentialConsumeRequest(ctx, requests)
})
}
func (o LogsOptions) parallelConsumeRequest(requests map[corev1.ObjectReference]rest.ResponseWrapper) error {
func (o LogsOptions) parallelConsumeRequest(ctx context.Context, requests map[corev1.ObjectReference]rest.ResponseWrapper) error {
reader, writer := io.Pipe()
wg := &sync.WaitGroup{}
wg.Add(len(requests))
@ -369,7 +398,7 @@ func (o LogsOptions) parallelConsumeRequest(requests map[corev1.ObjectReference]
go func(objRef corev1.ObjectReference, request rest.ResponseWrapper) {
defer wg.Done()
out := o.addPrefixIfNeeded(objRef, writer)
if err := o.ConsumeRequestFn(request, out); err != nil {
if err := o.ConsumeRequestFn(ctx, request, out); err != nil {
if !o.IgnoreLogErrors {
writer.CloseWithError(err)
@ -392,10 +421,10 @@ func (o LogsOptions) parallelConsumeRequest(requests map[corev1.ObjectReference]
return err
}
func (o LogsOptions) sequentialConsumeRequest(requests map[corev1.ObjectReference]rest.ResponseWrapper) error {
func (o LogsOptions) sequentialConsumeRequest(ctx context.Context, requests map[corev1.ObjectReference]rest.ResponseWrapper) error {
for objRef, request := range requests {
out := o.addPrefixIfNeeded(objRef, o.Out)
if err := o.ConsumeRequestFn(request, out); err != nil {
if err := o.ConsumeRequestFn(ctx, request, out); err != nil {
if !o.IgnoreLogErrors {
return err
}
@ -436,8 +465,8 @@ func (o LogsOptions) addPrefixIfNeeded(ref corev1.ObjectReference, writer io.Wri
// A successful read returns err == nil, not err == io.EOF.
// Because the function is defined to read from request until io.EOF, it does
// not treat an io.EOF as an error to be reported.
func DefaultConsumeRequest(request rest.ResponseWrapper, out io.Writer) error {
readCloser, err := request.Stream(context.TODO())
func DefaultConsumeRequest(ctx context.Context, request rest.ResponseWrapper, out io.Writer) error {
readCloser, err := request.Stream(ctx)
if err != nil {
return err
}

View File

@ -304,7 +304,7 @@ func TestLog(t *testing.T) {
o := NewLogsOptions(streams)
o.LogsForObject = mock.mockLogsForObject
o.ConsumeRequestFn = func(req restclient.ResponseWrapper, out io.Writer) error {
o.ConsumeRequestFn = func(ctx context.Context, req restclient.ResponseWrapper, out io.Writer) error {
return errors.New("Error from the ConsumeRequestFn")
}
return o
@ -378,7 +378,7 @@ func TestLog(t *testing.T) {
o := NewLogsOptions(streams)
o.LogsForObject = mock.mockLogsForObject
o.ConsumeRequestFn = func(req restclient.ResponseWrapper, out io.Writer) error {
o.ConsumeRequestFn = func(ctx context.Context, req restclient.ResponseWrapper, out io.Writer) error {
return errors.New("Error from the ConsumeRequestFn")
}
o.Follow = true
@ -401,7 +401,7 @@ func TestLog(t *testing.T) {
o := NewLogsOptions(streams)
o.LogsForObject = mock.mockLogsForObject
o.ConsumeRequestFn = func(req restclient.ResponseWrapper, out io.Writer) error {
o.ConsumeRequestFn = func(ctx context.Context, req restclient.ResponseWrapper, out io.Writer) error {
return errors.New("Error from the ConsumeRequestFn")
}
o.Follow = true
@ -808,7 +808,7 @@ func TestDefaultConsumeRequest(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
buf := &bytes.Buffer{}
err := DefaultConsumeRequest(test.request, buf)
err := DefaultConsumeRequest(context.TODO(), test.request, buf)
if err != nil && !strings.Contains(err.Error(), test.expectedErr) {
t.Errorf("%s: expected to find:\n\t%s\nfound:\n\t%s\n", test.name, test.expectedErr, err.Error())
@ -932,8 +932,8 @@ type logTestMock struct {
wg *sync.WaitGroup
}
func (l *logTestMock) mockConsumeRequest(request restclient.ResponseWrapper, out io.Writer) error {
readCloser, err := request.Stream(context.Background())
func (l *logTestMock) mockConsumeRequest(ctx context.Context, request restclient.ResponseWrapper, out io.Writer) error {
readCloser, err := request.Stream(ctx)
if err != nil {
return err
}

View File

@ -22,7 +22,6 @@ import (
"reflect"
"strings"
"github.com/pkg/errors"
"github.com/spf13/cobra"
jsonpatch "gopkg.in/evanphx/json-patch.v4"
"k8s.io/klog/v2"
@ -45,7 +44,6 @@ import (
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/completion"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/slice"
"k8s.io/kubectl/pkg/util/templates"
)
@ -107,8 +105,6 @@ var (
kubectl patch deployment nginx-deployment --subresource='scale' --type='merge' -p '{"spec":{"replicas":2}}'`))
)
var supportedSubresources = []string{"status", "scale"}
func NewPatchOptions(ioStreams genericiooptions.IOStreams) *PatchOptions {
return &PatchOptions{
RecordFlags: genericclioptions.NewRecordFlags(),
@ -140,12 +136,12 @@ func NewCmdPatch(f cmdutil.Factory, ioStreams genericiooptions.IOStreams) *cobra
cmd.Flags().StringVarP(&o.Patch, "patch", "p", "", "The patch to be applied to the resource JSON file.")
cmd.Flags().StringVar(&o.PatchFile, "patch-file", "", "A file containing a patch to be applied to the resource.")
cmd.Flags().StringVar(&o.PatchType, "type", "strategic", fmt.Sprintf("The type of patch being provided; one of %v", sets.StringKeySet(patchTypes).List()))
cmd.Flags().StringVar(&o.PatchType, "type", "strategic", fmt.Sprintf("The type of patch being provided; one of %v", sets.List(sets.KeySet(patchTypes))))
cmdutil.AddDryRunFlag(cmd)
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "identifying the resource to update")
cmd.Flags().BoolVar(&o.Local, "local", o.Local, "If true, patch will operate on the content of the file, not the server-side resource.")
cmdutil.AddFieldManagerFlagVar(cmd, &o.fieldManager, "kubectl-patch")
cmdutil.AddSubresourceFlags(cmd, &o.Subresource, "If specified, patch will operate on the subresource of the requested object.", supportedSubresources...)
cmdutil.AddSubresourceFlags(cmd, &o.Subresource, "If specified, patch will operate on the subresource of the requested object.")
return cmd
}
@ -197,12 +193,9 @@ func (o *PatchOptions) Validate() error {
}
if len(o.PatchType) != 0 {
if _, ok := patchTypes[strings.ToLower(o.PatchType)]; !ok {
return fmt.Errorf("--type must be one of %v, not %q", sets.StringKeySet(patchTypes).List(), o.PatchType)
return fmt.Errorf("--type must be one of %v, not %q", sets.List(sets.KeySet(patchTypes)), o.PatchType)
}
}
if len(o.Subresource) > 0 && !slice.ContainsString(supportedSubresources, o.Subresource, nil) {
return fmt.Errorf("invalid subresource value: %q. Must be one of %v", o.Subresource, supportedSubresources)
}
return nil
}
@ -266,7 +259,7 @@ func (o *PatchOptions) RunPatch() error {
patchedObj, err := helper.Patch(namespace, name, patchType, patchBytes, nil)
if err != nil {
if apierrors.IsUnsupportedMediaType(err) {
return errors.Wrap(err, fmt.Sprintf("%s is not supported by %s", patchType, mapping.GroupVersionKind))
return fmt.Errorf("%s is not supported by %s: %w", patchType, mapping.GroupVersionKind, err)
}
return err
}

View File

@ -223,7 +223,9 @@ func convertPodNamedPortToNumber(ports []string, pod corev1.Pod) ([]string, erro
var converted []string
for _, port := range ports {
localPort, remotePort := splitPort(port)
if remotePort == "" {
return nil, fmt.Errorf("remote port cannot be empty")
}
containerPortStr := remotePort
_, err := strconv.Atoi(remotePort)
if err != nil {
@ -245,7 +247,7 @@ func convertPodNamedPortToNumber(ports []string, pod corev1.Pod) ([]string, erro
return converted, nil
}
func checkUDPPorts(udpOnlyPorts sets.Int, ports []string, obj metav1.Object) error {
func checkUDPPorts(udpOnlyPorts sets.Set[int], ports []string, obj metav1.Object) error {
for _, port := range ports {
_, remotePort := splitPort(port)
portNum, err := strconv.Atoi(remotePort)
@ -279,8 +281,8 @@ func checkUDPPorts(udpOnlyPorts sets.Int, ports []string, obj metav1.Object) err
// checkUDPPortInService returns an error if remote port in Service is a UDP port
// TODO: remove this check after #47862 is solved
func checkUDPPortInService(ports []string, svc *corev1.Service) error {
udpPorts := sets.NewInt()
tcpPorts := sets.NewInt()
udpPorts := sets.New[int]()
tcpPorts := sets.New[int]()
for _, port := range svc.Spec.Ports {
portNum := int(port.Port)
switch port.Protocol {
@ -296,8 +298,8 @@ func checkUDPPortInService(ports []string, svc *corev1.Service) error {
// checkUDPPortInPod returns an error if remote port in Pod is a UDP port
// TODO: remove this check after #47862 is solved
func checkUDPPortInPod(ports []string, pod *corev1.Pod) error {
udpPorts := sets.NewInt()
tcpPorts := sets.NewInt()
udpPorts := sets.New[int]()
tcpPorts := sets.New[int]()
for _, ct := range pod.Spec.Containers {
for _, ctPort := range ct.Ports {
portNum := int(ctPort.ContainerPort)
@ -331,7 +333,7 @@ func (o *PortForwardOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
getPodTimeout, err := cmdutil.GetPodRunningTimeoutFlag(cmd)
if err != nil {
return cmdutil.UsageErrorf(cmd, err.Error())
return cmdutil.UsageErrorf(cmd, "%s", err.Error())
}
resourceName := args[0]

View File

@ -820,6 +820,24 @@ func TestConvertPodNamedPortToNumber(t *testing.T) {
ports: []string{"https", "http"},
err: true,
},
{
name: "empty port name",
pod: corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Ports: []corev1.ContainerPort{
{
ContainerPort: int32(27017)},
},
},
},
},
},
ports: []string{"28015:"},
converted: nil,
err: true,
},
}
for _, tc := range cases {

View File

@ -17,6 +17,7 @@ limitations under the License.
package replace
import (
"context"
"fmt"
"net/url"
"os"
@ -40,7 +41,6 @@ import (
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/slice"
"k8s.io/kubectl/pkg/util/templates"
"k8s.io/kubectl/pkg/validation"
)
@ -68,8 +68,6 @@ var (
kubectl replace --force -f ./pod.json`))
)
var supportedSubresources = []string{"status", "scale"}
type ReplaceOptions struct {
PrintFlags *genericclioptions.PrintFlags
RecordFlags *genericclioptions.RecordFlags
@ -136,7 +134,7 @@ func NewCmdReplace(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra
cmd.Flags().StringVar(&o.Raw, "raw", o.Raw, "Raw URI to PUT to the server. Uses the transport specified by the kubeconfig file.")
cmdutil.AddFieldManagerFlagVar(cmd, &o.fieldManager, "kubectl-replace")
cmdutil.AddSubresourceFlags(cmd, &o.Subresource, "If specified, replace will operate on the subresource of the requested object.", supportedSubresources...)
cmdutil.AddSubresourceFlags(cmd, &o.Subresource, "If specified, replace will operate on the subresource of the requested object.")
return cmd
}
@ -249,10 +247,6 @@ func (o *ReplaceOptions) Validate() error {
}
}
if len(o.Subresource) > 0 && !slice.ContainsString(supportedSubresources, o.Subresource, nil) {
return fmt.Errorf("invalid subresource value: %q. Must be one of %v", o.Subresource, supportedSubresources)
}
return nil
}
@ -365,8 +359,7 @@ func (o *ReplaceOptions) forceReplace() error {
if err != nil {
return err
}
return wait.PollImmediate(1*time.Second, timeout, func() (bool, error) {
return wait.PollUntilContextTimeout(context.Background(), 1*time.Second, timeout, true, func(ctx context.Context) (bool, error) {
if err := info.Get(); !errors.IsNotFound(err) {
return false, err
}

View File

@ -105,7 +105,7 @@ func NewCmdRolloutHistory(f cmdutil.Factory, streams genericiooptions.IOStreams)
return cmd
}
// Complete completes al the required options
// Complete completes all the required options
func (o *RolloutHistoryOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Resources = args
@ -177,7 +177,15 @@ func (o *RolloutHistoryOptions) Run() error {
}
if o.Revision > 0 {
printer.PrintObj(historyInfo[o.Revision], o.Out)
// Ensure the specified revision exists before printing
revision, exists := historyInfo[o.Revision]
if !exists {
return fmt.Errorf("unable to find the specified revision")
}
if err := printer.PrintObj(revision, o.Out); err != nil {
return err
}
} else {
sortedKeys := make([]int64, 0, len(historyInfo))
for k := range historyInfo {

View File

@ -280,15 +280,12 @@ func TestRolloutHistoryWithOutput(t *testing.T) {
"kind": "ReplicaSet",
"apiVersion": "apps/v1",
"metadata": {
"name": "rev2",
"creationTimestamp": null
"name": "rev2"
},
"spec": {
"selector": null,
"template": {
"metadata": {
"creationTimestamp": null
},
"metadata": {},
"spec": {
"containers": null
}
@ -305,13 +302,11 @@ func TestRolloutHistoryWithOutput(t *testing.T) {
expectedOutput: `apiVersion: apps/v1
kind: ReplicaSet
metadata:
creationTimestamp: null
name: rev2
spec:
selector: null
template:
metadata:
creationTimestamp: null
metadata: {}
spec:
containers: null
status:
@ -323,13 +318,11 @@ status:
expectedOutput: `apiVersion: apps/v1
kind: ReplicaSet
metadata:
creationTimestamp: null
name: rev1
spec:
selector: null
template:
metadata:
creationTimestamp: null
metadata: {}
spec:
containers: null
status:
@ -338,13 +331,11 @@ status:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
creationTimestamp: null
name: rev2
spec:
selector: null
template:
metadata:
creationTimestamp: null
metadata: {}
spec:
containers: null
status:
@ -401,6 +392,88 @@ replicaset.apps/rev2
}
}
func TestRolloutHistoryErrors(t *testing.T) {
ns := scheme.Codecs.WithoutConversion()
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON)
encoder := ns.EncoderForVersion(info.Serializer, rolloutPauseGroupVersionEncoder)
tf.Client = &RolloutPauseRESTClient{
RESTClient: &fake.RESTClient{
GroupVersion: rolloutPauseGroupVersionEncoder,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/deployments/foo" && m == "GET":
responseDeployment := &appsv1.Deployment{}
responseDeployment.Name = "foo"
body := io.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(encoder, responseDeployment))))
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
},
}
testCases := map[string]struct {
revision int64
outputFormat string
expectedError string
}{
"get non-existing revision as yaml": {
revision: 999,
outputFormat: "yaml",
expectedError: "unable to find the specified revision",
},
"get non-existing revision as json": {
revision: 999,
outputFormat: "json",
expectedError: "unable to find the specified revision",
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
fhv := setupFakeHistoryViewer(t)
fhv.getHistoryFn = func(namespace, name string) (map[int64]runtime.Object, error) {
return map[int64]runtime.Object{
1: &appsv1.ReplicaSet{ObjectMeta: v1.ObjectMeta{Name: "rev1"}},
2: &appsv1.ReplicaSet{ObjectMeta: v1.ObjectMeta{Name: "rev2"}},
}, nil
}
streams := genericiooptions.NewTestIOStreamsDiscard()
o := NewRolloutHistoryOptions(streams)
printFlags := &genericclioptions.PrintFlags{
JSONYamlPrintFlags: &genericclioptions.JSONYamlPrintFlags{
ShowManagedFields: true,
},
OutputFormat: &tc.outputFormat,
OutputFlagSpecified: func() bool {
return true
},
}
o.PrintFlags = printFlags
o.Revision = tc.revision
if err := o.Complete(tf, nil, []string{"deployment/foo"}); err != nil {
t.Fatalf("unexpected error: %v", err)
}
err := o.Run()
if err != nil && err.Error() != tc.expectedError {
t.Fatalf("expected '%s' error, but got: %v", tc.expectedError, err)
}
})
}
}
func TestValidate(t *testing.T) {
opts := RolloutHistoryOptions{
Revision: 0,

View File

@ -504,7 +504,7 @@ func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *corev1.Po
return err
}
for _, request := range requests {
if err := logs.DefaultConsumeRequest(request, opts.Out); err != nil {
if err := logs.DefaultConsumeRequest(context.Background(), request, opts.Out); err != nil {
return err
}
}

View File

@ -655,7 +655,6 @@ func TestRunOverride(t *testing.T) {
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: test
name: test
@ -678,7 +677,6 @@ status: {}
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: test
name: test
@ -701,7 +699,6 @@ status: {}
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: test
name: test
@ -729,7 +726,6 @@ status: {}
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
foo: bar
run: test

View File

@ -229,6 +229,9 @@ func (o *ScaleOptions) RunScale() error {
}
if len(infos) == 0 {
if infoErr != nil {
return fmt.Errorf("no objects passed to scale %w", infoErr)
}
return fmt.Errorf("no objects passed to scale")
}

View File

@ -15,4 +15,4 @@ limitations under the License.
*/
// Package env provides functions to incorporate environment variables into set env.
package env // import "k8s.io/kubectl/pkg/cmd/set/env"
package env

View File

@ -61,7 +61,7 @@ func SplitEnvironmentFromResources(args []string) (resources, envArgs []string,
// envVarType is for making errors more specific to user intentions.
func parseIntoEnvVar(spec []string, defaultReader io.Reader, envVarType string) ([]v1.EnvVar, []string, bool, error) {
env := []v1.EnvVar{}
exists := sets.NewString()
exists := sets.New[string]()
var remove []string
usedStdin := false
for _, envSpec := range spec {

View File

@ -158,11 +158,11 @@ func splitMaybeSubscriptedPath(fieldPath string) (string, string, bool) {
// formatMap formats map[string]string to a string.
func formatMap(m map[string]string) (fmtStr string) {
// output with keys in sorted order to provide stable output
keys := sets.NewString()
keys := sets.New[string]()
for key := range m {
keys.Insert(key)
}
for _, key := range keys.List() {
for _, key := range sets.List(keys) {
fmtStr += fmt.Sprintf("%v=%q\n", key, m[key])
}
fmtStr = strings.TrimSuffix(fmtStr, "\n")

View File

@ -19,7 +19,7 @@ package set
import (
"strings"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/strategicpatch"
@ -139,7 +139,7 @@ func findEnv(env []v1.EnvVar, name string) (v1.EnvVar, bool) {
// If a variable is both added and removed, the removal takes precedence.
func updateEnv(existing []v1.EnvVar, env []v1.EnvVar, remove []string) []v1.EnvVar {
out := []v1.EnvVar{}
covered := sets.NewString(remove...)
covered := sets.New[string](remove...)
for _, e := range existing {
if covered.Has(e.Name) {
continue

View File

@ -503,7 +503,7 @@ func TestSetEnvRemote(t *testing.T) {
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"value":`+`"`+"prod"+`"`, fmt.Sprintf("env not updated for %#v", input.object))
assert.Containsf(t, string(bytes), `"value":`+`"`+"prod"+`"`, "env not updated for %#v", input.object)
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)

View File

@ -641,7 +641,7 @@ func TestSetImageRemote(t *testing.T) {
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"image":`+`"`+"thingy"+`"`, fmt.Sprintf("image not updated for %#v", input.object))
assert.Containsf(t, string(bytes), `"image":`+`"`+"thingy"+`"`, "image not updated for %#v", input.object)
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
@ -753,8 +753,8 @@ func TestSetImageRemoteWithSpecificContainers(t *testing.T) {
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"image":"`+"thingy"+`","name":`+`"nginx"`, fmt.Sprintf("image not updated for %#v", input.object))
assert.NotContains(t, string(bytes), `"image":"`+"thingy"+`","name":`+`"busybox"`, fmt.Sprintf("image updated for %#v", input.object))
assert.Containsf(t, string(bytes), `"image":"`+"thingy"+`","name":`+`"nginx"`, "image not updated for %#v", input.object)
assert.NotContainsf(t, string(bytes), `"image":"`+"thingy"+`","name":`+`"busybox"`, "image updated for %#v", input.object)
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)

View File

@ -487,7 +487,7 @@ func TestSetResourcesRemote(t *testing.T) {
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), "200m", fmt.Sprintf("resources not updated for %#v", input.object))
assert.Containsf(t, string(bytes), "200m", "resources not updated for %#v", input.object)
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "resources", req.Method, req.URL, req)

View File

@ -94,7 +94,7 @@ func TestSetServiceAccountLocal(t *testing.T) {
assert.NoError(t, err)
err = saConfig.Run()
assert.NoError(t, err)
assert.Contains(t, buf.String(), "serviceAccountName: "+serviceAccount, fmt.Sprintf("serviceaccount not updated for %s", input.yaml))
assert.Containsf(t, buf.String(), "serviceAccountName: "+serviceAccount, "serviceaccount not updated for %s", input.yaml)
})
}
}
@ -337,7 +337,7 @@ func TestSetServiceAccountRemote(t *testing.T) {
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"serviceAccountName":`+`"`+serviceAccount+`"`, fmt.Sprintf("serviceaccount not updated for %#v", input.object))
assert.Containsf(t, string(bytes), `"serviceAccountName":`+`"`+serviceAccount+`"`, "serviceaccount not updated for %#v", input.object)
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "serviceaccount", req.Method, req.URL, req)

View File

@ -206,7 +206,7 @@ func (o *SubjectOptions) Validate() error {
func (o *SubjectOptions) Run(fn updateSubjects) error {
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) {
subjects := []rbacv1.Subject{}
for _, user := range sets.NewString(o.Users...).List() {
for _, user := range sets.List(sets.New[string](o.Users...)) {
subject := rbacv1.Subject{
Kind: rbacv1.UserKind,
APIGroup: rbacv1.GroupName,
@ -214,7 +214,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
}
subjects = append(subjects, subject)
}
for _, group := range sets.NewString(o.Groups...).List() {
for _, group := range sets.List(sets.New[string](o.Groups...)) {
subject := rbacv1.Subject{
Kind: rbacv1.GroupKind,
APIGroup: rbacv1.GroupName,
@ -222,7 +222,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
}
subjects = append(subjects, subject)
}
for _, sa := range sets.NewString(o.ServiceAccounts...).List() {
for _, sa := range sets.List(sets.New[string](o.ServiceAccounts...)) {
tokens := strings.Split(sa, ":")
namespace := tokens[0]
name := tokens[1]

View File

@ -183,7 +183,7 @@ func (o *TaintOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
}
if o.taintsToAdd, o.taintsToRemove, err = parseTaints(taintArgs); err != nil {
return cmdutil.UsageErrorf(cmd, err.Error())
return cmdutil.UsageErrorf(cmd, "%s", err.Error())
}
o.builder = f.NewBuilder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).

View File

@ -38,7 +38,7 @@ const (
// It also validates the spec. For example, the form `<key>` may be used to remove a taint, but not to add one.
func parseTaints(spec []string) ([]corev1.Taint, []corev1.Taint, error) {
var taints, taintsToRemove []corev1.Taint
uniqueTaints := map[corev1.TaintEffect]sets.String{}
uniqueTaints := map[corev1.TaintEffect]sets.Set[string]{}
for _, taintSpec := range spec {
if strings.HasSuffix(taintSpec, "-") {
@ -62,7 +62,7 @@ func parseTaints(spec []string) ([]corev1.Taint, []corev1.Taint, error) {
}
// add taint to existingTaints for uniqueness check
if len(uniqueTaints[newTaint.Effect]) == 0 {
uniqueTaints[newTaint.Effect] = sets.String{}
uniqueTaints[newTaint.Effect] = sets.Set[string]{}
}
uniqueTaints[newTaint.Effect].Insert(newTaint.Key)

View File

@ -19,9 +19,9 @@ package top
import (
"context"
"errors"
"github.com/spf13/cobra"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/cli-runtime/pkg/genericiooptions"
@ -45,6 +45,7 @@ type TopNodeOptions struct {
NoHeaders bool
UseProtocolBuffers bool
ShowCapacity bool
ShowSwap bool
NodeClient corev1client.CoreV1Interface
Printer *metricsutil.TopCmdPrinter
@ -95,6 +96,7 @@ func NewCmdTopNode(f cmdutil.Factory, o *TopNodeOptions, streams genericiooption
cmd.Flags().BoolVar(&o.NoHeaders, "no-headers", o.NoHeaders, "If present, print output without headers")
cmd.Flags().BoolVar(&o.UseProtocolBuffers, "use-protocol-buffers", o.UseProtocolBuffers, "Enables using protocol-buffers to access Metrics API.")
cmd.Flags().BoolVar(&o.ShowCapacity, "show-capacity", o.ShowCapacity, "Print node resources based on Capacity instead of Allocatable(default) of the nodes.")
cmd.Flags().BoolVar(&o.ShowSwap, "show-swap", o.ShowSwap, "Print node resources related to swap memory.")
return cmd
}
@ -127,7 +129,7 @@ func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
o.NodeClient = clientset.CoreV1()
o.Printer = metricsutil.NewTopCmdPrinter(o.Out)
o.Printer = metricsutil.NewTopCmdPrinter(o.Out, o.ShowSwap)
return nil
}
@ -198,6 +200,14 @@ func (o TopNodeOptions) RunTopNode() error {
} else {
availableResources[n.Name] = n.Status.Capacity
}
if n.Status.NodeInfo.Swap != nil && n.Status.NodeInfo.Swap.Capacity != nil {
swapCapacity := *n.Status.NodeInfo.Swap.Capacity
availableResources[n.Name]["swap"] = *resource.NewQuantity(swapCapacity, resource.BinarySI)
} else {
o.Printer.RegisterMissingResource(n.Name, metricsutil.ResourceSwap)
}
}
return o.Printer.PrintNodeMetrics(metrics.Items, availableResources, o.NoHeaders, o.SortBy)

View File

@ -424,3 +424,111 @@ func TestTopNodeWithSortByMemoryMetricsFrom(t *testing.T) {
}
}
func TestTopNodeWithSwap(t *testing.T) {
runTopCmd := func(expectedMetrics *metricsv1beta1api.NodeMetricsList, nodes *v1.NodeList) (result string) {
cmdtesting.InitTestErrorHandler(t)
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
ns := scheme.Codecs.WithoutConversion()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/api":
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: io.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis":
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: io.NopCloser(bytes.NewReader([]byte(apisbodyWithMetrics)))}, nil
case p == expectedNodePath && m == "GET":
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, nodes)}, nil
default:
t.Fatalf("unexpected request: %#v\nGot URL: %#v\n", req, req.URL)
return nil, nil
}
}),
}
fakemetricsClientset := &metricsfake.Clientset{}
fakemetricsClientset.AddReactor("list", "nodes", func(action core.Action) (handled bool, ret runtime.Object, err error) {
return true, expectedMetrics, nil
})
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
streams, _, buf, _ := genericiooptions.NewTestIOStreams()
cmd := NewCmdTopNode(tf, nil, streams)
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
// TODO then check the particular Run functionality and harvest results from fake clients
cmdOptions := &TopNodeOptions{
IOStreams: streams,
ShowSwap: true,
}
if err := cmdOptions.Complete(tf, cmd, []string{}); err != nil {
t.Fatal(err)
}
cmdOptions.MetricsClient = fakemetricsClientset
if err := cmdOptions.Validate(); err != nil {
t.Fatal(err)
}
if err := cmdOptions.RunTopNode(); err != nil {
t.Fatal(err)
}
return buf.String()
}
for _, tc := range []struct {
name string
isSwapDisabledOnNodes bool
}{
{
name: "nodes with swap",
isSwapDisabledOnNodes: false,
},
{
name: "nodes without swap",
isSwapDisabledOnNodes: true,
},
} {
t.Run(tc.name, func(t *testing.T) {
expectedMetrics, nodes := testNodeV1beta1MetricsData()
if tc.isSwapDisabledOnNodes {
for i := range expectedMetrics.Items {
delete(expectedMetrics.Items[i].Usage, "swap")
}
for i := range nodes.Items {
nodes.Items[i].Status.NodeInfo.Swap = nil
}
}
result := runTopCmd(expectedMetrics, nodes)
fmt.Printf("%s\n", result)
if !strings.Contains(result, "SWAP(bytes)") {
t.Errorf("missing SWAP(bytes) header: \n%s", result)
}
if !strings.Contains(result, "SWAP(%)") {
t.Errorf("missing SWAP(%%) header: \n%s", result)
}
if tc.isSwapDisabledOnNodes {
if !strings.Contains(result, "<unknown>") {
t.Errorf("expected swap to be <unknown>: \n%s", result)
}
}
for _, m := range expectedMetrics.Items {
if !strings.Contains(result, m.Name) {
t.Errorf("missing metrics for %s: \n%s", m.Name, result)
}
if _, foundSwapMetric := m.Usage["swap"]; foundSwapMetric != !tc.isSwapDisabledOnNodes {
t.Errorf("missing swap metric for %s: \n%s", m.Name, result)
}
}
})
}
}

View File

@ -53,6 +53,7 @@ type TopPodOptions struct {
NoHeaders bool
UseProtocolBuffers bool
Sum bool
ShowSwap bool
PodClient corev1client.PodsGetter
Printer *metricsutil.TopCmdPrinter
@ -117,6 +118,7 @@ func NewCmdTopPod(f cmdutil.Factory, o *TopPodOptions, streams genericiooptions.
cmd.Flags().BoolVar(&o.NoHeaders, "no-headers", o.NoHeaders, "If present, print output without headers.")
cmd.Flags().BoolVar(&o.UseProtocolBuffers, "use-protocol-buffers", o.UseProtocolBuffers, "Enables using protocol-buffers to access Metrics API.")
cmd.Flags().BoolVar(&o.Sum, "sum", o.Sum, "Print the sum of the resource usage")
cmd.Flags().BoolVar(&o.ShowSwap, "show-swap", o.ShowSwap, "Print pod resources related to swap memory.")
return cmd
}
@ -152,7 +154,7 @@ func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
o.PodClient = clientset.CoreV1()
o.Printer = metricsutil.NewTopCmdPrinter(o.Out)
o.Printer = metricsutil.NewTopCmdPrinter(o.Out, o.ShowSwap)
return nil
}

View File

@ -168,6 +168,12 @@ func TestTopPod(t *testing.T) {
namespaces: []string{testNS, testNS, testNS},
containers: true,
},
{
name: "with swap",
options: &TopPodOptions{AllNamespaces: true, ShowSwap: true},
namespaces: []string{testNS, "secondtestns", "thirdtestns"},
listsNamespaces: true,
},
}
cmdtesting.InitTestErrorHandler(t)
for _, testCase := range testCases {
@ -284,10 +290,101 @@ func TestTopPod(t *testing.T) {
t.Errorf("containers not matching:\n\texpectedContainers: %v\n\tresultContainers: %v\n", testCase.expectedContainers, resultContainers)
}
}
if testCase.options != nil && testCase.options.ShowSwap {
if !strings.Contains(result, "SWAP(bytes)") {
t.Errorf("missing SWAP(bytes) header: \n%s", result)
}
}
})
}
}
func TestTopPodWithSwap(t *testing.T) {
cmdtesting.InitTestErrorHandler(t)
const testName = "TestTopPodWithSwap"
t.Run(testName, func(t *testing.T) {
metricsList := testV1beta1PodMetricsData()
fakemetricsClientset := &metricsfake.Clientset{}
fakemetricsClientset.AddReactor("list", "pods", func(action core.Action) (handled bool, ret runtime.Object, err error) {
res := &metricsv1beta1api.PodMetricsList{
Items: metricsList,
}
return true, res, nil
})
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := scheme.Codecs.WithoutConversion()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch req.URL.Path {
case "/api":
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: io.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case "/apis":
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: io.NopCloser(bytes.NewReader([]byte(apisbodyWithMetrics)))}, nil
default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v",
testName, req, req.URL)
return nil, nil
}
}),
}
streams, _, buf, _ := genericiooptions.NewTestIOStreams()
cmd := NewCmdTopPod(tf, nil, streams)
cmdOptions := &TopPodOptions{
ShowSwap: true,
}
cmdOptions.IOStreams = streams
if err := cmdOptions.Complete(tf, cmd, nil); err != nil {
t.Fatal(err)
}
cmdOptions.MetricsClient = fakemetricsClientset
if err := cmdOptions.Validate(); err != nil {
t.Fatal(err)
}
if err := cmdOptions.RunTopPod(); err != nil {
t.Fatal(err)
}
result := buf.String()
expectedSwapBytes := map[string]string{
"pod1": "4Mi",
"pod2": "0Mi",
"pod3": "3Mi",
}
actualSwapBytes := map[string]string{}
for _, line := range strings.Split(result, "\n")[1:] {
lineFields := strings.Fields(line)
if len(lineFields) < 4 {
continue
}
podName := lineFields[0]
swapBytes := lineFields[3]
actualSwapBytes[podName] = swapBytes
}
for expectedPodName, expectedSwapBytes := range expectedSwapBytes {
actualSwapBytes, found := actualSwapBytes[expectedPodName]
if !found {
t.Errorf("missing swap metrics for pod %s", expectedPodName)
}
if actualSwapBytes != expectedSwapBytes {
t.Errorf("unexpected swap metrics for pod %s: expected %s, got %s", expectedPodName, expectedSwapBytes, actualSwapBytes)
}
}
})
}
func getResultColumnValues(result string, columnIndex int) []string {
resultLines := strings.Split(result, "\n")
values := make([]string, len(resultLines)-2) // don't process first (header) and last (empty) line
@ -410,6 +507,7 @@ func testV1beta1PodMetricsData() []metricsv1beta1api.PodMetrics {
Usage: v1.ResourceList{
v1.ResourceCPU: *resource.NewMilliQuantity(1, resource.DecimalSI),
v1.ResourceMemory: *resource.NewQuantity(2*(1024*1024), resource.DecimalSI),
"swap": *resource.NewQuantity(1*(1024*1024), resource.DecimalSI),
v1.ResourceStorage: *resource.NewQuantity(3*(1024*1024), resource.DecimalSI),
},
},
@ -418,6 +516,7 @@ func testV1beta1PodMetricsData() []metricsv1beta1api.PodMetrics {
Usage: v1.ResourceList{
v1.ResourceCPU: *resource.NewMilliQuantity(4, resource.DecimalSI),
v1.ResourceMemory: *resource.NewQuantity(5*(1024*1024), resource.DecimalSI),
"swap": *resource.NewQuantity(3*(1024*1024), resource.DecimalSI),
v1.ResourceStorage: *resource.NewQuantity(6*(1024*1024), resource.DecimalSI),
},
},
@ -462,6 +561,7 @@ func testV1beta1PodMetricsData() []metricsv1beta1api.PodMetrics {
Usage: v1.ResourceList{
v1.ResourceCPU: *resource.NewMilliQuantity(7, resource.DecimalSI),
v1.ResourceMemory: *resource.NewQuantity(8*(1024*1024), resource.DecimalSI),
"swap": *resource.NewQuantity(3*(1024*1024), resource.DecimalSI),
v1.ResourceStorage: *resource.NewQuantity(9*(1024*1024), resource.DecimalSI),
},
},

View File

@ -30,6 +30,7 @@ import (
"k8s.io/cli-runtime/pkg/genericiooptions"
cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
"k8s.io/utils/ptr"
)
func TestTopSubcommandsExist(t *testing.T) {
@ -63,6 +64,7 @@ func testNodeV1beta1MetricsData() (*metricsv1beta1api.NodeMetricsList, *v1.NodeL
Window: metav1.Duration{Duration: time.Minute},
Usage: v1.ResourceList{
v1.ResourceCPU: *resource.NewMilliQuantity(1, resource.DecimalSI),
"swap": *resource.NewQuantity(1*(1024*1024), resource.DecimalSI),
v1.ResourceMemory: *resource.NewQuantity(2*(1024*1024), resource.DecimalSI),
v1.ResourceStorage: *resource.NewQuantity(3*(1024*1024), resource.DecimalSI),
},
@ -72,6 +74,7 @@ func testNodeV1beta1MetricsData() (*metricsv1beta1api.NodeMetricsList, *v1.NodeL
Window: metav1.Duration{Duration: time.Minute},
Usage: v1.ResourceList{
v1.ResourceCPU: *resource.NewMilliQuantity(5, resource.DecimalSI),
"swap": *resource.NewQuantity(2*(1024*1024), resource.DecimalSI),
v1.ResourceMemory: *resource.NewQuantity(6*(1024*1024), resource.DecimalSI),
v1.ResourceStorage: *resource.NewQuantity(7*(1024*1024), resource.DecimalSI),
},
@ -81,6 +84,7 @@ func testNodeV1beta1MetricsData() (*metricsv1beta1api.NodeMetricsList, *v1.NodeL
Window: metav1.Duration{Duration: time.Minute},
Usage: v1.ResourceList{
v1.ResourceCPU: *resource.NewMilliQuantity(3, resource.DecimalSI),
"swap": *resource.NewQuantity(0, resource.DecimalSI),
v1.ResourceMemory: *resource.NewQuantity(4*(1024*1024), resource.DecimalSI),
v1.ResourceStorage: *resource.NewQuantity(5*(1024*1024), resource.DecimalSI),
},
@ -100,6 +104,11 @@ func testNodeV1beta1MetricsData() (*metricsv1beta1api.NodeMetricsList, *v1.NodeL
v1.ResourceMemory: *resource.NewQuantity(20*(1024*1024), resource.DecimalSI),
v1.ResourceStorage: *resource.NewQuantity(30*(1024*1024), resource.DecimalSI),
},
NodeInfo: v1.NodeSystemInfo{
Swap: &v1.NodeSwapStatus{
Capacity: ptr.To(int64(10 * (1024 * 1024 * 1024))),
},
},
},
},
{
@ -110,6 +119,11 @@ func testNodeV1beta1MetricsData() (*metricsv1beta1api.NodeMetricsList, *v1.NodeL
v1.ResourceMemory: *resource.NewQuantity(60*(1024*1024), resource.DecimalSI),
v1.ResourceStorage: *resource.NewQuantity(70*(1024*1024), resource.DecimalSI),
},
NodeInfo: v1.NodeSystemInfo{
Swap: &v1.NodeSwapStatus{
Capacity: ptr.To(int64(20 * (1024 * 1024 * 1024))),
},
},
},
},
{
@ -120,6 +134,11 @@ func testNodeV1beta1MetricsData() (*metricsv1beta1api.NodeMetricsList, *v1.NodeL
v1.ResourceMemory: *resource.NewQuantity(40*(1024*1024), resource.DecimalSI),
v1.ResourceStorage: *resource.NewQuantity(50*(1024*1024), resource.DecimalSI),
},
NodeInfo: v1.NodeSystemInfo{
Swap: &v1.NodeSwapStatus{
Capacity: ptr.To(int64(30 * (1024 * 1024 * 1024))),
},
},
},
},
},

View File

@ -52,11 +52,8 @@ import (
"k8s.io/kubectl/pkg/cmd/util/editor/crlf"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util"
"k8s.io/kubectl/pkg/util/slice"
)
var SupportedSubresources = []string{"status"}
// EditOptions contains all the options for running edit cli command.
type EditOptions struct {
resource.FilenameOptions
@ -230,9 +227,6 @@ func (o *EditOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Comm
// Validate checks the EditOptions to see if there is sufficient information to run the command.
func (o *EditOptions) Validate() error {
if len(o.Subresource) > 0 && !slice.ContainsString(SupportedSubresources, o.Subresource, nil) {
return fmt.Errorf("invalid subresource value: %q. Must be one of %v", o.Subresource, SupportedSubresources)
}
return nil
}

View File

@ -222,7 +222,7 @@ func checkErr(err error, handleErr func(string, int)) {
func statusCausesToAggrError(scs []metav1.StatusCause) utilerrors.Aggregate {
errs := make([]error, 0, len(scs))
errorMsgs := sets.NewString()
errorMsgs := sets.New[string]()
for _, sc := range scs {
// check for duplicate error messages and skip them
msg := fmt.Sprintf("%s: %s", sc.Field, sc.Message)
@ -243,7 +243,7 @@ func statusCausesToAggrError(scs []metav1.StatusCause) utilerrors.Aggregate {
// commands.
func StandardErrorMessage(err error) (string, bool) {
if debugErr, ok := err.(debugError); ok {
klog.V(4).Infof(debugErr.DebugError())
klog.V(4).Info(debugErr.DebugError())
}
status, isStatus := err.(apierrors.APIStatus)
switch {
@ -425,12 +425,36 @@ func GetPodRunningTimeoutFlag(cmd *cobra.Command) (time.Duration, error) {
type FeatureGate string
const (
ApplySet FeatureGate = "KUBECTL_APPLYSET"
CmdPluginAsSubcommand FeatureGate = "KUBECTL_ENABLE_CMD_SHADOW"
OpenAPIV3Patch FeatureGate = "KUBECTL_OPENAPIV3_PATCH"
// owner: @soltysh
// kep: https://kep.k8s.io/859
//
// HTTP headers with command name and flags used.
CmdHeaders FeatureGate = "KUBECTL_COMMAND_HEADERS"
// owner: @ardaguclu
// kep: https://kep.k8s.io/3104
//
// Separate kubectl user preferences.
KubeRC FeatureGate = "KUBECTL_KUBERC"
// owner: @soltysh
// kep: https://kep.k8s.io/3515
//
// Improved kubectl apply --prune behavior.
OpenAPIV3Patch FeatureGate = "KUBECTL_OPENAPIV3_PATCH"
// owner: @justinb
// kep: https://kep.k8s.io/3659
//
// Improved kubectl apply --prune behavior.
ApplySet FeatureGate = "KUBECTL_APPLYSET"
// owner: @seans
// kep: https://kep.k8s.io/4006
//
// Transition to WebSockets.
RemoteCommandWebsockets FeatureGate = "KUBECTL_REMOTE_COMMAND_WEBSOCKETS"
PortForwardWebsockets FeatureGate = "KUBECTL_PORT_FORWARD_WEBSOCKETS"
DebugCustomProfile FeatureGate = "KUBECTL_DEBUG_CUSTOM_PROFILE"
)
// IsEnabled returns true iff environment variable is set to true.
@ -451,10 +475,7 @@ func AddValidateFlags(cmd *cobra.Command) {
cmd.Flags().String(
"validate",
"strict",
`Must be one of: strict (or true), warn, ignore (or false).
"true" or "strict" will use a schema to validate the input and fail the request if invalid. It will perform server side validation if ServerSideFieldValidation is enabled on the api-server, but will fall back to less reliable client-side validation if not.
"warn" will warn about unknown or duplicate fields without blocking the request if server-side field validation is enabled on the API server, and behave as "ignore" otherwise.
"false" or "ignore" will not perform any schema validation, silently dropping any unknown or duplicate fields.`,
`Must be one of: strict (or true), warn, ignore (or false). "true" or "strict" will use a schema to validate the input and fail the request if invalid. It will perform server side validation if ServerSideFieldValidation is enabled on the api-server, but will fall back to less reliable client-side validation if not. "warn" will warn about unknown or duplicate fields without blocking the request if server-side field validation is enabled on the API server, and behave as "ignore" otherwise. "false" or "ignore" will not perform any schema validation, silently dropping any unknown or duplicate fields.`,
)
cmd.Flags().Lookup("validate").NoOptDefVal = "strict"
@ -521,7 +542,7 @@ func AddChunkSizeFlag(cmd *cobra.Command, value *int64) {
}
func AddLabelSelectorFlagVar(cmd *cobra.Command, p *string) {
cmd.Flags().StringVarP(p, "selector", "l", *p, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2). Matching objects must satisfy all of the specified label constraints.")
cmd.Flags().StringVarP(p, "selector", "l", *p, "Selector (label query) to filter on, supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 in (value3)). Matching objects must satisfy all of the specified label constraints.")
}
func AddPruningFlags(cmd *cobra.Command, prune *bool, pruneAllowlist *[]string, all *bool, applySetRef *string) {
@ -539,10 +560,11 @@ func AddPruningFlags(cmd *cobra.Command, prune *bool, pruneAllowlist *[]string,
}
}
func AddSubresourceFlags(cmd *cobra.Command, subresource *string, usage string, allowedSubresources ...string) {
cmd.Flags().StringVar(subresource, "subresource", "", fmt.Sprintf("%s Must be one of %v. This flag is beta and may change in the future.", usage, allowedSubresources))
func AddSubresourceFlags(cmd *cobra.Command, subresource *string, usage string) {
cmd.Flags().StringVar(subresource, "subresource", "", usage)
CheckErr(cmd.RegisterFlagCompletionFunc("subresource", func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
return allowedSubresources, cobra.ShellCompDirectiveNoFileComp
var commonSubresources = []string{"status", "scale", "resize"}
return commonSubresources, cobra.ShellCompDirectiveNoFileComp
}))
}

View File

@ -18,10 +18,10 @@ package version
import (
"fmt"
"io"
"math"
"k8s.io/apimachinery/pkg/util/version"
apimachineryversion "k8s.io/apimachinery/pkg/version"
"math"
)
// supportedMinorVersionSkew is the maximum supported difference between the client and server minor versions.
@ -29,26 +29,26 @@ import (
// and server versions 1.18, 1.19, and 1.20 would be within the supported version skew for client version 1.19.
const supportedMinorVersionSkew = 1
// printVersionSkewWarning prints a warning message if the difference between the client and version is greater than
// getVersionSkewWarning returns a warning message if the difference between the client and version is greater than
// the supported version skew.
func printVersionSkewWarning(w io.Writer, clientVersion, serverVersion apimachineryversion.Info) error {
func getVersionSkewWarning(clientVersion, serverVersion apimachineryversion.Info) (string, error) {
parsedClientVersion, err := version.ParseSemantic(clientVersion.GitVersion)
if err != nil {
return err
return "", fmt.Errorf("client version error: %w", err)
}
parsedServerVersion, err := version.ParseSemantic(serverVersion.GitVersion)
if err != nil {
return err
return "", fmt.Errorf("server version error: %w", err)
}
majorVersionDifference := math.Abs(float64(parsedClientVersion.Major()) - float64(parsedServerVersion.Major()))
minorVersionDifference := math.Abs(float64(parsedClientVersion.Minor()) - float64(parsedServerVersion.Minor()))
if majorVersionDifference > 0 || minorVersionDifference > supportedMinorVersionSkew {
fmt.Fprintf(w, "WARNING: version difference between client (%d.%d) and server (%d.%d) exceeds the supported minor version skew of +/-%d\n",
warningMessage := fmt.Sprintf("version difference between client (%d.%d) and server (%d.%d) exceeds the supported minor version skew of +/-%d",
parsedClientVersion.Major(), parsedClientVersion.Minor(), parsedServerVersion.Major(), parsedServerVersion.Minor(), supportedMinorVersionSkew)
return warningMessage, nil
}
return nil
return "", nil
}

View File

@ -17,14 +17,12 @@ limitations under the License.
package version
import (
"bytes"
apimachineryversion "k8s.io/apimachinery/pkg/version"
"testing"
apimachineryversion "k8s.io/apimachinery/pkg/version"
)
func TestPrintVersionSkewWarning(t *testing.T) {
output := &bytes.Buffer{}
testCases := []struct {
name string
clientVersion apimachineryversion.Info
@ -82,14 +80,15 @@ func TestPrintVersionSkewWarning(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
output.Reset()
warningMessage, err := getVersionSkewWarning(tc.clientVersion, tc.serverVersion)
if err != nil {
t.Errorf("error: %s", err)
}
printVersionSkewWarning(output, tc.clientVersion, tc.serverVersion)
if tc.isWarningExpected && output.Len() == 0 {
t.Error("warning was expected, but not written to the output")
} else if !tc.isWarningExpected && output.Len() > 0 {
t.Errorf("warning was not expected, but was written to the output: %s", output.String())
if tc.isWarningExpected && warningMessage == "" {
t.Error("warning was expected")
} else if !tc.isWarningExpected && warningMessage != "" {
t.Errorf("warning was not expected. but got %s", warningMessage)
}
})
}

View File

@ -36,7 +36,7 @@ import (
)
// TODO(knverey): remove this hardcoding once kubectl being built with module support makes BuildInfo available.
const kustomizeVersion = "v5.4.2"
const kustomizeVersion = "v5.5.0"
// Version is a struct for version information
type Version struct {
@ -53,8 +53,9 @@ var (
// Options is a struct to support version command
type Options struct {
ClientOnly bool
Output string
ClientOnly bool
Output string
WarningsAsErrors bool
args []string
@ -93,6 +94,9 @@ func NewCmdVersion(f cmdutil.Factory, ioStreams genericiooptions.IOStreams) *cob
// Complete completes all the required options
func (o *Options) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
var err error
o.WarningsAsErrors = cmd.Flags().Lookup("warnings-as-errors").Value.String() == "true"
if o.ClientOnly {
return nil
}
@ -162,11 +166,17 @@ func (o *Options) Run() error {
}
if versionInfo.ServerVersion != nil {
if err := printVersionSkewWarning(o.ErrOut, *versionInfo.ClientVersion, *versionInfo.ServerVersion); err != nil {
warningMessage, err := getVersionSkewWarning(*versionInfo.ClientVersion, *versionInfo.ServerVersion)
if err != nil {
return err
}
if warningMessage != "" {
if o.WarningsAsErrors {
return errors.New(warningMessage)
}
fmt.Fprintf(o.ErrOut, "Warning: %s\n", warningMessage) //nolint:errcheck
}
}
return serverErr
}

View File

@ -20,8 +20,6 @@ import (
"strings"
"testing"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericiooptions"
cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
@ -32,13 +30,18 @@ func TestNewCmdVersionClientVersion(t *testing.T) {
defer tf.Cleanup()
streams, _, buf, _ := genericiooptions.NewTestIOStreams()
o := NewOptions(streams)
if err := o.Complete(tf, &cobra.Command{}, nil); err != nil {
cmd := NewCmdVersion(tf, streams)
cmd.Flags().Bool("warnings-as-errors", false, "")
if err := o.Complete(tf, cmd, nil); err != nil {
t.Errorf("Unexpected error: %v", err)
}
if err := o.Validate(); err != nil {
t.Errorf("Unexpected error: %v", err)
}
if err := o.Complete(tf, &cobra.Command{}, []string{"extraParameter0"}); err != nil {
if err := o.Complete(tf, cmd, []string{"extraParameter0"}); err != nil {
t.Errorf("Unexpected error: %v", err)
}
if err := o.Validate(); !strings.Contains(err.Error(), "extra arguments") {

View File

@ -51,8 +51,8 @@ var (
The command takes multiple resources and waits until the specified condition
is seen in the Status field of every given resource.
Alternatively, the command can wait for the given set of resources to be deleted
by providing the "delete" keyword as the value to the --for flag.
Alternatively, the command can wait for the given set of resources to be created or
deleted by providing the "create" or "delete" keyword as the value to the --for flag.
A successful message will be printed to stdout indicating when the specified
condition has been met. You can use -o option to change to output destination.`))
@ -73,6 +73,10 @@ var (
# Wait for the service "loadbalancer" to have ingress
kubectl wait --for=jsonpath='{.status.loadBalancer.ingress}' service/loadbalancer
# Wait for the secret "busybox1" to be created, with a timeout of 30s
kubectl create secret generic busybox1
kubectl wait --for=create secret/busybox1 --timeout=30s
# Wait for the pod "busybox1" to be deleted, with a timeout of 60s, after having issued the "delete" command
kubectl delete pod/busybox1
kubectl wait --for=delete pod/busybox1 --timeout=60s`))
@ -119,7 +123,7 @@ func NewCmdWait(restClientGetter genericclioptions.RESTClientGetter, streams gen
flags := NewWaitFlags(restClientGetter, streams)
cmd := &cobra.Command{
Use: "wait ([-f FILENAME] | resource.group/resource.name | resource.group [(-l label | --all)]) [--for=delete|--for condition=available|--for=jsonpath='{}'[=value]]",
Use: "wait ([-f FILENAME] | resource.group/resource.name | resource.group [(-l label | --all)]) [--for=create|--for=delete|--for condition=available|--for=jsonpath='{}'[=value]]",
Short: i18n.T("Experimental: Wait for a specific condition on one or many resources"),
Long: waitLong,
Example: waitExample,
@ -143,8 +147,8 @@ func (flags *WaitFlags) AddFlags(cmd *cobra.Command) {
flags.PrintFlags.AddFlags(cmd)
flags.ResourceBuilderFlags.AddFlags(cmd.Flags())
cmd.Flags().DurationVar(&flags.Timeout, "timeout", flags.Timeout, "The length of time to wait before giving up. Zero means check once and don't wait, negative means wait for a week.")
cmd.Flags().StringVar(&flags.ForCondition, "for", flags.ForCondition, "The condition to wait on: [delete|condition=condition-name[=condition-value]|jsonpath='{JSONPath expression}'=[JSONPath value]]. The default condition-value is true. Condition values are compared after Unicode simple case folding, which is a more general form of case-insensitivity.")
cmd.Flags().DurationVar(&flags.Timeout, "timeout", flags.Timeout, "The length of time to wait before giving up. Zero means check once and don't wait, negative means wait for a week.")
cmd.Flags().StringVar(&flags.ForCondition, "for", flags.ForCondition, "The condition to wait on: [create|delete|condition=condition-name[=condition-value]|jsonpath='{JSONPath expression}'=[JSONPath value]]. The default condition-value is true. Condition values are compared after Unicode simple case folding, which is a more general form of case-insensitivity.")
}
// ToOptions converts from CLI inputs to runtime inputs
@ -195,8 +199,8 @@ func conditionFuncFor(condition string, errOut io.Writer) (ConditionFunc, error)
case lowercaseCond == "create":
return IsCreated, nil
case strings.HasPrefix(lowercaseCond, "condition="):
conditionName := lowercaseCond[len("condition="):]
case strings.HasPrefix(condition, "condition="):
conditionName := strings.TrimPrefix(condition, "condition=")
conditionValue := "true"
if equalsIndex := strings.Index(conditionName, "="); equalsIndex != -1 {
conditionValue = conditionName[equalsIndex+1:]
@ -209,8 +213,8 @@ func conditionFuncFor(condition string, errOut io.Writer) (ConditionFunc, error)
errOut: errOut,
}.IsConditionMet, nil
case strings.HasPrefix(lowercaseCond, "jsonpath="):
jsonPathInput := strings.TrimPrefix(lowercaseCond, "jsonpath=")
case strings.HasPrefix(condition, "jsonpath="):
jsonPathInput := strings.TrimPrefix(condition, "jsonpath=")
jsonPathExp, jsonPathValue, err := processJSONPathInput(jsonPathInput)
if err != nil {
return nil, err
@ -325,7 +329,9 @@ func (o *WaitOptions) RunWait() error {
// or functions from ResourceBuilder for parsing those. Lastly, this poll
// should be replaced with a ListWatch cache.
if err := wait.PollUntilContextTimeout(ctx, 500*time.Millisecond, o.Timeout, true, func(context.Context) (done bool, err error) {
foundResource := false
visitErr := o.ResourceFinder.Do().Visit(func(info *resource.Info, err error) error {
foundResource = true
return nil
})
if apierrors.IsNotFound(visitErr) {
@ -334,7 +340,7 @@ func (o *WaitOptions) RunWait() error {
if visitErr != nil {
return false, visitErr
}
return true, nil
return foundResource, nil
}); err != nil {
if errors.Is(err, context.DeadlineExceeded) {
return fmt.Errorf("%s", wait.ErrWaitTimeout.Error()) // nolint:staticcheck // SA1019
@ -356,7 +362,7 @@ func (o *WaitOptions) RunWait() error {
return nil
}
if err == nil {
return fmt.Errorf("%v unsatisified for unknown reason", finalObject)
return fmt.Errorf("%v unsatisfied for unknown reason", finalObject)
}
return err
}

View File

@ -232,7 +232,7 @@ func createUnstructured(t *testing.T, config string) *unstructured.Unstructured
t.Helper()
result := map[string]interface{}{}
require.False(t, strings.Contains(config, "\t"), "Yaml %s cannot contain tabs", config)
require.NotContains(t, config, "\t", "Yaml %s cannot contain tabs", config)
require.NoError(t, yaml.Unmarshal([]byte(config), &result), "Could not parse config:\n\n%s\n", config)
return &unstructured.Unstructured{

12
pkg/config/OWNERS Normal file
View File

@ -0,0 +1,12 @@
# See the OWNERS docs at https://go.k8s.io/owners
# Disable inheritance as this is an api owners file
options:
no_parent_owners: true
approvers:
- api-approvers
reviewers:
- api-reviewers
- sig-cli-reviewers
labels:
- kind/api-change

Some files were not shown because too many files have changed in this diff Show More