Compare commits

...

72 Commits

Author SHA1 Message Date
Parship Chowdhury 7c240e5828
Add support for sonatype nancy vulnerability scanning (#153)
* added sonatype nancy vulnerability scanning

Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>

* fix 1

Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>

* fix 2

Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>

* vulnerability check fixed

Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>

---------

Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>
2025-07-22 21:26:30 +08:00
Gautam Manchandani da2b3fbac8
added unit test for util package (#138)
Signed-off-by: GautamBytes <manchandanigautam@gmail.com>
2025-07-21 13:00:51 +08:00
Gautam Manchandani ebb124d8cd
updated actions and enhanced build process (#137)
Signed-off-by: GautamBytes <manchandanigautam@gmail.com>
2025-07-08 09:51:29 +08:00
Gautam Manchandani 68d571ec42
add Go module & build cache to speed up CI (#135)
Signed-off-by: GautamBytes <manchandanigautam@gmail.com>
Co-authored-by: Jeremy <hantmac@outlook.com>
2025-07-06 22:41:44 +08:00
Gautam Manchandani d973c2aa1d
verify go.mod & go.sum consistency in CI (#136)
Signed-off-by: GautamBytes <manchandanigautam@gmail.com>
2025-07-06 18:22:15 +08:00
Gautam Manchandani 94742398cd
support UnitedDeployment in kubectl-kruise rollout restart (#128)
Signed-off-by: GautamBytes <manchandanigautam@gmail.com>
2025-06-23 17:01:26 +08:00
Zhen Zhang 0fc1342e14
fix namespace setting (#127)
Signed-off-by: 守辰 <shouchen.zz@alibaba-inc.com>
2025-06-16 21:37:47 +08:00
Zhen Zhang c9efb12a8a
fix build problem by replace go dependency (#125)
Signed-off-by: shouchen.zz <shouchen.zz@gmail.com>
Co-authored-by: shouchen.zz <shouchen.zz@gmail.com>
2025-06-06 23:03:31 +08:00
dependabot[bot] 60858fed19
Bump golang.org/x/net in the go_modules group across 1 directory (#123)
Bumps the go_modules group with 1 update in the / directory: [golang.org/x/net](https://github.com/golang/net).


Updates `golang.org/x/net` from 0.33.0 to 0.38.0
- [Commits](https://github.com/golang/net/compare/v0.33.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.38.0
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-15 16:00:11 +08:00
Vaibhav K f3a7f4bd33
add kubectl kruise get all command (#119)
* feat/cmd: add support for kruise get all command

Signed-off-by: Vaibhav <vaibhaavv8@gmail.com>

* add viewer for crr, cronjob, Resource Distribution, United Deployments, Broadcast

Signed-off-by: Vaibhav <vaibhaavv8@gmail.com>

* add viewer for sidecar, podprobe, imagepull, podBudget

Signed-off-by: Vaibhav <vaibhaavv8@gmail.com>

* fix golangci-lint

Signed-off-by: Vaibhav <vaibhaavv8@gmail.com>

---------

Signed-off-by: Vaibhav <vaibhaavv8@gmail.com>
2025-05-15 15:57:49 +08:00
Zhen Zhang b8db027748
update kruise-api to 1.8.0 (#124)
Signed-off-by: 守辰 <shouchen.zz@alibaba-inc.com>
2025-04-21 14:21:27 +08:00
Harkirat Singh 82ce71b931
feat: add support for blue-green in describe rollout (#122)
Signed-off-by: Harkirat Singh <multaniharry714@gmail.com>
2025-03-20 19:25:06 +08:00
Ai Ranthem 791f2b6075
Feature: rollout undo command supports fast rollback (#117)
* add rollout rollback command
* generate doc
* update ci
---------

Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>
2025-03-12 19:30:07 +08:00
dependabot[bot] a4fc9a3051
Bump golang.org/x/net from 0.24.0 to 0.33.0 (#116)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.24.0 to 0.33.0.
- [Commits](https://github.com/golang/net/compare/v0.24.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-10 16:29:09 +08:00
Ai Ranthem 355ed0a11a
can approve blue-green release (#115)
Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>
2025-02-07 13:01:23 +08:00
Kiraat f422c7d1cd
feat: show pods related to current step of the Rollout in describe cmd (#111)
* feat: show pods related to current step of the Rollout in describe cmd

Signed-off-by: maanugh <manusin46@gmail.com>
2025-01-30 08:32:58 +08:00
myname4423 2d0a16f996
fix a rollout version bug (#113)
Signed-off-by: yunbo <yunbo10124scut@gmail.com>
Co-authored-by: yunbo <yunbo10124scut@gmail.com>
2024-12-09 14:55:15 +08:00
Kiraat 9d68939d6c
feat: add support for v1alpha1 resources (#112)
* feat: add support for v1alpha1 resources

Signed-off-by: maanugh <manusin46@gmail.com>
2024-11-26 09:54:59 +08:00
Kiraat 631fde0936
feat: add support for describe command (#96)
* feat: add support for rollout describe command

Signed-off-by: maanugh <manusin46@gmail.com>
2024-11-13 09:40:47 +08:00
hantmac cafa34158f fix 2024-11-11 09:38:37 +08:00
hantmac 6193994cfe fix 2024-11-11 09:38:37 +08:00
hantmac 7935dd511e fix 2024-11-11 09:38:37 +08:00
hantmac 33d8021ea2 fix: ci download sha256 file
Signed-off-by: hantmac <hantmac@outlook.com>
2024-11-11 09:38:37 +08:00
Jeremy 93a0cefcfd
fix: shasum file in release ci (#109) 2024-11-06 15:29:22 +08:00
Jeremy 7b60eae6d4
fix: add release tag in assert name (#108) 2024-11-06 15:13:22 +08:00
Ai Ranthem ea79dee83f
update dependencies (#106)
* update dependencies

Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>

* update workflow go version

Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>

---------

Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>
Co-authored-by: Jeremy <hantmac@outlook.com>
2024-11-05 09:01:41 +08:00
dependabot[bot] 039650b77e
Bump github.com/golang-jwt/jwt/v4 from 4.5.0 to 4.5.1 (#107)
Bumps [github.com/golang-jwt/jwt/v4](https://github.com/golang-jwt/jwt) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/golang-jwt/jwt/releases)
- [Changelog](https://github.com/golang-jwt/jwt/blob/main/VERSION_HISTORY.md)
- [Commits](https://github.com/golang-jwt/jwt/compare/v4.5.0...v4.5.1)

---
updated-dependencies:
- dependency-name: github.com/golang-jwt/jwt/v4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-05 08:39:18 +08:00
Ai Ranthem a1f4d247e2
support both rollout api v1beta1 and v1alpha1 (#105)
Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>
2024-10-29 17:16:32 +08:00
Jeremy 7ee5bea175 fix: Update release.yaml
Fix https://github.com/openkruise/kruise-tools/actions/runs/11381166096
2024-10-18 14:31:04 +08:00
hantmac 266c773468 fix: rollout approve docs 2024-10-18 14:29:44 +08:00
Jeremy 1fa53d0806
feat: support auto completion (#102)
* feat: support auto completion

Signed-off-by: hantmac <hantmac@outlook.com>

* add readme

Signed-off-by: hantmac <hantmac@outlook.com>

---------

Signed-off-by: hantmac <hantmac@outlook.com>
2024-10-17 16:24:09 +08:00
Kiraat cfd9de24fc
feat: add docs generation for kruise (#98)
* feat: add docs generation for kruise

Signed-off-by: maanugh <manusin46@gmail.com>

* remove unnecessary sub commands docs

Signed-off-by: maanugh <manusin46@gmail.com>

---------

Signed-off-by: maanugh <manusin46@gmail.com>
2024-09-19 17:55:59 +08:00
dependabot[bot] 5cee01a250
Bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows (#100)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 4.1.7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v2...v4.1.7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-04 10:04:13 +08:00
dependabot[bot] dbe976db3a
Bump golang.org/x/net from 0.17.0 to 0.23.0 (#93)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-22 09:37:54 +08:00
myname4423 519472cf18
Allow deployment rollback when in the process of cannary/partition (#91)
add comment



an improvement for canary rollback during another rollback

Signed-off-by: yunbo <yunbo10124scut@gmail.com>
Co-authored-by: yunbo <yunbo10124scut@gmail.com>
2024-02-04 23:13:44 +08:00
Zhen Zhang ce1b663964
update kruise rollout dependency to v0.5.0 (#90)
Signed-off-by: 守辰 <shouchen.zz@alibaba-inc.com>
2024-01-27 20:30:48 +08:00
dependabot[bot] 515401de9d
Bump golang.org/x/crypto (#87)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.0.0-20220214200702-86341886e292 to 0.17.0.
- [Commits](https://github.com/golang/crypto/commits/v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-23 19:05:32 +08:00
Zhen Zhang 52fc8c1e9d
fix golanglint error (#89)
Signed-off-by: 守辰 <shouchen.zz@alibaba-inc.com>
2024-01-23 17:22:11 +08:00
dependabot[bot] 7a0e8a5860
Bump golang.org/x/net from 0.8.0 to 0.17.0 (#86)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.8.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.8.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-23 15:26:49 +08:00
Zhen Zhang 23c092bac9
update k8s dependency to 1.24 (#85)
Signed-off-by: 守辰 <shouchen.zz@alibaba-inc.com>
2024-01-23 15:21:32 +08:00
myname4423 d4bbc24ecf
集成kruise rollout对象的undo功能 (#78)
Signed-off-by: yunbo <yunbo10124scut@gmail.com>

[temporary] temporary commit for sync

Signed-off-by: yunbo <yunbo10124scut@gmail.com>

[temporary] temporary commit for sync from local to work

Signed-off-by: yunbo <yunbo10124scut@gmail.com>

[temporary] temporary commit for sync from local to work

Signed-off-by: yunbo <yunbo10124scut@gmail.com>

rollout undo integration version2

Signed-off-by: yunbo <yunbo10124scut@gmail.com>

update README.md

Signed-off-by: yunbo <yunbo10124scut@gmail.com>

remove the comment code

Signed-off-by: yunbo <yunbo10124scut@gmail.com>

hide the same-workload-error

Signed-off-by: yunbo <yunbo10124scut@gmail.com>

update README

Co-authored-by: yunbo <yun@bo.com>
2023-12-18 15:49:59 +08:00
Wei-Xiang Sun ac41c04df6
update ci runner version (#79)
Signed-off-by: mingzhou.swx <mingzhou.swx@alibaba-inc.com>
Co-authored-by: mingzhou.swx <mingzhou.swx@alibaba-inc.com>
2023-12-11 13:56:52 +08:00
Jeremy 42ca53125e
Merge pull request #74 from asa3311/Update-k8s-registry-references
Update k8s registry references
2023-04-02 11:27:08 +08:00
xin gu a2d7d93d86 Update k8s registry references
Signed-off-by: xin gu <418294249@qq.com>
2023-03-08 22:25:45 +08:00
Jeremy debf778f75
Merge pull request #72 from chengleqi/issue-1106
feat: Support set image operation for sidecarsets
2023-03-03 15:39:16 +08:00
chengleqi b9a1b6f7bd
fix typo
Signed-off-by: chengleqi <chengleqi5g@hotmail.com>
2023-03-01 11:00:25 +08:00
chengleqi b372841756
fix golangci-lint and add signature
Signed-off-by: chengleqi <chengleqi5g@hotmail.com>
2023-02-28 23:32:43 +08:00
dong a27ae8ca65
merge resourcedistribution generator mods and makefiles (#70)
Signed-off-by: dong <dong4325@126.com>

Signed-off-by: dong <dong4325@126.com>
2022-10-13 14:45:07 +08:00
Jeremy aa2398418d
Merge pull request #71 from FillZpp/fix-ads-rollout-undo
Fix ads patch for rollout undo
2022-10-13 14:44:25 +08:00
Siyu Wang 0246934710 Fix ads patch for rollout undo
Signed-off-by: Siyu Wang <FillZpp.pub@gmail.com>
2022-10-12 10:25:07 +08:00
dong ba2f3db897
feat: add resourcedistribution generator (#69)
Signed-off-by: dong <dong4325@126.com>

Signed-off-by: dong <dong4325@126.com>
2022-10-05 22:39:04 +08:00
Jeremy aedda2032d
fix rollout status of partitioned update (#68)
* fix rollout status of partitioned update

Signed-off-by: hantmac <hantmac@outlook.com>

* use CalculatePartitionReplicas

Signed-off-by: hantmac <hantmac@outlook.com>
2022-08-01 10:33:46 +08:00
Jeremy b03c12488a
support kubectl-kruise create ContainerRecreateRequest (#66)
Signed-off-by: hantmac <hantmac@outlook.com>

fix ci lint

Signed-off-by: hantmac <hantmac@outlook.com>

fix

Signed-off-by: hantmac <hantmac@outlook.com>
2022-07-25 11:16:39 +08:00
Jeremy e1b55f7d11
add more info for rollout status cloneset (#65)
* add more info for rollout status cloneset

Signed-off-by: hantmac <hantmac@outlook.com>

* add  flag for rollout status

Signed-off-by: hantmac <hantmac@outlook.com>
2022-07-22 19:51:37 +08:00
Jeremy 8012780546
support create job and broadcastJob (#63)
Signed-off-by: hantmac <hantmac@outlook.com>
2022-05-23 14:10:41 +08:00
Jeremy c819f4c7a7
Merge pull request #64 from FillZpp/update-golangci-lint-action
Update golangci-lint-action to v3
2022-05-05 13:57:00 +08:00
Siyu Wang 095695cfb3 Update golangci-lint-action to v3
Signed-off-by: Siyu Wang <FillZpp.pub@gmail.com>
2022-05-05 12:09:53 +08:00
Jeremy 4749626a73
update docs (#61)
Signed-off-by: hantmac <hantmac@outlook.com>
2022-04-29 09:30:18 +08:00
Jeremy 3b2014acc8
Merge pull request #60 from hantmac/fix/release-krew
fix auto release krew index
2022-04-27 18:24:08 +08:00
hantmac 9240365aff fix auto release krew index
Signed-off-by: hantmac <hantmac@outlook.com>
2022-04-27 17:46:31 +08:00
Jeremy d858e70080
Merge pull request #47 from veophi/rollout
Bump dependencies to 1.22 & Add `pause`, `resume` and `approve` command for kruise rollout
2022-04-27 16:26:09 +08:00
mingzhou.swx 0ca6904c68 bump to 1.22 & add approve/pause/resume command for kruise rollout
Signed-off-by: mingzhou.swx <mingzhou.swx@alibaba-inc.com>
2022-04-27 16:22:06 +08:00
Siyu Wang fe9775640a
Add ads into docs and examples (#52)
Signed-off-by: Siyu Wang <FillZpp.pub@gmail.com>
2022-03-16 10:35:45 +08:00
Siyu Wang 42d6bd5001
Support set image and rollout commands for ads (#50)
Signed-off-by: Siyu Wang <FillZpp.pub@gmail.com>
2022-03-15 15:31:44 +08:00
Jeremy 1d835fb07f
fix set cmd bug caused by MergePatchType (#49)
Signed-off-by: hantmac <hantmac@outlook.com>
2022-03-09 11:08:23 +08:00
Jeremy fb8c5606e8
re-add .krew.yaml (#46)
Signed-off-by: hantmac <hantmac@outlook.com>
2022-02-16 11:09:32 +08:00
Jeremy 699aeaf4e8
update krew.yaml (#45)
Signed-off-by: hantmac <hantmac@outlook.com>
2022-02-09 10:40:16 +08:00
Jeremy 991a3833b3
add krew.yaml (#43)
Signed-off-by: hantmac <hantmac@outlook.com>
2022-02-07 14:08:41 +08:00
ChenghaoYu 935a228bdc
auth support (#42)
Signed-off-by: ychdesign <a838115682@gmail.com>
2022-01-28 18:13:39 +08:00
Jeremy 33eda78ab8
update plugin by krew index (#40)
Signed-off-by: hantmac <hantmac@outlook.com>
2022-01-10 10:48:13 +08:00
Jeremy 8048c1a852
Support exec current working sidecar container (#39)
* Support exec current working sidecar container

Signed-off-by: hantmac <hantmac@outlook.com>

* add test file

Signed-off-by: hantmac <hantmac@outlook.com>
2022-01-07 10:26:35 +08:00
Jeremy 57c6384628
opt docs (#37)
Signed-off-by: hantmac <hantmac@outlook.com>
2021-12-23 10:41:52 +08:00
126 changed files with 12891 additions and 1196 deletions

View File

@ -12,48 +12,112 @@ on:
env:
# Common versions
GO_VERSION: '1.16'
GOLANGCI_VERSION: 'v1.42'
GO_VERSION: '1.23'
GOLANGCI_VERSION: 'v1.55.2'
jobs:
golangci-lint:
runs-on: ubuntu-18.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- name: Setup Go
uses: actions/setup-go@v2
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: ${{ env.GO_VERSION }}
- name: Verify go.mod is tidy
run: |
go mod tidy
if [ -n "$(git status --porcelain go.mod go.sum)" ]; then
echo "go.mod or go.sum is not tidy"
git diff go.mod go.sum
exit 1
fi
- name: Cache Go Dependencies
uses: actions/cache@v2
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-go-
- name: Lint golang code
uses: golangci/golangci-lint-action@v2
uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 # v6.5.0
with:
version: ${{ env.GOLANGCI_VERSION }}
args: --verbose
build-and-test:
name: ci-build
runs-on: ubuntu-18.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- name: Setup Go
uses: actions/setup-go@v2
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: ${{ env.GO_VERSION }}
- name: Cache Go modules and build cache
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-go-
- name: Verify go.mod is tidy
run: |
go mod tidy
if [ -n "$(git status --porcelain go.mod go.sum)" ]; then
echo "go.mod or go.sum is not tidy"
git diff go.mod go.sum
exit 1
fi
- name: Build
run: |
make build
- name: Test
run: |
make test
security-scan:
name: Security Vulnerability Scan
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
- name: Setup Go
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: ${{ env.GO_VERSION }}
- name: Cache Go Dependencies
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-go-
- name: Generate go.list file for Nancy
run: go list -json -deps ./... > go.list
- name: Run Nancy vulnerability scan
uses: sonatype-nexus-community/nancy-github-action@main
with:
nancyCommand: sleuth
goListFile: go.list
- name: Install and run govulncheck
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...

View File

@ -6,91 +6,145 @@ on:
- created
env:
# Common versions
GO_VERSION: '1.16'
GO_VERSION: '1.22'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
build_and_upload:
runs-on: ubuntu-18.04
runs-on: ubuntu-24.04
strategy:
matrix:
TARGETS: [ linux/amd64, darwin/amd64, windows/amd64, linux/arm64, darwin/arm64 ]
include:
- os: linux
arch: amd64
- os: linux
arch: arm64
- os: darwin
arch: amd64
- os: darwin
arch: arm64
- os: windows
arch: amd64
env:
GO_BUILD_ENV: GO111MODULE=on CGO_ENABLED=0
DIST_DIRS: find * -type d -exec
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Needed for version.sh to work properly
- name: Setup Go
uses: actions/setup-go@v2
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: ${{ env.GO_VERSION }}
- name: Get release
id: get_release
uses: bruceadams/get-release@v1.2.2
- name: Get matrix
id: get_matrix
run: |
TARGETS=${{matrix.TARGETS}}
echo ::set-output name=OS::${TARGETS%/*}
echo ::set-output name=ARCH::${TARGETS#*/}
cache: true # Enable built-in Go caching
- name: Get ldflags
id: get_ldflags
run: |
LDFLAGS=$(./version.sh)
echo "LDFLAGS=${LDFLAGS}" >> $GITHUB_ENV
- name: Build
echo "LDFLAGS=${LDFLAGS}" >> $GITHUB_OUTPUT
- name: Build kubectl-kruise
run: |
${{ env.GO_BUILD_ENV }} GOOS=${{ steps.get_matrix.outputs.OS }} GOARCH=${{ steps.get_matrix.outputs.ARCH }} \
go build -ldflags "${{ env.LDFLAGS }}" \
-o _bin/kubectl-kruise/${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}/kubectl-kruise -v \
${{ env.GO_BUILD_ENV }} GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} \
go build -ldflags "${{ steps.get_ldflags.outputs.LDFLAGS }}" \
-o _bin/kubectl-kruise/${{ matrix.os }}-${{ matrix.arch }}/kubectl-kruise${{ matrix.os == 'windows' && '.exe' || '' }} \
./cmd/plugin/main.go
- name: Compress
- name: Build resourcedistribution-generator
run: |
cd _bin/kubectl-kruise && \
${{ env.DIST_DIRS }} cp ../../LICENSE {} \; && \
${{ env.DIST_DIRS }} cp ../../README.md {} \; && \
${{ env.DIST_DIRS }} tar -zcf kubectl-kruise-{}.tar.gz {} \; && \
cd .. && \
sha256sum kubectl-kruise/kubectl-kruise-* >> sha256-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.txt \
- name: Upload Kubectl-kruise tar.gz
uses: actions/upload-release-asset@v1.0.2
${{ env.GO_BUILD_ENV }} GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} \
go build -ldflags "${{ steps.get_ldflags.outputs.LDFLAGS }}" \
-o _bin/resourcedistribution-generator/${{ matrix.os }}-${{ matrix.arch }}/resourcedistributiongenerator${{ matrix.os == 'windows' && '.exe' || '' }} \
./cmd/resourcedistributiongenerator/main.go
- name: Package artifacts
run: |
# Package kubectl-kruise
cd _bin/kubectl-kruise/${{ matrix.os }}-${{ matrix.arch }}
cp ../../../LICENSE .
cp ../../../README.md .
if [ "${{ matrix.os }}" = "windows" ]; then
zip -r kubectl-kruise-${{ matrix.os }}-${{ matrix.arch }}.zip .
else
tar -czf kubectl-kruise-${{ matrix.os }}-${{ matrix.arch }}.tar.gz .
fi
cd ../../..
# Package resourcedistribution-generator
cd _bin/resourcedistribution-generator/${{ matrix.os }}-${{ matrix.arch }}
if [ "${{ matrix.os }}" = "windows" ]; then
zip -r resourcedistribution-generator-${{ matrix.os }}-${{ matrix.arch }}.zip .
else
tar -czf resourcedistribution-generator-${{ matrix.os }}-${{ matrix.arch }}.tar.gz .
fi
cd ../../..
- name: Generate checksums
run: |
cd _bin
find . -name "*.tar.gz" -o -name "*.zip" | xargs sha256sum > sha256-${{ matrix.os }}-${{ matrix.arch }}.txt
- name: Upload checksums artifact
uses: actions/upload-artifact@v4.4.3
with:
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./_bin/kubectl-kruise/kubectl-kruise-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
asset_name: kubectl-kruise-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
asset_content_type: binary/octet-stream
- name: Post sha256
uses: actions/upload-artifact@v2
with:
name: sha256sums
path: ./_bin/sha256-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.txt
name: sha256sums-${{ matrix.os }}-${{ matrix.arch }}
path: _bin/sha256-${{ matrix.os }}-${{ matrix.arch }}.txt
retention-days: 1
upload-sha256sums-plugin:
- name: Upload build artifacts
uses: actions/upload-artifact@v4.4.3
with:
name: binaries-${{ matrix.os }}-${{ matrix.arch }}
path: |
_bin/kubectl-kruise/${{ matrix.os }}-${{ matrix.arch }}/*.tar.gz
_bin/kubectl-kruise/${{ matrix.os }}-${{ matrix.arch }}/*.zip
_bin/resourcedistribution-generator/${{ matrix.os }}-${{ matrix.arch }}/*.tar.gz
_bin/resourcedistribution-generator/${{ matrix.os }}-${{ matrix.arch }}/*.zip
retention-days: 1
upload-release-assets:
needs: build_and_upload
runs-on: ubuntu-latest
name: upload-sha256sums
permissions:
contents: write
steps:
- name: Get release
id: get_release
uses: bruceadams/get-release@v1.2.2
- name: Download sha256sums
uses: actions/download-artifact@v2
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Download all artifacts
uses: actions/download-artifact@v4.1.7
with:
name: sha256sums
- shell: bash
pattern: "*"
merge-multiple: true
path: artifacts
- name: Prepare release assets
run: |
for file in *.txt
do
cat ${file} >> sha256sums.txt
mkdir -p release-assets
# Move binary archives to release assets
find artifacts -name "*.tar.gz" -o -name "*.zip" | while read file; do
filename=$(basename "$file")
# Add version tag to filename
name_part="${filename%.*}"
ext="${filename##*.}"
if [[ "$filename" == *.tar.gz ]]; then
ext="tar.gz"
name_part="${filename%.tar.gz}"
fi
cp "$file" "release-assets/${name_part}-${GITHUB_REF_NAME}.${ext}"
done
- name: Upload Checksums
uses: actions/upload-release-asset@v1.0.2
# Combine all checksums
cat artifacts/sha256-*.txt > release-assets/sha256sums-${GITHUB_REF_NAME}.txt
- name: Upload release assets
uses: softprops/action-gh-release@v2.0.8
with:
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: sha256sums.txt
asset_name: sha256sums.txt
asset_content_type: text/plain
# first time manual upload krew
# - name: Update kubectl plugin version in krew-index
# uses: rajatjindal/krew-release-bot@v0.0.40
files: release-assets/*
fail_on_unmatched_files: true
- name: Update kubectl plugin version in krew-index
uses: rajatjindal/krew-release-bot@v0.0.46

68
.krew.yaml Normal file
View File

@ -0,0 +1,68 @@
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: kruise
spec:
version: "{{ .TagName }}"
platforms:
- selector:
matchLabels:
os: linux
arch: amd64
{{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-linux-amd64.tar.gz" .TagName }}
files:
- from: "*/kubectl-kruise"
to: "."
- from: "*/LICENSE"
to: "."
bin: "kubectl-kruise"
- selector:
matchLabels:
os: linux
arch: arm64
{{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-linux-arm64.tar.gz" .TagName }}
files:
- from: "*/kubectl-kruise"
to: "."
- from: "*/LICENSE"
to: "."
bin: "kubectl-kruise"
- selector:
matchLabels:
os: darwin
arch: amd64
{{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-darwin-amd64.tar.gz" .TagName }}
files:
- from: "*/kubectl-kruise"
to: "."
- from: "*/LICENSE"
to: "."
bin: "kubectl-kruise"
- selector:
matchLabels:
os: darwin
arch: arm64
{{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-darwin-arm64.tar.gz" .TagName }}
files:
- from: "*/kubectl-kruise"
to: "."
- from: "*/LICENSE"
to: "."
bin: "kubectl-kruise"
- selector:
matchLabels:
os: windows
arch: amd64
{{addURIAndSha "https://github.com/openkruise/kruise-tools/releases/download/{{ .TagName }}/kubectl-kruise-windows-amd64.tar.gz" .TagName }}
files:
- from: "*/kubectl-kruise"
to: "."
- from: "*/LICENSE"
to: "."
bin: "kubectl-kruise"
shortDescription: Easily handle OpenKruise workloads
homepage: https://openkruise.io/
description: |
kubectl kruise is a kubectl plugin from the OpenKruise project. OpenKruise is an extended component suite for Kubernetes,
which mainly focuses on application automations, such as deployment, upgrade, ops and avalibility protection.
This plugin allows you to better handle, manage and maintain OpenKruise workloads.

3
.nancy-ignore Normal file
View File

@ -0,0 +1,3 @@
# Temporary exclusion - proxy/tokenizer vulnerabilities don't affect our usage
CVE-2025-22870
CVE-2025-22872

View File

@ -4,12 +4,21 @@ LDFLAGS = $(shell ./version.sh)
default: build
build: kubectl-kruise
build: kubectl-kruise resource-distribution-generator
kubectl-kruise:
kubectl-kruise: fmt vet
GO111MODULE=on CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o bin/kubectl-kruise cmd/plugin/main.go
resource-distribution-generator: fmt vet
GO111MODULE=on CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o bin/resourcedistributiongenerator cmd/resourcedistributiongenerator/main.go
test:
find . -iname '*.go' -type f | grep -v /vendor/ | xargs gofmt -l
GO111MODULE=on go test -v -race ./...
go vet ./...
fmt: ## Run go fmt against code.
go fmt ./...
vet: ## Run go vet against code.
go vet ./...

320
README.md
View File

@ -1,124 +1,160 @@
# kubectl-kruise
# Kruise-tools
kubectl plugin for OpenKruise
`kubectl` supports a plug-in mechanism, but the rollout and other related operations provided by this tool itself only support the native workload resources of Kubernetes.
Therefore, we need to create a kubectl plugin for OpenKruise, through which community users can use kubectl to operate Kruises workload resources.
[Kruise-tools](https://github.com/openkruise/kruise-tools) provides commandline tools for kruise features, such as `kubectl-kruise`, which is a standard plugin of `kubectl`.
So, `kubectl-kruise` was created.
## Install
### Install via Krew
1. [Krew](https://krew.sigs.k8s.io/) itself is a kubectl plugin that is installed and updated via Krew (yes, Krew self-hosts).
First, [install krew](https://krew.sigs.k8s.io/docs/user-guide/setup/install/).
### How to use
The development of `kubectl-kruise` is in progress, if you wanna to experience it, you can clone it and make it:
```
make build && cp bin/kubectl-kruise /usr/local/bin
```
### Use with command-line
Then you can operate Openkruise resource by `kubectl-kruise`.
By now the `rollout` cmd such as `rollout undo`, `rollout status`, `rollout history` have been developed.
![](https://tva1.sinaimg.cn/large/008i3skNgy1gqmmcx5nlqj31eo0je420.jpg)
2. Run `kubectl krew install kruise` to install kruise plugin via Krew.
3. Then you can use it with `kubectl-kruise` or `kubectl kruise`.
```bash
$kubectl-kruise --help
kubectl-kruise controls the OpenKruise manager.
$ kubectl-kruise --help
Find more information at: https://openkruise.io/
Aliases:
kubectl-kruise, kk
CloneSet Commands:
rollout Manage the rollout of a resource
set Set specific features on objects
migrate Migrate from K8s original workloads to Kruise workloads
AdvancedStatefulSet Commands:
rollout Manage the rollout of a resource
set Set specific features on objects
Basic Commands:
scale Set a new size for a CloneSet, Deployment, ReplicaSet or Replication Controller
autoscale Auto-scale a CloneSet, Deployment, ReplicaSet, or ReplicationController
Cluster Management Commands:
certificate Modify certificate resources.
cluster-info Display cluster info
top Display Resource (CPU/Memory/Storage) usage.
cordon Mark node as unschedulable
uncordon Mark node as schedulable
drain Drain node in preparation for maintenance
taint Update the taints on one or more nodes
Troubleshooting and Debugging Commands:
describe Show details of a specific resource or group of resources
logs Print the logs for a container in a pod
attach Attach to a running container
exec Execute a command in a container
port-forward Forward one or more local ports to a pod
debug Attach a debug container to a running pod
Advanced Commands:
diff Diff live version against would-be applied version
apply Apply a configuration to a resource by filename or stdin
patch Update field(s) of a resource using strategic merge patch
replace Replace a resource by filename or stdin
wait Experimental: Wait for a specific condition on one or many resources.
kustomize Build a kustomization target from a directory or a remote url.
Other Commands:
api-resources Print the supported API resources on the server
api-versions Print the supported API versions on the server, in the form of "group/version"
config Modify kubeconfig files
plugin Provides utilities for interacting with plugins.
version Print the client and server version information
Usage:
kubectl-kruise [flags] [options]
Use "kubectl-kruise <command> --help" for more information about a given command.
Use "kubectl-kruise options" for a list of global command-line options (applies to all commands).
# or
$ kubectl kruise --help
```
### Install manually
1. You can simply download the binary from the [releases](https://github.com/openkruise/kruise-tools/releases) page. Currently `linux`, `darwin`(OS X), `windows` with `x86_64` and `arm64` are provided. If you are using some other systems or architectures, you have to download the source code and execute `make build` to build the binary.
Currently it also supports to migrate Pods from Deployment to CloneSet by `kruise migrate [options]`.
You can also import `github.com/openkruise/kruise-tools/pkg/migration` and trigger migration with its api.
2. Extract and move it to system PATH.
```bash
$ kubectl-kruise migrate --help
kruise is a command-line tool to use Kruise.
Usage:
kruise [flags]
kruise [command]
Available Commands:
help Help about any command
migrate Migrate from K8s original workloads to Kruise workloads
Flags:
--as string Username to impersonate for the operation
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--cache-dir string Default HTTP cache directory (default "/Users/wsy/.kube/http-cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
-h, --help help for kruise
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
Use "kubectl-kruise [command] --help" for more information about a command.
$ tar xvf kubectl-kruise-darwin-amd64.tar.gz
$ mv darwin-amd64/kubectl-kruise /usr/local/bin/
```
3. Then you can use it with `kubectl-kruise` or `kubectl kruise`.
```bash
$ kubectl-kruise --help
# or
$ kubectl kruise --help
```
## Upgrade
### Upgrade via krew
Run `kubectl krew upgrade kruise` to upgrade kruise plugin via Krew.
### Upgrade manually
Same to `install manually`.
## Usage
### completion
```bash
To load auto completions:
Bash:
$ source <(kubectl-kruise completion bash)
Zsh:
# If shell completion is not already enabled in your environment,
# you will need to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
$ kubectl-kruise completion zsh > "${fpath[1]}/_kubectl-kruise"
Fish:
$ kubectl-kruise completion fish | source
PowerShell:
PS> kubectl-kruise completion powershell | Out-String | Invoke-Expression
### expose
Take a workload(e.g. deployment, cloneset), service or pod and expose it as a new Kubernetes Service.
```bash
$ kubectl kruise expose cloneset nginx --port=80 --target-port=8000
```
### scale
Set a new size for a Deployment, ReplicaSet, CloneSet, or Advanced StatefulSet.
```bash
$ kubectl kruise scale --replicas=3 cloneset nginx
```
It equals to `kubectl scale --replicas=3 cloneset nginx`.
### rollout
Available commands: `history`, `pause`, `restart`, `resume`, `status`, `undo`, `approve`.
```bash
$ kubectl kruise rollout undo cloneset/nginx
# built-in statefulsets
$ kubectl kruise rollout status statefulsets/sts1
# kruise statefulsets
$ kubectl kruise rollout status statefulsets.apps.kruise.io/sts2
# approve a kruise rollout resource named "rollout-demo" in "ns-demo" namespace
$ kubectl kruise rollout approve rollout/rollout-demo -n ns-demo`
# undo a kruise rollout resource
$ kubectl kruise rollout undo rollout/rollout-demo
# Fast rollback during blue-green release (will go back to a previous step with no traffic and most replicas)
$ kubectl kruise rollout undo rollout/rollout-demo --fast
```
### set
Available commands: `env`, `image`, `resources`, `selector`, `serviceaccount`, `subject`.
```bash
$ kubectl kruise set env cloneset/nginx STORAGE_DIR=/local
$ kubectl kruise set image cloneset/nginx busybox=busybox nginx=nginx:1.9.1
```
### migrate
Currently it supports migrate from Deployment to CloneSet.
```bash
# Create an empty CloneSet from an existing Deployment.
$ kubectl kruise migrate CloneSet --from Deployment -n default --dst-name deployment-name --create
# Create a same replicas CloneSet from an existing Deployment.
$ kubectl kruise migrate CloneSet --from Deployment -n default --dst-name deployment-name --create --copy
# Migrate replicas from an existing Deployment to an existing CloneSet.
$ kubectl-kruise migrate CloneSet --from Deployment -n default --src-name cloneset-name --dst-name deployment-name --replicas 10 --max-surge=2
```
### scaledown
Scaledown a cloneset with selective Pods.
```bash
# Scale down 2 with selective pods
$ kubectl kruise scaledown cloneset/nginx --pods pod-a,pod-b
```
It will decrease **replicas=replicas-2** of this cloneset and delete the specified pods.
### exec
Exec working sidecar container of pod when sidecarset is hot-upgrade.
```bash
# Get output from running 'date' command in working sidecar container from pod mypod
kubectl kruise exec mypod -S sidecar-container -- date
# Switch to raw terminal mode, sends stdin to 'bash' in working sidecar container from cloneset myclone
# and sends stdout/stderr from 'bash' back to the client
kubectl kruise exec clone/myclone -S sidecar-container -it -- bash
```
### TODO
@ -129,7 +165,7 @@ $ kubectl-kruise migrate --help
```bash
kubectl kruise migrate CloneSet --from Deployment --src-name deployment-demo --dst-name cloneset-demo --create --copy
```
#### kubectl kruise rollout for CloneSet workload
* [x] undo
* [x] history
@ -137,7 +173,7 @@ kubectl kruise migrate CloneSet --from Deployment --src-name deployment-demo --d
* [x] pause
* [x] resume
* [x] restart
#### kubectl kruise rollout for Advanced StatefulSet
* [x] undo
* [x] history
@ -146,22 +182,76 @@ kubectl kruise migrate CloneSet --from Deployment --src-name deployment-demo --d
#### kubectl kruise expose for CloneSet workload
* [x] kubectl kruise expose cloneset demo-clone --port=80 --target-port=8000
#### kubectl kruise set SUBCOMMAND [options] for CloneSet
* [x] kubectl kruise set image cloneset/abc
* [x] kubectl kruise set env cloneset/abc
* [x] kubectl kruise set serviceaccount cloneset/abc
* [x] kubectl kruise set resources cloneset/abc
#### kubectl kruise set SUBCOMMAND [options] for Advanced StatefulSet
* [x] kubectl kruise set image asts/abc
* [x] kubectl kruise set env asts/abc
* [x] kubectl kruise set serviceaccount asts/abc
* [x] kubectl kruise set resources asts/abc
#### kubectl kruise autoscale SUBCOMMAND [options]
* [ ] kubectl kruise autoscale
## Security
This project includes automated vulnerability scanning to ensure the security of dependencies.
### Vulnerability Scanning
We use two complementary tools to scan for vulnerabilities in our Go dependencies:
1. **Nancy by Sonatype** - Comprehensive dependency scanning against the Sonatype OSS Index
2. **govulncheck** - Official Go vulnerability scanner with call graph analysis to reduce false positives
### CI/CD Security Integration
Security scans are automatically run:
- On every push to `master` and `release*` branches
- On every pull request
- Daily at 2 AM UTC via scheduled workflow
### Handling Vulnerabilities
If vulnerabilities are found:
1. **Review the vulnerability report** - Check if the vulnerability affects your usage
2. **Update dependencies** - Upgrade to a non-vulnerable version if available
3. **Apply workarounds** - If no update is available, consider alternative approaches
4. **Temporary exclusions** - For false positives or accepted risks, add the CVE ID to `.nancy-ignore`
#### Excluding Vulnerabilities
To exclude specific vulnerabilities from Nancy scans, add the CVE ID or OSS Index ID to the `.nancy-ignore` file:
```
# Example: Exclude a specific CVE
CVE-2021-12345
# Example: Exclude by OSS Index ID
9eb9a5bc-8310-4104-bf85-3a820d28ba79
```
### Running Security Scans Locally
To run vulnerability scans locally:
```bash
# Install tools
go install github.com/sonatype-nexus-community/nancy@latest
go install golang.org/x/vuln/cmd/govulncheck@latest
# Run Nancy scan
go list -json -deps ./... > go.list
nancy sleuth --loud
# Run govulncheck
govulncheck ./...
```
### Contributing
We encourage you to help out by reporting issues, improving documentation, fixing bugs, or adding new features.

View File

@ -0,0 +1,51 @@
/*
Copyright 2022 The Kruise Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 generator
const tmpl = `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
`
// Field names
const (
kindField = "kind"
nameField = "name"
listField = "list"
allNamespacesField = "allNamespaces"
immutableField = "immutable"
typeField = "type"
matchExpressionsField = "matchExpressions"
keyField = "key"
operatorField = "operator"
valuesField = "values"
)
var metadataLabelsPath = []string{"metadata", "labels"}
var metadataAnnotationsPath = []string{"metadata", "annotations"}
var resourcePath = []string{"spec", "resource"}
var metadataPath = []string{"spec", "resource", "metadata"}
var resourceLabelsPath = []string{"spec", "resource", "metadata", "labels"}
var resourceAnnotationsPath = []string{"spec", "resource", "metadata", "annotations"}
var targetsPath = []string{"spec", "targets"}
var includedNamespacesPath = []string{"spec", "targets", "includedNamespaces"}
var excludedNamespacesPath = []string{"spec", "targets", "excludedNamespaces"}
var NamespaceLabelSelectorPath = []string{"spec", "targets", "namespaceLabelSelector"}
var MatchLabelsPath = []string{"spec", "targets", "namespaceLabelSelector", "matchLabels"}

View File

@ -0,0 +1,183 @@
/*
Copyright 2022 The Kruise Authors.
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 generator
import (
"github.com/go-errors/errors"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/fn/framework"
"sigs.k8s.io/kustomize/kyaml/fn/framework/command"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
type ResourceDistributionPlugin struct {
types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
ResourceArgs `json:"resource,omitempty" yaml:"resource,omitempty"`
TargetsArgs `json:"targets,omitempty" yaml:"targets,omitempty"`
// Options for the resourcedistribution.
// GeneratorOptions same as configmap and secret generator Options
//
// The features of fields DisableNameSuffixHash and Immutable in Options are not implemented yet
Options *types.GeneratorOptions `json:"options,omitempty" yaml:"options,omitempty"`
// Behavior of generated resource, must be one of:
// 'create': create a new one
// 'replace': replace the existing one
// 'merge': merge with the existing one
//
// The feature of this field is not implemented yet
//Behavior string `json:"behavior,omitempty" yaml:"behavior,omitempty"`
}
// ResourceArgs contain arguments for the resource to be distributed.
type ResourceArgs struct {
// Name of the resource to be distributed.
ResourceName string `json:"resourceName,omitempty" yaml:"resourceName,omitempty"`
// Only configmap and secret are available
ResourceKind string `json:"resourceKind,omitempty" yaml:"resourceKind,omitempty"`
// KvPairSources defines places to obtain key value pairs.
// same as configmap and secret generator KvPairSources
types.KvPairSources `json:",inline,omitempty" yaml:",inline,omitempty"`
// Options for the resource to be distributed.
// GeneratorOptions same as configmap and secret generator Options
//
// The feature of field DisableNameSuffixHash in ResourceOptions is not implemented yet
ResourceOptions *types.GeneratorOptions `json:"resourceOptions,omitempty" yaml:"resourceOptions,omitempty"`
// Type of the secret. It can be "Opaque" (default), or "kubernetes.io/tls".
//
// If type is "kubernetes.io/tls", then "literals" or "files" must have exactly two
// keys: "tls.key" and "tls.crt"
Type string `json:"type,omitempty" yaml:"type,omitempty"`
}
// TargetsArgs defines places to obtain target namespace args.
type TargetsArgs struct {
// AllNamespaces if true distribute all namespaces
AllNamespaces bool `json:"allNamespaces,omitempty" yaml:"allNamespaces,omitempty"`
// ExcludedNamespaces is a list of excluded namespaces name.
ExcludedNamespaces []string `json:"excludedNamespaces,omitempty" yaml:"excludedNamespaces,omitempty"`
// IncludedNamespaces is a list of included namespaces name.
IncludedNamespaces []string `json:"includedNamespaces,omitempty" yaml:"includedNamespaces,omitempty"`
// NamespaceLabelSelector for the generator.
NamespaceLabelSelector *LabelSelector `json:"namespaceLabelSelector,omitempty" yaml:"namespaceLabelSelector,omitempty"`
}
// It is the same as metav1.LabelSelector except that the YAMl tag is added after each field
//
// A label selector is a label query over a set of resources. The result of matchLabels and
// matchExpressions are ANDed. An empty label selector matches all objects. A null
// label selector matches no objects.
// +structType=atomic
type LabelSelector struct {
// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
// map is equivalent to an element of matchExpressions, whose key field is "key", the
// operator is "In", and the values array contains only "value". The requirements are ANDed.
// +optional
MatchLabels map[string]string `json:"matchLabels,omitempty" protobuf:"bytes,1,rep,name=matchLabels" yaml:"matchLabels,omitempty"`
// matchExpressions is a list of label selector requirements. The requirements are ANDed.
// +optional
MatchExpressions []LabelSelectorRequirement `json:"matchExpressions,omitempty" protobuf:"bytes,2,rep,name=matchExpressions" yaml:"matchExpressions,omitempty"`
}
// A label selector requirement is a selector that contains values, a key, and an operator that
// relates the key and values.
type LabelSelectorRequirement struct {
// key is the label key that the selector applies to.
// +patchMergeKey=key
// +patchStrategy=merge
Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key" yaml:"key,omitempty"`
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
Operator metav1.LabelSelectorOperator `json:"operator" protobuf:"bytes,2,opt,name=operator,casttype=LabelSelectorOperator" yaml:"operator,omitempty"`
// values is an array of string values. If the operator is In or NotIn,
// the values array must be non-empty. If the operator is Exists or DoesNotExist,
// the values array must be empty. This array is replaced during a strategic
// merge patch.
// +optional
Values []string `json:"values,omitempty" protobuf:"bytes,3,rep,name=values" yaml:"values,omitempty"`
}
func BuildCmd() *cobra.Command {
config := new(ResourceDistributionPlugin)
fn := func(items []*yaml.RNode) ([]*yaml.RNode, error) {
rn, err := MakeResourceDistribution(config)
if err != nil {
return nil, err
}
var itemsOutput []*yaml.RNode
itemsOutput = append(itemsOutput, rn)
return itemsOutput, nil
}
p := framework.SimpleProcessor{Config: config, Filter: kio.FilterFunc(fn)}
cmd := command.Build(p, command.StandaloneDisabled, false)
return cmd
}
// MakeResourceDistribution makes a ResourceDistribution.
//
// ResourceDistribution: https://openkruise.io/docs/user-manuals/resourcedistribution
func MakeResourceDistribution(config *ResourceDistributionPlugin) (*yaml.RNode, error) {
rn, err := makeBaseNode(&config.ObjectMeta)
if err != nil {
return nil, err
}
// set Labels and Annotations for ResourceDistribution
if config.Options != nil {
err = setLabelsOrAnnotations(rn, config.Options.Annotations, metadataAnnotationsPath)
if err != nil {
return nil, err
}
err = setLabelsOrAnnotations(rn, config.Options.Labels, metadataLabelsPath)
if err != nil {
return nil, err
}
}
if config.ObjectMeta.Name == "" {
return nil, errors.Errorf("a ResourceDistribution must have a name ")
}
err = rn.PipeE(yaml.SetK8sName(config.ObjectMeta.Name))
if err != nil {
return nil, err
}
err = setResource(rn, &config.ResourceArgs)
if err != nil {
return nil, err
}
err = setTargets(rn, &config.TargetsArgs)
if err != nil {
return nil, err
}
return rn, nil
}

View File

@ -0,0 +1,219 @@
/*
Copyright 2022 The Kruise Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 generator
import (
"sort"
"strconv"
"strings"
"github.com/go-errors/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func setTargets(rn *yaml.RNode, args *TargetsArgs) error {
if args.AllNamespaces == false && args.IncludedNamespaces == nil && args.ExcludedNamespaces == nil &&
(args.NamespaceLabelSelector == nil ||
args.NamespaceLabelSelector.MatchLabels == nil && args.NamespaceLabelSelector.MatchExpressions == nil) {
return errors.Errorf("The targets field of the ResourceDistribution cannot be empty")
}
err := setAllNs(rn, args.AllNamespaces)
if err != nil {
return err
}
err = setIncludedExcludedNs(rn, args.ExcludedNamespaces, excludedNamespacesPath)
if err != nil {
return err
}
err = setIncludedExcludedNs(rn, args.IncludedNamespaces, includedNamespacesPath)
if err != nil {
return err
}
err = setNsLabelSelector(rn, args.NamespaceLabelSelector)
if err != nil {
return err
}
return nil
}
// setIncludedExcludedNs set IncludedNamespaces Or ExcludedNamespaces for targets field
func setIncludedExcludedNs(rn *yaml.RNode, v []string, inExNsPath []string) error {
if v == nil {
return nil
}
if err := rn.SetMapField(newNameListRNode(v...), append(inExNsPath, listField)...); err != nil {
return err
}
return nil
}
// newNameListRNode returns a new List *RNode
// containing the provided scalar values prefixed with a string of name.
func newNameListRNode(values ...string) *yaml.RNode {
matchSeq := &yaml.Node{Kind: yaml.SequenceNode}
for _, v := range values {
node := &yaml.Node{
Kind: yaml.MappingNode,
}
node.Content = append(node.Content, &yaml.Node{
Kind: yaml.ScalarNode,
Value: nameField,
}, &yaml.Node{
Kind: yaml.ScalarNode,
Value: v,
})
matchSeq.Content = append(matchSeq.Content, node)
}
return yaml.NewRNode(matchSeq)
}
// setAllNs set AllNamespaces true for targets field
// The allNamespaces field is false by default and is not displayed
func setAllNs(rn *yaml.RNode, allNs bool) error {
if !allNs {
return nil
}
allNamespaces := strconv.FormatBool(allNs)
n := &yaml.Node{
Kind: yaml.ScalarNode,
Value: allNamespaces,
Tag: yaml.NodeTagBool,
}
if err := rn.SetMapField(yaml.NewRNode(n), append(targetsPath, allNamespacesField)...); err != nil {
return err
}
return nil
}
func setNsLabelSelector(rn *yaml.RNode, sel *LabelSelector) error {
if sel == nil {
return nil
}
err := setMatchExpressions(rn, sel.MatchExpressions)
if err != nil {
return err
}
err = setMatchLabels(rn, sel.MatchLabels)
if err != nil {
return err
}
return nil
}
func setMatchLabels(rn *yaml.RNode, matchLabels map[string]string) error {
if matchLabels == nil {
return nil
}
for _, k := range yaml.SortedMapKeys(matchLabels) {
v := matchLabels[k]
if err := rn.SetMapField(yaml.NewStringRNode(v), append(MatchLabelsPath, k)...); err != nil {
return err
}
}
return nil
}
func setMatchExpressions(rn *yaml.RNode, args []LabelSelectorRequirement) error {
if args == nil {
return nil
}
sort.Slice(args, func(i, j int) bool {
return strings.Compare(args[i].Key, args[j].Key) < 0
})
// matchExpList will be seted to the matchExpressions field
matchExpList := &yaml.Node{Kind: yaml.SequenceNode}
for _, matchExpArgs := range args {
matchExpElement := &yaml.Node{
Kind: yaml.MappingNode,
}
// add key for matchExpression
if matchExpArgs.Key == "" {
return errors.Errorf("the field " +
"ResourceDistribution.targets.namespaceLabelSelector.matchExpressions.key cannot be empty")
}
matchExpElement.Content = append(matchExpElement.Content, newNode(keyField), newNode(matchExpArgs.Key))
// add operator for matchExpression
if matchExpArgs.Operator != metav1.LabelSelectorOpIn &&
matchExpArgs.Operator != metav1.LabelSelectorOpNotIn &&
matchExpArgs.Operator != metav1.LabelSelectorOpExists &&
matchExpArgs.Operator != metav1.LabelSelectorOpDoesNotExist {
return errors.Errorf("the field " +
"ResourceDistribution.targets.namespaceLabelSelector.matchExpressions.operator is invalid")
}
operator := string(matchExpArgs.Operator)
matchExpElement.Content = append(matchExpElement.Content, newNode(operatorField), newNode(operator))
if matchExpArgs.Operator == metav1.LabelSelectorOpIn ||
matchExpArgs.Operator == metav1.LabelSelectorOpNotIn {
// add values for matchExpression
if matchExpArgs.Values == nil {
return errors.Errorf("the field " +
"ResourceDistribution.targets.namespaceLabelSelector.matchExpressions.values for In and NotIn cannot be empty")
}
valSeq := &yaml.Node{Kind: yaml.SequenceNode}
knowValue := make(map[string]bool)
sort.Strings(matchExpArgs.Values)
for _, val := range matchExpArgs.Values {
if val == "" {
return errors.Errorf("the element of field " +
"ResourceDistribution.targets.namespaceLabelSelector.matchExpressions.values is invalid")
}
if knowValue[val] {
return errors.Errorf("the element of field " +
"ResourceDistribution.targets.namespaceLabelSelector.matchExpressions.values cannot be repeated")
}
valSeq.Content = append(valSeq.Content, newNode(val))
knowValue[val] = true
}
matchExpElement.Content = append(matchExpElement.Content, newNode(valuesField), valSeq)
} else {
if matchExpArgs.Values != nil {
return errors.Errorf("the field " +
"ResourceDistribution.targets.namespaceLabelSelector.matchExpressions.values for Exist and DoesNotExist must be empty")
}
}
// element is added to the list
matchExpList.Content = append(matchExpList.Content, matchExpElement)
}
err := rn.SetMapField(yaml.NewRNode(matchExpList), append(NamespaceLabelSelectorPath, matchExpressionsField)...)
if err != nil {
return err
}
return nil
}
func newNode(value string) *yaml.Node {
return &yaml.Node{
Kind: yaml.ScalarNode, Value: value,
}
}

View File

@ -0,0 +1,272 @@
/*
Copyright 2022 The Kruise Authors.
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 generator
import (
"encoding/base64"
"strings"
"unicode/utf8"
"github.com/go-errors/errors"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/kv"
"sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func makeBaseNode(meta *types.ObjectMeta) (*yaml.RNode, error) {
rn, err := yaml.Parse(tmpl)
if err != nil {
return nil, err
}
return rn, nil
}
func setResource(rn *yaml.RNode, args *ResourceArgs) error {
if err := setData(rn, args); err != nil {
return err
}
if err := setImmutable(rn, args.ResourceOptions); err != nil {
return err
}
if err := setResourceKind(rn, args.ResourceKind); err != nil {
return err
}
// set Labels And Annotions for Secret or ConfigMap
if args.ResourceOptions != nil {
if err := setLabelsOrAnnotations(rn, args.ResourceOptions.Annotations, resourceAnnotationsPath); err != nil {
return err
}
if err := setLabelsOrAnnotations(rn, args.ResourceOptions.Labels, resourceLabelsPath); err != nil {
return err
}
}
if err := setResourceName(rn, args.ResourceName); err != nil {
return err
}
if err := setResourceType(rn, args); err != nil {
return err
}
return nil
}
func setResourceName(rn *yaml.RNode, name string) error {
if name == "" {
return errors.Errorf("a ResourceDistribution must have a resource name ")
}
if err := rn.SetMapField(yaml.NewStringRNode(name), append(metadataPath, nameField)...); err != nil {
return err
}
return nil
}
func setResourceType(rn *yaml.RNode, args *ResourceArgs) error {
if args.ResourceKind == "Secret" {
t := "Opaque"
if args.Type != "" {
t = args.Type
}
if err := rn.SetMapField(yaml.NewStringRNode(t), append(resourcePath, typeField)...); err != nil {
return err
}
}
return nil
}
func setResourceKind(
rn *yaml.RNode, kind string) error {
if kind == "" || kind != "Secret" && kind != "ConfigMap" {
return errors.Errorf("resourceKind must be ConfigMap or Secret ")
}
if err := rn.SetMapField(yaml.NewStringRNode(kind), append(resourcePath, kindField)...); err != nil {
return err
}
return nil
}
func setLabelsOrAnnotations(
rn *yaml.RNode, labelsOrAnnotations map[string]string, labelsOrAnnotationsPath []string) error {
if labelsOrAnnotations == nil {
return nil
}
for _, k := range yaml.SortedMapKeys(labelsOrAnnotations) {
v := labelsOrAnnotations[k]
if err := rn.SetMapField(yaml.NewStringRNode(v), append(labelsOrAnnotationsPath, k)...); err != nil {
return err
}
}
return nil
}
func setData(rn *yaml.RNode, args *ResourceArgs) error {
ldr, err := loader.NewLoader(loader.RestrictionRootOnly,
"./", filesys.MakeFsOnDisk())
if err != nil {
return err
}
kvLdr := kv.NewLoader(ldr, provider.NewDefaultDepProvider().GetFieldValidator())
m, err := makeValidatedDataMap(kvLdr, args.ResourceName, args.KvPairSources)
if err != nil {
return err
}
if args.ResourceKind == "ConfigMap" {
if err = loadMapIntoConfigMapData(m, rn); err != nil {
return err
}
} else {
if err = loadMapIntoSecretData(m, rn); err != nil {
return err
}
}
return nil
}
// copy from sigs.k8s.io/kustomize/api/internal/generators/utils.go
func makeValidatedDataMap(
ldr ifc.KvLoader, name string, sources types.KvPairSources) (map[string]string, error) {
pairs, err := ldr.Load(sources)
if err != nil {
return nil, errors.WrapPrefix(err, "loading KV pairs", 0)
}
knownKeys := make(map[string]string)
for _, p := range pairs {
// legal key: alphanumeric characters, '-', '_' or '.'
if err := ldr.Validator().ErrIfInvalidKey(p.Key); err != nil {
return nil, err
}
if _, ok := knownKeys[p.Key]; ok {
return nil, errors.Errorf(
"configmap %s illegally repeats the key `%s`", name, p.Key)
}
knownKeys[p.Key] = p.Value
}
return knownKeys, nil
}
func setImmutable(
rn *yaml.RNode, opts *types.GeneratorOptions) error {
if opts == nil {
return nil
}
if opts.Immutable {
n := &yaml.Node{
Kind: yaml.ScalarNode,
Value: "true",
Tag: yaml.NodeTagBool,
}
if err := rn.SetMapField(yaml.NewRNode(n), append(resourcePath, immutableField)...); err != nil {
return err
}
}
return nil
}
// copy from sigs.k8s.io/kustomize/kyaml/yaml/datamap.go
// The resourcePath prefix is added to the fldName
func loadMapIntoConfigMapData(m map[string]string, rn *yaml.RNode) error {
for _, k := range yaml.SortedMapKeys(m) {
fldName, vrN := makeConfigMapValueRNode(m[k])
if _, err := rn.Pipe(
yaml.LookupCreate(yaml.MappingNode, append(resourcePath, fldName)...),
yaml.SetField(k, vrN)); err != nil {
return err
}
}
return nil
}
// copy from sigs.k8s.io/kustomize/kyaml/yaml/datamap.go
func makeConfigMapValueRNode(s string) (field string, rN *yaml.RNode) {
yN := &yaml.Node{Kind: yaml.ScalarNode}
yN.Tag = yaml.NodeTagString
if utf8.ValidString(s) {
field = yaml.DataField
yN.Value = s
} else {
field = yaml.BinaryDataField
yN.Value = encodeBase64(s)
}
if strings.Contains(yN.Value, "\n") {
yN.Style = yaml.LiteralStyle
}
return field, yaml.NewRNode(yN)
}
// copy from sigs.k8s.io/kustomize/kyaml/yaml/datamap.go
func encodeBase64(s string) string {
const lineLen = 70
encLen := base64.StdEncoding.EncodedLen(len(s))
lines := encLen/lineLen + 1
buf := make([]byte, encLen*2+lines)
in := buf[0:encLen]
out := buf[encLen:]
base64.StdEncoding.Encode(in, []byte(s))
k := 0
for i := 0; i < len(in); i += lineLen {
j := i + lineLen
if j > len(in) {
j = len(in)
}
k += copy(out[k:], in[i:j])
if lines > 1 {
out[k] = '\n'
k++
}
}
return string(out[:k])
}
// copy from sigs.k8s.io/kustomize/kyaml/yaml/datamap.go
// The resourcePath prefix is added to the yaml.DataField
func loadMapIntoSecretData(m map[string]string, rn *yaml.RNode) error {
mapNode, err := rn.Pipe(yaml.LookupCreate(yaml.MappingNode, append(resourcePath, yaml.DataField)...))
if err != nil {
return err
}
for _, k := range yaml.SortedMapKeys(m) {
vrN := makeSecretValueRNode(m[k])
if _, err := mapNode.Pipe(yaml.SetField(k, vrN)); err != nil {
return err
}
}
return nil
}
// copy from sigs.k8s.io/kustomize/kyaml/yaml/datamap.go
func makeSecretValueRNode(s string) *yaml.RNode {
yN := &yaml.Node{Kind: yaml.ScalarNode}
// Purposely don't use YAML tags to identify the data as being plain text or
// binary. It kubernetes Secrets the values in the `data` map are expected
// to be base64 encoded, and in ConfigMaps that same can be said for the
// values in the `binaryData` field.
yN.Tag = yaml.NodeTagString
yN.Value = encodeBase64(s)
if strings.Contains(yN.Value, "\n") {
yN.Style = yaml.LiteralStyle
}
return yaml.NewRNode(yN)
}

View File

@ -0,0 +1,30 @@
/*
Copyright 2022 The Kruise Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 main
import (
"os"
"github.com/openkruise/kruise-tools/cmd/resourcedistributiongenerator/generator"
)
func main() {
cmd := generator.BuildCmd()
if err := cmd.Execute(); err != nil {
os.Exit(1)
}
}

View File

@ -0,0 +1,917 @@
/*
Copyright 2022 The Kruise Authors.
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
"github.com/openkruise/kruise-tools/cmd/resourcedistributiongenerator/generator"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func TestResourceDistributionGenerator(t *testing.T) {
tests := []struct {
name string
in string
expect string
filename []string
envFilename []string
setupFile func(t *testing.T, FileSources []string) func()
setupEnvFile func(t *testing.T, EnvFileSources []string) func()
}{
{
name: "configmap-literals-envs-files-resourceOptions-options-allTargets",
setupFile: setupBinaryFile([]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}),
filename: []string{"foo1", "foo2"},
setupEnvFile: setupEnvFile([][]string{{"key1=value1", "#", "", "key2=value2"}, {"key3=value3"}}),
envFilename: []string{"file1.env", "file2.env"},
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: ConfigMap
resourceName: cmname
literals:
- JAVA_HOME=/opt/java/jdk
- A=b
envs:
- file1.env
- file2.env
files:
- foo1
- foo2
resourceOptions:
annotations:
dashboard: "1"
immutable: true
labels:
test: true
rsla: rs
options:
labels:
app.kubernetes.io/name: "app1"
annotations:
an: rdan
targets:
allNamespaces: true
includedNamespaces:
- ns-1
excludedNamespaces:
- ns-2
namespaceLabelSelector:
matchLabels:
group: "test"
matchExpressions:
- key: ffxc
operator: In
values:
- l
- a
- key: exc
operator: NotIn
values:
- albc
- a
- key: abc
operator: Exists
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
A: b
JAVA_HOME: /opt/java/jdk
foo1: hello world
foo2: hello world
key1: value1
key2: value2
key3: value3
immutable: true
kind: ConfigMap
metadata:
annotations:
dashboard: "1"
labels:
rsla: rs
test: "true"
name: cmname
targets:
allNamespaces: true
excludedNamespaces:
list:
- name: ns-2
includedNamespaces:
list:
- name: ns-1
namespaceLabelSelector:
matchExpressions:
- key: abc
operator: Exists
- key: exc
operator: NotIn
values:
- a
- albc
- key: ffxc
operator: In
values:
- a
- l
matchLabels:
group: test
metadata:
annotations:
an: rdan
labels:
app.kubernetes.io/name: app1
name: rdname
`,
},
{
name: "configmap-literals-includedNamespaces",
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: ConfigMap
resourceName: cmname
literals:
- JAVA_HOME= /opt/java/jdk
- A=b
targets:
includedNamespaces:
- ns-1
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
A: b
JAVA_HOME: ' /opt/java/jdk'
kind: ConfigMap
metadata:
name: cmname
targets:
includedNamespaces:
list:
- name: ns-1
metadata:
name: rdname
`,
},
{
name: "configmap-literals-includedNamespaces",
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: ConfigMap
resourceName: cmname
literals:
- JAVA_HOME=/opt/java/jdk
- A=b
targets:
includedNamespaces:
- ns-1
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
A: b
JAVA_HOME: /opt/java/jdk
kind: ConfigMap
metadata:
name: cmname
targets:
includedNamespaces:
list:
- name: ns-1
metadata:
name: rdname
`,
},
{
name: "configmap-envs-resourceOptions-allNamespaces",
setupEnvFile: setupEnvFile([][]string{{"key1=value1"}}),
envFilename: []string{"file1.env"},
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: ConfigMap
resourceName: cmname
envs:
- file1.env
resourceOptions:
annotations:
dashboard: "1"
immutable: false
targets:
allNamespaces: true
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
key1: value1
kind: ConfigMap
metadata:
annotations:
dashboard: "1"
name: cmname
targets:
allNamespaces: true
metadata:
name: rdname
`,
},
{
name: "configmap-files-resourceOptions-matchLabels",
setupFile: setupBinaryFile([]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}),
filename: []string{"foo1", "foo2"},
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: ConfigMap
resourceName: cmname
files:
- foo1
resourceOptions:
labels:
rsla: rs
immutable: true
targets:
namespaceLabelSelector:
matchLabels:
group: "test"
app: "dev"
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
foo1: hello world
immutable: true
kind: ConfigMap
metadata:
labels:
rsla: rs
name: cmname
targets:
namespaceLabelSelector:
matchLabels:
app: dev
group: test
metadata:
name: rdname
`,
},
{
name: "configmap-literals-envs-options-matchExpressions",
setupFile: setupBinaryFile([]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}),
filename: []string{"foo1", "foo2"},
setupEnvFile: setupEnvFile([][]string{{"key1=value1", "#", "", " key2=value2"}, {"key3=value3"}}),
envFilename: []string{"file1.env", "file2.env"},
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: ConfigMap
resourceName: cmname
literals:
- JAVA_HOME=/opt/java/jdk
- A=b
files:
- foo1
options:
labels:
app.kubernetes.io/name: "app1"
targets:
namespaceLabelSelector:
matchExpressions:
- key: ffxc
operator: DoesNotExist
- key: exc
operator: Exists
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
A: b
JAVA_HOME: /opt/java/jdk
foo1: hello world
kind: ConfigMap
metadata:
name: cmname
targets:
namespaceLabelSelector:
matchExpressions:
- key: exc
operator: Exists
- key: ffxc
operator: DoesNotExist
metadata:
labels:
app.kubernetes.io/name: app1
name: rdname
`,
},
{
name: "configmap-envs-files-options-matchExpressions",
setupFile: setupBinaryFile([]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}),
filename: []string{"foo1"},
setupEnvFile: setupEnvFile([][]string{{"key1=value1", "#", "", "key2=value2"}}),
envFilename: []string{"file1.env"},
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: ConfigMap
resourceName: cmname
envs:
- file1.env
files:
- foo1
options:
annotations:
node: 123
an: rdan
targets:
namespaceLabelSelector:
matchExpressions:
- key: exc
operator: NotIn
values:
- albc
- key: abc
operator: Exists
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
foo1: hello world
key1: value1
key2: value2
kind: ConfigMap
metadata:
name: cmname
targets:
namespaceLabelSelector:
matchExpressions:
- key: abc
operator: Exists
- key: exc
operator: NotIn
values:
- albc
metadata:
annotations:
an: rdan
node: "123"
name: rdname
`,
},
{
name: "secret-literals-envs-files-resourceOptions-options-allTargets",
setupFile: setupBinaryFile([]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}),
filename: []string{"foo1", "foo2"},
setupEnvFile: setupEnvFile([][]string{{"key1=value1", "#", "", "key2=value2"}, {"key3=value3"}}),
envFilename: []string{"file1.env", "file2.env"},
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: Secret
resourceName: cmname
literals:
- JAVA_HOME=/opt/java/jdk
- A=b
envs:
- file1.env
- file2.env
files:
- foo1
- foo2
resourceOptions:
annotations:
dashboard: "1"
immutable: true
labels:
test: true
rsla: rs
options:
labels:
app.kubernetes.io/name: "app1"
annotations:
an: rdan
targets:
allNamespaces: true
includedNamespaces:
- ns-1
namespaceLabelSelector:
matchLabels:
group: "test"
matchExpressions:
- key: ffxc
operator: NotIn
values:
- l
- a
- key: exc
operator: NotIn
values:
- albc
- a
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
A: Yg==
JAVA_HOME: L29wdC9qYXZhL2pkaw==
foo1: aGVsbG8gd29ybGQ=
foo2: aGVsbG8gd29ybGQ=
key1: dmFsdWUx
key2: dmFsdWUy
key3: dmFsdWUz
immutable: true
kind: Secret
metadata:
annotations:
dashboard: "1"
labels:
rsla: rs
test: "true"
name: cmname
type: Opaque
targets:
allNamespaces: true
includedNamespaces:
list:
- name: ns-1
namespaceLabelSelector:
matchExpressions:
- key: exc
operator: NotIn
values:
- a
- albc
- key: ffxc
operator: NotIn
values:
- a
- l
matchLabels:
group: test
metadata:
annotations:
an: rdan
labels:
app.kubernetes.io/name: app1
name: rdname
`,
},
{
name: "secret-envs-files-resourceOptions-allNamespaces-excludedNamespaces",
setupFile: setupBinaryFile([]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}),
filename: []string{"foo1"},
setupEnvFile: setupEnvFile([][]string{{"key1=value1", "#", "", "key2=value2"}}),
envFilename: []string{"file1.env"},
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: Secret
resourceName: cmname
envs:
- file1.env
files:
- foo1
resourceOptions:
annotations:
dashboard: "1"
node: 2
immutable: false
labels:
test: true
rsla: rs
targets:
allNamespaces: true
excludedNamespaces:
- ns-2
- ns-3
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
foo1: aGVsbG8gd29ybGQ=
key1: dmFsdWUx
key2: dmFsdWUy
kind: Secret
metadata:
annotations:
dashboard: "1"
node: "2"
labels:
rsla: rs
test: "true"
name: cmname
type: Opaque
targets:
allNamespaces: true
excludedNamespaces:
list:
- name: ns-2
- name: ns-3
metadata:
name: rdname
`,
},
{
name: "secret-literals-options-allNamespaces-includedNamespaces",
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: Secret
resourceName: cmname
literals:
- JAVA_HOME=/opt/java/jdk
type: Opaque
options:
labels:
app.kubernetes.io/name: app1
annotations:
an: "rdan"
targets:
allNamespaces: true
includedNamespaces:
- ns-1
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
JAVA_HOME: L29wdC9qYXZhL2pkaw==
kind: Secret
metadata:
name: cmname
type: Opaque
targets:
allNamespaces: true
includedNamespaces:
list:
- name: ns-1
metadata:
annotations:
an: rdan
labels:
app.kubernetes.io/name: app1
name: rdname
`,
},
{
name: "secret-kubernetes.io/tls-literals-allNamespaces-matchExpressions",
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: Secret
resourceName: cmname
literals:
- tls.crt=LS0tLS1CRUd...tCg==
- tls.key=LS0tLS1CRUd...0tLQo=
type: kubernetes.io/tls
targets:
allNamespaces: true
namespaceLabelSelector:
matchLabels:
group: "test"
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
tls.crt: TFMwdExTMUNSVWQuLi50Q2c9PQ==
tls.key: TFMwdExTMUNSVWQuLi4wdExRbz0=
kind: Secret
metadata:
name: cmname
type: kubernetes.io/tls
targets:
allNamespaces: true
namespaceLabelSelector:
matchLabels:
group: test
metadata:
name: rdname
`,
},
{
name: "secret-kubernetes.io/tls-envs-files-allNamespaces-matchExpressions",
setupEnvFile: setupEnvFile([][]string{{"tls.crt=LS0tLS1CRUd...tCg==", "tls.key=LS0tLS1CRUd...0tLQo="}}),
envFilename: []string{"file1.env"},
in: `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: Secret
resourceName: cmname
envs:
- file1.env
type: kubernetes.io/tls
targets:
allNamespaces: true
namespaceLabelSelector:
matchExpressions:
- key: ffxc
operator: Exists
- key: exc
operator: NotIn
values:
- albc
- a
`,
expect: `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
data:
tls.crt: TFMwdExTMUNSVWQuLi50Q2c9PQ==
tls.key: TFMwdExTMUNSVWQuLi4wdExRbz0=
kind: Secret
metadata:
name: cmname
type: kubernetes.io/tls
targets:
allNamespaces: true
namespaceLabelSelector:
matchExpressions:
- key: exc
operator: NotIn
values:
- a
- albc
- key: ffxc
operator: Exists
metadata:
name: rdname
`,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.setupFile != nil {
if teardown := test.setupFile(t, test.filename); teardown != nil {
defer teardown()
}
}
if test.setupEnvFile != nil {
if teardown := test.setupEnvFile(t, test.envFilename); teardown != nil {
defer teardown()
}
}
cmd := generator.BuildCmd()
cmd.SetIn(bytes.NewBufferString(test.in))
buf := &bytes.Buffer{}
cmd.SetOut(buf)
if err := cmd.Execute(); err != nil {
require.NoError(t, err)
}
//Extract resourceDistribution from the output
out, _ := yaml.Parse(buf.String())
items, _ := out.Pipe(yaml.Get("items"))
elements, _ := items.Elements()
rd, _ := elements[0].String()
if !(strings.TrimSpace(rd) == strings.TrimSpace(test.expect)) {
reportDiffAndFail(t, []byte(strings.TrimSpace(rd)), strings.TrimSpace(test.expect))
}
})
}
}
func setupEnvFile(lines [][]string) func(*testing.T, []string) func() {
return func(t *testing.T, EnvFileSources []string) func() {
filenames := EnvFileSources
for i, filename := range filenames {
data := []byte("")
for _, l := range lines[i] {
data = append(data, []byte(l)...)
data = append(data, []byte("\r\n")...)
}
ioutil.WriteFile(filename, data, 0644)
}
return func() {
for _, file := range filenames {
os.Remove(file)
}
}
}
}
func setupBinaryFile(data []byte) func(*testing.T, []string) func() {
return func(t *testing.T, FileSources []string) func() {
files := FileSources
for _, file := range files {
ioutil.WriteFile(file, data, 0644)
}
return func() {
for _, file := range files {
os.Remove(file)
}
}
}
}
// Pretty printing of file differences.
func reportDiffAndFail(
t *testing.T, actual []byte, expected string) {
t.Helper()
sE, maxLen := convertToArray(expected)
sA, _ := convertToArray(string(actual))
fmt.Println("===== ACTUAL BEGIN ========================================")
fmt.Print(string(actual))
fmt.Println("===== ACTUAL END ==========================================")
format := fmt.Sprintf("%%s %%-%ds %%s\n", maxLen+4)
var limit int
if len(sE) < len(sA) {
limit = len(sE)
} else {
limit = len(sA)
}
fmt.Printf(format, " ", "EXPECTED", "ACTUAL")
fmt.Printf(format, " ", "--------", "------")
for i := 0; i < limit; i++ {
fmt.Printf(format, hint(sE[i], sA[i]), sE[i], sA[i])
}
if len(sE) < len(sA) {
for i := len(sE); i < len(sA); i++ {
fmt.Printf(format, "X", "", sA[i])
}
} else {
for i := len(sA); i < len(sE); i++ {
fmt.Printf(format, "X", sE[i], "")
}
}
t.Fatalf("Expected not equal to actual")
}
func hint(a, b string) string {
if a == b {
return " "
}
return "X"
}
func convertToArray(x string) ([]string, int) {
a := strings.Split(strings.TrimSuffix(x, "\n"), "\n")
maxLen := 0
for i, v := range a {
z := tabToSpace(v)
if len(z) > maxLen {
maxLen = len(z)
}
a[i] = z
}
return a, maxLen
}
func tabToSpace(input string) string {
var result []string
for _, i := range input {
if i == 9 {
result = append(result, " ")
} else {
result = append(result, string(i))
}
}
return strings.Join(result, "")
}

55
docs/kubectl-kruise.md Normal file
View File

@ -0,0 +1,55 @@
## kubectl-kruise
kubectl-kruise controls the OpenKruise CRs
### Synopsis
kubectl-kruise controls the OpenKruise manager.
Find more information at: https://openkruise.io/
```
kubectl-kruise [flags]
```
### Options
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
-h, --help help for kubectl-kruise
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise create](kubectl-kruise_create.md) - Create a resource from a file or from stdin.
* [kubectl-kruise describe](kubectl-kruise_describe.md) - Show details of a specific resource or group of resources
* [kubectl-kruise expose](kubectl-kruise_expose.md) - Take a workload(e.g. deployment, cloneset), service or pod and expose it as a new Kubernetes Service
* [kubectl-kruise migrate](kubectl-kruise_migrate.md) - Migrate from K8s original workloads to Kruise workloads
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
* [kubectl-kruise scaledown](kubectl-kruise_scaledown.md) - Scaledown a cloneset with selective Pods
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,88 @@
## kubectl-kruise create
Create a resource from a file or from stdin.
### Synopsis
Create a resource from a file or from stdin.
JSON and YAML formats are accepted.
```
kubectl-kruise create -f FILENAME
```
### Examples
```
# Create a pod using the data in pod.json.
kubectl create -f ./pod.json
# Create a pod based on the JSON passed into stdin.
cat pod.json | kubectl create -f -
# Edit the data in docker-registry.yaml in JSON then create the resource using the edited data.
kubectl create -f docker-registry.yaml --edit -o json
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
--edit Edit the API resource before creating
--field-manager string Name of the manager used to track field ownership. (default "kubectl-create")
-f, --filename strings Filename, directory, or URL to files to use to create the resource
-h, --help help for create
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
--raw string Raw URI to POST to the server. Uses the transport specified by the kubeconfig file.
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--save-config If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
-l, --selector string Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
--validate string[="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. (default "strict")
--windows-line-endings Only relevant if --edit=true. Defaults to the line ending native to your platform.
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
* [kubectl-kruise create ContainerRecreateRequest](kubectl-kruise_create_ContainerRecreateRequest.md) - Create a crr with the specified name.
* [kubectl-kruise create broadcastJob](kubectl-kruise_create_broadcastJob.md) - Create a broadcastJob with the specified name.
* [kubectl-kruise create job](kubectl-kruise_create_job.md) - Create a job with the specified name.
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,87 @@
## kubectl-kruise create ContainerRecreateRequest
Create a crr with the specified name.
### Synopsis
Create a crr with the specified name.
```
kubectl-kruise create ContainerRecreateRequest NAME --pod=podName [--containers=container]
```
### Examples
```
NOTE: The default value of CRR is:
strategy:
failurePolicy: Fail
orderedRecreate: false
unreadyGracePeriodSeconds: 3
activeDeadlineSeconds: 300
ttlSecondsAfterFinished: 1800
# Create a crr with default value to restart all containers in pod-1
kubectl kruise create ContainerRecreateRequest my-crr --namespace=ns --pod=pod-1
# Create a crr with default value to restart container-1 in pod-1
kubectl kruise create ContainerRecreateRequest my-crr --namespace=ns --pod=pod-1 --containers=container-1
# Create a crr with unreadyGracePeriodSeconds 5 and terminationGracePeriodSeconds 30 to restart container-1 in pod-1
kubectl kruise create ContainerRecreateRequest my-crr --namespace=ns --pod=pod-1 --containers=container-1 --unreadyGracePeriodSeconds=5 --terminationGracePeriodSeconds=30
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--containers strings The containers those need to restarted.
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
--field-manager string Name of the manager used to track field ownership. (default "kubectl kruise-create")
-h, --help help for ContainerRecreateRequest
-m, --minStartedSeconds int32 Minimum number of seconds for which a newly created container should be started and ready without any of its container crashing, for it to be considered Succeeded.Defaults to 0 (container will be considered Succeeded as soon as it is started and ready)
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-p, --pod string The name of the pod).
--save-config If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
-u, --unreadyGracePeriodSeconds int UnreadyGracePeriodSeconds is the optional duration in seconds to mark Pod as not ready over this duration before executing preStop hook and stopping the container
--validate string[="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. (default "strict")
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise create](kubectl-kruise_create.md) - Create a resource from a file or from stdin.
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,78 @@
## kubectl-kruise create broadcastJob
Create a broadcastJob with the specified name.
### Synopsis
Create a broadcastJob with the specified name.
```
kubectl-kruise create broadcastJob NAME --image=image [--from=cronjob/name] -- [COMMAND] [args...]
```
### Examples
```
# Create a broadcastJob
kubectl kruise create broadcastJob my-bcj --image=busybox
# Create a broadcastJob with command
kubectl kruise create broadcastJob my-bcj --image=busybox -- date
# Create a broadcastJob from a AdvancedCronJob named "a-advancedCronjob"
kubectl kruise create broadcastJob test-bcj --from=acj/a-advancedCronjob
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
--field-manager string Name of the manager used to track field ownership. (default "kubectl kruise-create")
--from string The name of the resource to create a BroadcastJob from (only advancedCronjob is supported).
-h, --help help for broadcastJob
--image string Image name to run.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
--save-config If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
--validate string[="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. (default "strict")
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise create](kubectl-kruise_create.md) - Create a resource from a file or from stdin.
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,78 @@
## kubectl-kruise create job
Create a job with the specified name.
### Synopsis
Create a job with the specified name.
```
kubectl-kruise create job NAME --image=image [--from=cronjob/name] -- [COMMAND] [args...]
```
### Examples
```
# Create a job
kubectl kruise create job my-job --image=busybox
# Create a job with command
kubectl kruise create job my-job --image=busybox -- date
# Create a job from a AdvancedCronJob named "a-advancedCronjob"
kubectl kruise create job test-job --from=acj/a-advancedCronjob
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
--field-manager string Name of the manager used to track field ownership. (default "kubectl kruise-create")
--from string The name of the resource to create a Job from (cronjob and advancedCronjob are supported).
-h, --help help for job
--image string Image name to run.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
--save-config If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
--validate string[="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. (default "strict")
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise create](kubectl-kruise_create.md) - Create a resource from a file or from stdin.
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,60 @@
## kubectl-kruise describe
Show details of a specific resource or group of resources
### Synopsis
Show details of a rollout.
```
kubectl-kruise describe SUBCOMMAND
```
### Examples
```
# Describe the rollout named rollout-demo
kubectl-kruise describe rollout rollout-demo
```
### Options
```
-h, --help help for describe
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
* [kubectl-kruise describe rollout](kubectl-kruise_describe_rollout.md) - Get details about a rollout
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,66 @@
## kubectl-kruise describe rollout
Get details about a rollout
### Synopsis
Get details about and visual representation of a rollout.
```
kubectl-kruise describe rollout SUBCOMMAND
```
### Examples
```
# Describe the rollout named rollout-demo within namespace default
kubectl-kruise describe rollout rollout-demo/default
# Watch for changes to the rollout named rollout-demo
kubectl-kruise describe rollout rollout-demo/default -w
```
### Options
```
--all Show all pods in the rollout
-h, --help help for rollout
--no-color If true, print output without color
--timeout int Timeout after specified seconds
-w, --watch Watch for changes to the rollout
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise describe](kubectl-kruise_describe.md) - Show details of a specific resource or group of resources
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,109 @@
## kubectl-kruise expose
Take a workload(e.g. deployment, cloneset), service or pod and expose it as a new Kubernetes Service
### Synopsis
Expose a resource as a new Kubernetes service.
Looks up a deployment, service, replica set, replication controller or pod by name and uses the selector for that resource as the selector for a new service on the specified port. A deployment or replica set will be exposed as a service only if its selector is convertible to a selector that service supports, i.e. when the selector contains only the matchLabels component. Note that if no port is specified via --port and the exposed resource has multiple ports, all will be re-used by the new service. Also if no labels are specified, the new service will re-use the labels from the resource it exposes.
Possible resources include (case insensitive):
pod (po), service (svc), replicationcontroller (rc), cloneset (clone), deployment (deploy), replicaset (rs)
```
kubectl-kruise expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type]
```
### Examples
```
# Create a service for an nginx cloneset, which serves on port 80 and connects to the containers on port 8000.
kubectl kruise expose cloneset nginx --port=80 --target-port=8000
# Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000.
kubectl expose rc nginx --port=80 --target-port=8000
# Create a service for a replication controller identified by type and name specified in "nginx-controller.yaml", which serves on port 80 and connects to the containers on port 8000.
kubectl expose -f nginx-controller.yaml --port=80 --target-port=8000
# Create a service for a pod valid-pod, which serves on port 444 with the name "frontend"
kubectl expose pod valid-pod --port=444 --name=frontend
# Create a second service based on the above service, exposing the container port 8443 as port 443 with the name "nginx-https"
kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https
# Create a service for a replicated streaming application on port 4100 balancing UDP traffic and named 'video-stream'.
kubectl expose rc streamer --port=4100 --protocol=UDP --name=video-stream
# Create a service for a replicated nginx using replica set, which serves on port 80 and connects to the containers on port 8000.
kubectl expose rs nginx --port=80 --target-port=8000
# Create a service for an nginx deployment, which serves on port 80 and connects to the containers on port 8000.
kubectl expose deployment nginx --port=80 --target-port=8000
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--cluster-ip string ClusterIP to be assigned to the service. Leave empty to auto-allocate, or set to 'None' to create a headless service.
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
--external-ip string Additional external IP address (not managed by Kubernetes) to accept for the service. If this IP is routed to a node, the service can be accessed by this IP in addition to its generated service IP.
--field-manager string Name of the manager used to track field ownership. (default "kubectl-expose")
-f, --filename strings Filename, directory, or URL to files identifying the resource to expose a service
--generator string The name of the API generator to use. There are 2 generators: 'service/v1' and 'service/v2'. The only difference between them is that service port in v1 is named 'default', while it is left unnamed in v2. Default is 'service/v2'. (default "service/v2")
-h, --help help for expose
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
-l, --labels string Labels to apply to the service created by this call.
--load-balancer-ip string IP to assign to the LoadBalancer. If empty, an ephemeral IP will be created and used (cloud-provider specific).
--name string The name for the newly created object.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
--overrides string An inline JSON override for the generated object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field.
--port string The port that the service should serve on. Copied from the resource being exposed, if unspecified
--protocol string The network protocol for the service to be created. Default is 'TCP'.
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--save-config If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
--selector string A label selector to use for this service. Only equality-based selector requirements are supported. If empty (the default) infer the selector from the replication controller or replica set.)
--session-affinity string If non-empty, set the session affinity for the service to this; legal values: 'None', 'ClientIP'
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--target-port string Name or number for the port on the container that the service should direct traffic to. Optional.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
--type string Type for this service: ClusterIP, NodePort, LoadBalancer, or ExternalName. Default is 'ClusterIP'.
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,75 @@
## kubectl-kruise migrate
Migrate from K8s original workloads to Kruise workloads
### Synopsis
Migrate from K8s original workloads to Kruise workloads
```
kubectl-kruise migrate [DST_KIND] --from [SRC_KIND] [flags]
```
### Examples
```
# Create an empty CloneSet from an existing Deployment.
kubectl-kruise migrate CloneSet --from Deployment -n default --dst-name deployment-name --create
# Create a same replicas CloneSet from an existing Deployment.
kubectl-kruise migrate CloneSet --from Deployment -n default --dst-name deployment-name --create --copy
# Migrate replicas from an existing Deployment to an existing CloneSet.
kubectl-kruise migrate CloneSet --from Deployment -n default --src-name cloneset-name --dst-name deployment-name --replicas 10 --max-surge=2
```
### Options
```
--copy Copy replicas from src workload when create.
--create Create dst workload with replicas=0 from src workload.
--dst-name string Name of the destination workload.
--from string Type of the source workload (e.g. Deployment).
-h, --help help for migrate
--max-surge int32 Max surge during migration. (default 1)
--replicas int32 The replicas needs to migrate, -1 indicates all replicas in src workload. (default -1)
--src-name string Name of the source workload.
--timeout-seconds int32 Timeout seconds for migration, -1 indicates no limited. (default -1)
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,79 @@
## kubectl-kruise rollout
Manage the rollout of a resource
### Synopsis
Manage the rollout of a resource.
Valid resource types include:
* deployments
* daemonsets
* statefulsets
* clonesets
* statefulsets.apps.kruise.io
* daemonsets.apps.kruise.io
* rollouts.rollouts.kruise.io
```
kubectl-kruise rollout SUBCOMMAND
```
### Examples
```
# Rollback to the previous cloneset
kubectl-kruise rollout undo cloneset/abc
# Check the rollout status of a daemonset
kubectl-kruise rollout status daemonset/foo
```
### Options
```
-h, --help help for rollout
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
* [kubectl-kruise rollout approve](kubectl-kruise_rollout_approve.md) - Approve a resource
* [kubectl-kruise rollout history](kubectl-kruise_rollout_history.md) - View rollout history
* [kubectl-kruise rollout pause](kubectl-kruise_rollout_pause.md) - Mark the provided resource as paused
* [kubectl-kruise rollout restart](kubectl-kruise_rollout_restart.md) - Restart a resource
* [kubectl-kruise rollout resume](kubectl-kruise_rollout_resume.md) - Resume a paused resource
* [kubectl-kruise rollout status](kubectl-kruise_rollout_status.md) - Show the status of the rollout
* [kubectl-kruise rollout undo](kubectl-kruise_rollout_undo.md) - Undo a previous rollout
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,69 @@
## kubectl-kruise rollout approve
Approve a resource
### Synopsis
Approve a resource which can be continued.
Paused resources will not be reconciled by a controller. By approving a resource, we allow it to be continue to rollout. Currently only kruise-rollouts support being approved.
```
kubectl-kruise rollout approve RESOURCE
```
### Examples
```
# approve a kruise rollout resource named "rollout-demo" in "ns-demo" namespace
kubectl-kruise rollout approve rollout/rollout-demo -n ns-demo
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for approve
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,73 @@
## kubectl-kruise rollout history
View rollout history
### Synopsis
View previous rollout revisions and configurations.
```
kubectl-kruise rollout history (TYPE NAME | TYPE/NAME) [flags]
```
### Examples
```
# View the rollout history of a cloneset
kubectl-kruise rollout history cloneset/abc
# View the rollout history of a advanced statefulset
kubectl-kruise rollout history asts/abc
# View the details of daemonset revision 3
kubectl-kruise rollout history daemonset/abc --revision=3
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for history
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--revision int See the details, including podTemplate of the revision specified
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,71 @@
## kubectl-kruise rollout pause
Mark the provided resource as paused
### Synopsis
Mark the provided resource as paused
Paused resources will not be reconciled by a controller. Use "kubectl rollout resume" to resume a paused resource. Currently deployments, clonesets, rollouts support being paused.
```
kubectl-kruise rollout pause RESOURCE
```
### Examples
```
# Mark the nginx deployment as paused. Any current state of
# the deployment will continue its function, new updates to the deployment will not
# have an effect as long as the deployment is paused.
kubectl-kruise rollout pause deployment/nginx
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for pause
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,76 @@
## kubectl-kruise rollout restart
Restart a resource
### Synopsis
Restart a resource.
Resource will be rollout restarted. Supported kinds include:
CloneSet, DaemonSet, Deployment, StatefulSet, and UnitedDeployment.
```
kubectl-kruise rollout restart RESOURCE
```
### Examples
```
# Restart a deployment
kubectl-kruise rollout restart deployment/nginx
kubectl-kruise rollout restart cloneset/abc
# Restart a daemonset
kubectl-kruise rollout restart daemonset/abc
# Restart a UnitedDeployment
kubectl-kruise rollout restart uniteddeployment/my-app
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for restart
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,71 @@
## kubectl-kruise rollout resume
Resume a paused resource
### Synopsis
Resume a paused resource
Paused resources will not be reconciled by a controller. By resuming a resource, we allow it to be reconciled again. Currently deployments, cloneset support being resumed.
```
kubectl-kruise rollout resume RESOURCE
```
### Examples
```
# Resume an already paused rollout/cloneset/deployment resource
kubectl-kruise rollout resume rollout/nginx
kubectl-kruise rollout resume cloneset/nginx
kubectl-kruise rollout resume deployment/nginx
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for resume
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,74 @@
## kubectl-kruise rollout status
Show the status of the rollout
### Synopsis
Show the status of the rollout.
By default 'rollout status' will watch the status of the latest rollout until it's done. If you don't want to wait for the rollout to finish then you can use --watch=false. Note that if a new rollout starts in-between, then 'rollout status' will continue watching the latest revision. If you want to pin to a specific revision and abort if it is rolled over by another revision, use --revision=N where N is the revision you need to watch for.
```
kubectl-kruise rollout status (TYPE NAME | TYPE/NAME) [flags]
```
### Examples
```
# Watch the rollout status of a deployment
kubectl-kruise rollout status deployment/nginx
# Watch the rollout status of a cloneset
kubectl-kruise rollout status cloneset/nginx
# Watch the rollout status of a advanced statefulset
kubectl-kruise rollout status asts/nginx
```
### Options
```
-d, --detail Show the detail status of the rollout.
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for status
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--revision int Pin to a specific revision for showing its status. Defaults to 0 (last revision).
--timeout duration The length of time to wait before ending watch, zero means never. Any other values should contain a corresponding time unit (e.g. 1s, 2m, 3h).
-w, --watch Watch the status of the rollout until it's done. (default true)
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,84 @@
## kubectl-kruise rollout undo
Undo a previous rollout
### Synopsis
Rollback to a previous rollout.
```
kubectl-kruise rollout undo (TYPE NAME | TYPE/NAME) [flags]
```
### Examples
```
# Rollback to the previous cloneset
kubectl-kruise rollout undo cloneset/abc
# Rollback to the previous Advanced StatefulSet
kubectl-kruise rollout undo asts/abc
# Rollback to daemonset revision 3
kubectl-kruise rollout undo daemonset/abc --to-revision=3
# Rollback to the previous deployment with dry-run
kubectl-kruise rollout undo --dry-run=server deployment/abc
# Rollback to workload via rollout api object
kubectl-kruise rollout undo rollout/abc
# Fast rollback during blue-green release (will go back to a previous step with no traffic and most replicas)
kubectl-kruise rollout undo rollout/abc --fast
```
### Options
```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
--fast fast rollback for blue-green release
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for undo
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
--to-revision int The revision to rollback to. Default to 0 (last revision).
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,62 @@
## kubectl-kruise scaledown
Scaledown a cloneset with selective Pods
### Synopsis
Scaledown a cloneset with selective Pods
```
kubectl-kruise scaledown [CLONESET] --pods [POD1,POD2] -n [NAMESPACE]
```
### Examples
```
# Scale down 2 with selective pods
kubectl-kruise scaledown CloneSet cloneset-demo --pods pod-1, pod-2 -n default
```
### Options
```
-h, --help help for scaledown
--pods string Name of the pods to delete
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,60 @@
## kubectl-kruise set
Set specific features on objects
### Synopsis
Configure application resources
These commands help you make changes to existing application resources.
```
kubectl-kruise set SUBCOMMAND
```
### Options
```
-h, --help help for set
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
* [kubectl-kruise set env](kubectl-kruise_set_env.md) - Update environment variables on a pod template
* [kubectl-kruise set image](kubectl-kruise_set_image.md) - Update image of a pod template
* [kubectl-kruise set resources](kubectl-kruise_set_resources.md) - Update resource requests/limits on objects with pod templates
* [kubectl-kruise set selector](kubectl-kruise_set_selector.md) - Set the selector on a resource
* [kubectl-kruise set serviceaccount](kubectl-kruise_set_serviceaccount.md) - Update ServiceAccount of a resource
* [kubectl-kruise set subject](kubectl-kruise_set_subject.md) - Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,117 @@
## kubectl-kruise set env
Update environment variables on a pod template
### Synopsis
Update environment variables on a pod template.
List environment variable definitions in one or more pods, pod templates. Add, update, or remove container environment variable definitions in one or more pod templates (within replication controllers or deployment configurations). View or modify the environment variable definitions on all containers in the specified pods or pod templates, or just those that match a wildcard.
If "--env -" is passed, environment variables can be read from STDIN using the standard env syntax.
Possible resources include (case insensitive):
pod (po), deployment (deploy), statefulset (sts), daemonset (ds), replicaset (rs), cloneset (clone), statefulset.apps.kruise.io (asts), daemonset.apps.kruise.io (ads)
```
kubectl-kruise set env RESOURCE/NAME KEY_1=VAL_1 ... KEY_N=VAL_N
```
### Examples
```
# Update cloneset 'sample' with a new environment variable
kubectl-kruise set env cloneset/sample STORAGE_DIR=/local
# List the environment variables defined on a cloneset 'sample'
kubectl-kruise set env cloneset/sample --list
# List the environment variables defined on all pods
kubectl-kruise set env pods --all --list
# Output modified cloneset in YAML, and does not alter the object on the server
kubectl-kruise set env cloneset/sample STORAGE_DIR=/data -o yaml
# Update all containers in all replication controllers in the project to have ENV=prod
kubectl-kruise set env rc --all ENV=prod
# Import environment from a secret
kubectl-kruise set env --from=secret/mysecret cloneset/sample
# Import environment from a config map with a prefix
kubectl-kruise set env --from=configmap/myconfigmap --prefix=MYSQL_ cloneset/sample
# Import specific keys from a config map
kubectl-kruise set env --keys=my-example-key --from=configmap/myconfigmap cloneset/sample
# Remove the environment variable ENV from container 'c1' in all deployment configs
kubectl-kruise set env clonesets --all --containers="c1" ENV-
# Remove the environment variable ENV from a deployment definition on disk and
# update the deployment config on the server
kubectl-kruise set env -f deploy.json ENV-
# Set some of the local shell environment into a deployment config on the server
env | grep RAILS_ | kubectl-kruise set env -e - cloneset/sample
```
### Options
```
--all If true, select all resources in the namespace of the specified resource types
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-c, --containers string The names of containers in the selected pod templates to change - may use wildcards (default "*")
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
-e, --env stringArray Specify a key-value pair for an environment variable to set into each container.
-f, --filename strings Filename, directory, or URL to files the resource to update the env
--from string The name of a resource from which to inject environment variables
-h, --help help for env
--keys strings Comma-separated list of keys to import from specified resource
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
--list If true, display the environment and any changes in the standard format. this flag will removed when we have kubectl view env.
--local If true, set env will NOT contact api-server but run locally.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
--overwrite If true, allow environment to be overwritten, otherwise reject updates that overwrite existing environment. (default true)
--prefix string Prefix to append to variable names
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--resolve If true, show secret or configmap references when listing variables
-l, --selector string Selector (label query) to filter on
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,83 @@
## kubectl-kruise set image
Update image of a pod template
### Synopsis
Update existing container image(s) of resources.
Possible resources include (case insensitive):
pod (po), deployment (deploy), statefulset (sts), daemonset (ds), replicaset (rs), cloneset (clone), statefulset.apps.kruise.io (asts), daemonset.apps.kruise.io (ads)
```
kubectl-kruise set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N
```
### Examples
```
# Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'.
kubectl-kruise set image cloneset/sample busybox=busybox nginx=nginx:1.9.1
# Update all deployments' and rc's nginx container's image to 'nginx:1.9.1'
kubectl-kruise set image cloneset,rc nginx=nginx:1.9.1 --all
# Update image of all containers of cloneset sample to 'nginx:1.9.1'
kubectl-kruise set image cloneset sample *=nginx:1.9.1
# Print result (in yaml format) of updating nginx container image from local file, without hitting the server
kubectl-kruise set image -f path/to/file.yaml nginx=nginx:1.9.1 --local -o yaml
```
### Options
```
--all Select all resources, including uninitialized ones, in the namespace of the specified resource types
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for image
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
--local If true, set image will NOT contact api-server but run locally.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
-l, --selector string Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,88 @@
## kubectl-kruise set resources
Update resource requests/limits on objects with pod templates
### Synopsis
Specify compute resource requirements (cpu, memory) for any resource that defines a pod template. If a pod is successfully scheduled, it is guaranteed the amount of resource requested, but may burst up to its specified limits.
for each compute resource, if a limit is specified and a request is omitted, the request will default to the limit.
Possible resources include (case insensitive):
pod (po), deployment (deploy), statefulset (sts), daemonset (ds), replicaset (rs), cloneset (clone), statefulset.apps.kruise.io (asts), daemonset.apps.kruise.io (ads)
```
kubectl-kruise set resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]
```
### Examples
```
# Set a deployments nginx container cpu limits to "200m" and memory to "512Mi"
kubectl-kruise set resources cloneset sample -c=nginx --limits=cpu=200m,memory=512Mi
# Set the resource request and limits for all containers in nginx
kubectl-kruise set resources cloneset sample --limits=cpu=200m,memory=512Mi --requests=cpu=100m,memory=256Mi
# Remove the resource requests for resources on containers in nginx
kubectl-kruise set resources cloneset sample --limits=cpu=0,memory=0 --requests=cpu=0,memory=0
# Print the result (in yaml format) of updating nginx container limits from a local, without hitting the server
kubectl-kruise set resources -f path/to/file.yaml --limits=cpu=200m,memory=512Mi --local -o yaml
```
### Options
```
--all Select all resources, including uninitialized ones, in the namespace of the specified resource types
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-c, --containers string The names of containers in the selected pod templates to change, all containers are selected by default - may use wildcards (default "*")
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for resources
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
--limits string The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.
--local If true, set resources will NOT contact api-server but run locally.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--requests string The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.
-l, --selector string Selector (label query) to filter on, not including uninitialized ones,supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,72 @@
## kubectl-kruise set selector
Set the selector on a resource
### Synopsis
Set the selector on a resource. Note that the new selector will overwrite the old selector if the resource had one prior to the invocation of 'set selector'.
A selector must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to 63 characters. If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used. Note: currently selectors can only be set on Service objects.
```
kubectl-kruise set selector (-f FILENAME | TYPE NAME) EXPRESSIONS [--resource-version=version]
```
### Examples
```
# set the labels and selector before creating a deployment/service pair.
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run=client | kubectl-kruise set selector --local -f - 'environment=qa' -o yaml | kubectl create -f -
kubectl create cloneset sample -o yaml --dry-run=client | kubectl label --local -f - environment=qa -o yaml | kubectl create -f -
```
### Options
```
--all Select all resources in the namespace of the specified resource types
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
-f, --filename strings identifying the resource.
-h, --help help for selector
--local If true, annotation will NOT contact api-server but run locally.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory. (default true)
--resource-version string If non-empty, the selectors update will only succeed if this is the current resource-version for the object. Only valid when specifying a single resource.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,76 @@
## kubectl-kruise set serviceaccount
Update ServiceAccount of a resource
### Synopsis
Update ServiceAccount of pod template resources.
Possible resources (case insensitive) can be:
replicationcontroller (rc), deployment (deploy), daemonset (ds), job, replicaset (rs), statefulset, cloneset (cs)
```
kubectl-kruise set serviceaccount (-f FILENAME | TYPE NAME) SERVICE_ACCOUNT
```
### Examples
```
# Set Deployment nginx-deployment's ServiceAccount to serviceaccount1
kubectl-kruise set serviceaccount cloneset sample serviceaccount1
# Print the result (in yaml format) of updated cloneset with serviceaccount from local file, without hitting apiserver
kubectl-kruise set sa -f CloneSet.yaml serviceaccount1 --local --dry-run=client -o yaml
```
### Options
```
--all Select all resources, including uninitialized ones, in the namespace of the specified resource types
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
-f, --filename strings Filename, directory, or URL to files identifying the resource to get from a server.
-h, --help help for serviceaccount
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
--local If true, set serviceaccount will NOT contact api-server but run locally.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,78 @@
## kubectl-kruise set subject
Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding
### Synopsis
Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding.
```
kubectl-kruise set subject (-f FILENAME | TYPE NAME) [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run=server|client|none]
```
### Examples
```
# Update a ClusterRoleBinding for serviceaccount1
kubectl-kruise set subject clusterrolebinding admin --serviceaccount=namespace:serviceaccount1
# Update a RoleBinding for user1, user2, and group1
kubectl-kruise set subject rolebinding admin --user=user1 --user=user2 --group=group1
# Print the result (in yaml format) of updating rolebinding subjects from a local, without hitting the server
kubectl create rolebinding admin --role=admin --user=admin -o yaml --dry-run=client | kubectl-kruise set subject --local -f - --user=foo -o yaml
```
### Options
```
--all Select all resources, including uninitialized ones, in the namespace of the specified resource types
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
--dry-run string[="unchanged"] Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. (default "none")
-f, --filename strings Filename, directory, or URL to files the resource to update the subjects
--group stringArray Groups to bind to the role
-h, --help help for subject
-k, --kustomize string Process the kustomization directory. This flag can't be used together with -f or -R.
--local If true, set subject will NOT contact api-server but run locally.
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
-R, --recursive Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
-l, --selector string Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
--serviceaccount stringArray Service accounts to bind to the role
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
--user stringArray Usernames to bind to the role
```
### Options inherited from parent commands
```
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request
--password string Password for basic authentication to the API server
--profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")
--profile-output string Name of the file to write the profile to (default "profile.pprof")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--username string Username for basic authentication to the API server
--warnings-as-errors Treat warnings received from the server as errors and exit with a non-zero exit code
```
### SEE ALSO
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
###### Auto generated by spf13/cobra on 12-Mar-2025

View File

@ -0,0 +1,87 @@
name: kubectl-kruise
synopsis: kubectl-kruise controls the OpenKruise CRs
description: |-
kubectl-kruise controls the OpenKruise manager.
Find more information at: https://openkruise.io/
usage: kubectl-kruise [flags]
options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: help
shorthand: h
default_value: "false"
usage: help for kubectl-kruise
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
see_also:
- kubectl-kruise create - Create a resource from a file or from stdin.
- kubectl-kruise describe - Show details of a specific resource or group of resources
- kubectl-kruise expose - Take a workload(e.g. deployment, cloneset), service or pod and expose it as a new Kubernetes Service
- kubectl-kruise migrate - Migrate from K8s original workloads to Kruise workloads
- kubectl-kruise rollout - Manage the rollout of a resource
- kubectl-kruise scaledown - Scaledown a cloneset with selective Pods
- kubectl-kruise set - Set specific features on objects

View File

@ -0,0 +1,151 @@
name: kubectl-kruise create
synopsis: Create a resource from a file or from stdin.
description: |-
Create a resource from a file or from stdin.
JSON and YAML formats are accepted.
usage: kubectl-kruise create -f FILENAME
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: edit
default_value: "false"
usage: Edit the API resource before creating
- name: field-manager
default_value: kubectl-create
usage: Name of the manager used to track field ownership.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files to use to create the resource
- name: help
shorthand: h
default_value: "false"
usage: help for create
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: raw
usage: |
Raw URI to POST to the server. Uses the transport specified by the kubeconfig file.
- name: record
default_value: "false"
usage: |
Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: save-config
default_value: "false"
usage: |
If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
- name: selector
shorthand: l
usage: |
Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
- name: validate
default_value: strict
usage: |-
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.
- name: windows-line-endings
default_value: "false"
usage: |
Only relevant if --edit=true. Defaults to the line ending native to your platform.
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Create a pod using the data in pod.json.\n kubectl create -f ./pod.json\n \n # Create a pod based on the JSON passed into stdin.\n cat pod.json | kubectl create -f -\n \n # Edit the data in docker-registry.yaml in JSON then create the resource using the edited data.\n kubectl create -f docker-registry.yaml --edit -o json"
see_also:
- kubectl-kruise - kubectl-kruise controls the OpenKruise CRs
- kubectl-kruise create ContainerRecreateRequest - Create a crr with the specified name.
- kubectl-kruise create broadcastJob - Create a broadcastJob with the specified name.
- kubectl-kruise create job - Create a job with the specified name.

View File

@ -0,0 +1,129 @@
name: kubectl-kruise create ContainerRecreateRequest
synopsis: Create a crr with the specified name.
description: Create a crr with the specified name.
usage: kubectl-kruise create ContainerRecreateRequest NAME --pod=podName [--containers=container]
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: containers
default_value: '[]'
usage: The containers those need to restarted.
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: field-manager
default_value: kubectl kruise-create
usage: Name of the manager used to track field ownership.
- name: help
shorthand: h
default_value: "false"
usage: help for ContainerRecreateRequest
- name: minStartedSeconds
shorthand: m
default_value: "0"
usage: |
Minimum number of seconds for which a newly created container should be started and ready without any of its container crashing, for it to be considered Succeeded.Defaults to 0 (container will be considered Succeeded as soon as it is started and ready)
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: pod
shorthand: p
usage: The name of the pod).
- name: save-config
default_value: "false"
usage: |
If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
- name: unreadyGracePeriodSeconds
shorthand: u
default_value: "0"
usage: |
UnreadyGracePeriodSeconds is the optional duration in seconds to mark Pod as not ready over this duration before executing preStop hook and stopping the container
- name: validate
default_value: strict
usage: |-
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.
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " NOTE: The default value of CRR is:\n strategy:\n failurePolicy: Fail\n orderedRecreate: false\n unreadyGracePeriodSeconds: 3\n activeDeadlineSeconds: 300\n ttlSecondsAfterFinished: 1800\n # Create a crr with default value to restart all containers in pod-1\n kubectl kruise create ContainerRecreateRequest my-crr --namespace=ns --pod=pod-1\n \n # Create a crr with default value to restart container-1 in pod-1\n kubectl kruise create ContainerRecreateRequest my-crr --namespace=ns --pod=pod-1 --containers=container-1\n \n # Create a crr with unreadyGracePeriodSeconds 5 and terminationGracePeriodSeconds 30 to restart container-1 in pod-1\n kubectl kruise create ContainerRecreateRequest my-crr --namespace=ns --pod=pod-1 --containers=container-1 --unreadyGracePeriodSeconds=5 --terminationGracePeriodSeconds=30"
see_also:
- kubectl-kruise create - Create a resource from a file or from stdin.

View File

@ -0,0 +1,118 @@
name: kubectl-kruise create broadcastJob
synopsis: Create a broadcastJob with the specified name.
description: Create a broadcastJob with the specified name.
usage: kubectl-kruise create broadcastJob NAME --image=image [--from=cronjob/name] -- [COMMAND] [args...]
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: field-manager
default_value: kubectl kruise-create
usage: Name of the manager used to track field ownership.
- name: from
usage: |
The name of the resource to create a BroadcastJob from (only advancedCronjob is supported).
- name: help
shorthand: h
default_value: "false"
usage: help for broadcastJob
- name: image
usage: Image name to run.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: save-config
default_value: "false"
usage: |
If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
- name: validate
default_value: strict
usage: |-
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.
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Create a broadcastJob\n kubectl kruise create broadcastJob my-bcj --image=busybox\n \n # Create a broadcastJob with command\n kubectl kruise create broadcastJob my-bcj --image=busybox -- date\n \n # Create a broadcastJob from a AdvancedCronJob named \"a-advancedCronjob\"\n kubectl kruise create broadcastJob test-bcj --from=acj/a-advancedCronjob"
see_also:
- kubectl-kruise create - Create a resource from a file or from stdin.

View File

@ -0,0 +1,118 @@
name: kubectl-kruise create job
synopsis: Create a job with the specified name.
description: Create a job with the specified name.
usage: kubectl-kruise create job NAME --image=image [--from=cronjob/name] -- [COMMAND] [args...]
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: field-manager
default_value: kubectl kruise-create
usage: Name of the manager used to track field ownership.
- name: from
usage: |
The name of the resource to create a Job from (cronjob and advancedCronjob are supported).
- name: help
shorthand: h
default_value: "false"
usage: help for job
- name: image
usage: Image name to run.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: save-config
default_value: "false"
usage: |
If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
- name: validate
default_value: strict
usage: |-
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.
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Create a job\n kubectl kruise create job my-job --image=busybox\n \n # Create a job with command\n kubectl kruise create job my-job --image=busybox -- date\n \n # Create a job from a AdvancedCronJob named \"a-advancedCronjob\"\n kubectl kruise create job test-job --from=acj/a-advancedCronjob"
see_also:
- kubectl-kruise create - Create a resource from a file or from stdin.

View File

@ -0,0 +1,83 @@
name: kubectl-kruise describe
synopsis: Show details of a specific resource or group of resources
description: Show details of a rollout.
usage: kubectl-kruise describe SUBCOMMAND
options:
- name: help
shorthand: h
default_value: "false"
usage: help for describe
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: |4-
# Describe the rollout named rollout-demo
kubectl-kruise describe rollout rollout-demo
see_also:
- kubectl-kruise - kubectl-kruise controls the OpenKruise CRs
- kubectl-kruise describe rollout - Get details about a rollout

View File

@ -0,0 +1,93 @@
name: kubectl-kruise describe rollout
synopsis: Get details about a rollout
description: Get details about and visual representation of a rollout.
usage: kubectl-kruise describe rollout SUBCOMMAND
options:
- name: all
default_value: "false"
usage: Show all pods in the rollout
- name: help
shorthand: h
default_value: "false"
usage: help for rollout
- name: no-color
default_value: "false"
usage: If true, print output without color
- name: timeout
default_value: "0"
usage: Timeout after specified seconds
- name: watch
shorthand: w
default_value: "false"
usage: Watch for changes to the rollout
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Describe the rollout named rollout-demo within namespace default\n kubectl-kruise describe rollout rollout-demo/default\n \n # Watch for changes to the rollout named rollout-demo\n kubectl-kruise describe rollout rollout-demo/default -w"
see_also:
- kubectl-kruise describe - Show details of a specific resource or group of resources

View File

@ -0,0 +1,173 @@
name: kubectl-kruise expose
synopsis: |
Take a workload(e.g. deployment, cloneset), service or pod and expose it as a new Kubernetes Service
description: |-
Expose a resource as a new Kubernetes service.
Looks up a deployment, service, replica set, replication controller or pod by name and uses the selector for that resource as the selector for a new service on the specified port. A deployment or replica set will be exposed as a service only if its selector is convertible to a selector that service supports, i.e. when the selector contains only the matchLabels component. Note that if no port is specified via --port and the exposed resource has multiple ports, all will be re-used by the new service. Also if no labels are specified, the new service will re-use the labels from the resource it exposes.
Possible resources include (case insensitive):
pod (po), service (svc), replicationcontroller (rc), cloneset (clone), deployment (deploy), replicaset (rs)
usage: kubectl-kruise expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type]
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: cluster-ip
usage: |
ClusterIP to be assigned to the service. Leave empty to auto-allocate, or set to 'None' to create a headless service.
- name: container-port
usage: Synonym for --target-port
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: external-ip
usage: |
Additional external IP address (not managed by Kubernetes) to accept for the service. If this IP is routed to a node, the service can be accessed by this IP in addition to its generated service IP.
- name: field-manager
default_value: kubectl-expose
usage: Name of the manager used to track field ownership.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to expose a service
- name: generator
default_value: service/v2
usage: |
The name of the API generator to use. There are 2 generators: 'service/v1' and 'service/v2'. The only difference between them is that service port in v1 is named 'default', while it is left unnamed in v2. Default is 'service/v2'.
- name: help
shorthand: h
default_value: "false"
usage: help for expose
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: labels
shorthand: l
usage: Labels to apply to the service created by this call.
- name: load-balancer-ip
usage: |
IP to assign to the LoadBalancer. If empty, an ephemeral IP will be created and used (cloud-provider specific).
- name: name
usage: The name for the newly created object.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: overrides
usage: |
An inline JSON override for the generated object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field.
- name: port
usage: |
The port that the service should serve on. Copied from the resource being exposed, if unspecified
- name: protocol
usage: |
The network protocol for the service to be created. Default is 'TCP'.
- name: record
default_value: "false"
usage: |
Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: save-config
default_value: "false"
usage: |
If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
- name: selector
usage: |
A label selector to use for this service. Only equality-based selector requirements are supported. If empty (the default) infer the selector from the replication controller or replica set.)
- name: session-affinity
usage: |
If non-empty, set the session affinity for the service to this; legal values: 'None', 'ClientIP'
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: target-port
usage: |
Name or number for the port on the container that the service should direct traffic to. Optional.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
- name: type
usage: |
Type for this service: ClusterIP, NodePort, LoadBalancer, or ExternalName. Default is 'ClusterIP'.
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Create a service for an nginx cloneset, which serves on port 80 and connects to the containers on port 8000.\n kubectl kruise expose cloneset nginx --port=80 --target-port=8000\n \n # Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000.\n kubectl expose rc nginx --port=80 --target-port=8000\n \n # Create a service for a replication controller identified by type and name specified in \"nginx-controller.yaml\", which serves on port 80 and connects to the containers on port 8000.\n kubectl expose -f nginx-controller.yaml --port=80 --target-port=8000\n \n # Create a service for a pod valid-pod, which serves on port 444 with the name \"frontend\"\n kubectl expose pod valid-pod --port=444 --name=frontend\n \n # Create a second service based on the above service, exposing the container port 8443 as port 443 with the name \"nginx-https\"\n kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https\n \n # Create a service for a replicated streaming application on port 4100 balancing UDP traffic and named 'video-stream'.\n kubectl expose rc streamer --port=4100 --protocol=UDP --name=video-stream\n \n # Create a service for a replicated nginx using replica set, which serves on port 80 and connects to the containers on port 8000.\n kubectl expose rs nginx --port=80 --target-port=8000\n \n # Create a service for an nginx deployment, which serves on port 80 and connects to the containers on port 8000.\n kubectl expose deployment nginx --port=80 --target-port=8000"
see_also:
- kubectl-kruise - kubectl-kruise controls the OpenKruise CRs

View File

@ -0,0 +1,110 @@
name: kubectl-kruise migrate
synopsis: Migrate from K8s original workloads to Kruise workloads
description: Migrate from K8s original workloads to Kruise workloads
usage: kubectl-kruise migrate [DST_KIND] --from [SRC_KIND] [flags]
options:
- name: copy
default_value: "false"
usage: Copy replicas from src workload when create.
- name: create
default_value: "false"
usage: Create dst workload with replicas=0 from src workload.
- name: dst-name
usage: Name of the destination workload.
- name: from
usage: Type of the source workload (e.g. Deployment).
- name: help
shorthand: h
default_value: "false"
usage: help for migrate
- name: max-surge
default_value: "1"
usage: Max surge during migration.
- name: replicas
default_value: "-1"
usage: |
The replicas needs to migrate, -1 indicates all replicas in src workload.
- name: src-name
usage: Name of the source workload.
- name: timeout-seconds
default_value: "-1"
usage: Timeout seconds for migration, -1 indicates no limited.
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: |4
# Create an empty CloneSet from an existing Deployment.
kubectl-kruise migrate CloneSet --from Deployment -n default --dst-name deployment-name --create
# Create a same replicas CloneSet from an existing Deployment.
kubectl-kruise migrate CloneSet --from Deployment -n default --dst-name deployment-name --create --copy
# Migrate replicas from an existing Deployment to an existing CloneSet.
kubectl-kruise migrate CloneSet --from Deployment -n default --src-name cloneset-name --dst-name deployment-name --replicas 10 --max-surge=2
see_also:
- kubectl-kruise - kubectl-kruise controls the OpenKruise CRs

View File

@ -0,0 +1,87 @@
name: kubectl-kruise rollout
synopsis: Manage the rollout of a resource
description: "Manage the rollout of a resource.\n \n Valid resource types include:\n\n * deployments\n * daemonsets\n * statefulsets\n * clonesets\n * statefulsets.apps.kruise.io\n * daemonsets.apps.kruise.io\n * rollouts.rollouts.kruise.io"
usage: kubectl-kruise rollout SUBCOMMAND
options:
- name: help
shorthand: h
default_value: "false"
usage: help for rollout
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Rollback to the previous cloneset\n kubectl-kruise rollout undo cloneset/abc\n \n # Check the rollout status of a daemonset\n kubectl-kruise rollout status daemonset/foo"
see_also:
- kubectl-kruise - kubectl-kruise controls the OpenKruise CRs
- kubectl-kruise rollout approve - Approve a resource
- kubectl-kruise rollout history - View rollout history
- kubectl-kruise rollout pause - Mark the provided resource as paused
- kubectl-kruise rollout restart - Restart a resource
- kubectl-kruise rollout resume - Resume a paused resource
- kubectl-kruise rollout status - Show the status of the rollout
- kubectl-kruise rollout undo - Undo a previous rollout

View File

@ -0,0 +1,112 @@
name: kubectl-kruise rollout approve
synopsis: Approve a resource
description: |-
Approve a resource which can be continued.
Paused resources will not be reconciled by a controller. By approving a resource, we allow it to be continue to rollout. Currently only kruise-rollouts support being approved.
usage: kubectl-kruise rollout approve RESOURCE
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for approve
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # approve a kruise rollout resource named \"rollout-demo\" in \"ns-demo\" namespace\n \n kubectl-kruise rollout approve rollout/rollout-demo -n ns-demo"
see_also:
- kubectl-kruise rollout - Manage the rollout of a resource

View File

@ -0,0 +1,113 @@
name: kubectl-kruise rollout history
synopsis: View rollout history
description: View previous rollout revisions and configurations.
usage: kubectl-kruise rollout history (TYPE NAME | TYPE/NAME) [flags]
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for history
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: revision
default_value: "0"
usage: |
See the details, including podTemplate of the revision specified
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # View the rollout history of a cloneset\n kubectl-kruise rollout history cloneset/abc\n \n # View the rollout history of a advanced statefulset\n kubectl-kruise rollout history asts/abc\n \n # View the details of daemonset revision 3\n kubectl-kruise rollout history daemonset/abc --revision=3"
see_also:
- kubectl-kruise rollout - Manage the rollout of a resource

View File

@ -0,0 +1,112 @@
name: kubectl-kruise rollout pause
synopsis: Mark the provided resource as paused
description: |-
Mark the provided resource as paused
Paused resources will not be reconciled by a controller. Use "kubectl rollout resume" to resume a paused resource. Currently deployments, clonesets, rollouts support being paused.
usage: kubectl-kruise rollout pause RESOURCE
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for pause
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Mark the nginx deployment as paused. Any current state of\n # the deployment will continue its function, new updates to the deployment will not\n # have an effect as long as the deployment is paused.\n \n kubectl-kruise rollout pause deployment/nginx"
see_also:
- kubectl-kruise rollout - Manage the rollout of a resource

View File

@ -0,0 +1,112 @@
name: kubectl-kruise rollout restart
synopsis: Restart a resource
description: |-
Restart a resource.
Resource will be rollout restarted.
usage: kubectl-kruise rollout restart RESOURCE
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for restart
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Restart a deployment\n kubectl-kruise rollout restart deployment/nginx\n kubectl-kruise rollout restart cloneset/abc\n \n # Restart a daemonset\n kubectl-kruise rollout restart daemonset/abc"
see_also:
- kubectl-kruise rollout - Manage the rollout of a resource

View File

@ -0,0 +1,112 @@
name: kubectl-kruise rollout resume
synopsis: Resume a paused resource
description: |-
Resume a paused resource
Paused resources will not be reconciled by a controller. By resuming a resource, we allow it to be reconciled again. Currently deployments, cloneset support being resumed.
usage: kubectl-kruise rollout resume RESOURCE
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for resume
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Resume an already paused rollout/cloneset/deployment resource\n \n kubectl-kruise rollout resume rollout/nginx\n kubectl-kruise rollout resume cloneset/nginx\n kubectl-kruise rollout resume deployment/nginx"
see_also:
- kubectl-kruise rollout - Manage the rollout of a resource

View File

@ -0,0 +1,113 @@
name: kubectl-kruise rollout status
synopsis: Show the status of the rollout
description: |-
Show the status of the rollout.
By default 'rollout status' will watch the status of the latest rollout until it's done. If you don't want to wait for the rollout to finish then you can use --watch=false. Note that if a new rollout starts in-between, then 'rollout status' will continue watching the latest revision. If you want to pin to a specific revision and abort if it is rolled over by another revision, use --revision=N where N is the revision you need to watch for.
usage: kubectl-kruise rollout status (TYPE NAME | TYPE/NAME) [flags]
options:
- name: detail
shorthand: d
default_value: "false"
usage: Show the detail status of the rollout.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for status
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: revision
default_value: "0"
usage: |
Pin to a specific revision for showing its status. Defaults to 0 (last revision).
- name: timeout
default_value: 0s
usage: |
The length of time to wait before ending watch, zero means never. Any other values should contain a corresponding time unit (e.g. 1s, 2m, 3h).
- name: watch
shorthand: w
default_value: "true"
usage: Watch the status of the rollout until it's done.
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Watch the rollout status of a deployment\n kubectl-kruise rollout status deployment/nginx\n \n # Watch the rollout status of a cloneset\n kubectl-kruise rollout status cloneset/nginx\n \n # Watch the rollout status of a advanced statefulset\n kubectl-kruise rollout status asts/nginx"
see_also:
- kubectl-kruise rollout - Manage the rollout of a resource

View File

@ -0,0 +1,119 @@
name: kubectl-kruise rollout undo
synopsis: Undo a previous rollout
description: Rollback to a previous rollout.
usage: kubectl-kruise rollout undo (TYPE NAME | TYPE/NAME) [flags]
options:
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: fast
default_value: "false"
usage: fast rollback for blue-green release
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for undo
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
- name: to-revision
default_value: "0"
usage: The revision to rollback to. Default to 0 (last revision).
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Rollback to the previous cloneset\n kubectl-kruise rollout undo cloneset/abc\n \n # Rollback to the previous Advanced StatefulSet\n kubectl-kruise rollout undo asts/abc\n \n # Rollback to daemonset revision 3\n kubectl-kruise rollout undo daemonset/abc --to-revision=3\n \n # Rollback to the previous deployment with dry-run\n kubectl-kruise rollout undo --dry-run=server deployment/abc\n \n # Rollback to workload via rollout api object\n kubectl-kruise rollout undo rollout/abc\n \n # Fast rollback during blue-green release (will go back to a previous step with no traffic and most replicas)\n kubectl-kruise rollout undo rollout/abc --fast"
see_also:
- kubectl-kruise rollout - Manage the rollout of a resource

View File

@ -0,0 +1,84 @@
name: kubectl-kruise scaledown
synopsis: Scaledown a cloneset with selective Pods
description: Scaledown a cloneset with selective Pods
usage: kubectl-kruise scaledown [CLONESET] --pods [POD1,POD2] -n [NAMESPACE]
options:
- name: help
shorthand: h
default_value: "false"
usage: help for scaledown
- name: pods
usage: Name of the pods to delete
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: |4
# Scale down 2 with selective pods
kubectl-kruise scaledown CloneSet cloneset-demo --pods pod-1, pod-2 -n default
see_also:
- kubectl-kruise - kubectl-kruise controls the OpenKruise CRs

View File

@ -0,0 +1,88 @@
name: kubectl-kruise set
synopsis: Set specific features on objects
description: |-
Configure application resources
These commands help you make changes to existing application resources.
usage: kubectl-kruise set SUBCOMMAND
options:
- name: help
shorthand: h
default_value: "false"
usage: help for set
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
see_also:
- kubectl-kruise - kubectl-kruise controls the OpenKruise CRs
- kubectl-kruise set env - Update environment variables on a pod template
- kubectl-kruise set image - Update image of a pod template
- kubectl-kruise set resources - Update resource requests/limits on objects with pod templates
- kubectl-kruise set selector - Set the selector on a resource
- kubectl-kruise set serviceaccount - Update ServiceAccount of a resource
- kubectl-kruise set subject - Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding

View File

@ -0,0 +1,164 @@
name: kubectl-kruise set env
synopsis: Update environment variables on a pod template
description: |-
Update environment variables on a pod template.
List environment variable definitions in one or more pods, pod templates. Add, update, or remove container environment variable definitions in one or more pod templates (within replication controllers or deployment configurations). View or modify the environment variable definitions on all containers in the specified pods or pod templates, or just those that match a wildcard.
If "--env -" is passed, environment variables can be read from STDIN using the standard env syntax.
Possible resources include (case insensitive):
pod (po), deployment (deploy), statefulset (sts), daemonset (ds), replicaset (rs), cloneset (clone), statefulset.apps.kruise.io (asts), daemonset.apps.kruise.io (ads)
usage: kubectl-kruise set env RESOURCE/NAME KEY_1=VAL_1 ... KEY_N=VAL_N
options:
- name: all
default_value: "false"
usage: |
If true, select all resources in the namespace of the specified resource types
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: containers
shorthand: c
default_value: '*'
usage: |
The names of containers in the selected pod templates to change - may use wildcards
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: env
shorthand: e
default_value: '[]'
usage: |
Specify a key-value pair for an environment variable to set into each container.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files the resource to update the env
- name: from
usage: |
The name of a resource from which to inject environment variables
- name: help
shorthand: h
default_value: "false"
usage: help for env
- name: keys
default_value: '[]'
usage: |
Comma-separated list of keys to import from specified resource
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: list
default_value: "false"
usage: |
If true, display the environment and any changes in the standard format. this flag will removed when we have kubectl view env.
- name: local
default_value: "false"
usage: |
If true, set env will NOT contact api-server but run locally.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: overwrite
default_value: "true"
usage: |
If true, allow environment to be overwritten, otherwise reject updates that overwrite existing environment.
- name: prefix
usage: Prefix to append to variable names
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: resolve
default_value: "false"
usage: |
If true, show secret or configmap references when listing variables
- name: selector
shorthand: l
usage: Selector (label query) to filter on
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Update cloneset 'sample' with a new environment variable\n kubectl-kruise set env cloneset/sample STORAGE_DIR=/local\n \n # List the environment variables defined on a cloneset 'sample'\n kubectl-kruise set env cloneset/sample --list\n \n # List the environment variables defined on all pods\n kubectl-kruise set env pods --all --list\n \n # Output modified cloneset in YAML, and does not alter the object on the server\n kubectl-kruise set env cloneset/sample STORAGE_DIR=/data -o yaml\n \n # Update all containers in all replication controllers in the project to have ENV=prod\n kubectl-kruise set env rc --all ENV=prod\n \n # Import environment from a secret\n kubectl-kruise set env --from=secret/mysecret cloneset/sample\n \n # Import environment from a config map with a prefix\n kubectl-kruise set env --from=configmap/myconfigmap --prefix=MYSQL_ cloneset/sample\n \n # Import specific keys from a config map\n kubectl-kruise set env --keys=my-example-key --from=configmap/myconfigmap cloneset/sample\n \n # Remove the environment variable ENV from container 'c1' in all deployment configs\n kubectl-kruise set env clonesets --all --containers=\"c1\" ENV-\n \n # Remove the environment variable ENV from a deployment definition on disk and\n # update the deployment config on the server\n kubectl-kruise set env -f deploy.json ENV-\n \n # Set some of the local shell environment into a deployment config on the server\n env | grep RAILS_ | kubectl-kruise set env -e - cloneset/sample"
see_also:
- kubectl-kruise set - Set specific features on objects

View File

@ -0,0 +1,134 @@
name: kubectl-kruise set image
synopsis: Update image of a pod template
description: |-
Update existing container image(s) of resources.
Possible resources include (case insensitive):
pod (po), deployment (deploy), statefulset (sts), daemonset (ds), replicaset (rs), cloneset (clone), statefulset.apps.kruise.io (asts), daemonset.apps.kruise.io (ads)
usage: kubectl-kruise set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N
options:
- name: all
default_value: "false"
usage: |
Select all resources, including uninitialized ones, in the namespace of the specified resource types
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for image
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: local
default_value: "false"
usage: |
If true, set image will NOT contact api-server but run locally.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: record
default_value: "false"
usage: |
Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: selector
shorthand: l
usage: |
Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'.\n kubectl-kruise set image cloneset/sample busybox=busybox nginx=nginx:1.9.1\n \n # Update all deployments' and rc's nginx container's image to 'nginx:1.9.1'\n kubectl-kruise set image cloneset,rc nginx=nginx:1.9.1 --all\n \n # Update image of all containers of cloneset sample to 'nginx:1.9.1'\n kubectl-kruise set image cloneset sample *=nginx:1.9.1\n \n # Print result (in yaml format) of updating nginx container image from local file, without hitting the server\n kubectl-kruise set image -f path/to/file.yaml nginx=nginx:1.9.1 --local -o yaml"
see_also:
- kubectl-kruise set - Set specific features on objects

View File

@ -0,0 +1,148 @@
name: kubectl-kruise set resources
synopsis: |
Update resource requests/limits on objects with pod templates
description: |-
Specify compute resource requirements (cpu, memory) for any resource that defines a pod template. If a pod is successfully scheduled, it is guaranteed the amount of resource requested, but may burst up to its specified limits.
for each compute resource, if a limit is specified and a request is omitted, the request will default to the limit.
Possible resources include (case insensitive):
pod (po), deployment (deploy), statefulset (sts), daemonset (ds), replicaset (rs), cloneset (clone), statefulset.apps.kruise.io (asts), daemonset.apps.kruise.io (ads)
usage: kubectl-kruise set resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]
options:
- name: all
default_value: "false"
usage: |
Select all resources, including uninitialized ones, in the namespace of the specified resource types
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: containers
shorthand: c
default_value: '*'
usage: |
The names of containers in the selected pod templates to change, all containers are selected by default - may use wildcards
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for resources
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: limits
usage: |
The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.
- name: local
default_value: "false"
usage: |
If true, set resources will NOT contact api-server but run locally.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: record
default_value: "false"
usage: |
Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: requests
usage: |
The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.
- name: selector
shorthand: l
usage: |
Selector (label query) to filter on, not including uninitialized ones,supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Set a deployments nginx container cpu limits to \"200m\" and memory to \"512Mi\"\n kubectl-kruise set resources cloneset sample -c=nginx --limits=cpu=200m,memory=512Mi\n \n # Set the resource request and limits for all containers in nginx\n kubectl-kruise set resources cloneset sample --limits=cpu=200m,memory=512Mi --requests=cpu=100m,memory=256Mi\n \n # Remove the resource requests for resources on containers in nginx\n kubectl-kruise set resources cloneset sample --limits=cpu=0,memory=0 --requests=cpu=0,memory=0\n \n # Print the result (in yaml format) of updating nginx container limits from a local, without hitting the server\n kubectl-kruise set resources -f path/to/file.yaml --limits=cpu=200m,memory=512Mi --local -o yaml"
see_also:
- kubectl-kruise set - Set specific features on objects

View File

@ -0,0 +1,129 @@
name: kubectl-kruise set selector
synopsis: Set the selector on a resource
description: |-
Set the selector on a resource. Note that the new selector will overwrite the old selector if the resource had one prior to the invocation of 'set selector'.
A selector must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to 63 characters. If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used. Note: currently selectors can only be set on Service objects.
usage: kubectl-kruise set selector (-f FILENAME | TYPE NAME) EXPRESSIONS [--resource-version=version]
options:
- name: all
default_value: "false"
usage: |
Select all resources in the namespace of the specified resource types
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: filename
shorthand: f
default_value: '[]'
usage: identifying the resource.
- name: help
shorthand: h
default_value: "false"
usage: help for selector
- name: local
default_value: "false"
usage: |
If true, annotation will NOT contact api-server but run locally.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: record
default_value: "false"
usage: |
Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.
- name: recursive
shorthand: R
default_value: "true"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: resource-version
usage: |
If non-empty, the selectors update will only succeed if this is the current resource-version for the object. Only valid when specifying a single resource.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: |4-
# set the labels and selector before creating a deployment/service pair.
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run=client | kubectl-kruise set selector --local -f - 'environment=qa' -o yaml | kubectl create -f -
kubectl create cloneset sample -o yaml --dry-run=client | kubectl label --local -f - environment=qa -o yaml | kubectl create -f -
see_also:
- kubectl-kruise set - Set specific features on objects

View File

@ -0,0 +1,130 @@
name: kubectl-kruise set serviceaccount
synopsis: Update ServiceAccount of a resource
description: |-
Update ServiceAccount of pod template resources.
Possible resources (case insensitive) can be:
replicationcontroller (rc), deployment (deploy), daemonset (ds), job, replicaset (rs), statefulset, cloneset (cs)
usage: kubectl-kruise set serviceaccount (-f FILENAME | TYPE NAME) SERVICE_ACCOUNT
options:
- name: all
default_value: "false"
usage: |
Select all resources, including uninitialized ones, in the namespace of the specified resource types
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files identifying the resource to get from a server.
- name: help
shorthand: h
default_value: "false"
usage: help for serviceaccount
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: local
default_value: "false"
usage: |
If true, set serviceaccount will NOT contact api-server but run locally.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: record
default_value: "false"
usage: |
Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: user
usage: The name of the kubeconfig user to use
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Set Deployment nginx-deployment's ServiceAccount to serviceaccount1\n kubectl-kruise set serviceaccount cloneset sample serviceaccount1\n \n # Print the result (in yaml format) of updated cloneset with serviceaccount from local file, without hitting apiserver\n kubectl-kruise set sa -f CloneSet.yaml serviceaccount1 --local --dry-run=client -o yaml"
see_also:
- kubectl-kruise set - Set specific features on objects

View File

@ -0,0 +1,134 @@
name: kubectl-kruise set subject
synopsis: |
Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding
description: |
Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding.
usage: kubectl-kruise set subject (-f FILENAME | TYPE NAME) [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run=server|client|none]
options:
- name: all
default_value: "false"
usage: |
Select all resources, including uninitialized ones, in the namespace of the specified resource types
- name: allow-missing-template-keys
default_value: "true"
usage: |
If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.
- name: dry-run
default_value: none
usage: |
Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.
- name: filename
shorthand: f
default_value: '[]'
usage: |
Filename, directory, or URL to files the resource to update the subjects
- name: group
default_value: '[]'
usage: Groups to bind to the role
- name: help
shorthand: h
default_value: "false"
usage: help for subject
- name: kustomize
shorthand: k
usage: |
Process the kustomization directory. This flag can't be used together with -f or -R.
- name: local
default_value: "false"
usage: |
If true, set subject will NOT contact api-server but run locally.
- name: output
shorthand: o
usage: |
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
- name: recursive
shorthand: R
default_value: "false"
usage: |
Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.
- name: selector
shorthand: l
usage: |
Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
- name: serviceaccount
default_value: '[]'
usage: Service accounts to bind to the role
- name: show-managed-fields
default_value: "false"
usage: |
If true, keep the managedFields when printing objects in JSON or YAML format.
- name: template
usage: |
Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
- name: user
default_value: '[]'
usage: Usernames to bind to the role
inherited_options:
- name: as
usage: |
Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
- name: as-group
default_value: '[]'
usage: |
Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
- name: as-uid
usage: UID to impersonate for the operation.
- name: cache-dir
default_value: $HOME/.kube/cache
usage: Default cache directory
- name: certificate-authority
usage: Path to a cert file for the certificate authority
- name: client-certificate
usage: Path to a client certificate file for TLS
- name: client-key
usage: Path to a client key file for TLS
- name: cluster
usage: The name of the kubeconfig cluster to use
- name: context
usage: The name of the kubeconfig context to use
- name: disable-compression
default_value: "false"
usage: |
If true, opt-out of response compression for all requests to the server
- name: insecure-skip-tls-verify
default_value: "false"
usage: |
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
- name: kubeconfig
usage: Path to the kubeconfig file to use for CLI requests.
- name: match-server-version
default_value: "false"
usage: Require server version to match client version
- name: namespace
shorthand: "n"
usage: If present, the namespace scope for this CLI request
- name: password
usage: Password for basic authentication to the API server
- name: profile
default_value: none
usage: |
Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex)
- name: profile-output
default_value: profile.pprof
usage: Name of the file to write the profile to
- name: request-timeout
default_value: "0"
usage: |
The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
- name: server
shorthand: s
usage: The address and port of the Kubernetes API server
- name: tls-server-name
usage: |
Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
- name: token
usage: Bearer token for authentication to the API server
- name: username
usage: Username for basic authentication to the API server
- name: warnings-as-errors
default_value: "false"
usage: |
Treat warnings received from the server as errors and exit with a non-zero exit code
example: " # Update a ClusterRoleBinding for serviceaccount1\n kubectl-kruise set subject clusterrolebinding admin --serviceaccount=namespace:serviceaccount1\n \n # Update a RoleBinding for user1, user2, and group1\n kubectl-kruise set subject rolebinding admin --user=user1 --user=user2 --group=group1\n \n # Print the result (in yaml format) of updating rolebinding subjects from a local, without hitting the server\n kubectl create rolebinding admin --role=admin --user=admin -o yaml --dry-run=client | kubectl-kruise set subject --local -f - --user=foo -o yaml"
see_also:
- kubectl-kruise set - Set specific features on objects

BIN
go.list Normal file

Binary file not shown.

118
go.mod
View File

@ -1,33 +1,103 @@
module github.com/openkruise/kruise-tools
go 1.16
go 1.23.0
toolchain go1.23.4
require (
github.com/go-logr/logr v0.2.1 // indirect
github.com/go-errors/errors v1.4.2
github.com/lithammer/dedent v1.1.0
github.com/openkruise/kruise-api v0.10.0
github.com/spf13/cobra v1.1.3
github.com/moby/term v0.0.0-20221205130635-1aeaba878587
github.com/openkruise/kruise-api v1.8.0
github.com/openkruise/kruise-rollout-api v0.6.0
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1
k8s.io/api v0.21.6
k8s.io/apimachinery v0.21.6
k8s.io/cli-runtime v0.21.6
k8s.io/client-go v0.21.6
k8s.io/component-base v0.21.6
k8s.io/klog/v2 v2.4.0
k8s.io/kubectl v0.21.6
sigs.k8s.io/controller-runtime v0.6.3
github.com/stretchr/testify v1.9.0
k8s.io/api v0.30.11
k8s.io/apimachinery v0.30.11
k8s.io/cli-runtime v0.30.11
k8s.io/client-go v0.30.11
k8s.io/component-base v0.30.11
k8s.io/klog/v2 v2.120.1
k8s.io/kubectl v0.30.11
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
sigs.k8s.io/controller-runtime v0.18.6
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3
)
// Replace to match K8s 1.20.12
replace (
k8s.io/api => k8s.io/api v0.20.12
k8s.io/apimachinery => k8s.io/apimachinery v0.20.12
k8s.io/cli-runtime => k8s.io/cli-runtime v0.20.12
k8s.io/client-go => k8s.io/client-go v0.20.12
k8s.io/code-generator => k8s.io/code-generator v0.20.12
k8s.io/component-base => k8s.io/component-base v0.20.12
k8s.io/component-helpers => k8s.io/component-helpers v0.20.12
k8s.io/kubectl => k8s.io/kubectl v0.20.12
k8s.io/metrics => k8s.io/metrics v0.20.12
require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // 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/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // 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.12 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // 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/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.17.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/term v0.30.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
sigs.k8s.io/gateway-api v0.7.1 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/kustomize/v5 v5.0.4-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
replace (
golang.org/x/net => golang.org/x/net v0.33.0
golang.org/x/sync => golang.org/x/sync v0.10.0
golang.org/x/sys => golang.org/x/sys v0.19.0
golang.org/x/term => golang.org/x/term v0.19.0
golang.org/x/text => golang.org/x/text v0.21.0
)

932
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,9 @@ package api
import (
kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
kruiseappsv1beta1 "github.com/openkruise/kruise-api/apps/v1beta1"
kruisepolicyv1alpha1 "github.com/openkruise/kruise-api/policy/v1alpha1"
kruiserolloutsv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1"
kruiserolloutsv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
apps "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -38,6 +41,9 @@ func init() {
_ = clientgoscheme.AddToScheme(Scheme)
_ = kruiseappsv1alpha1.AddToScheme(Scheme)
_ = kruiseappsv1beta1.AddToScheme(Scheme)
_ = kruiserolloutsv1alpha1.AddToScheme(Scheme)
_ = kruiserolloutsv1beta1.AddToScheme(Scheme)
_ = kruisepolicyv1alpha1.AddToScheme(Scheme)
}
func GetScheme() *runtime.Scheme {

View File

@ -0,0 +1,49 @@
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
func NewAutoCompleteCommand() *cobra.Command {
var completionCmd = &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate completion script",
Long: `To load completions:
Bash:
$ source <(kubectl-kruise completion bash)
Zsh:
# If shell completion is not already enabled in your environment,
# you will need to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
$ kubectl-kruise completion zsh > "${fpath[1]}/_kubectl-kruise"
Fish:
$ kubectl-kruise completion fish | source
PowerShell:
PS> kubectl-kruise completion powershell | Out-String | Invoke-Expression
`,
RunE: func(cmd *cobra.Command, args []string) error {
switch args[0] {
case "bash":
return cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
return cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
return cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
return cmd.Root().GenPowerShellCompletion(os.Stdout)
default:
return fmt.Errorf("unsupported shell type %q", args[0])
}
},
}
return completionCmd
}

View File

@ -21,13 +21,20 @@ import (
"io"
"os"
"github.com/spf13/cobra"
"github.com/openkruise/kruise-tools/pkg/cmd/create"
"github.com/openkruise/kruise-tools/pkg/cmd/describe"
cmdexec "github.com/openkruise/kruise-tools/pkg/cmd/exec"
"github.com/openkruise/kruise-tools/pkg/cmd/expose"
"github.com/openkruise/kruise-tools/pkg/cmd/get"
"github.com/openkruise/kruise-tools/pkg/cmd/migrate"
krollout "github.com/openkruise/kruise-tools/pkg/cmd/rollout"
"github.com/openkruise/kruise-tools/pkg/cmd/scaledown"
kset "github.com/openkruise/kruise-tools/pkg/cmd/set"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/client-go/tools/clientcmd"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/kubectl/pkg/cmd/apiresources"
@ -366,10 +373,17 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
{
Message: "Basic Commands:",
Commands: []*cobra.Command{
create.NewCmdCreate(f, ioStreams),
expose.NewCmdExposeService(f, ioStreams),
cmdWithShortOverwrite(scale.NewCmdScale(f, ioStreams), "Set a new size for a Deployment, ReplicaSet, CloneSet, or Advanced StatefulSet"),
},
},
{
Message: "Troubleshooting and Debugging Commands:",
Commands: []*cobra.Command{
cmdexec.NewCmdExec(f, ioStreams),
},
},
{
Message: "CloneSet Commands:",
@ -429,8 +443,12 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
}
cmds.AddCommand(alpha)
cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams))
cmds.AddCommand(plugin.NewCmdPlugin(f, ioStreams))
cmds.AddCommand(NewCmdGenerateDocs(f, ioStreams))
cmds.AddCommand(NewAutoCompleteCommand())
cmds.AddCommand(get.NewCmdGet(f, ioStreams))
cmds.AddCommand(describe.NewCmdDescibe(f, ioStreams))
cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), ioStreams))
cmds.AddCommand(plugin.NewCmdPlugin(ioStreams))
cmds.AddCommand(version.NewCmdVersion(f, ioStreams))
cmds.AddCommand(apiresources.NewCmdAPIVersions(f, ioStreams))
cmds.AddCommand(apiresources.NewCmdAPIResources(f, ioStreams))

448
pkg/cmd/create/create.go Normal file
View File

@ -0,0 +1,448 @@
/*
Copyright 2022 The Kruise Authors.
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package create
import (
"context"
"fmt"
"io"
"net/url"
"runtime"
"strings"
"github.com/spf13/cobra"
"k8s.io/klog/v2"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
kruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/dynamic"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/cmd/util/editor"
"k8s.io/kubectl/pkg/generate"
"k8s.io/kubectl/pkg/rawhttp"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)
// CreateOptions is the commandline options for 'create' sub command
type CreateOptions struct {
PrintFlags *genericclioptions.PrintFlags
RecordFlags *genericclioptions.RecordFlags
DryRunStrategy cmdutil.DryRunStrategy
ValidationDirective string
fieldManager string
FilenameOptions resource.FilenameOptions
Selector string
EditBeforeCreate bool
Raw string
Recorder genericclioptions.Recorder
PrintObj func(obj kruntime.Object) error
genericclioptions.IOStreams
}
var (
createLong = templates.LongDesc(i18n.T(`
Create a resource from a file or from stdin.
JSON and YAML formats are accepted.`))
createExample = templates.Examples(i18n.T(`
# Create a pod using the data in pod.json.
kubectl create -f ./pod.json
# Create a pod based on the JSON passed into stdin.
cat pod.json | kubectl create -f -
# Edit the data in docker-registry.yaml in JSON then create the resource using the edited data.
kubectl create -f docker-registry.yaml --edit -o json`))
)
// NewCreateOptions returns an initialized CreateOptions instance
func NewCreateOptions(ioStreams genericclioptions.IOStreams) *CreateOptions {
return &CreateOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
RecordFlags: genericclioptions.NewRecordFlags(),
Recorder: genericclioptions.NoopRecorder{},
IOStreams: ioStreams,
}
}
// NewCmdCreate returns new initialized instance of create sub command
func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewCreateOptions(ioStreams)
cmd := &cobra.Command{
Use: "create -f FILENAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a resource from a file or from stdin."),
Long: createLong,
Example: createExample,
Run: func(cmd *cobra.Command, args []string) {
if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) {
ioStreams.ErrOut.Write([]byte("Error: must specify one of -f and -k\n\n"))
defaultRunFunc := cmdutil.DefaultSubCommandRun(ioStreams.ErrOut)
defaultRunFunc(cmd, args)
return
}
cmdutil.CheckErr(o.Complete(f, cmd))
cmdutil.CheckErr(o.ValidateArgs(cmd, args))
cmdutil.CheckErr(o.RunCreate(f, cmd))
},
}
// bind flag structs
o.RecordFlags.AddFlags(cmd)
usage := "to use to create the resource"
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
cmdutil.AddValidateFlags(cmd)
cmd.Flags().BoolVar(&o.EditBeforeCreate, "edit", o.EditBeforeCreate, "Edit the API resource before creating")
cmd.Flags().Bool("windows-line-endings", runtime.GOOS == "windows",
"Only relevant if --edit=true. Defaults to the line ending native to your platform.")
cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddDryRunFlag(cmd)
cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().StringVar(&o.Raw, "raw", o.Raw, "Raw URI to POST to the server. Uses the transport specified by the kubeconfig file.")
cmdutil.AddFieldManagerFlagVar(cmd, &o.fieldManager, "kubectl-create")
o.PrintFlags.AddFlags(cmd)
// create subcommands
cmd.AddCommand(NewCmdCreateJob(f, ioStreams))
cmd.AddCommand(NewCmdCreateBroadcastJob(f, ioStreams))
cmd.AddCommand(NewCmdCreateCRR(f, ioStreams))
return cmd
}
// ValidateArgs makes sure there is no discrepency in command options
func (o *CreateOptions) ValidateArgs(cmd *cobra.Command, args []string) error {
if len(args) != 0 {
return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args)
}
if len(o.Raw) > 0 {
if o.EditBeforeCreate {
return cmdutil.UsageErrorf(cmd, "--raw and --edit are mutually exclusive")
}
if len(o.FilenameOptions.Filenames) != 1 {
return cmdutil.UsageErrorf(cmd, "--raw can only use a single local file or stdin")
}
if strings.Index(o.FilenameOptions.Filenames[0], "http://") == 0 || strings.Index(o.FilenameOptions.Filenames[0], "https://") == 0 {
return cmdutil.UsageErrorf(cmd, "--raw cannot read from a url")
}
if o.FilenameOptions.Recursive {
return cmdutil.UsageErrorf(cmd, "--raw and --recursive are mutually exclusive")
}
if len(o.Selector) > 0 {
return cmdutil.UsageErrorf(cmd, "--raw and --selector (-l) are mutually exclusive")
}
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
return cmdutil.UsageErrorf(cmd, "--raw and --output are mutually exclusive")
}
if _, err := url.ParseRequestURI(o.Raw); err != nil {
return cmdutil.UsageErrorf(cmd, "--raw must be a valid URL path: %v", err)
}
}
return nil
}
// Complete completes all the required options
func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
var err error
o.RecordFlags.Complete(cmd)
o.Recorder, err = o.RecordFlags.ToRecorder()
if err != nil {
return err
}
o.DryRunStrategy, err = cmdutil.GetDryRunStrategy(cmd)
if err != nil {
return err
}
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
o.ValidationDirective, err = cmdutil.GetValidationDirective(cmd)
if err != nil {
return err
}
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return err
}
o.PrintObj = func(obj kruntime.Object) error {
return printer.PrintObj(obj, o.Out)
}
return nil
}
// RunCreate performs the creation
func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error {
// raw only makes sense for a single file resource multiple objects aren't likely to do what you want.
// the validator enforces this, so
if len(o.Raw) > 0 {
restClient, err := f.RESTClient()
if err != nil {
return err
}
return rawhttp.RawPost(restClient, o.IOStreams, o.Raw, o.FilenameOptions.Filenames[0])
}
if o.EditBeforeCreate {
return RunEditOnCreate(f, o.PrintFlags, o.RecordFlags, o.IOStreams, cmd, &o.FilenameOptions, o.fieldManager)
}
schema, err := f.Validator(o.ValidationDirective)
if err != nil {
return err
}
cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
r := f.NewBuilder().
Unstructured().
Schema(schema).
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
LabelSelectorParam(o.Selector).
Flatten().
Do()
err = r.Err()
if err != nil {
return err
}
count := 0
err = r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
if err := util.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info.Object, scheme.DefaultJSONEncoder()); err != nil {
return cmdutil.AddSourceToErr("creating", info.Source, err)
}
if err := o.Recorder.Record(info.Object); err != nil {
klog.V(4).Infof("error recording current command: %v", err)
}
if o.DryRunStrategy != cmdutil.DryRunClient {
obj, err := resource.
NewHelper(info.Client, info.Mapping).
DryRun(o.DryRunStrategy == cmdutil.DryRunServer).
WithFieldManager(o.fieldManager).
Create(info.Namespace, true, info.Object)
if err != nil {
return cmdutil.AddSourceToErr("creating", info.Source, err)
}
info.Refresh(obj, true)
}
count++
return o.PrintObj(info.Object)
})
if err != nil {
return err
}
if count == 0 {
return fmt.Errorf("no objects passed to create")
}
return nil
}
// RunEditOnCreate performs edit on creation
func RunEditOnCreate(f cmdutil.Factory, printFlags *genericclioptions.PrintFlags, recordFlags *genericclioptions.RecordFlags, ioStreams genericclioptions.IOStreams, cmd *cobra.Command, options *resource.FilenameOptions, fieldManager string) error {
editOptions := editor.NewEditOptions(editor.EditBeforeCreateMode, ioStreams)
editOptions.FilenameOptions = *options
validationDirective, err := cmdutil.GetValidationDirective(cmd)
if err != nil {
return err
}
editOptions.ValidateOptions = cmdutil.ValidateOptions{
ValidationDirective: validationDirective,
}
editOptions.PrintFlags = printFlags
editOptions.ApplyAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
editOptions.RecordFlags = recordFlags
editOptions.FieldManager = "kubectl-create"
err = editOptions.Complete(f, []string{}, cmd)
if err != nil {
return err
}
return editOptions.Run()
}
// NameFromCommandArgs is a utility function for commands that assume the first argument is a resource name
func NameFromCommandArgs(cmd *cobra.Command, args []string) (string, error) {
argsLen := cmd.ArgsLenAtDash()
// ArgsLenAtDash returns -1 when -- was not specified
if argsLen == -1 {
argsLen = len(args)
}
if argsLen != 1 {
return "", cmdutil.UsageErrorf(cmd, "exactly one NAME is required, got %d", argsLen)
}
return args[0], nil
}
// CreateSubcommandOptions is an options struct to support create subcommands
type CreateSubcommandOptions struct {
// PrintFlags holds options necessary for obtaining a printer
PrintFlags *genericclioptions.PrintFlags
// Name of resource being created
Name string
// StructuredGenerator is the resource generator for the object being created
StructuredGenerator generate.StructuredGenerator
DryRunStrategy cmdutil.DryRunStrategy
CreateAnnotation bool
FieldManager string
Namespace string
EnforceNamespace bool
Mapper meta.RESTMapper
DynamicClient dynamic.Interface
PrintObj printers.ResourcePrinterFunc
genericclioptions.IOStreams
}
// NewCreateSubcommandOptions returns initialized CreateSubcommandOptions
func NewCreateSubcommandOptions(ioStreams genericclioptions.IOStreams) *CreateSubcommandOptions {
return &CreateSubcommandOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
IOStreams: ioStreams,
}
}
// Complete completes all the required options
func (o *CreateSubcommandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string, generator generate.StructuredGenerator) error {
name, err := NameFromCommandArgs(cmd, args)
if err != nil {
return err
}
o.Name = name
o.StructuredGenerator = generator
o.DryRunStrategy, err = cmdutil.GetDryRunStrategy(cmd)
if err != nil {
return err
}
o.CreateAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return err
}
o.PrintObj = func(obj kruntime.Object, out io.Writer) error {
return printer.PrintObj(obj, out)
}
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
o.DynamicClient, err = f.DynamicClient()
if err != nil {
return err
}
o.Mapper, err = f.ToRESTMapper()
if err != nil {
return err
}
return nil
}
// Run executes a create subcommand using the specified options
func (o *CreateSubcommandOptions) Run() error {
obj, err := o.StructuredGenerator.StructuredGenerate()
if err != nil {
return err
}
if err := util.CreateOrUpdateAnnotation(o.CreateAnnotation, obj, scheme.DefaultJSONEncoder()); err != nil {
return err
}
if o.DryRunStrategy != cmdutil.DryRunClient {
// create subcommands have compiled knowledge of things they create, so type them directly
gvks, _, err := scheme.Scheme.ObjectKinds(obj)
if err != nil {
return err
}
gvk := gvks[0]
mapping, err := o.Mapper.RESTMapping(schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}, gvk.Version)
if err != nil {
return err
}
asUnstructured := &unstructured.Unstructured{}
if err := scheme.Scheme.Convert(obj, asUnstructured, nil); err != nil {
return err
}
if mapping.Scope.Name() == meta.RESTScopeNameRoot {
o.Namespace = ""
}
createOptions := metav1.CreateOptions{}
if o.FieldManager != "" {
createOptions.FieldManager = o.FieldManager
}
if o.DryRunStrategy == cmdutil.DryRunServer {
createOptions.DryRun = []string{metav1.DryRunAll}
}
actualObject, err := o.DynamicClient.Resource(mapping.Resource).Namespace(o.Namespace).Create(context.TODO(), asUnstructured, createOptions)
if err != nil {
return err
}
// ensure we pass a versioned object to the printer
obj = actualObject
} else {
if meta, err := meta.Accessor(obj); err == nil && o.EnforceNamespace {
meta.SetNamespace(o.Namespace)
}
}
return o.PrintObj(obj, o.Out)
}

View File

@ -0,0 +1,291 @@
/*
Copyright 2022 The Kruise Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package create
import (
"context"
"fmt"
kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
kruiseclientsets "github.com/openkruise/kruise-api/client/clientset/versioned"
"github.com/spf13/cobra"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)
var (
broadcastJobLong = templates.LongDesc(i18n.T(`
Create a broadcastJob with the specified name.`))
broadcastJobExample = templates.Examples(i18n.T(`
# Create a broadcastJob
kubectl kruise create broadcastJob my-bcj --image=busybox
# Create a broadcastJob with command
kubectl kruise create broadcastJob my-bcj --image=busybox -- date
# Create a broadcastJob from a AdvancedCronJob named "a-advancedCronjob"
kubectl kruise create broadcastJob test-bcj --from=acj/a-advancedCronjob`))
)
// CreateBroadcastJobOptions is the command line options for 'create broadcastJob'
type CreateBroadcastJobOptions struct {
PrintFlags *genericclioptions.PrintFlags
PrintObj func(obj runtime.Object) error
Name string
Image string
From string
Command []string
Namespace string
EnforceNamespace bool
kruisev1alpha1Client kruiseclientsets.Interface
DryRunStrategy cmdutil.DryRunStrategy
Builder *resource.Builder
FieldManager string
CreateAnnotation bool
genericclioptions.IOStreams
}
// NewCreateBroadcastJobOptions initializes and returns new CreateBroadcastJobOptions instance
func NewCreateBroadcastJobOptions(ioStreams genericclioptions.IOStreams) *CreateBroadcastJobOptions {
return &CreateBroadcastJobOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
IOStreams: ioStreams,
}
}
// NewCmdCreateBroadcastJob is a command to ease creating BroadcastJobs from AdvancedCronJobs.
func NewCmdCreateBroadcastJob(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewCreateBroadcastJobOptions(ioStreams)
cmd := &cobra.Command{
Use: "broadcastJob NAME --image=image [--from=cronjob/name] -- [COMMAND] [args...]",
DisableFlagsInUseLine: true,
Short: broadcastJobLong,
Long: broadcastJobLong,
Example: broadcastJobExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.Run())
},
}
o.PrintFlags.AddFlags(cmd)
cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddValidateFlags(cmd)
cmdutil.AddDryRunFlag(cmd)
cmd.Flags().StringVar(&o.Image, "image", o.Image, "Image name to run.")
cmd.Flags().StringVar(&o.From, "from", o.From, "The name of the resource to create a BroadcastJob from (only advancedCronjob is supported).")
cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl kruise-create")
return cmd
}
// Complete completes all the required options
func (o *CreateBroadcastJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args)
if err != nil {
return err
}
o.Name = name
if len(args) > 1 {
o.Command = args[1:]
}
clientConfig, err := f.ToRESTConfig()
if err != nil {
return err
}
o.kruisev1alpha1Client, err = kruiseclientsets.NewForConfig(clientConfig)
if err != nil {
return err
}
o.CreateAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
o.Builder = f.NewBuilder()
o.DryRunStrategy, err = cmdutil.GetDryRunStrategy(cmd)
if err != nil {
return err
}
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return err
}
o.PrintObj = func(obj runtime.Object) error {
return printer.PrintObj(obj, o.Out)
}
return nil
}
// Validate makes sure provided values and valid BroadcastJob options
func (o *CreateBroadcastJobOptions) Validate() error {
if (len(o.Image) == 0 && len(o.From) == 0) || (len(o.Image) != 0 && len(o.From) != 0) {
return fmt.Errorf("either --image or --from must be specified")
}
if o.Command != nil && len(o.Command) != 0 && len(o.From) != 0 {
return fmt.Errorf("cannot specify --from and command")
}
return nil
}
// Run performs the execution of 'create broadcastJob' sub command
func (o *CreateBroadcastJobOptions) Run() error {
var job *kruiseappsv1alpha1.BroadcastJob
if len(o.Image) > 0 {
job = o.createBroadcastJob()
} else {
infos, err := o.Builder.
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
ResourceTypeOrNameArgs(false, o.From).
Flatten().
Latest().
Do().
Infos()
if err != nil {
return err
}
if len(infos) != 1 {
return fmt.Errorf("from must be an existing advancedCronJob")
}
switch obj := infos[0].Object.(type) {
case *kruiseappsv1alpha1.AdvancedCronJob:
job, err = o.createBroadcastJobFromAdvancedCronJob(obj)
if err != nil {
return err
}
default:
return fmt.Errorf("unknown object type %T", obj)
}
}
if err := util.CreateOrUpdateAnnotation(o.CreateAnnotation, job, scheme.DefaultJSONEncoder()); err != nil {
return err
}
if o.DryRunStrategy != cmdutil.DryRunClient {
createOptions := metav1.CreateOptions{}
if o.FieldManager != "" {
createOptions.FieldManager = o.FieldManager
}
if o.DryRunStrategy == cmdutil.DryRunServer {
createOptions.DryRun = []string{metav1.DryRunAll}
}
var err error
job, err = o.kruisev1alpha1Client.AppsV1alpha1().BroadcastJobs(o.Namespace).Create(context.TODO(), job, createOptions)
if err != nil {
return fmt.Errorf("failed to create job: %v", err)
}
}
return o.PrintObj(job)
}
func (o *CreateBroadcastJobOptions) createBroadcastJob() *kruiseappsv1alpha1.BroadcastJob {
job := &kruiseappsv1alpha1.BroadcastJob{
// this is ok because we know exactly how we want to be serialized
TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: kruiseappsv1alpha1.AdvancedCronJobKind},
ObjectMeta: metav1.ObjectMeta{
Name: o.Name,
},
Spec: kruiseappsv1alpha1.BroadcastJobSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: o.Name,
Image: o.Image,
Command: o.Command,
},
},
RestartPolicy: corev1.RestartPolicyNever,
},
},
},
}
if o.EnforceNamespace {
job.Namespace = o.Namespace
}
return job
}
func (o *CreateBroadcastJobOptions) createBroadcastJobFromAdvancedCronJob(cronJob *kruiseappsv1alpha1.AdvancedCronJob) (*kruiseappsv1alpha1.BroadcastJob, error) {
if cronJob.Status.Type != kruiseappsv1alpha1.BroadcastJobTemplate {
return nil, fmt.Errorf("from must be a broadcastJob template, but got %v", cronJob.Status.Type)
}
job := o.createBroadcastJobFromBroadcastJobTemplate(cronJob.GetName(), cronJob.GetUID(), cronJob.Spec.Template.BroadcastJobTemplate)
return job, nil
}
func (o *CreateBroadcastJobOptions) createBroadcastJobFromBroadcastJobTemplate(ownerReferenceName string, ownerReferenceUID types.UID,
broadcastJobTemplate *kruiseappsv1alpha1.BroadcastJobTemplateSpec) *kruiseappsv1alpha1.BroadcastJob {
annotations := make(map[string]string)
broadcastJob := &kruiseappsv1alpha1.BroadcastJob{}
annotations["cronjob.kubernetes.io/instantiate"] = "manual"
for k, v := range broadcastJobTemplate.Annotations {
annotations[k] = v
}
broadcastJob = &kruiseappsv1alpha1.BroadcastJob{
// this is ok because we know exactly how we want to be serialized
TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "Job"},
ObjectMeta: metav1.ObjectMeta{
Name: o.Name,
Annotations: annotations,
Labels: broadcastJobTemplate.Labels,
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: kruiseappsv1alpha1.SchemeGroupVersion.String(),
Kind: kruiseappsv1alpha1.AdvancedCronJobKind,
Name: ownerReferenceName,
UID: ownerReferenceUID,
},
},
},
Spec: broadcastJobTemplate.Spec,
}
if o.EnforceNamespace {
broadcastJob.Namespace = o.Namespace
}
return broadcastJob
}

View File

@ -0,0 +1,296 @@
/*
Copyright 2022 The Kruise Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 create
import (
"context"
"fmt"
kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
kruiseclientsets "github.com/openkruise/kruise-api/client/clientset/versioned"
internalapi "github.com/openkruise/kruise-tools/pkg/api"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/kubernetes"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
utilpointer "k8s.io/utils/pointer"
)
var (
crrLong = templates.LongDesc(i18n.T(`
Create a crr with the specified name.`))
crrExample = templates.Examples(i18n.T(`
NOTE: The default value of CRR is:
strategy:
failurePolicy: Fail
orderedRecreate: false
unreadyGracePeriodSeconds: 3
activeDeadlineSeconds: 300
ttlSecondsAfterFinished: 1800
# Create a crr with default value to restart all containers in pod-1
kubectl kruise create ContainerRecreateRequest my-crr --namespace=ns --pod=pod-1
# Create a crr with default value to restart container-1 in pod-1
kubectl kruise create ContainerRecreateRequest my-crr --namespace=ns --pod=pod-1 --containers=container-1
# Create a crr with unreadyGracePeriodSeconds 5 and terminationGracePeriodSeconds 30 to restart container-1 in pod-1
kubectl kruise create ContainerRecreateRequest my-crr --namespace=ns --pod=pod-1 --containers=container-1 --unreadyGracePeriodSeconds=5 --terminationGracePeriodSeconds=30`))
defaultCRRStrategy = kruiseappsv1alpha1.ContainerRecreateRequestStrategy{
FailurePolicy: kruiseappsv1alpha1.ContainerRecreateRequestFailurePolicyFail,
OrderedRecreate: false,
UnreadyGracePeriodSeconds: utilpointer.Int64Ptr(3),
MinStartedSeconds: 3,
}
defaultActiveDeadlineSeconds int64 = 300
defaultTtlSecondsAfterFinished int32 = 1800
)
// CreateCRROptions is the command line options for 'create crr'
type CreateCRROptions struct {
PrintFlags *genericclioptions.PrintFlags
PrintObj func(obj runtime.Object) error
PodName string
UnreadyGracePeriodSeconds int64
MinStartedSeconds int32
Containers []string
ContainerRecreateRequestContainer []kruiseappsv1alpha1.ContainerRecreateRequestContainer
Namespace string
Name string
From string
kruisev1alpha1Client kruiseclientsets.Interface
ClientSet kubernetes.Interface
EnforceNamespace bool
DryRunStrategy cmdutil.DryRunStrategy
Builder *resource.Builder
FieldManager string
CreateAnnotation bool
genericclioptions.IOStreams
}
// NewCreateCRROptions initializes and returns new CreateCRROptions instance
func NewCreateCRROptions(ioStreams genericclioptions.IOStreams) *CreateCRROptions {
return &CreateCRROptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(internalapi.GetScheme()),
IOStreams: ioStreams,
}
}
// NewCmdCreateCRR is a command to ease creating ContainerRecreateRequest.
func NewCmdCreateCRR(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewCreateCRROptions(ioStreams)
cmd := &cobra.Command{
Use: "ContainerRecreateRequest NAME --pod=podName [--containers=container]",
DisableFlagsInUseLine: true,
Short: crrLong,
Long: crrLong,
Example: crrExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.Run())
},
}
o.PrintFlags.AddFlags(cmd)
cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddValidateFlags(cmd)
cmdutil.AddDryRunFlag(cmd)
cmd.Flags().StringVarP(&o.PodName, "pod", "p", o.PodName, "The name of the pod).")
cmd.Flags().StringSlice("containers", o.Containers, "The containers those need to restarted.")
cmd.Flags().Int64VarP(&o.UnreadyGracePeriodSeconds, "unreadyGracePeriodSeconds", "u", o.UnreadyGracePeriodSeconds, "UnreadyGracePeriodSeconds is the optional duration in seconds to mark Pod as not ready over this duration before executing preStop hook and stopping the container")
cmd.Flags().Int32VarP(&o.MinStartedSeconds, "minStartedSeconds", "m", o.MinStartedSeconds, "Minimum number of seconds for which a newly created container should be started and ready without any of its container crashing, for it to be considered Succeeded.Defaults to 0 (container will be considered Succeeded as soon as it is started and ready)")
cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl kruise-create")
return cmd
}
// Complete completes all the required options
func (o *CreateCRROptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args)
if err != nil {
return err
}
o.Name = name
clientConfig, err := f.ToRESTConfig()
if err != nil {
return err
}
o.ClientSet, err = kubernetes.NewForConfig(clientConfig)
if err != nil {
return err
}
o.kruisev1alpha1Client, err = kruiseclientsets.NewForConfig(clientConfig)
if err != nil {
return err
}
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
if len(o.Namespace) == 0 {
o.Namespace = "default"
}
o.CreateAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
o.Builder = f.NewBuilder()
if len(o.Containers) == 0 {
// restart all containers in pod
o.ContainerRecreateRequestContainer, err = o.getAllCRRContainersInPod()
if err != nil {
return err
}
}
o.DryRunStrategy, err = cmdutil.GetDryRunStrategy(cmd)
if err != nil {
return err
}
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return err
}
o.PrintObj = func(obj runtime.Object) error {
return printer.PrintObj(obj, o.Out)
}
return nil
}
// Validate makes sure provided values and valid crr options
func (o *CreateCRROptions) Validate() error {
// validate whether containers in pod
if !o.isPodExist() {
return fmt.Errorf("pod %s in namespace %s not exist", o.Name, o.Namespace)
}
var containers []string
crrContainers, err := o.getAllCRRContainersInPod()
if err != nil {
return fmt.Errorf("found containers failed")
}
for i := range crrContainers {
containers = append(containers, crrContainers[i].Name)
}
allContainerSet := sets.NewString(containers...)
if !allContainerSet.HasAll(o.Containers...) {
return fmt.Errorf("has container not exist")
}
return nil
}
// Run performs the execution of 'create crr' sub command
func (o *CreateCRROptions) Run() error {
crr := o.createCRR()
if o.DryRunStrategy != cmdutil.DryRunClient {
createOptions := metav1.CreateOptions{}
if o.FieldManager != "" {
createOptions.FieldManager = o.FieldManager
}
if o.DryRunStrategy == cmdutil.DryRunServer {
createOptions.DryRun = []string{metav1.DryRunAll}
}
var err error
crr, err = o.kruisev1alpha1Client.AppsV1alpha1().ContainerRecreateRequests(o.Namespace).Create(context.TODO(), crr, createOptions)
if err != nil {
return fmt.Errorf("failed to create crr: %v", err)
}
}
return o.PrintObj(crr)
}
func (o *CreateCRROptions) getAllCRRContainersInPod() ([]kruiseappsv1alpha1.ContainerRecreateRequestContainer, error) {
var crrContainers []kruiseappsv1alpha1.ContainerRecreateRequestContainer
var selectedCrrContainers []kruiseappsv1alpha1.ContainerRecreateRequestContainer
selectedContainers := sets.NewString(o.Containers...)
pod, err := o.ClientSet.CoreV1().Pods(o.Namespace).Get(context.TODO(), o.PodName, metav1.GetOptions{})
if err != nil {
return crrContainers, err
}
for _, container := range pod.Spec.Containers {
crrContainer := kruiseappsv1alpha1.ContainerRecreateRequestContainer{}
if container.Lifecycle != nil {
crrContainer.PreStop = &kruiseappsv1alpha1.ProbeHandler{
Exec: container.Lifecycle.PreStop.Exec,
HTTPGet: container.Lifecycle.PreStop.HTTPGet,
TCPSocket: container.Lifecycle.PreStop.TCPSocket,
}
}
crrContainer.Name = container.Name
crrContainer.Ports = container.Ports
crrContainers = append(crrContainers, crrContainer)
}
if len(o.Containers) == 0 {
return crrContainers, nil
} else {
for _, container := range crrContainers {
if selectedContainers.Has(container.Name) {
selectedCrrContainers = append(selectedCrrContainers, container)
}
}
return selectedCrrContainers, nil
}
}
func (o *CreateCRROptions) isPodExist() bool {
_, err := o.ClientSet.CoreV1().Pods(o.Namespace).Get(context.TODO(), o.PodName, metav1.GetOptions{})
if err != nil {
return false
}
return true
}
func (o *CreateCRROptions) createCRR() *kruiseappsv1alpha1.ContainerRecreateRequest {
crr := &kruiseappsv1alpha1.ContainerRecreateRequest{
TypeMeta: metav1.TypeMeta{APIVersion: kruiseappsv1alpha1.SchemeGroupVersion.String(), Kind: "ContainerRecreateRequest"},
ObjectMeta: metav1.ObjectMeta{
Name: o.Name,
Namespace: o.Namespace,
},
Spec: kruiseappsv1alpha1.ContainerRecreateRequestSpec{
PodName: o.PodName,
Containers: o.ContainerRecreateRequestContainer,
Strategy: &defaultCRRStrategy,
ActiveDeadlineSeconds: utilpointer.Int64Ptr(defaultActiveDeadlineSeconds),
TTLSecondsAfterFinished: utilpointer.Int32Ptr(defaultTtlSecondsAfterFinished),
},
}
if o.EnforceNamespace {
crr.Namespace = o.Namespace
}
return crr
}

View File

@ -0,0 +1,359 @@
/*
Copyright 2022 The Kruise Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package create
import (
"context"
"fmt"
kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
"github.com/spf13/cobra"
batchv1 "k8s.io/api/batch/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
batchv1client "k8s.io/client-go/kubernetes/typed/batch/v1"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)
var (
jobLong = templates.LongDesc(i18n.T(`
Create a job with the specified name.`))
jobExample = templates.Examples(i18n.T(`
# Create a job
kubectl kruise create job my-job --image=busybox
# Create a job with command
kubectl kruise create job my-job --image=busybox -- date
# Create a job from a AdvancedCronJob named "a-advancedCronjob"
kubectl kruise create job test-job --from=acj/a-advancedCronjob`))
)
// CreateJobOptions is the command line options for 'create job'
type CreateJobOptions struct {
PrintFlags *genericclioptions.PrintFlags
PrintObj func(obj runtime.Object) error
Name string
Image string
From string
Command []string
Namespace string
EnforceNamespace bool
Client batchv1client.BatchV1Interface
DryRunStrategy cmdutil.DryRunStrategy
Builder *resource.Builder
FieldManager string
CreateAnnotation bool
genericclioptions.IOStreams
}
// NewCreateJobOptions initializes and returns new CreateJobOptions instance
func NewCreateJobOptions(ioStreams genericclioptions.IOStreams) *CreateJobOptions {
return &CreateJobOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
IOStreams: ioStreams,
}
}
// NewCmdCreateJob is a command to ease creating Jobs from CronJobs.
func NewCmdCreateJob(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewCreateJobOptions(ioStreams)
cmd := &cobra.Command{
Use: "job NAME --image=image [--from=cronjob/name] -- [COMMAND] [args...]",
DisableFlagsInUseLine: true,
Short: jobLong,
Long: jobLong,
Example: jobExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.Run())
},
}
o.PrintFlags.AddFlags(cmd)
cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddValidateFlags(cmd)
cmdutil.AddDryRunFlag(cmd)
cmd.Flags().StringVar(&o.Image, "image", o.Image, "Image name to run.")
cmd.Flags().StringVar(&o.From, "from", o.From, "The name of the resource to create a Job from (cronjob and advancedCronjob are supported).")
cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl kruise-create")
return cmd
}
// Complete completes all the required options
func (o *CreateJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args)
if err != nil {
return err
}
o.Name = name
if len(args) > 1 {
o.Command = args[1:]
}
clientConfig, err := f.ToRESTConfig()
if err != nil {
return err
}
o.Client, err = batchv1client.NewForConfig(clientConfig)
if err != nil {
return err
}
o.CreateAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
o.Builder = f.NewBuilder()
o.DryRunStrategy, err = cmdutil.GetDryRunStrategy(cmd)
if err != nil {
return err
}
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return err
}
o.PrintObj = func(obj runtime.Object) error {
return printer.PrintObj(obj, o.Out)
}
return nil
}
// Validate makes sure provided values and valid Job options
func (o *CreateJobOptions) Validate() error {
if (len(o.Image) == 0 && len(o.From) == 0) || (len(o.Image) != 0 && len(o.From) != 0) {
return fmt.Errorf("either --image or --from must be specified")
}
if o.Command != nil && len(o.Command) != 0 && len(o.From) != 0 {
return fmt.Errorf("cannot specify --from and command")
}
return nil
}
// Run performs the execution of 'create job' sub command
func (o *CreateJobOptions) Run() error {
var job *batchv1.Job
if len(o.Image) > 0 {
job = o.createJob()
} else {
infos, err := o.Builder.
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
ResourceTypeOrNameArgs(false, o.From).
Flatten().
Latest().
Do().
Infos()
if err != nil {
return err
}
if len(infos) != 1 {
return fmt.Errorf("from must be an existing cronjob")
}
switch obj := infos[0].Object.(type) {
case *batchv1.CronJob:
job = o.createJobFromCronJob(obj)
case *batchv1beta1.CronJob:
job = o.createJobFromCronJobV1Beta1(obj)
case *kruiseappsv1alpha1.AdvancedCronJob:
job, err = o.createJobFromAdvancedCronJob(obj)
if err != nil {
return err
}
default:
return fmt.Errorf("unknown object type %T", obj)
}
}
if err := util.CreateOrUpdateAnnotation(o.CreateAnnotation, job, scheme.DefaultJSONEncoder()); err != nil {
return err
}
if o.DryRunStrategy != cmdutil.DryRunClient {
createOptions := metav1.CreateOptions{}
if o.FieldManager != "" {
createOptions.FieldManager = o.FieldManager
}
if o.DryRunStrategy == cmdutil.DryRunServer {
createOptions.DryRun = []string{metav1.DryRunAll}
}
var err error
job, err = o.Client.Jobs(o.Namespace).Create(context.TODO(), job, createOptions)
if err != nil {
return fmt.Errorf("failed to create job: %v", err)
}
}
return o.PrintObj(job)
}
func (o *CreateJobOptions) createJob() *batchv1.Job {
job := &batchv1.Job{
// this is ok because we know exactly how we want to be serialized
TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "Job"},
ObjectMeta: metav1.ObjectMeta{
Name: o.Name,
},
Spec: batchv1.JobSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: o.Name,
Image: o.Image,
Command: o.Command,
},
},
RestartPolicy: corev1.RestartPolicyNever,
},
},
},
}
if o.EnforceNamespace {
job.Namespace = o.Namespace
}
return job
}
func (o *CreateJobOptions) createJobFromCronJobV1Beta1(cronJob *batchv1beta1.CronJob) *batchv1.Job {
annotations := make(map[string]string)
annotations["cronjob.kubernetes.io/instantiate"] = "manual"
for k, v := range cronJob.Spec.JobTemplate.Annotations {
annotations[k] = v
}
job := &batchv1.Job{
// this is ok because we know exactly how we want to be serialized
TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "Job"},
ObjectMeta: metav1.ObjectMeta{
Name: o.Name,
Annotations: annotations,
Labels: cronJob.Spec.JobTemplate.Labels,
OwnerReferences: []metav1.OwnerReference{
{
// TODO (soltysh): switch this to v1 in v1.22, when n-1 skew will be fulfilled
APIVersion: batchv1beta1.SchemeGroupVersion.String(),
Kind: "CronJob",
Name: cronJob.GetName(),
UID: cronJob.GetUID(),
},
},
},
Spec: cronJob.Spec.JobTemplate.Spec,
}
if o.EnforceNamespace {
job.Namespace = o.Namespace
}
return job
}
func (o *CreateJobOptions) createJobFromCronJob(cronJob *batchv1.CronJob) *batchv1.Job {
annotations := make(map[string]string)
annotations["cronjob.kubernetes.io/instantiate"] = "manual"
for k, v := range cronJob.Spec.JobTemplate.Annotations {
annotations[k] = v
}
job := &batchv1.Job{
// this is ok because we know exactly how we want to be serialized
TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "Job"},
ObjectMeta: metav1.ObjectMeta{
Name: o.Name,
Annotations: annotations,
Labels: cronJob.Spec.JobTemplate.Labels,
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: batchv1beta1.SchemeGroupVersion.String(),
Kind: "CronJob",
Name: cronJob.GetName(),
UID: cronJob.GetUID(),
},
},
},
Spec: cronJob.Spec.JobTemplate.Spec,
}
if o.EnforceNamespace {
job.Namespace = o.Namespace
}
return job
}
func (o *CreateJobOptions) createJobFromAdvancedCronJob(cronJob *kruiseappsv1alpha1.AdvancedCronJob) (*batchv1.Job, error) {
if cronJob.Status.Type != kruiseappsv1alpha1.JobTemplate {
return nil, fmt.Errorf("from must be a job template, but got %v", cronJob.Status.Type)
}
job := o.createJobFromJobTemplate(cronJob.GetName(), cronJob.GetUID(), cronJob.Spec.Template.JobTemplate)
return job, nil
}
func (o *CreateJobOptions) createJobFromJobTemplate(ownerReferenceName string, ownerReferenceUID types.UID,
jobTemplate *batchv1.JobTemplateSpec) *batchv1.Job {
annotations := make(map[string]string)
job := &batchv1.Job{}
annotations["cronjob.kubernetes.io/instantiate"] = "manual"
for k, v := range jobTemplate.Annotations {
annotations[k] = v
}
job = &batchv1.Job{
// this is ok because we know exactly how we want to be serialized
TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "Job"},
ObjectMeta: metav1.ObjectMeta{
Name: o.Name,
Annotations: annotations,
Labels: jobTemplate.Labels,
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: kruiseappsv1alpha1.SchemeGroupVersion.String(),
Kind: kruiseappsv1alpha1.AdvancedCronJobKind,
Name: ownerReferenceName,
UID: ownerReferenceUID,
},
},
},
Spec: jobTemplate.Spec,
}
if o.EnforceNamespace {
job.Namespace = o.Namespace
}
return job
}

View File

@ -0,0 +1,50 @@
package describe
/*
Copyright 2021 The Kruise Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)
var (
describeLong = templates.LongDesc(i18n.T(`
Show details of a rollout.`))
describeExample = templates.Examples(`
# Describe the rollout named rollout-demo
kubectl-kruise describe rollout rollout-demo`)
)
// NewCmdRollout returns a Command instance for 'rollout' sub command
func NewCmdDescibe(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{
Use: "describe SUBCOMMAND",
DisableFlagsInUseLine: true,
Short: i18n.T("Show details of a specific resource or group of resources"),
Long: describeLong,
Example: describeExample,
Run: cmdutil.DefaultSubCommandRun(streams.Out),
}
// subcommands
cmd.AddCommand(NewCmdDescribeRollout(f, streams))
return cmd
}

View File

@ -0,0 +1,806 @@
/*
Copyright 2024 The Kruise Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 describe
import (
"context"
"fmt"
"reflect"
"sort"
"strconv"
"strings"
"text/tabwriter"
"time"
kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
kruiseappsv1beta1 "github.com/openkruise/kruise-api/apps/v1beta1"
rolloutsapi "github.com/openkruise/kruise-rollout-api/client/clientset/versioned"
rolloutv1alpha1types "github.com/openkruise/kruise-rollout-api/client/clientset/versioned/typed/rollouts/v1alpha1"
rolloutsv1beta1types "github.com/openkruise/kruise-rollout-api/client/clientset/versioned/typed/rollouts/v1beta1"
rolloutsapiv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1"
rolloutsapiv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
internalapi "github.com/openkruise/kruise-tools/pkg/api"
internalpolymorphichelpers "github.com/openkruise/kruise-tools/pkg/internal/polymorphichelpers"
"github.com/spf13/cobra"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/duration"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/kubernetes/scheme"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)
const (
tableFormat = "%-19s%v\n"
)
var (
rolloutLong = templates.LongDesc(i18n.T(`
Get details about and visual representation of a rollout.`))
rolloutExample = templates.Examples(`
# Describe the rollout named rollout-demo within namespace default
kubectl-kruise describe rollout rollout-demo -n default
# Watch for changes to the rollout named rollout-demo
kubectl-kruise describe rollout rollout-demo -n default -w`)
)
type DescribeRolloutOptions struct {
genericclioptions.IOStreams
Builder func() *resource.Builder
Namespace string
EnforceNamespace bool
Resources []string
RolloutViewerFn func(runtime.Object) (interface{}, error)
Watch bool
NoColor bool
All bool
TimeoutSeconds int
RolloutsV1beta1Client rolloutsv1beta1types.RolloutInterface
RolloutsV1alpha1Client rolloutv1alpha1types.RolloutInterface
}
type WorkloadInfo struct {
Name string
Kind string
Images []string
Replicas struct {
Desired int32
Current int32
Updated int32
Ready int32
Available int32
}
Pod []struct {
Name string
BatchID string
Status string
Ready string
Age string
Restarts string
Revision string
}
CurrentRevision string
UpdateRevision string
}
type RolloutInfo struct {
Name string
Namespace string
Phase string
Message string
ObservedGeneration int64
Generation int64
CurrentStepIndex int32
CurrentStepState string
CanaryStrategy rolloutsapiv1beta1.CanaryStrategy
BlueGreenStrategy rolloutsapiv1beta1.BlueGreenStrategy
TrafficRoutingRef string
WorkloadRef RolloutWorkloadRef
StrategyType string
}
func NewCmdDescribeRollout(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := &DescribeRolloutOptions{IOStreams: streams}
cmd := &cobra.Command{
Use: "rollout SUBCOMMAND",
DisableFlagsInUseLine: true,
Short: i18n.T("Get details about a rollout"),
Long: rolloutLong,
Example: rolloutExample,
Aliases: []string{"rollouts", "ro"},
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, args))
cmdutil.CheckErr(o.Run())
},
}
cmd.Flags().BoolVarP(&o.Watch, "watch", "w", false, "Watch for changes to the rollout")
cmd.Flags().BoolVar(&o.NoColor, "no-color", false, "If true, print output without color")
cmd.Flags().IntVar(&o.TimeoutSeconds, "timeout", 0, "Timeout after specified seconds")
cmd.Flags().BoolVar(&o.All, "all", false, "Show all pods in the rollout")
return cmd
}
func (o *DescribeRolloutOptions) Complete(f cmdutil.Factory, args []string) error {
var err error
if len(args) == 0 {
return fmt.Errorf("required rollout name not specified")
}
o.Resources = args
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
o.Resources = []string{args[0]}
o.RolloutViewerFn = internalpolymorphichelpers.RolloutViewerFn
o.Builder = f.NewBuilder
config, err := f.ToRESTConfig()
if err != nil {
return err
}
rolloutsClientset, err := rolloutsapi.NewForConfig(config)
if err != nil {
return err
}
o.RolloutsV1beta1Client = rolloutsClientset.RolloutsV1beta1().Rollouts(o.Namespace)
o.RolloutsV1alpha1Client = rolloutsClientset.RolloutsV1alpha1().Rollouts(o.Namespace)
return nil
}
func (o *DescribeRolloutOptions) Run() error {
rolloutName := o.Resources[0]
r := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
ResourceNames("rollouts.rollouts.kruise.io", rolloutName).
ContinueOnError().
Latest().
Flatten().
Do()
if err := r.Err(); err != nil {
return err
}
if !o.Watch {
return r.Visit(o.describeRollout)
}
return o.watchRollout(r)
}
func (o *DescribeRolloutOptions) describeRollout(info *resource.Info, err error) error {
if err != nil {
return err
}
rollout, err := o.RolloutViewerFn(info.Object)
if err != nil {
return err
}
o.printRolloutInfo(rollout)
return nil
}
func (o *DescribeRolloutOptions) watchRollout(r *resource.Result) error {
infos, err := r.Infos()
if err != nil {
return err
}
if len(infos) != 1 {
return fmt.Errorf("watch is only supported on a single rollout")
}
info := infos[0]
var watcher watch.Interface
switch info.Object.(type) {
case *rolloutsapiv1beta1.Rollout:
watcher, err = o.RolloutsV1beta1Client.Watch(context.TODO(), metav1.ListOptions{
FieldSelector: "metadata.name=" + info.Name,
})
case *rolloutsapiv1alpha1.Rollout:
watcher, err = o.RolloutsV1alpha1Client.Watch(context.TODO(), metav1.ListOptions{
FieldSelector: "metadata.name=" + info.Name,
})
default:
return fmt.Errorf("unsupported rollout type %T", info.Object)
}
if err != nil {
return err
}
defer watcher.Stop()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
if o.TimeoutSeconds > 0 {
ctx, cancel = context.WithTimeout(ctx, time.Duration(o.TimeoutSeconds)*time.Second)
defer cancel()
}
return o.watchRolloutUpdates(ctx, watcher)
}
func (o *DescribeRolloutOptions) watchRolloutUpdates(ctx context.Context, watcher watch.Interface) error {
for {
select {
case event, ok := <-watcher.ResultChan():
if !ok {
return nil
}
if event.Type == watch.Added || event.Type == watch.Modified {
var rollout interface{}
switch obj := event.Object.(type) {
case *rolloutsapiv1beta1.Rollout:
rollout = obj
case *rolloutsapiv1alpha1.Rollout:
rollout = obj
default:
continue
}
o.clearScreen()
o.printRolloutInfo(rollout)
}
case <-ctx.Done():
return ctx.Err()
}
}
}
func (o *DescribeRolloutOptions) clearScreen() {
fmt.Fprint(o.Out, "\033[2J\033[H")
}
type RolloutWorkloadRef struct {
Kind string
Name string
StableRevision string
CanaryRevision string
UpdatedRevision string
PodTemplateHash string
CurrentStepIndex int32
}
func (o *DescribeRolloutOptions) GetResources(rollout RolloutWorkloadRef) (*WorkloadInfo, error) {
resources := []string{rollout.Kind + "/" + rollout.Name}
r := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
ResourceTypeOrNameArgs(true, resources...).
ContinueOnError().
Latest().
Flatten().
Do()
if err := r.Err(); err != nil {
return nil, err
}
obj, err := r.Object()
if err != nil {
return nil, err
}
workloadInfo := &WorkloadInfo{}
objValue := reflect.ValueOf(obj).Elem()
workloadInfo.Name = objValue.FieldByName("Name").String()
workloadInfo.Kind = objValue.Type().Name()
podTemplateSpec := objValue.FieldByName("Spec").FieldByName("Template").FieldByName("Spec")
containers := podTemplateSpec.FieldByName("Containers")
for i := 0; i < containers.Len(); i++ {
container := containers.Index(i)
workloadInfo.Images = append(workloadInfo.Images, container.FieldByName("Image").String())
}
// Deployment,StatefulSet,CloneSet,Advanced StatefulSet,Advanced DaemonSet
switch o := obj.(type) {
case *appsv1.Deployment:
workloadInfo.Replicas.Desired = *o.Spec.Replicas
workloadInfo.Replicas.Current = o.Status.Replicas
workloadInfo.Replicas.Updated = o.Status.UpdatedReplicas
workloadInfo.Replicas.Ready = o.Status.ReadyReplicas
workloadInfo.Replicas.Available = o.Status.AvailableReplicas
case *appsv1.StatefulSet:
workloadInfo.Replicas.Desired = *o.Spec.Replicas
workloadInfo.Replicas.Current = o.Status.Replicas
workloadInfo.Replicas.Updated = o.Status.UpdatedReplicas
workloadInfo.Replicas.Ready = o.Status.ReadyReplicas
workloadInfo.Replicas.Available = o.Status.AvailableReplicas
case *kruiseappsv1alpha1.DaemonSet:
workloadInfo.Replicas.Desired = o.Spec.BurstReplicas.IntVal
workloadInfo.Replicas.Current = o.Status.CurrentNumberScheduled
workloadInfo.Replicas.Updated = o.Status.UpdatedNumberScheduled
workloadInfo.Replicas.Ready = o.Status.NumberReady
workloadInfo.Replicas.Available = o.Status.NumberAvailable
case *kruiseappsv1beta1.StatefulSet:
workloadInfo.Replicas.Desired = *o.Spec.Replicas
workloadInfo.Replicas.Current = o.Status.Replicas
workloadInfo.Replicas.Updated = o.Status.UpdatedReplicas
workloadInfo.Replicas.Ready = o.Status.ReadyReplicas
workloadInfo.Replicas.Available = o.Status.AvailableReplicas
case *kruiseappsv1alpha1.CloneSet:
workloadInfo.Replicas.Desired = *o.Spec.Replicas
workloadInfo.Replicas.Current = o.Status.Replicas
workloadInfo.Replicas.Updated = o.Status.UpdatedReplicas
workloadInfo.Replicas.Ready = o.Status.ReadyReplicas
workloadInfo.Replicas.Available = o.Status.AvailableReplicas
default:
return nil, fmt.Errorf("unsupported workload kind %T", obj)
}
workloadInfo.CurrentRevision = rollout.StableRevision
workloadInfo.UpdateRevision = rollout.CanaryRevision
if rollout.UpdatedRevision != "" {
workloadInfo.UpdateRevision = rollout.UpdatedRevision
}
var labelSelectorParam string
switch obj.(type) {
case *appsv1.Deployment:
labelSelectorParam = "pod-template-hash"
default:
labelSelectorParam = "controller-revision-hash"
}
selectorParam := rollout.PodTemplateHash
if selectorParam == "" {
selectorParam = rollout.StableRevision
}
labelSelectors := []string{
fmt.Sprintf("%s=%s", labelSelectorParam, selectorParam),
}
if !o.All && rollout.CurrentStepIndex != 0 {
labelSelectors = append(labelSelectors,
fmt.Sprintf("rollouts.kruise.io/rollout-batch-id=%v",
rollout.CurrentStepIndex))
}
// Fetch pods
r2 := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
ResourceTypes("pods").
LabelSelectorParam(strings.Join(labelSelectors, ",")).
Latest().
Flatten().
Do()
if err := r2.Err(); err != nil {
return nil, err
}
err = r2.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
pod, ok := info.Object.(*corev1.Pod)
if !ok {
return fmt.Errorf("expected *corev1.Pod, got %T", info.Object)
}
podInfo := struct {
Name string
BatchID string
Status string
Ready string
Age string
Restarts string
Revision string
}{
Name: pod.Name,
BatchID: pod.Labels["rollouts.kruise.io/rollout-batch-id"],
Status: string(pod.Status.Phase),
Age: duration.HumanDuration(time.Since(pod.CreationTimestamp.Time)),
Restarts: "0",
}
if pod.DeletionTimestamp != nil {
podInfo.Status = "Terminating"
}
if len(pod.Status.ContainerStatuses) > 0 {
restartCount := 0
for _, containerStatus := range pod.Status.ContainerStatuses {
restartCount += int(containerStatus.RestartCount)
}
podInfo.Restarts = strconv.Itoa(restartCount)
}
// Calculate ready status
readyContainers := 0
for _, containerStatus := range pod.Status.ContainerStatuses {
if containerStatus.Ready {
readyContainers++
}
}
podInfo.Ready = fmt.Sprintf("%d/%d", readyContainers, len(pod.Spec.Containers))
// Calculate revision
if pod.Labels["pod-template-hash"] != "" {
podInfo.Revision = pod.Labels["pod-template-hash"]
} else if pod.Labels["controller-revision-hash"] != "" {
podInfo.Revision = pod.Labels["controller-revision-hash"]
}
workloadInfo.Pod = append(workloadInfo.Pod, podInfo)
return nil
})
if err != nil {
return nil, err
}
// Sort pods by batch ID and ready count
sort.Slice(workloadInfo.Pod, func(i, j int) bool {
if workloadInfo.Pod[i].BatchID != workloadInfo.Pod[j].BatchID {
return workloadInfo.Pod[i].BatchID < workloadInfo.Pod[j].BatchID
}
iReady := strings.Split(workloadInfo.Pod[i].Ready, "/")
jReady := strings.Split(workloadInfo.Pod[j].Ready, "/")
iReadyCount, _ := strconv.Atoi(iReady[0])
jReadyCount, _ := strconv.Atoi(jReady[0])
return iReadyCount > jReadyCount
})
return workloadInfo, nil
}
func (o *DescribeRolloutOptions) colorizeIcon(phase string) string {
if o.NoColor || phase == "" {
return ""
}
switch phase {
case string(rolloutsapiv1beta1.RolloutPhaseHealthy), string(corev1.PodRunning):
return "\033[32m✔\033[0m"
case string(rolloutsapiv1beta1.RolloutPhaseProgressing), string(corev1.PodPending):
return "\033[33m⚠\033[0m"
case string(rolloutsapiv1beta1.RolloutPhaseDisabled), string(corev1.PodUnknown), string(rolloutsapiv1beta1.RolloutPhaseTerminating), string(rolloutsapiv1beta1.RolloutPhaseDisabling), string(corev1.PodFailed):
return "\033[31m✘\033[0m"
case string(rolloutsapiv1beta1.RolloutPhaseInitial):
return "\033[33m⚠\033[0m"
default:
return ""
}
}
func (o *DescribeRolloutOptions) printTrafficRouting(trafficRouting []rolloutsapiv1beta1.TrafficRoutingRef) {
if len(trafficRouting) == 0 {
return
}
fmt.Fprint(o.Out, "Traffic Routings:\n")
for _, trafficRouting := range trafficRouting {
fmt.Fprintf(o.Out, tableFormat, " - Service: ", trafficRouting.Service)
if trafficRouting.Ingress != nil {
fmt.Fprintln(o.Out, ` Ingress: `)
fmt.Fprintf(o.Out, tableFormat, " classType: ", trafficRouting.Ingress.ClassType)
fmt.Fprintf(o.Out, tableFormat, " name: ", trafficRouting.Ingress.Name)
}
if trafficRouting.Gateway != nil {
fmt.Fprintln(o.Out, ` Gateway: `)
fmt.Fprintf(o.Out, tableFormat, " HttpRouteName: ", trafficRouting.Gateway.HTTPRouteName)
}
if trafficRouting.CustomNetworkRefs != nil {
fmt.Fprintln(o.Out, ` CustomNetworkRefs: `)
for _, customNetworkRef := range trafficRouting.CustomNetworkRefs {
fmt.Fprintf(o.Out, tableFormat, " name: ", customNetworkRef.Name)
fmt.Fprintf(o.Out, tableFormat, " kind: ", customNetworkRef.Kind)
fmt.Fprintf(o.Out, tableFormat, " apiVersion: ", customNetworkRef.APIVersion)
}
}
}
}
func convertCustomNetworkRefs(refs []rolloutsapiv1alpha1.CustomNetworkRef) []rolloutsapiv1beta1.ObjectRef {
var result []rolloutsapiv1beta1.ObjectRef
for _, ref := range refs {
result = append(result, rolloutsapiv1beta1.ObjectRef{
Name: ref.Name,
Kind: ref.Kind,
APIVersion: ref.APIVersion,
})
}
return result
}
func extractRolloutInfo(obj interface{}) *RolloutInfo {
info := &RolloutInfo{}
switch r := obj.(type) {
case *rolloutsapiv1beta1.Rollout:
info.Name = r.Name
info.Namespace = r.Namespace
info.Phase = string(r.Status.Phase)
info.Message = r.Status.Message
info.ObservedGeneration = r.Status.ObservedGeneration
info.Generation = r.GetObjectMeta().GetGeneration()
if r.Spec.Strategy.BlueGreen != nil {
info.CurrentStepIndex = r.Status.BlueGreenStatus.CurrentStepIndex
info.CurrentStepState = string(r.Status.BlueGreenStatus.CurrentStepState)
info.WorkloadRef = RolloutWorkloadRef{
Kind: r.Spec.WorkloadRef.Kind,
Name: r.Spec.WorkloadRef.Name,
StableRevision: r.Status.BlueGreenStatus.StableRevision,
UpdatedRevision: r.Status.BlueGreenStatus.UpdatedRevision,
PodTemplateHash: r.Status.BlueGreenStatus.PodTemplateHash,
CurrentStepIndex: r.Status.BlueGreenStatus.CurrentStepIndex,
}
} else {
info.CurrentStepIndex = r.Status.CanaryStatus.CurrentStepIndex
info.CurrentStepState = string(r.Status.CanaryStatus.CurrentStepState)
info.WorkloadRef = RolloutWorkloadRef{
Kind: r.Spec.WorkloadRef.Kind,
Name: r.Spec.WorkloadRef.Name,
StableRevision: r.Status.CanaryStatus.StableRevision,
CanaryRevision: r.Status.CanaryStatus.CanaryRevision,
PodTemplateHash: r.Status.CanaryStatus.PodTemplateHash,
CurrentStepIndex: r.Status.CanaryStatus.CurrentStepIndex,
}
}
if r.Spec.Strategy.Canary != nil {
info.CanaryStrategy = *r.Spec.Strategy.Canary
info.StrategyType = "Canary"
info.TrafficRoutingRef = r.Spec.Strategy.Canary.TrafficRoutingRef
} else if r.Spec.Strategy.BlueGreen != nil {
info.BlueGreenStrategy = *r.Spec.Strategy.BlueGreen
info.StrategyType = "BlueGreen"
}
case *rolloutsapiv1alpha1.Rollout:
info.Name = r.Name
info.Namespace = r.Namespace
info.Phase = string(r.Status.Phase)
info.Message = r.Status.Message
info.ObservedGeneration = r.Status.ObservedGeneration
info.Generation = r.GetObjectMeta().GetGeneration()
info.CurrentStepIndex = r.Status.CanaryStatus.CurrentStepIndex
info.CurrentStepState = string(r.Status.CanaryStatus.CurrentStepState)
info.WorkloadRef = RolloutWorkloadRef{
Kind: r.Spec.ObjectRef.WorkloadRef.Kind,
Name: r.Spec.ObjectRef.WorkloadRef.Name,
StableRevision: r.Status.CanaryStatus.StableRevision,
CanaryRevision: r.Status.CanaryStatus.CanaryRevision,
PodTemplateHash: r.Status.CanaryStatus.PodTemplateHash,
CurrentStepIndex: r.Status.CanaryStatus.CurrentStepIndex,
}
if r.Spec.Strategy.Canary != nil {
info.StrategyType = "Canary"
info.TrafficRoutingRef = r.ObjectMeta.Annotations["rollouts.kruise.io/trafficrouting"]
}
// BlueGreen strategy is not supported in v1alpha1 API
}
if obj.(*rolloutsapiv1beta1.Rollout).Spec.Strategy.Canary != nil {
info.CanaryStrategy = *obj.(*rolloutsapiv1beta1.Rollout).Spec.Strategy.Canary
} else if obj.(*rolloutsapiv1beta1.Rollout).Spec.Strategy.BlueGreen != nil {
info.BlueGreenStrategy = *obj.(*rolloutsapiv1beta1.Rollout).Spec.Strategy.BlueGreen
}
return info
}
func (o *DescribeRolloutOptions) fetchAndPrintTrafficRoutingRef(ref string) {
r := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
ResourceNames("trafficroutings.rollouts.kruise.io", ref).
ContinueOnError().
Latest().
Flatten().
Do()
if err := r.Err(); err != nil {
fmt.Fprintf(o.Out, "Error getting TrafficRoutingRef: %v\n", err)
return
}
err := r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
trafficRouting, ok := info.Object.(*rolloutsapiv1alpha1.TrafficRouting)
if !ok {
return fmt.Errorf("expected *rolloutsapiv1alpha1.TrafficRouting")
}
var trafficRoutingRef []rolloutsapiv1beta1.TrafficRoutingRef
for _, ref := range trafficRouting.Spec.ObjectRef {
trafficRoutingRef = append(trafficRoutingRef, rolloutsapiv1beta1.TrafficRoutingRef{
Service: ref.Service,
Ingress: (*rolloutsapiv1beta1.IngressTrafficRouting)(ref.Ingress),
Gateway: (*rolloutsapiv1beta1.GatewayTrafficRouting)(ref.Gateway),
CustomNetworkRefs: convertCustomNetworkRefs(ref.CustomNetworkRefs),
})
}
o.printTrafficRouting(trafficRoutingRef)
return nil
})
if err != nil {
return
}
}
func (o *DescribeRolloutOptions) printRolloutInfo(rollout interface{}) {
info := extractRolloutInfo(rollout)
// Print basic info
fmt.Fprintf(o.Out, tableFormat, "Name:", info.Name)
fmt.Fprintf(o.Out, tableFormat, "Namespace:", info.Namespace)
if info.ObservedGeneration == info.Generation {
fmt.Fprintf(o.Out, tableFormat, "Status:", o.colorizeIcon(info.Phase)+" "+info.Phase)
if info.Message != "" {
fmt.Fprintf(o.Out, tableFormat, "Message:", info.Message)
}
}
// Print strategy
fmt.Fprintf(o.Out, tableFormat, "Strategy:", info.StrategyType)
if info.StrategyType == "Canary" {
fmt.Fprintf(o.Out, tableFormat, " Step:", strconv.Itoa(int(info.CurrentStepIndex))+"/"+strconv.Itoa(len(info.CanaryStrategy.Steps)))
fmt.Fprint(o.Out, " Steps:\n")
o.printSteps(info)
o.printTrafficRouting(info.CanaryStrategy.TrafficRoutings)
} else if info.StrategyType == "BlueGreen" {
fmt.Fprintf(o.Out, tableFormat, " Step:", strconv.Itoa(int(info.CurrentStepIndex))+"/"+strconv.Itoa(len(info.BlueGreenStrategy.Steps)))
fmt.Fprint(o.Out, " Steps:\n")
o.printSteps(info)
o.printTrafficRouting(info.BlueGreenStrategy.TrafficRoutings)
}
if info.TrafficRoutingRef != "" {
o.fetchAndPrintTrafficRoutingRef(info.TrafficRoutingRef)
}
// Print workload info
workloadInfo, err := o.GetResources(info.WorkloadRef)
if err != nil {
fmt.Fprintf(o.Out, "Error getting resources: %v\n", err)
return
}
// Print images
for i, image := range workloadInfo.Images {
if i == 0 {
fmt.Fprintf(o.Out, tableFormat, "Images:", image)
} else {
fmt.Fprintf(o.Out, tableFormat, "", image)
}
}
// Print revisions
fmt.Fprintf(o.Out, tableFormat, "Current Revision:", workloadInfo.CurrentRevision)
fmt.Fprintf(o.Out, tableFormat, "Update Revision:", workloadInfo.UpdateRevision)
// Print replicas
if info.ObservedGeneration == info.Generation {
o.printReplicas(workloadInfo)
}
// Print pods
if len(workloadInfo.Pod) > 0 {
o.printPods(workloadInfo)
}
}
func (o *DescribeRolloutOptions) printSteps(info *RolloutInfo) {
currentStepIndex := int(info.CurrentStepIndex)
Steps := info.CanaryStrategy.Steps
if info.StrategyType == "BlueGreen" {
Steps = info.BlueGreenStrategy.Steps
}
for i, step := range Steps {
isCurrentStep := (i + 1) == currentStepIndex
if isCurrentStep {
fmt.Fprint(o.Out, "\033[32m")
}
if step.Replicas != nil {
fmt.Fprintf(o.Out, tableFormat, " - Replicas: ", step.Replicas)
}
if step.Traffic != nil {
fmt.Fprintf(o.Out, tableFormat, " Traffic: ", *step.Traffic)
}
if len(step.Matches) > 0 {
fmt.Fprintln(o.Out, " Matches: ")
for _, match := range step.Matches {
fmt.Fprintln(o.Out, " - Headers: ")
for _, header := range match.Headers {
fmt.Fprintf(o.Out, tableFormat, " - Name:", header.Name)
fmt.Fprintf(o.Out, tableFormat, " Value:", header.Value)
fmt.Fprintf(o.Out, tableFormat, " Type:", *header.Type)
}
}
}
if isCurrentStep {
fmt.Fprintf(o.Out, tableFormat, " State:", info.CurrentStepState)
fmt.Fprint(o.Out, "\033[0m")
}
}
}
func (o *DescribeRolloutOptions) printReplicas(info *WorkloadInfo) {
fmt.Fprint(o.Out, "Replicas:\n")
fmt.Fprintf(o.Out, tableFormat, " Desired:", info.Replicas.Desired)
fmt.Fprintf(o.Out, tableFormat, " Updated:", info.Replicas.Updated)
fmt.Fprintf(o.Out, tableFormat, " Current:", info.Replicas.Current)
fmt.Fprintf(o.Out, tableFormat, " Ready:", info.Replicas.Ready)
fmt.Fprintf(o.Out, tableFormat, " Available:", info.Replicas.Available)
}
func (o *DescribeRolloutOptions) printPods(info *WorkloadInfo) {
w := tabwriter.NewWriter(o.Out, 0, 0, 2, ' ', 0)
fmt.Fprintln(w, "NAME\tREADY\tBATCH ID\tREVISION\tAGE\tRESTARTS\tSTATUS")
for _, pod := range info.Pod {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s %s\n",
pod.Name,
pod.Ready,
pod.BatchID,
pod.Revision,
pod.Age,
pod.Restarts,
o.colorizeIcon(pod.Status),
pod.Status,
)
}
w.Flush()
}

383
pkg/cmd/exec/exec.go Normal file
View File

@ -0,0 +1,383 @@
/*
Copyright 2021 The Kruise Authors.
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package exec
import (
"context"
"fmt"
"io"
"net/url"
"time"
dockerterm "github.com/moby/term"
"github.com/openkruise/kruise-tools/pkg/cmd/util"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
coreclient "k8s.io/client-go/kubernetes/typed/core/v1"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/remotecommand"
internalpolymorphichelpers "github.com/openkruise/kruise-tools/pkg/internal/polymorphichelpers"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/interrupt"
"k8s.io/kubectl/pkg/util/templates"
"k8s.io/kubectl/pkg/util/term"
)
var (
execExample = templates.Examples(i18n.T(`
# Get output from running 'date' command in working sidecar container from pod mypod
kubectl kruise exec mypod -S sidecar-container -- date
# Switch to raw terminal mode, sends stdin to 'bash' in working sidecar container from pod mypod
# and sends stdout/stderr from 'bash' back to the client
kubectl kruise exec mypod -S sidecar-container -i -t -- bash -il
# Get output from running 'date' command from the first pod of the cloneset myclone, using the first container by default
kubectl kruise exec clone/myclone -- date
# Switch to raw terminal mode, sends stdin to 'bash' in working sidecar container from cloneset myclone
# and sends stdout/stderr from 'bash' back to the client
kubectl kruise exec clone/myclone -S sidecar-container -it -- bash
`))
)
const (
defaultPodExecTimeout = 60 * time.Second
)
func NewCmdExec(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
options := &ExecOptions{
StreamOptions: StreamOptions{
IOStreams: streams,
},
Executor: &DefaultRemoteExecutor{},
}
cmd := &cobra.Command{
Use: "exec (POD | TYPE/NAME) [-c CONTAINER] [-S SIDECARSET_CONTAINER] [flags] -- COMMAND [args...]",
DisableFlagsInUseLine: true,
Short: i18n.T("Execute a command in a container"),
Long: i18n.T("Execute a command in a container."),
Example: execExample,
Run: func(cmd *cobra.Command, args []string) {
argsLenAtDash := cmd.ArgsLenAtDash()
cmdutil.CheckErr(options.Complete(f, cmd, args, argsLenAtDash))
cmdutil.CheckErr(options.Validate())
cmdutil.CheckErr(options.Run())
},
}
cmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodExecTimeout)
cmdutil.AddJsonFilenameFlag(cmd.Flags(), &options.FilenameOptions.Filenames, "to use to exec into the resource")
// TODO support UID
cmd.Flags().StringVarP(&options.ContainerName, "container", "c", options.ContainerName, "Container name. If omitted, the first container in the pod will be chosen")
cmd.Flags().StringVarP(&options.SidecarSetContainer, "sidecar", "S", options.SidecarSetContainer, "SidecarSet container name.When sidecarset is hotUpgrade, the working container will be chosen")
cmd.Flags().BoolVarP(&options.Stdin, "stdin", "i", options.Stdin, "Pass stdin to the container")
cmd.Flags().BoolVarP(&options.TTY, "tty", "t", options.TTY, "Stdin is a TTY")
return cmd
}
// RemoteExecutor defines the interface accepted by the Exec command - provided for test stubbing
type RemoteExecutor interface {
Execute(method string, 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(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error {
exec, err := remotecommand.NewSPDYExecutor(config, method, url)
if err != nil {
return err
}
return exec.Stream(remotecommand.StreamOptions{
Stdin: stdin,
Stdout: stdout,
Stderr: stderr,
Tty: tty,
TerminalSizeQueue: terminalSizeQueue,
})
}
type StreamOptions struct {
Namespace string
PodName string
ContainerName string
SidecarSetContainer string
Stdin bool
TTY bool
// minimize unnecessary output
Quiet bool
// InterruptParent, if set, is used to handle interrupts while attached
InterruptParent *interrupt.Handler
genericclioptions.IOStreams
// for testing
overrideStreams func() (io.ReadCloser, io.Writer, io.Writer)
isTerminalIn func(t term.TTY) bool
}
// ExecOptions declare the arguments accepted by the Exec command
type ExecOptions struct {
StreamOptions
resource.FilenameOptions
ResourceName string
Command []string
EnforceNamespace bool
ParentCommandName string
EnableSuggestedCmdUsage bool
Builder func() *resource.Builder
ExecutablePodFn internalpolymorphichelpers.AttachablePodForObjectFunc
restClientGetter genericclioptions.RESTClientGetter
Pod *corev1.Pod
Executor RemoteExecutor
PodClient coreclient.PodsGetter
GetPodTimeout time.Duration
Config *restclient.Config
}
// Complete verifies command line arguments and loads data from the command environment
func (p *ExecOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, argsIn []string, argsLenAtDash int) error {
if len(argsIn) > 0 && argsLenAtDash != 0 {
p.ResourceName = argsIn[0]
}
if argsLenAtDash > -1 {
p.Command = argsIn[argsLenAtDash:]
} else if len(argsIn) > 1 {
fmt.Fprint(p.ErrOut, "kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.\n")
p.Command = argsIn[1:]
} else if len(argsIn) > 0 && len(p.FilenameOptions.Filenames) != 0 {
fmt.Fprint(p.ErrOut, "kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.\n")
p.Command = argsIn[0:]
p.ResourceName = ""
}
var err error
p.Namespace, p.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
p.ExecutablePodFn = internalpolymorphichelpers.AttachablePodForObjectFn
p.GetPodTimeout, err = cmdutil.GetPodRunningTimeoutFlag(cmd)
if err != nil {
return cmdutil.UsageErrorf(cmd, err.Error())
}
p.Builder = f.NewBuilder
p.restClientGetter = f
cmdParent := cmd.Parent()
if cmdParent != nil {
p.ParentCommandName = cmdParent.CommandPath()
}
if len(p.ParentCommandName) > 0 && cmdutil.IsSiblingCommandExists(cmd, "describe") {
p.EnableSuggestedCmdUsage = true
}
p.Config, err = f.ToRESTConfig()
if err != nil {
return err
}
clientset, err := f.KubernetesClientSet()
if err != nil {
return err
}
p.PodClient = clientset.CoreV1()
return nil
}
// Validate checks that the provided exec options are specified.
func (p *ExecOptions) Validate() error {
if len(p.PodName) == 0 && len(p.ResourceName) == 0 && len(p.FilenameOptions.Filenames) == 0 {
return fmt.Errorf("pod, type/name or --filename must be specified")
}
if len(p.Command) == 0 {
return fmt.Errorf("you must specify at least one command for the container")
}
if p.Out == nil || p.ErrOut == nil {
return fmt.Errorf("both output and error output must be provided")
}
return nil
}
func (o *StreamOptions) SetupTTY() term.TTY {
t := term.TTY{
Parent: o.InterruptParent,
Out: o.Out,
}
if !o.Stdin {
// need to nil out o.In to make sure we don't create a stream for stdin
o.In = nil
o.TTY = false
return t
}
t.In = o.In
if !o.TTY {
return t
}
if o.isTerminalIn == nil {
o.isTerminalIn = func(tty term.TTY) bool {
return tty.IsTerminalIn()
}
}
if !o.isTerminalIn(t) {
o.TTY = false
if o.ErrOut != nil {
fmt.Fprintln(o.ErrOut, "Unable to use a TTY - input is not a terminal or the right kind of file")
}
return t
}
// if we get to here, the user wants to attach stdin, wants a TTY, and o.In is a terminal, so we
// can safely set t.Raw to true
t.Raw = true
if o.overrideStreams == nil {
// use dockerterm.StdStreams() to get the right I/O handles on Windows
o.overrideStreams = dockerterm.StdStreams
}
stdin, stdout, _ := o.overrideStreams()
o.In = stdin
t.In = stdin
if o.Out != nil {
o.Out = stdout
t.Out = stdout
}
return t
}
// Run executes a validated remote execution against a pod.
func (p *ExecOptions) Run() error {
var (
err error
containerName string
)
// we still need legacy pod getter when PodName in ExecOptions struct is provided,
// since there are any other command run this function by providing Podname with PodsGetter
// and without resource builder, eg: `kubectl cp`.
if len(p.PodName) != 0 {
p.Pod, err = p.PodClient.Pods(p.Namespace).Get(context.TODO(), p.PodName, metav1.GetOptions{})
if err != nil {
return err
}
} else {
builder := p.Builder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
FilenameParam(p.EnforceNamespace, &p.FilenameOptions).
NamespaceParam(p.Namespace).DefaultNamespace()
if len(p.ResourceName) > 0 {
builder = builder.ResourceNames("pods", p.ResourceName)
}
obj, err := builder.Do().Object()
if err != nil {
return err
}
p.Pod, err = p.ExecutablePodFn(p.restClientGetter, obj, p.GetPodTimeout)
if err != nil {
return err
}
}
pod := p.Pod
if pod.Status.Phase == corev1.PodSucceeded || pod.Status.Phase == corev1.PodFailed {
return fmt.Errorf("cannot exec into a container in a completed pod; current phase is %s", pod.Status.Phase)
}
hotUpgradeContainerInfos := util.GetPodHotUpgradeInfoInAnnotations(pod)
if workingContainer, ok := hotUpgradeContainerInfos[p.SidecarSetContainer]; ok {
containerName = workingContainer
fmt.Fprintf(p.ErrOut, "Enter working container %s of SidecarSet.\n", containerName)
} else {
containerName = p.ContainerName
}
if len(containerName) == 0 {
if len(pod.Spec.Containers) > 1 {
fmt.Fprintf(p.ErrOut, "Defaulting container name to %s.\n", pod.Spec.Containers[0].Name)
if p.EnableSuggestedCmdUsage {
fmt.Fprintf(p.ErrOut, "Use '%s describe pod/%s -n %s' to see all of the containers in this pod.\n", p.ParentCommandName, pod.Name, p.Namespace)
}
}
containerName = pod.Spec.Containers[0].Name
}
// ensure we can recover the terminal while attached
t := p.SetupTTY()
var sizeQueue remotecommand.TerminalSizeQueue
if t.Raw {
// this call spawns a goroutine to monitor/update the terminal size
sizeQueue = t.MonitorSize(t.GetSize())
// unset p.Err if it was previously set because both stdout and stderr go over p.Out when tty is
// true
p.ErrOut = nil
}
fn := func() error {
restClient, err := restclient.RESTClientFor(p.Config)
if err != nil {
return err
}
// TODO: consider abstracting into a client invocation or client helper
req := restClient.Post().
Resource("pods").
Name(pod.Name).
Namespace(pod.Namespace).
SubResource("exec")
req.VersionedParams(&corev1.PodExecOptions{
Container: containerName,
Command: p.Command,
Stdin: p.Stdin,
Stdout: p.Out != nil,
Stderr: p.ErrOut != nil,
TTY: t.Raw,
}, scheme.ParameterCodec)
return p.Executor.Execute("POST", req.URL(), p.Config, p.In, p.Out, p.ErrOut, t.Raw, sizeQueue)
}
if err := t.Safe(fn); err != nil {
return err
}
return nil
}

526
pkg/cmd/exec/exec_test.go Normal file
View File

@ -0,0 +1,526 @@
/*
Copyright 2021 The Kruise Authors.
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package exec
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"reflect"
"strings"
"testing"
"github.com/openkruise/kruise-tools/pkg/cmd/util"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/client-go/tools/remotecommand"
cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/term"
)
type fakeRemoteExecutor struct {
method string
url *url.URL
execErr error
}
func (f *fakeRemoteExecutor) Execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error {
f.method = method
f.url = url
return f.execErr
}
func TestPodAndContainer(t *testing.T) {
tests := []struct {
args []string
argsLenAtDash int
p *ExecOptions
name string
expectError bool
expectedPod string
expectedContainer string
expectedArgs []string
obj *corev1.Pod
}{
{
p: &ExecOptions{},
argsLenAtDash: -1,
expectError: true,
name: "empty",
},
{
p: &ExecOptions{},
argsLenAtDash: -1,
expectError: true,
name: "no cmd",
obj: execPod(),
},
{
p: &ExecOptions{StreamOptions: StreamOptions{ContainerName: "bar"}},
argsLenAtDash: -1,
expectError: true,
name: "no cmd, w/ container",
obj: execPod(),
},
{
p: &ExecOptions{},
args: []string{"foo", "cmd"},
argsLenAtDash: 0,
expectError: true,
name: "no pod, pod name is behind dash",
obj: execPod(),
},
{
p: &ExecOptions{},
args: []string{"foo"},
argsLenAtDash: -1,
expectError: true,
name: "no cmd, w/o flags",
obj: execPod(),
},
{
p: &ExecOptions{},
args: []string{"foo", "cmd"},
argsLenAtDash: 1,
expectedPod: "foo",
expectedArgs: []string{"cmd"},
name: "cmd, w/o flags",
obj: execPod(),
},
{
p: &ExecOptions{},
args: []string{"foo", "cmd"},
argsLenAtDash: -1,
expectedPod: "foo",
expectedArgs: []string{"cmd"},
name: "cmd, cmd is behind dash",
obj: execPod(),
},
{
p: &ExecOptions{StreamOptions: StreamOptions{ContainerName: "bar"}},
args: []string{"foo", "cmd"},
argsLenAtDash: -1,
expectedPod: "foo",
expectedContainer: "bar",
expectedArgs: []string{"cmd"},
name: "cmd, container in flag",
obj: execPod(),
},
{
p: &ExecOptions{StreamOptions: StreamOptions{SidecarSetContainer: "sidecar"}},
args: []string{"foo", "cmd"},
argsLenAtDash: -1,
expectedPod: "foo",
expectedContainer: "sidecar-1",
expectedArgs: []string{"cmd"},
name: "cmd, working container in flag",
obj: execPod(),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var err error
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
ns := scheme.Codecs.WithoutConversion()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
}
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
cmd := NewCmdExec(tf, genericclioptions.NewTestIOStreamsDiscard())
options := test.p
if test.obj != nil {
if containerName, ok := util.GetPodHotUpgradeInfoInAnnotations(test.obj)[options.SidecarSetContainer]; ok {
options.ContainerName = containerName
}
}
options.ErrOut = bytes.NewBuffer([]byte{})
options.Out = bytes.NewBuffer([]byte{})
err = options.Complete(tf, cmd, test.args, test.argsLenAtDash)
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
err = options.Validate()
if test.expectError && err == nil {
t.Errorf("%s: unexpected non-error", test.name)
}
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
if err != nil {
return
}
pod, _ := options.ExecutablePodFn(tf, test.obj, defaultPodExecTimeout)
if pod.Name != test.expectedPod {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName)
}
if options.ContainerName != test.expectedContainer {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName)
}
if !reflect.DeepEqual(test.expectedArgs, options.Command) {
t.Errorf("%s: expected: %v, got %v", test.name, test.expectedArgs, options.Command)
}
})
}
}
func TestExecWorkingContainer(t *testing.T) {
version := "v1"
tests := []struct {
name, version, podPath, fetchPodPath, execPath string
pod *corev1.Pod
execErr bool
}{
{
name: "pod exec",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo",
fetchPodPath: "/namespaces/test/pods/foo",
execPath: "/api/" + version + "/namespaces/test/pods/foo/exec",
pod: execPod(),
},
{
name: "pod exec error",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo",
fetchPodPath: "/namespaces/test/pods/foo",
execPath: "/api/" + version + "/namespaces/test/pods/foo/exec",
pod: execPod(),
execErr: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
ns := scheme.Codecs.WithoutConversion()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: scheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
ex := &fakeRemoteExecutor{}
if test.execErr {
ex.execErr = fmt.Errorf("exec error")
}
params := &ExecOptions{
StreamOptions: StreamOptions{
PodName: "foo",
SidecarSetContainer: "sidecar",
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
},
Executor: ex,
}
cmd := NewCmdExec(tf, genericclioptions.NewTestIOStreamsDiscard())
args := []string{"pod/foo", "command"}
if err := params.Complete(tf, cmd, args, -1); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.execErr && err != ex.execErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
return
}
if !test.execErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
return
}
if test.execErr {
return
}
if ex.url.Path != test.execPath {
t.Errorf("%s: Did not get expected path for exec request", test.name)
return
}
if strings.Count(ex.url.RawQuery, "container=sidecar-1") != 1 {
t.Errorf("%s: Did not get expected container query param for exec request", test.name)
t.Errorf("query param: %s", ex.url.RawQuery)
return
}
if ex.method != "POST" {
t.Errorf("%s: Did not get method for exec request: %s", test.name, ex.method)
}
})
}
}
func TestExec(t *testing.T) {
version := "v1"
tests := []struct {
name, version, podPath, fetchPodPath, execPath string
pod *corev1.Pod
execErr bool
}{
{
name: "pod exec",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo",
fetchPodPath: "/namespaces/test/pods/foo",
execPath: "/api/" + version + "/namespaces/test/pods/foo/exec",
pod: execPod(),
},
{
name: "pod exec error",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo",
fetchPodPath: "/namespaces/test/pods/foo",
execPath: "/api/" + version + "/namespaces/test/pods/foo/exec",
pod: execPod(),
execErr: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
ns := scheme.Codecs.WithoutConversion()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: scheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
ex := &fakeRemoteExecutor{}
if test.execErr {
ex.execErr = fmt.Errorf("exec error")
}
params := &ExecOptions{
StreamOptions: StreamOptions{
PodName: "foo",
ContainerName: "bar",
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
},
Executor: ex,
}
cmd := NewCmdExec(tf, genericclioptions.NewTestIOStreamsDiscard())
args := []string{"pod/foo", "command"}
if err := params.Complete(tf, cmd, args, -1); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.execErr && err != ex.execErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
return
}
if !test.execErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
return
}
if test.execErr {
return
}
if ex.url.Path != test.execPath {
t.Errorf("%s: Did not get expected path for exec request", test.name)
return
}
if strings.Count(ex.url.RawQuery, "container=bar") != 1 {
t.Errorf("%s: Did not get expected container query param for exec request", test.name)
return
}
if ex.method != "POST" {
t.Errorf("%s: Did not get method for exec request: %s", test.name, ex.method)
}
})
}
}
func execPod() *corev1.Pod {
return &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10", Annotations: map[string]string{util.SidecarSetWorkingHotUpgradeContainer: "{\"sidecar\":\"sidecar-1\"}"}},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyAlways,
DNSPolicy: corev1.DNSClusterFirst,
Containers: []corev1.Container{
{
Name: "bar",
},
{
Name: "sidecar-1",
},
},
},
Status: corev1.PodStatus{
Phase: corev1.PodRunning,
},
}
}
func TestSetupTTY(t *testing.T) {
streams, _, _, stderr := genericclioptions.NewTestIOStreams()
// test 1 - don't attach stdin
o := &StreamOptions{
// InterruptParent: ,
Stdin: false,
IOStreams: streams,
TTY: true,
}
tty := o.SetupTTY()
if o.In != nil {
t.Errorf("don't attach stdin: o.In should be nil")
}
if tty.In != nil {
t.Errorf("don't attach stdin: tty.In should be nil")
}
if o.TTY {
t.Errorf("don't attach stdin: o.TTY should be false")
}
if tty.Raw {
t.Errorf("don't attach stdin: tty.Raw should be false")
}
if len(stderr.String()) > 0 {
t.Errorf("don't attach stdin: stderr wasn't empty: %s", stderr.String())
}
// tests from here on attach stdin
// test 2 - don't request a TTY
o.Stdin = true
o.In = &bytes.Buffer{}
o.TTY = false
tty = o.SetupTTY()
if o.In == nil {
t.Errorf("attach stdin, no TTY: o.In should not be nil")
}
if tty.In != o.In {
t.Errorf("attach stdin, no TTY: tty.In should equal o.In")
}
if o.TTY {
t.Errorf("attach stdin, no TTY: o.TTY should be false")
}
if tty.Raw {
t.Errorf("attach stdin, no TTY: tty.Raw should be false")
}
if len(stderr.String()) > 0 {
t.Errorf("attach stdin, no TTY: stderr wasn't empty: %s", stderr.String())
}
// test 3 - request a TTY, but stdin is not a terminal
o.Stdin = true
o.In = &bytes.Buffer{}
o.ErrOut = stderr
o.TTY = true
tty = o.SetupTTY()
if o.In == nil {
t.Errorf("attach stdin, TTY, not a terminal: o.In should not be nil")
}
if tty.In != o.In {
t.Errorf("attach stdin, TTY, not a terminal: tty.In should equal o.In")
}
if o.TTY {
t.Errorf("attach stdin, TTY, not a terminal: o.TTY should be false")
}
if tty.Raw {
t.Errorf("attach stdin, TTY, not a terminal: tty.Raw should be false")
}
if !strings.Contains(stderr.String(), "input is not a terminal") {
t.Errorf("attach stdin, TTY, not a terminal: expected 'input is not a terminal' to stderr")
}
// test 4 - request a TTY, stdin is a terminal
o.Stdin = true
o.In = &bytes.Buffer{}
stderr.Reset()
o.TTY = true
overrideStdin := ioutil.NopCloser(&bytes.Buffer{})
overrideStdout := &bytes.Buffer{}
overrideStderr := &bytes.Buffer{}
o.overrideStreams = func() (io.ReadCloser, io.Writer, io.Writer) {
return overrideStdin, overrideStdout, overrideStderr
}
o.isTerminalIn = func(tty term.TTY) bool {
return true
}
tty = o.SetupTTY()
if o.In != overrideStdin {
t.Errorf("attach stdin, TTY, is a terminal: o.In should equal overrideStdin")
}
if tty.In != o.In {
t.Errorf("attach stdin, TTY, is a terminal: tty.In should equal o.In")
}
if !o.TTY {
t.Errorf("attach stdin, TTY, is a terminal: o.TTY should be true")
}
if !tty.Raw {
t.Errorf("attach stdin, TTY, is a terminal: tty.Raw should be true")
}
if len(stderr.String()) > 0 {
t.Errorf("attach stdin, TTY, is a terminal: stderr wasn't empty: %s", stderr.String())
}
if o.Out != overrideStdout {
t.Errorf("attach stdin, TTY, is a terminal: o.Out should equal overrideStdout")
}
if tty.Out != o.Out {
t.Errorf("attach stdin, TTY, is a terminal: tty.Out should equal o.Out")
}
}

View File

@ -92,7 +92,6 @@ type ExposeServiceOptions struct {
PrintObj printers.ResourcePrinterFunc
DryRunStrategy cmdutil.DryRunStrategy
DryRunVerifier *resource.DryRunVerifier
EnforceNamespace bool
fieldManager string
@ -178,15 +177,6 @@ func (o *ExposeServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) e
if err != nil {
return err
}
dynamicClient, err := f.DynamicClient()
if err != nil {
return err
}
discoveryClient, err := f.ToDiscoveryClient()
if err != nil {
return err
}
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
printer, err := o.PrintFlags.ToPrinter()
@ -360,11 +350,6 @@ func (o *ExposeServiceOptions) RunExpose(cmd *cobra.Command, args []string) erro
if err != nil {
return err
}
if o.DryRunStrategy == cmdutil.DryRunServer {
if err := o.DryRunVerifier.HasSupport(objMapping.GroupVersionKind); err != nil {
return err
}
}
// Serialize the object with the annotation applied.
client, err := o.ClientForMapping(objMapping)
if err != nil {

106
pkg/cmd/generate-docs.go Normal file
View File

@ -0,0 +1,106 @@
/*
Copyright 2021 The Kruise Authors.
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
"k8s.io/cli-runtime/pkg/genericclioptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
)
var (
defaultDocDir = "docs"
yamlDir = "yaml"
)
func NewCmdGenerateDocs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{
Use: "generate-docs",
Short: "Generate documentation for kruise",
Long: "Generate documentation for kruise",
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(generateDocs(cmd))
},
Hidden: true,
}
cmd.Flags().String("directory", "", "The directory to write the generated docs to")
return cmd
}
func generateDocs(cmd *cobra.Command) error {
directory, err := cmd.Flags().GetString("directory")
if err != nil {
return err
}
if directory == "" {
directory = defaultDocDir
}
// Remove the commands from the root command tree
removeCmds(cmd.Root(), []string{"exec", "apply", "wait", "diff", "options", "help", "api-resources", "api-versions", "patch", "plugin", "scale", "replace", "options", "kustomize", "version", "config", "completion"})
err = os.MkdirAll(directory, os.ModePerm)
if err != nil {
return err
}
err = os.MkdirAll(filepath.Join(directory, yamlDir), os.ModePerm)
if err != nil {
return err
}
err = doc.GenMarkdownTree(cmd.Root(), directory)
if err != nil {
return err
}
err = doc.GenYamlTree(cmd.Root(), filepath.Join(directory, yamlDir))
if err != nil {
return err
}
fmt.Println("documentation generated successfully")
return nil
}
func removeCmds(rootCmd *cobra.Command, cmdsToRemove []string) {
// Keep track of command names to detect duplicates
encountered := make(map[string]bool)
for _, cmdName := range cmdsToRemove {
for _, cmd := range rootCmd.Commands() {
if cmd.Name() == cmdName {
rootCmd.RemoveCommand(cmd)
}
}
}
// Remove duplicates
var uniqueCmds []*cobra.Command
for _, cmd := range rootCmd.Commands() {
if encountered[cmd.Name()] {
continue
}
encountered[cmd.Name()] = true
uniqueCmds = append(uniqueCmds, cmd)
}
rootCmd.ResetCommands()
rootCmd.AddCommand(uniqueCmds...)
}

421
pkg/cmd/get/get.go Normal file
View File

@ -0,0 +1,421 @@
/*
Copyright 2025 The Kruise Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 get
import (
"fmt"
"time"
kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
kruiseappsv1beta1 "github.com/openkruise/kruise-api/apps/v1beta1"
kruisepolicyv1alpha1 "github.com/openkruise/kruise-api/policy/v1alpha1"
rolloutv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1"
rolloutv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
internalpolymorphichelpers "github.com/openkruise/kruise-tools/pkg/internal/polymorphichelpers"
"github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)
var (
getLong = templates.Examples(i18n.T(`
Display one or many resources related to kruise.`))
getExample = templates.Examples(i18n.T(`
# List all resources in the default namespace
kubectl-kruise get all
# List all resources in the specific namespace
kubectl-kruise get all -n namespace
# Watch all resources in the default namespace
kubectl-kruise get all -w`))
)
type GetOptions struct {
genericclioptions.IOStreams
Builder func() *resource.Builder
Resources []string
Namespace string
EnforceNamespace bool
GetViewerFn internalpolymorphichelpers.GetViewerFunc
}
func NewCmdGet(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := &GetOptions{IOStreams: streams}
cmd := &cobra.Command{
Use: "get all",
DisableFlagsInUseLine: true,
Short: i18n.T("Display one or many resources"),
Long: getLong,
Example: getExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, args))
cmdutil.CheckErr(o.Run())
},
}
cmd.Flags().StringVarP(&o.Namespace, "namespace", "n", o.Namespace, "If present, the namespace scope for this CLI request")
return cmd
}
func (o *GetOptions) Complete(f cmdutil.Factory, args []string) error {
var err error
if len(args) == 0 {
return fmt.Errorf("required resource not specified")
}
o.Resources = args
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
o.GetViewerFn = internalpolymorphichelpers.GetViewerFn
o.Builder = f.NewBuilder
return nil
}
func (o *GetOptions) Run() error {
if len(o.Resources) == 0 {
return fmt.Errorf("you must specify the type of resource to get")
}
if o.Resources[0] == "all" {
resourceTypes := []string{
"clonesets.apps.kruise.io",
"statefulsets.apps.kruise.io",
"daemonsets.apps.kruise.io",
"rollouts.rollouts.kruise.io",
"broadcastjobs.apps.kruise.io",
"containerrecreaterequests.apps.kruise.io",
"advancedcronjobs.apps.kruise.io",
"resourcedistributions.apps.kruise.io",
"uniteddeployments.apps.kruise.io",
"sidecarsets.apps.kruise.io",
"podprobemarkers.apps.kruise.io",
"imagepulljobs.apps.kruise.io",
"podunavailablebudgets.policy.kruise.io",
}
for _, resourceType := range resourceTypes {
b := o.Builder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
ResourceTypeOrNameArgs(true, resourceType).
ContinueOnError().
Latest().
Flatten()
if resourceType == "sidecarsets.apps.kruise.io" {
b = b.AllNamespaces(true)
}
infos, err := b.Do().Infos()
if err != nil {
return err
}
if len(infos) > 0 {
// Print resource type header and table header only if there are resources
fmt.Fprintf(o.Out, "\n%s:\n", resourceType)
switch resourceType {
case "clonesets.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-14s\t%-18s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "UPDATED", "UPDATED_READY", "UPDATED_AVAILABLE", "READY", "TOTAL", "AGE")
case "statefulsets.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "CURRENT", "UPDATED", "READY", "AGE")
case "daemonsets.apps.kruise.io":
fmt.Fprintf(o.Out, "%-8s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "CURRENT", "READY", "UP-TO-DATE", "AVAILABLE", "NODE SELECTOR", "AGE")
case "rollouts.rollouts.kruise.io":
fmt.Fprintf(o.Out, "%-20s\t%-8s\t%-12s\t%-12s\t%-40s\t%-s\n",
"NAME", "STATUS", "CANARY_STEP", "CANARY_STATE", "MESSAGE", "AGE")
case "broadcastjobs.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "ACTIVE", "SUCCEEDED", "FAILED", "AGE")
case "containerrecreaterequests.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "PHASE", "COMPLETED", "FAILED", "AGE")
case "advancedcronjobs.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "SCHEDULE", "SUSPEND", "ACTIVE", "LAST SCHEDULE", "AGE")
case "resourcedistributions.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "TARGETS", "SUCCEEDED", "FAILED", "AGE")
case "uniteddeployments.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "UPDATED", "READY", "AVAILABLE", "AGE")
case "sidecarsets.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "MATCHED", "UPDATED", "READY", "INJECTED", "AGE")
case "podprobemarkers.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-s\n",
"NAME", "TARGETS", "PROBES", "AGE")
case "imagepulljobs.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "PHASE", "COMPLETED", "FAILED", "TOTAL", "AGE")
case "podunavailablebudgets.policy.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "MAXUNAVAILABLE", "UNAVAILABLE", "DISRUPTIONS", "TARGETS", "AGE")
}
for _, info := range infos {
if err := o.printResourceInfo(info.Object, resourceType); err != nil {
return err
}
}
}
}
return nil
}
// Handle single resource type
b := o.Builder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
ResourceTypeOrNameArgs(true, o.Resources...).
ContinueOnError().
Latest().
Flatten()
infos, err := b.Do().Infos()
if err != nil {
return err
}
if len(infos) > 0 {
switch o.Resources[0] {
case "clonesets.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-14s\t%-18s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "UPDATED", "UPDATED_READY", "UPDATED_AVAILABLE", "READY", "TOTAL", "AGE")
case "statefulsets.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "CURRENT", "UPDATED", "READY", "AGE")
case "daemonsets.apps.kruise.io":
fmt.Fprintf(o.Out, "%-8s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "CURRENT", "READY", "UP-TO-DATE", "AVAILABLE", "NODE SELECTOR", "AGE")
case "rollouts.rollouts.kruise.io":
fmt.Fprintf(o.Out, "%-20s\t%-8s\t%-12s\t%-12s\t%-40s\t%-s\n",
"NAME", "STATUS", "CANARY_STEP", "CANARY_STATE", "MESSAGE", "AGE")
case "broadcastjobs.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "ACTIVE", "SUCCEEDED", "FAILED", "AGE")
case "containerrecreaterequests.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "PHASE", "COMPLETED", "FAILED", "AGE")
case "advancedcronjobs.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "SCHEDULE", "SUSPEND", "ACTIVE", "LAST SCHEDULE", "AGE")
case "resourcedistributions.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "TARGETS", "SUCCEEDED", "FAILED", "AGE")
case "uniteddeployments.apps.kruise.io":
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-8s\t%-s\n",
"NAME", "DESIRED", "UPDATED", "READY", "AVAILABLE", "AGE")
}
for _, info := range infos {
if err := o.printResourceInfo(info.Object, o.Resources[0]); err != nil {
return err
}
}
}
return nil
}
func (o *GetOptions) printResourceInfo(obj runtime.Object, resourceType string) error {
metaObj, ok := obj.(v1.Object)
if !ok {
return fmt.Errorf("object does not implement v1.Object interface")
}
name := metaObj.GetName()
age := time.Since(metaObj.GetCreationTimestamp().Time).Round(time.Second)
// Print based on resource type
switch resourceType {
case "clonesets.apps.kruise.io":
cloneset, ok := obj.(*kruiseappsv1alpha1.CloneSet)
if !ok {
return fmt.Errorf("object is not a CloneSet")
}
desired := cloneset.Spec.Replicas
updated := cloneset.Status.UpdatedReplicas
updatedReady := cloneset.Status.UpdatedReadyReplicas
updatedAvailable := cloneset.Status.UpdatedAvailableReplicas
ready := cloneset.Status.ReadyReplicas
total := cloneset.Status.Replicas
fmt.Fprintf(o.Out, "%-12s\t%-8d\t%-8d\t%-14d\t%-18d\t%-8d\t%-8d\t%-s\n",
name, *desired, updated, updatedReady, updatedAvailable, ready, total, age)
case "statefulsets.apps.kruise.io":
statefulset, ok := obj.(*kruiseappsv1beta1.StatefulSet)
if !ok {
return fmt.Errorf("object is not a StatefulSet")
}
desired := statefulset.Spec.Replicas
current := statefulset.Status.CurrentReplicas
updated := statefulset.Status.UpdatedReplicas
ready := statefulset.Status.ReadyReplicas
fmt.Fprintf(o.Out, "%-12s\t%-8d\t%-8d\t%-8d\t%-8d\t%-s\n",
name, *desired, current, updated, ready, age)
case "daemonsets.apps.kruise.io":
daemonset, ok := obj.(*kruiseappsv1alpha1.DaemonSet)
if !ok {
return fmt.Errorf("object is not a DaemonSet")
}
desired := daemonset.Status.DesiredNumberScheduled
current := daemonset.Status.CurrentNumberScheduled
ready := daemonset.Status.NumberReady
updated := daemonset.Status.UpdatedNumberScheduled
available := daemonset.Status.NumberAvailable
nodeSelector := daemonset.Spec.Template.Spec.NodeSelector
fmt.Fprintf(o.Out, "%-8s\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\t%-8s\t%-s\n",
name, desired, current, ready, updated, available, fmt.Sprintf("%v", nodeSelector), age)
case "rollouts.rollouts.kruise.io":
rollout, ok := obj.(*rolloutv1beta1.Rollout)
if !ok {
rolloutV1alpha1, ok := obj.(*rolloutv1alpha1.Rollout)
if !ok {
return fmt.Errorf("object is not a Rollout")
}
status := rolloutV1alpha1.Status.Phase
canaryStep := int32(0)
canaryState := string(rolloutv1alpha1.CanaryStepStateCompleted)
message := rolloutV1alpha1.Status.Message
if rolloutV1alpha1.Status.CanaryStatus != nil {
canaryStep = rolloutV1alpha1.Status.CanaryStatus.CurrentStepIndex
canaryState = string(rolloutV1alpha1.Status.CanaryStatus.CurrentStepState)
}
fmt.Fprintf(o.Out, "%-20s\t%-8s\t%-12d\t%-12s\t%-40s\t%-s\n",
name, status, canaryStep, canaryState, message, age)
return nil
}
status := rollout.Status.Phase
canaryStep := int32(0)
canaryState := string(rolloutv1beta1.CanaryStepStateCompleted)
message := rollout.Status.Message
if rollout.Status.CanaryStatus != nil {
canaryStep = rollout.Status.CanaryStatus.CurrentStepIndex
canaryState = string(rollout.Status.CanaryStatus.CurrentStepState)
}
fmt.Fprintf(o.Out, "%-20s\t%-8s\t%-12d\t%-12s\t%-40s\t%-s\n",
name, status, canaryStep, canaryState, message, age)
case "broadcastjobs.apps.kruise.io":
broadcastjob, ok := obj.(*kruiseappsv1alpha1.BroadcastJob)
if !ok {
return fmt.Errorf("object is not a BroadcastJob")
}
desired := broadcastjob.Spec.Parallelism
active := broadcastjob.Status.Active
successful := broadcastjob.Status.Succeeded
failed := broadcastjob.Status.Failed
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8d\t%-8d\t%-8d\t%-s\n",
name, desired.String(), active, successful, failed, age)
case "containerrecreaterequests.apps.kruise.io":
containerrecreaterequest, ok := obj.(*kruiseappsv1alpha1.ContainerRecreateRequest)
if !ok {
return fmt.Errorf("object is not a ContainerRecreateRequest")
}
phase := containerrecreaterequest.Status.Phase
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-s\n",
name, phase, "-", "-", age)
case "advancedcronjobs.apps.kruise.io":
advancedcronjob, ok := obj.(*kruiseappsv1alpha1.AdvancedCronJob)
if !ok {
return fmt.Errorf("object is not a AdvancedCronJob")
}
schedule := advancedcronjob.Spec.Schedule
suspend := advancedcronjob.Spec.Paused
active := len(advancedcronjob.Status.Active)
lastSchedule := advancedcronjob.Status.LastScheduleTime
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8v\t%-8d\t%-8s\t%-s\n",
name, schedule, suspend, active, lastSchedule, age)
case "resourcedistributions.apps.kruise.io":
_, ok := obj.(*kruiseappsv1alpha1.ResourceDistribution)
if !ok {
return fmt.Errorf("object is not a ResourceDistribution")
}
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8s\t%-8s\t%-s\n",
name, "-", "-", "-", age)
case "uniteddeployments.apps.kruise.io":
uniteddeployment, ok := obj.(*kruiseappsv1alpha1.UnitedDeployment)
if !ok {
return fmt.Errorf("object is not a UnitedDeployment")
}
desired := uniteddeployment.Spec.Replicas
updated := uniteddeployment.Status.UpdatedReplicas
ready := uniteddeployment.Status.ReadyReplicas
total := uniteddeployment.Status.Replicas
fmt.Fprintf(o.Out, "%-12s\t%-8d\t%-8d\t%-8d\t%-8d\t%-s\n",
name, *desired, updated, ready, total, age)
case "sidecarsets.apps.kruise.io":
sidecarset, ok := obj.(*kruiseappsv1alpha1.SidecarSet)
if !ok {
return fmt.Errorf("object is not a SidecarSet")
}
matched := sidecarset.Status.MatchedPods
updated := sidecarset.Status.UpdatedPods
ready := sidecarset.Status.ReadyPods
fmt.Fprintf(o.Out, "%-12s\t%-8d\t%-8d\t%-8d\t%-8s\t%-s\n",
name, matched, updated, ready, "-", age)
case "podprobemarkers.apps.kruise.io":
podprobemarker, ok := obj.(*kruiseappsv1alpha1.PodProbeMarker)
if !ok {
return fmt.Errorf("object is not a PodProbeMarker")
}
targets := len(podprobemarker.Spec.Selector.MatchLabels)
probes := len(podprobemarker.Spec.Probes)
fmt.Fprintf(o.Out, "%-12s\t%-8d\t%-8d\t%-s\n",
name, targets, probes, age)
case "imagepulljobs.apps.kruise.io":
imagepulljob, ok := obj.(*kruiseappsv1alpha1.ImagePullJob)
if !ok {
return fmt.Errorf("object is not a ImagePullJob")
}
completed := imagepulljob.Status.Succeeded
failed := imagepulljob.Status.Failed
total := imagepulljob.Status.Desired
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8d\t%-8d\t%-8d\t%-s\n",
name, "-", completed, failed, total, age)
case "podunavailablebudgets.policy.kruise.io":
pub, ok := obj.(*kruisepolicyv1alpha1.PodUnavailableBudget)
if !ok {
return fmt.Errorf("object is not a PodUnavailableBudget")
}
maxUnavailable := pub.Spec.MaxUnavailable
unavailable := pub.Status.UnavailablePods
disruptions := pub.Status.DisruptedPods
targets := len(pub.Spec.Selector.MatchLabels)
fmt.Fprintf(o.Out, "%-12s\t%-8s\t%-8d\t%-8d\t%-8d\t%-s\n",
name, maxUnavailable.String(), len(unavailable), len(disruptions), targets, age)
}
return nil
}

View File

@ -45,6 +45,9 @@ var (
* daemonsets
* statefulsets
* clonesets
* statefulsets.apps.kruise.io
* daemonsets.apps.kruise.io
* rollouts.rollouts.kruise.io
`)
)
@ -65,6 +68,7 @@ func NewCmdRollout(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobr
cmd.AddCommand(NewCmdRolloutUndo(f, streams))
cmd.AddCommand(NewCmdRolloutStatus(f, streams))
cmd.AddCommand(NewCmdRolloutRestart(f, streams))
cmd.AddCommand(NewCmdRolloutApprove(f, streams))
return cmd
}

View File

@ -0,0 +1,198 @@
/*
Copyright 2021 The Kruise Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 rollout
import (
"fmt"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/kubectl/pkg/cmd/set"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
internalapi "github.com/openkruise/kruise-tools/pkg/api"
"github.com/openkruise/kruise-tools/pkg/cmd/util"
internalpolymorphichelpers "github.com/openkruise/kruise-tools/pkg/internal/polymorphichelpers"
)
// ApproveOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
// referencing the cmd.Flags()
type ApproveOptions struct {
PrintFlags *genericclioptions.PrintFlags
ToPrinter func(string) (printers.ResourcePrinter, error)
Resources []string
Builder func() *resource.Builder
Approver internalpolymorphichelpers.ObjectApproverFunc
Namespace string
EnforceNamespace bool
resource.FilenameOptions
genericclioptions.IOStreams
}
var (
ApproveLong = templates.LongDesc(`
Approve a resource which can be continued.
Paused resources will not be reconciled by a controller. By approving a
resource, we allow it to be continue to rollout.
Currently only kruise-rollouts support being approved.`)
ApproveExample = templates.Examples(`
# approve a kruise rollout resource named "rollout-demo" in "ns-demo" namespace
kubectl-kruise rollout approve rollout/rollout-demo -n ns-demo`)
)
// NewRolloutApproveOptions returns an initialized ApproveOptions instance
func NewRolloutApproveOptions(streams genericclioptions.IOStreams) *ApproveOptions {
return &ApproveOptions{
PrintFlags: genericclioptions.NewPrintFlags("approved").WithTypeSetter(internalapi.GetScheme()),
IOStreams: streams,
}
}
// NewCmdRolloutApprove returns a Command instance for 'rollout approve' sub command
func NewCmdRolloutApprove(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutApproveOptions(streams)
cmd := &cobra.Command{
Use: "approve RESOURCE",
DisableFlagsInUseLine: true,
Short: i18n.T("Approve a resource"),
Long: ApproveLong,
Example: ApproveExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.RunApprove())
},
}
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
o.PrintFlags.AddFlags(cmd)
return cmd
}
// Complete completes all the required options
func (o *ApproveOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Resources = args
o.Approver = internalpolymorphichelpers.ObjectApproverFn
var err error
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) {
o.PrintFlags.NamePrintFlags.Operation = operation
return o.PrintFlags.ToPrinter()
}
o.Builder = f.NewBuilder
return nil
}
func (o *ApproveOptions) Validate() error {
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
return fmt.Errorf("required resource not specified")
}
return nil
}
// RunApprove performs the execution of 'rollout approve' sub command
func (o *ApproveOptions) RunApprove() error {
r := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
ResourceTypeOrNameArgs(true, o.Resources...).
ContinueOnError().
Latest().
Flatten().
Do()
if err := r.Err(); err != nil {
return err
}
allErrs := []error{}
infos, err := r.Infos()
if err != nil {
// restore previous command behavior where
// an error caused by retrieving infos due to
// at least a single broken object did not result
// in an immediate return, but rather an overall
// aggregation of errors.
allErrs = append(allErrs, err)
}
for _, patch := range set.CalculatePatches(infos, scheme.DefaultJSONEncoder(), set.PatchFn(o.Approver)) {
info := patch.Info
if patch.Err != nil {
resourceString := info.Mapping.Resource.Resource
if len(info.Mapping.Resource.Group) > 0 {
resourceString = resourceString + "." + info.Mapping.Resource.Group
}
allErrs = append(allErrs, fmt.Errorf("error: %s %q %v", resourceString, info.Name, patch.Err))
continue
}
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
printer, err := o.ToPrinter("already approved")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(info.Object, o.Out); err != nil {
allErrs = append(allErrs, err)
}
continue
}
obj, err := util.PatchSubResource(info.Client, info.Mapping.Resource.Resource, "status", info.Namespace, info.Name, info.Namespaced(), types.MergePatchType, patch.Patch, nil)
if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch: %v", err))
continue
}
info.Refresh(obj, true)
printer, err := o.ToPrinter("approved")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(info.Object, o.Out); err != nil {
allErrs = append(allErrs, err)
}
}
return utilerrors.NewAggregate(allErrs)
}

View File

@ -57,12 +57,13 @@ var (
Paused resources will not be reconciled by a controller.
Use "kubectl rollout resume" to resume a paused resource.
Currently deployments, clonesets support being paused.`)
Currently deployments, clonesets, rollouts support being paused.`)
pauseExample = templates.Examples(`
# Mark the nginx deployment as paused. Any current state of
# the deployment will continue its function, new updates to the deployment will not
# have an effect as long as the deployment is paused.
kubectl-kruise rollout pause deployment/nginx`)
)
@ -73,7 +74,7 @@ func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams)
IOStreams: streams,
}
validArgs := []string{"deployment", "cloneset"}
validArgs := []string{"deployment", "cloneset", "rollout"}
cmd := &cobra.Command{
Use: "pause RESOURCE",

View File

@ -65,7 +65,10 @@ var (
kubectl-kruise rollout restart cloneset/abc
# Restart a daemonset
kubectl-kruise rollout restart daemonset/abc`)
kubectl-kruise rollout restart daemonset/abc
# Restart a UnitedDeployment
kubectl-kruise rollout restart uniteddeployment/my-app`)
)
// NewRolloutRestartOptions returns an initialized RestartOptions instance
@ -80,7 +83,7 @@ func NewRolloutRestartOptions(streams genericclioptions.IOStreams) *RestartOptio
func NewCmdRolloutRestart(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutRestartOptions(streams)
validArgs := []string{"deployment", "daemonset", "statefulset", "cloneset"}
validArgs := []string{"deployment", "daemonset", "statefulset", "cloneset", "uniteddeployment"}
cmd := &cobra.Command{
Use: "restart RESOURCE",
@ -158,7 +161,7 @@ func (o RestartOptions) RunRestart() error {
}
switch infos[0].Object.(type) {
case *kruiseappsv1alpha1.CloneSet:
case *kruiseappsv1alpha1.CloneSet, *kruiseappsv1beta1.StatefulSet, *kruiseappsv1alpha1.DaemonSet:
obj, err := resource.
NewHelper(infos[0].Client, infos[0].Mapping).
@ -166,37 +169,11 @@ func (o RestartOptions) RunRestart() error {
if err != nil {
return err
}
res := obj.(*kruiseappsv1alpha1.CloneSet)
internalpolymorphichelpers.UpdateResourceEnv(res)
internalpolymorphichelpers.UpdateResourceEnv(obj)
_, err = resource.
NewHelper(infos[0].Client, infos[0].Mapping).
Replace(infos[0].Namespace, infos[0].Name, true, res)
if err != nil {
return err
}
printer, err := o.ToPrinter("restarted")
if err != nil {
allErrs = append(allErrs, err)
}
if err = printer.PrintObj(infos[0].Object, o.Out); err != nil {
allErrs = append(allErrs, err)
}
return utilerrors.NewAggregate(allErrs)
case *kruiseappsv1beta1.StatefulSet:
obj, err := resource.
NewHelper(infos[0].Client, infos[0].Mapping).
Get(infos[0].Namespace, infos[0].Name)
if err != nil {
return err
}
res := obj.(*kruiseappsv1beta1.StatefulSet)
internalpolymorphichelpers.UpdateResourceEnv(res)
_, err = resource.
NewHelper(infos[0].Client, infos[0].Mapping).
Replace(infos[0].Namespace, infos[0].Name, true, res)
Replace(infos[0].Namespace, infos[0].Name, true, obj)
if err != nil {
return err
}

View File

@ -61,8 +61,9 @@ var (
Currently deployments, cloneset support being resumed.`)
resumeExample = templates.Examples(`
# Resume an already paused deployment
# Resume an already paused rollout/cloneset/deployment resource
kubectl-kruise rollout resume rollout/nginx
kubectl-kruise rollout resume cloneset/nginx
kubectl-kruise rollout resume deployment/nginx`)
)
@ -79,7 +80,7 @@ func NewRolloutResumeOptions(streams genericclioptions.IOStreams) *ResumeOptions
func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutResumeOptions(streams)
validArgs := []string{"deployment", "cloneset"}
validArgs := []string{"deployment", "cloneset", "rollout"}
cmd := &cobra.Command{
Use: "resume RESOURCE",

View File

@ -35,6 +35,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
watchtools "k8s.io/client-go/tools/watch"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
@ -77,10 +78,12 @@ type RolloutStatusOptions struct {
Watch bool
Revision int64
Timeout time.Duration
Detail bool
StatusViewerFn func(*meta.RESTMapping) (internalpolymorphichelpers.StatusViewer, error)
Builder func() *resource.Builder
DynamicClient dynamic.Interface
ClientSet kubernetes.Interface
FilenameOptions *resource.FilenameOptions
genericclioptions.IOStreams
@ -94,6 +97,7 @@ func NewRolloutStatusOptions(streams genericclioptions.IOStreams) *RolloutStatus
IOStreams: streams,
Watch: true,
Timeout: 0,
Detail: false,
}
}
@ -122,6 +126,7 @@ func NewCmdRolloutStatus(f cmdutil.Factory, streams genericclioptions.IOStreams)
cmd.Flags().BoolVarP(&o.Watch, "watch", "w", o.Watch, "Watch the status of the rollout until it's done.")
cmd.Flags().Int64Var(&o.Revision, "revision", o.Revision, "Pin to a specific revision for showing its status. Defaults to 0 (last revision).")
cmd.Flags().DurationVar(&o.Timeout, "timeout", o.Timeout, "The length of time to wait before ending watch, zero means never. Any other values should contain a corresponding time unit (e.g. 1s, 2m, 3h).")
cmd.Flags().BoolVarP(&o.Detail, "detail", "d", o.Detail, "Show the detail status of the rollout.")
return cmd
}
@ -149,6 +154,11 @@ func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error
return err
}
o.ClientSet, err = kubernetes.NewForConfig(clientConfig)
if err != nil {
return err
}
return nil
}
@ -224,17 +234,23 @@ func (o *RolloutStatusOptions) Run() error {
// if the rollout isn't done yet, keep watching deployment status
ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), o.Timeout)
intr := interrupt.New(nil, cancel)
var status string
var consideredDone bool
return intr.Run(func() error {
_, err = watchtools.UntilWithSync(ctx, lw, &unstructured.Unstructured{}, preconditionFunc, func(e watch.Event) (bool, error) {
switch t := e.Type; t {
case watch.Added, watch.Modified:
status, done, err := statusViewer.Status(e.Object.(runtime.Unstructured), o.Revision)
if o.Detail {
status, consideredDone, err = statusViewer.DetailStatus(o.ClientSet, e.Object.(runtime.Unstructured), o.Detail, o.Revision)
} else {
status, consideredDone, err = statusViewer.Status(o.ClientSet, e.Object.(runtime.Unstructured), o.Revision)
}
if err != nil {
return false, err
}
fmt.Fprintf(o.Out, "%s", status)
// Quit waiting if the rollout is done
if done {
if consideredDone {
return true, nil
}

View File

@ -20,13 +20,19 @@ package rollout
import (
"fmt"
rolloutsapiv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1"
rolloutsapiv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
internalapi "github.com/openkruise/kruise-tools/pkg/api"
"github.com/openkruise/kruise-tools/pkg/cmd/util"
internalpolymorphichelpers "github.com/openkruise/kruise-tools/pkg/internal/polymorphichelpers"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/errors"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/kubectl/pkg/cmd/set"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/i18n"
@ -42,12 +48,13 @@ type UndoOptions struct {
Builder func() *resource.Builder
ToRevision int64
DryRunStrategy cmdutil.DryRunStrategy
DryRunVerifier *resource.DryRunVerifier
Resources []string
Namespace string
EnforceNamespace bool
RESTClientGetter genericclioptions.RESTClientGetter
Fast bool // fast rollback for blue-green
resource.FilenameOptions
genericclioptions.IOStreams
}
@ -67,7 +74,13 @@ var (
kubectl-kruise rollout undo daemonset/abc --to-revision=3
# Rollback to the previous deployment with dry-run
kubectl-kruise rollout undo --dry-run=server deployment/abc`)
kubectl-kruise rollout undo --dry-run=server deployment/abc
# Rollback to workload via rollout api object
kubectl-kruise rollout undo rollout/abc
# Fast rollback during blue-green release (will go back to a previous step with no traffic and most replicas)
kubectl-kruise rollout undo rollout/abc --fast`)
)
// NewRolloutUndoOptions returns an initialized UndoOptions instance
@ -83,7 +96,7 @@ func NewRolloutUndoOptions(streams genericclioptions.IOStreams) *UndoOptions {
func NewCmdRolloutUndo(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutUndoOptions(streams)
validArgs := []string{"deployment", "daemonset", "statefulset", "cloneset", "advanced statefulset"}
validArgs := []string{"deployment", "daemonset", "statefulset", "cloneset", "advanced statefulset", "rollout"}
cmd := &cobra.Command{
Use: "undo (TYPE NAME | TYPE/NAME) [flags]",
@ -94,12 +107,17 @@ func NewCmdRolloutUndo(f cmdutil.Factory, streams genericclioptions.IOStreams) *
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.RunUndo())
if o.Fast {
cmdutil.CheckErr(o.FastUndo())
} else {
cmdutil.CheckErr(o.RunUndo())
}
},
ValidArgs: validArgs,
}
cmd.Flags().Int64Var(&o.ToRevision, "to-revision", o.ToRevision, "The revision to rollback to. Default to 0 (last revision).")
cmd.Flags().BoolVar(&o.Fast, "fast", false, "fast rollback for blue-green release")
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
cmdutil.AddDryRunFlag(cmd)
@ -115,15 +133,6 @@ func (o *UndoOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str
if err != nil {
return err
}
dynamicClient, err := f.DynamicClient()
if err != nil {
return err
}
discoveryClient, err := f.ToDiscoveryClient()
if err != nil {
return err
}
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
if o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace(); err != nil {
return err
@ -148,8 +157,7 @@ func (o *UndoOptions) Validate() error {
return nil
}
// RunUndo performs the execution of 'rollout undo' sub command
func (o *UndoOptions) RunUndo() error {
func (o *UndoOptions) FastUndo() error {
r := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
@ -163,7 +171,78 @@ func (o *UndoOptions) RunUndo() error {
return err
}
err := r.Visit(func(info *resource.Info, err error) error {
allErrs := []error{}
infos, err := r.Infos()
if err != nil {
// restore previous command behavior where
// an error caused by retrieving infos due to
// at least a single broken object did not result
// in an immediate return, but rather an overall
// aggregation of errors.
allErrs = append(allErrs, err)
}
for _, patch := range set.CalculatePatches(infos, scheme.DefaultJSONEncoder(), internalpolymorphichelpers.DefaultFastRollbackFunc) {
info := patch.Info
if patch.Err != nil {
resourceString := info.Mapping.Resource.Resource
if len(info.Mapping.Resource.Group) > 0 {
resourceString = resourceString + "." + info.Mapping.Resource.Group
}
allErrs = append(allErrs, fmt.Errorf("error: %s %q %v", resourceString, info.Name, patch.Err))
continue
}
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
printer, err := o.ToPrinter("already rolled back")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(info.Object, o.Out); err != nil {
allErrs = append(allErrs, err)
}
continue
}
obj, err := util.PatchSubResource(info.Client, info.Mapping.Resource.Resource, "status", info.Namespace, info.Name, info.Namespaced(), types.MergePatchType, patch.Patch, nil)
if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch: %v", err))
continue
}
info.Refresh(obj, true)
printer, err := o.ToPrinter("rolled back" +
"")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(info.Object, o.Out); err != nil {
allErrs = append(allErrs, err)
}
}
return errors.NewAggregate(allErrs)
}
// RunUndo performs the execution of 'rollout undo' sub command
func (o *UndoOptions) RunUndo() error {
r := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
ResourceTypeOrNameArgs(true, o.Resources...).
ContinueOnError().
Latest().
Flatten().Do()
if err := r.Err(); err != nil {
return err
}
// perform undo logic here
undoFunc := func(info *resource.Info, err error) error {
if err != nil {
return err
}
@ -172,11 +251,6 @@ func (o *UndoOptions) RunUndo() error {
return err
}
if o.DryRunStrategy == cmdutil.DryRunServer {
if err := o.DryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
return err
}
}
result, err := rollbacker.Rollback(info.Object, nil, o.ToRevision, o.DryRunStrategy)
if err != nil {
return err
@ -188,7 +262,86 @@ func (o *UndoOptions) RunUndo() error {
}
return printer.PrintObj(info.Object, o.Out)
}
var refResources []string
// deduplication: If a rollout arg references a workload which is also specified as an arg in the same command,
// performing multiple undo operations on the workload within a single command is not smart. Such an action could
// lead to confusion and yield unintended consequences. Therefore, undo operations in this context are disallowed.
// Should such a scenario occur, only the first argument that points to the workload will be executed.
deDuplica := make(map[string]struct{})
err := r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
if info.Mapping.GroupVersionKind.Group == "rollouts.kruise.io" && info.Mapping.GroupVersionKind.Kind == "Rollout" {
obj := info.Object
if obj == nil {
return fmt.Errorf("Rollout object not found")
}
workloadRef, err := getWorkloadRefFromRollout(obj)
if err != nil {
return err
}
gv, err := schema.ParseGroupVersion(workloadRef.APIVersion)
if err != nil {
return err
}
deDuplicaKey := workloadRef.Kind + "." + gv.Version + "." + gv.Group + "/" + workloadRef.Name
if _, ok := deDuplica[deDuplicaKey]; ok {
return nil
}
deDuplica[deDuplicaKey] = struct{}{}
refResources = append(refResources, deDuplicaKey)
return nil
}
gvk := info.Mapping.GroupVersionKind
deDuplicaKey := gvk.Kind + "." + gvk.Version + "." + gvk.Group + "/" + info.Name
if _, ok := deDuplica[deDuplicaKey]; ok {
return nil
}
deDuplica[deDuplicaKey] = struct{}{}
return undoFunc(info, nil)
})
return err
if len(refResources) < 1 {
return err
}
var aggErrs []error
aggErrs = append(aggErrs, err)
r2 := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
ResourceTypeOrNameArgs(true, refResources...).
ContinueOnError().
Latest().
Flatten().Do()
if err = r2.Err(); err != nil {
aggErrs = append(aggErrs, err)
return errors.NewAggregate(aggErrs)
}
err = r2.Visit(undoFunc)
aggErrs = append(aggErrs, err)
return errors.NewAggregate(aggErrs)
}
func getWorkloadRefFromRollout(obj interface{}) (workloadRef *rolloutsapiv1beta1.ObjectRef, err error) {
switch rollout := obj.(type) {
case *rolloutsapiv1alpha1.Rollout:
workloadRef = &rolloutsapiv1beta1.ObjectRef{
Kind: rollout.Spec.ObjectRef.WorkloadRef.Kind,
APIVersion: rollout.Spec.ObjectRef.WorkloadRef.APIVersion,
Name: rollout.Spec.ObjectRef.WorkloadRef.Name,
}
case *rolloutsapiv1beta1.Rollout:
workloadRef = &rollout.Spec.WorkloadRef
default:
return nil, fmt.Errorf("unsupported version of Rollout")
}
return workloadRef, nil
}

View File

@ -131,15 +131,15 @@ func extractFieldPathAsString(obj interface{}, fieldPath string) (string, error)
// splitMaybeSubscriptedPath checks whether the specified fieldPath is
// subscripted, and
// - if yes, this function splits the fieldPath into path and subscript, and
// returns (path, subscript, true).
// - if no, this function returns (fieldPath, "", false).
// - if yes, this function splits the fieldPath into path and subscript, and
// returns (path, subscript, true).
// - if no, this function returns (fieldPath, "", false).
//
// Example inputs and outputs:
// - "metadata.annotations['myKey']" --> ("metadata.annotations", "myKey", true)
// - "metadata.annotations['a[b]c']" --> ("metadata.annotations", "a[b]c", true)
// - "metadata.labels['']" --> ("metadata.labels", "", true)
// - "metadata.labels" --> ("metadata.labels", "", false)
// - "metadata.annotations['myKey']" --> ("metadata.annotations", "myKey", true)
// - "metadata.annotations['a[b]c']" --> ("metadata.annotations", "a[b]c", true)
// - "metadata.labels[”]" --> ("metadata.labels", "", true)
// - "metadata.labels" --> ("metadata.labels", "", false)
func splitMaybeSubscriptedPath(fieldPath string) (string, string, bool) {
if !strings.HasSuffix(fieldPath, "']") {
return fieldPath, "", false

View File

@ -28,8 +28,8 @@ import (
// selectContainers allows one or more containers to be matched against a string or wildcard
func selectContainers(containers []v1.Container, spec string) ([]*v1.Container, []*v1.Container) {
var out []*v1.Container
var skipped []*v1.Container
out := []*v1.Container{}
skipped := []*v1.Container{}
for i, c := range containers {
if selectString(c.Name, spec) {
out = append(out, &containers[i])
@ -54,6 +54,7 @@ func selectString(s, spec string) bool {
pos := 0
match := true
parts := strings.Split(spec, "*")
Loop:
for i, part := range parts {
if len(part) == 0 {
continue
@ -69,7 +70,7 @@ func selectString(s, spec string) bool {
// last part does not exactly match remaining part of string
case i == (len(parts)-1) && len(s) != (len(part)+next):
match = false
break
break Loop
default:
pos = next
}
@ -131,7 +132,7 @@ func findEnv(env []v1.EnvVar, name string) (v1.EnvVar, bool) {
}
func updateEnv(existing []v1.EnvVar, env []v1.EnvVar, remove []string) []v1.EnvVar {
var out []v1.EnvVar
out := []v1.EnvVar{}
covered := sets.NewString(remove...)
for _, e := range existing {
if covered.Has(e.Name) {

View File

@ -47,7 +47,7 @@ import (
var (
validEnvNameRegexp = regexp.MustCompile("[^a-zA-Z0-9_]")
envResources = `
pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), job, replicaset (rs), cloneset (cs)`
pod (po), deployment (deploy), statefulset (sts), daemonset (ds), replicaset (rs), cloneset (clone), statefulset.apps.kruise.io (asts), daemonset.apps.kruise.io (ads)`
envLong = templates.LongDesc(`
Update environment variables on a pod template.
@ -123,7 +123,6 @@ type EnvOptions struct {
resources []string
output string
dryRunStrategy cmdutil.DryRunStrategy
dryRunVerifier *resource.DryRunVerifier
builder func() *resource.Builder
updatePodSpecForObject polymorphichelpers.UpdatePodSpecForObjectFunc
namespace string
@ -226,15 +225,6 @@ func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
if err != nil {
return err
}
dynamicClient, err := f.DynamicClient()
if err != nil {
return err
}
discoveryClient, err := f.ToDiscoveryClient()
if err != nil {
return err
}
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.dryRunStrategy)
printer, err := o.PrintFlags.ToPrinter()
@ -275,7 +265,7 @@ func (o *EnvOptions) Validate() error {
// RunEnv contains all the necessary functionality for the OpenShift cli env command
func (o *EnvOptions) RunEnv() error {
env, remove, err := envutil.ParseEnv(append(o.EnvParams, o.envArgs...), o.In)
env, remove, _, err := envutil.ParseEnv(append(o.EnvParams, o.envArgs...), o.In)
if err != nil {
return err
@ -785,13 +775,6 @@ func (o *EnvOptions) RunEnv() error {
continue
}
if o.dryRunStrategy == cmdutil.DryRunServer {
if err := o.dryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
allErrs = append(allErrs, err)
continue
}
}
actual, err := resource.
NewHelper(info.Client, info.Mapping).
DryRun(o.dryRunStrategy == cmdutil.DryRunServer).

View File

@ -19,6 +19,7 @@ package set
import (
"fmt"
kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
"github.com/openkruise/kruise-tools/pkg/internal/polymorphichelpers"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
@ -46,7 +47,6 @@ type SetImageOptions struct {
Infos []*resource.Info
Selector string
DryRunStrategy cmdutil.DryRunStrategy
DryRunVerifier *resource.DryRunVerifier
All bool
Output string
Local bool
@ -64,7 +64,7 @@ type SetImageOptions struct {
var (
imageResources = `
pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), replicaset (rs), cloneset(cs)`
pod (po), deployment (deploy), statefulset (sts), daemonset (ds), replicaset (rs), cloneset (clone), statefulset.apps.kruise.io (asts), daemonset.apps.kruise.io (ads)`
imageLong = templates.LongDesc(`
Update existing container image(s) of resources.
@ -146,15 +146,6 @@ func (o *SetImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
if err != nil {
return err
}
dynamicClient, err := f.DynamicClient()
if err != nil {
return err
}
discoveryClient, err := f.ToDiscoveryClient()
if err != nil {
return err
}
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
o.Output = cmdutil.GetFlagString(cmd, "output")
o.ResolveImage = resolveImageFunc
@ -240,9 +231,15 @@ func (o *SetImageOptions) Run() error {
}
continue
}
initContainerFound := setImage(spec.InitContainers, name, resolvedImageName)
containerFound := setImage(spec.Containers, name, resolvedImageName)
var initContainerFound, containerFound bool
// Check if the type is kruiseappsv1alpha1.SidecarSet, and if the placeholder is nil.
if t, ok := obj.(*kruiseappsv1alpha1.SidecarSet); ok && spec == nil {
initContainerFound = setSideCarImage(t.Spec.InitContainers, name, resolvedImageName)
containerFound = setSideCarImage(t.Spec.Containers, name, resolvedImageName)
} else {
initContainerFound = setImage(spec.InitContainers, name, resolvedImageName)
containerFound = setImage(spec.Containers, name, resolvedImageName)
}
if !containerFound && !initContainerFound {
allErrs = append(allErrs, fmt.Errorf("error: unable to find container named %q", name))
}
@ -280,17 +277,11 @@ func (o *SetImageOptions) Run() error {
continue
}
if o.DryRunStrategy == cmdutil.DryRunServer {
if err := o.DryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
return err
}
}
// patch the change
actual, err := resource.
NewHelper(info.Client, info.Mapping).
DryRun(o.DryRunStrategy == cmdutil.DryRunServer).
Patch(info.Namespace, info.Name, types.MergePatchType, patch.Patch, nil)
Patch(info.Namespace, info.Name, types.MergePatchType, patch.After, nil)
if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch image update to pod template: %v", err))
continue
@ -316,6 +307,19 @@ func setImage(containers []corev1.Container, containerName string, image string)
return containerFound
}
// setSideCarImage
func setSideCarImage(containers []kruiseappsv1alpha1.SidecarContainer, containerName string, image string) bool {
containerFound := false
// Find the container to update, and update its image
for i, c := range containers {
if c.Name == containerName || containerName == "*" {
containerFound = true
containers[i].Image = image
}
}
return containerFound
}
// getResourcesAndImages retrieves resources and container name:images pair from given args
func getResourcesAndImages(args []string) (resources []string, containerImages map[string]string, err error) {
pairType := "image"

View File

@ -23,6 +23,8 @@ import (
"strings"
"testing"
kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
@ -612,6 +614,22 @@ func TestSetImageRemote(t *testing.T) {
path: "/namespaces/test/replicationcontrollers/nginx",
args: []string{"replicationcontroller", "nginx", "*=thingy"},
},
{
name: "set image kruiseappsv1alpha1.SidecarSet",
object: &kruiseappsv1alpha1.SidecarSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: kruiseappsv1alpha1.SidecarSetSpec{
Containers: []kruiseappsv1alpha1.SidecarContainer{
{
Container: corev1.Container{Name: "nginx", Image: "nginx"},
},
},
},
},
groupVersion: corev1.SchemeGroupVersion,
path: "/namespaces/test/sidecarsets/nginx",
args: []string{"sidecarsets", "nginx", "*=thingy"},
},
}
for _, input := range inputs {
t.Run(input.name, func(t *testing.T) {
@ -746,8 +764,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.Contains(t, string(bytes), `"name":"`+"nginx"+`","image":`+`"thingy"`, fmt.Sprintf("image not updated for %#v", input.object))
assert.NotContains(t, string(bytes), `"name":"`+"busybox"+`","image":`+`"thingy"`, fmt.Sprintf("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

@ -42,12 +42,16 @@ import (
)
var (
resourcesResources = `
pod (po), deployment (deploy), statefulset (sts), daemonset (ds), replicaset (rs), cloneset (clone), statefulset.apps.kruise.io (asts), daemonset.apps.kruise.io (ads)`
resourcesLong = templates.LongDesc(`
Specify compute resource requirements (cpu, memory) for any resource that defines a pod template. If a pod is successfully scheduled, it is guaranteed the amount of resource requested, but may burst up to its specified limits.
for each compute resource, if a limit is specified and a request is omitted, the request will default to the limit.
Possible resources include (case insensitive): %s.`)
Possible resources include (case insensitive):
` + resourcesResources)
resourcesExample = templates.Examples(`
# Set a deployments nginx container cpu limits to "200m" and memory to "512Mi"
@ -89,7 +93,6 @@ type SetResourcesOptions struct {
UpdatePodSpecForObject polymorphichelpers.UpdatePodSpecForObjectFunc
Resources []string
DryRunVerifier *resource.DryRunVerifier
genericclioptions.IOStreams
}
@ -117,7 +120,7 @@ func NewCmdResources(f cmdutil.Factory, streams genericclioptions.IOStreams) *co
Use: "resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]",
DisableFlagsInUseLine: true,
Short: i18n.T("Update resource requests/limits on objects with pod templates"),
Long: fmt.Sprintf(resourcesLong, cmdutil.SuggestAPIResources("kubectl")),
Long: resourcesLong,
Example: resourcesExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))
@ -163,15 +166,6 @@ func (o *SetResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, ar
if err != nil {
return err
}
dynamicClient, err := f.DynamicClient()
if err != nil {
return err
}
discoveryClient, err := f.ToDiscoveryClient()
if err != nil {
return err
}
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
printer, err := o.PrintFlags.ToPrinter()
@ -431,13 +425,6 @@ func (o *SetResourcesOptions) Run() error {
continue
}
if o.DryRunStrategy == cmdutil.DryRunServer {
if err := o.DryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch resources update to pod template %v", err))
continue
}
}
actual, err := resource.
NewHelper(info.Client, info.Mapping).
DryRun(o.DryRunStrategy == cmdutil.DryRunServer).

View File

@ -45,7 +45,6 @@ type SetSelectorOptions struct {
PrintFlags *genericclioptions.PrintFlags
RecordFlags *genericclioptions.RecordFlags
dryRunStrategy cmdutil.DryRunStrategy
dryRunVerifier *resource.DryRunVerifier
// set by args
resources []string
@ -134,15 +133,6 @@ func (o *SetSelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
if err != nil {
return err
}
dynamicClient, err := f.DynamicClient()
if err != nil {
return err
}
discoveryClient, err := f.ToDiscoveryClient()
if err != nil {
return err
}
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
o.resources, o.selector, err = getResourcesAndSelector(args)
if err != nil {
@ -215,16 +205,11 @@ func (o *SetSelectorOptions) RunSelector() error {
if !o.WriteToServer {
return o.PrintObj(info.Object, o.Out)
}
if o.dryRunStrategy == cmdutil.DryRunServer {
if err := o.dryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
return err
}
}
actual, err := resource.
NewHelper(info.Client, info.Mapping).
DryRun(o.dryRunStrategy == cmdutil.DryRunServer).
Patch(info.Namespace, info.Name, types.MergePatchType, patch.Patch, nil)
Patch(info.Namespace, info.Name, types.MergePatchType, patch.After, nil)
if err != nil {
return err
}

View File

@ -63,7 +63,6 @@ type SetServiceAccountOptions struct {
fileNameOptions resource.FilenameOptions
dryRunStrategy cmdutil.DryRunStrategy
dryRunVerifier *resource.DryRunVerifier
shortOutput bool
all bool
output string
@ -136,15 +135,7 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman
if o.local && o.dryRunStrategy == cmdutil.DryRunServer {
return fmt.Errorf("cannot specify --local and --dry-run=server - did you mean --dry-run=client?")
}
dynamicClient, err := f.DynamicClient()
if err != nil {
return err
}
discoveryClient, err := f.ToDiscoveryClient()
if err != nil {
return err
}
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
o.output = cmdutil.GetFlagString(cmd, "output")
o.updatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn
@ -215,16 +206,10 @@ func (o *SetServiceAccountOptions) Run() error {
}
continue
}
if o.dryRunStrategy == cmdutil.DryRunServer {
if err := o.dryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
patchErrs = append(patchErrs, err)
continue
}
}
actual, err := resource.
NewHelper(info.Client, info.Mapping).
DryRun(o.dryRunStrategy == cmdutil.DryRunServer).
Patch(info.Namespace, info.Name, types.MergePatchType, patch.Patch, nil)
Patch(info.Namespace, info.Name, types.MergePatchType, patch.After, nil)
if err != nil {
patchErrs = append(patchErrs, fmt.Errorf("failed to patch ServiceAccountName %v", err))
continue

View File

@ -66,7 +66,6 @@ type SubjectOptions struct {
Output string
All bool
DryRunStrategy cmdutil.DryRunStrategy
DryRunVerifier *resource.DryRunVerifier
Local bool
Users []string
@ -126,15 +125,6 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
if err != nil {
return err
}
dynamicClient, err := f.DynamicClient()
if err != nil {
return err
}
discoveryClient, err := f.ToDiscoveryClient()
if err != nil {
return err
}
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
printer, err := o.PrintFlags.ToPrinter()
@ -272,16 +262,10 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
continue
}
if o.DryRunStrategy == cmdutil.DryRunServer {
if err := o.DryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
allErrs = append(allErrs, err)
continue
}
}
actual, err := resource.
NewHelper(info.Client, info.Mapping).
DryRun(o.DryRunStrategy == cmdutil.DryRunServer).
Patch(info.Namespace, info.Name, types.MergePatchType, patch.Patch, nil)
Patch(info.Namespace, info.Name, types.MergePatchType, patch.After, nil)
if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch subjects to rolebinding: %v", err))
continue
@ -294,7 +278,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
return utilerrors.NewAggregate(allErrs)
}
//Note: the obj mutates in the function
// Note: the obj mutates in the function
func updateSubjectForObject(obj runtime.Object, subjects []rbacv1.Subject, fn updateSubjects) (bool, error) {
switch t := obj.(type) {
case *rbacv1.RoleBinding:

View File

@ -133,18 +133,3 @@ func (f *factoryImpl) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, e
func (f *factoryImpl) ToRawKubeConfigLoader() clientcmd.ClientConfig {
return f.clientGetter.ToRawKubeConfigLoader()
}
/*
func (f *factoryImpl) OpenAPIGetter() discovery.OpenAPISchemaInterface {
discovery, err := f.clientGetter.ToDiscoveryClient()
if err != nil {
return nil
}
f.getter.Do(func() {
f.openAPIGetter = openapi.NewOpenAPIGetter(discovery)
})
return f.openAPIGetter
}
*/

View File

@ -17,11 +17,16 @@ limitations under the License.
package util
import (
"context"
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/klog/v2"
)
@ -70,3 +75,18 @@ func CheckErr(err error) {
func AddFieldManagerFlagVar(cmd *cobra.Command, p *string, defaultFieldManager string) {
cmd.Flags().StringVar(p, "field-manager", defaultFieldManager, "Name of the manager used to track field ownership.")
}
func PatchSubResource(RESTClient resource.RESTClient, resource, subResource, namespace, name string, namespaceScoped bool, pt types.PatchType, data []byte, options *metav1.PatchOptions) (runtime.Object, error) {
if options == nil {
options = &metav1.PatchOptions{}
}
return RESTClient.Patch(pt).
NamespaceIfScoped(namespace, namespaceScoped).
Resource(resource).
SubResource(subResource).
Name(name).
VersionedParams(options, metav1.ParameterCodec).
Body(data).
Do(context.TODO()).
Get()
}

View File

@ -0,0 +1,27 @@
package util
import (
"encoding/json"
corev1 "k8s.io/api/core/v1"
)
const (
// SidecarSetWorkingHotUpgradeContainer record which hot upgrade container is working currently
SidecarSetWorkingHotUpgradeContainer = "kruise.io/sidecarset-working-hotupgrade-container"
)
func GetPodHotUpgradeInfoInAnnotations(pod *corev1.Pod) map[string]string {
hotUpgradeWorkContainer := make(map[string]string)
currentStr, ok := pod.Annotations[SidecarSetWorkingHotUpgradeContainer]
if !ok {
//klog.V(6).Infof("Pod(%s.%s) annotations(%s) Not Found", pod.Namespace, pod.Name, SidecarSetWorkingHotUpgradeContainer)
return hotUpgradeWorkContainer
}
if err := json.Unmarshal([]byte(currentStr), &hotUpgradeWorkContainer); err != nil {
//klog.Errorf("Parse Pod(%s.%s) annotations(%s) Value(%s) failed: %s", pod.Namespace, pod.Name,
// SidecarSetWorkingHotUpgradeContainer, currentStr, err.Error())
return hotUpgradeWorkContainer
}
return hotUpgradeWorkContainer
}

View File

@ -34,7 +34,6 @@ func DeploymentToCloneSet(deploy *apps.Deployment, dstCloneSetName string) *apps
Labels: from.Labels,
Annotations: from.Annotations,
Finalizers: from.Finalizers,
ClusterName: from.ClusterName,
},
Spec: appsv1alpha1.CloneSetSpec{
Replicas: from.Spec.Replicas,

View File

@ -38,7 +38,11 @@ type control struct {
func NewControl(cfg *rest.Config) (creation.Control, error) {
scheme := api.GetScheme()
mapper, err := apiutil.NewDynamicRESTMapper(cfg)
c, err := rest.HTTPClientFor(cfg)
if err != nil {
return nil, err
}
mapper, err := apiutil.NewDynamicRESTMapper(cfg, c)
if err != nil {
return nil, err
}

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