Compare commits
19 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
7c240e5828 | |
|
|
da2b3fbac8 | |
|
|
ebb124d8cd | |
|
|
68d571ec42 | |
|
|
d973c2aa1d | |
|
|
94742398cd | |
|
|
0fc1342e14 | |
|
|
c9efb12a8a | |
|
|
60858fed19 | |
|
|
f3a7f4bd33 | |
|
|
b8db027748 | |
|
|
82ce71b931 | |
|
|
791f2b6075 | |
|
|
a4fc9a3051 | |
|
|
355ed0a11a | |
|
|
f422c7d1cd | |
|
|
2d0a16f996 | |
|
|
9d68939d6c | |
|
|
631fde0936 |
|
|
@ -12,48 +12,112 @@ on:
|
|||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.20'
|
||||
GOLANGCI_VERSION: 'v1.51'
|
||||
GO_VERSION: '1.23'
|
||||
GOLANGCI_VERSION: 'v1.55.2'
|
||||
|
||||
jobs:
|
||||
golangci-lint:
|
||||
runs-on: ubuntu-20.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@v3.5.0
|
||||
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-20.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 ./...
|
||||
|
|
@ -6,110 +6,145 @@ on:
|
|||
- created
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.20'
|
||||
GO_VERSION: '1.22'
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build_and_upload:
|
||||
runs-on: ubuntu-20.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@v4
|
||||
- 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@v4
|
||||
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
|
||||
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
|
||||
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 }}-${{ steps.get_release.outputs.tag_name }}.tar.gz
|
||||
asset_content_type: binary/octet-stream
|
||||
|
||||
- name: Build resourcedistribution-generator
|
||||
run: |
|
||||
${{ env.GO_BUILD_ENV }} GOOS=${{ steps.get_matrix.outputs.OS }} GOARCH=${{ steps.get_matrix.outputs.ARCH }} \
|
||||
go build -ldflags "${{ env.LDFLAGS }}" \
|
||||
-o _bin/resourcedistribution-generator/${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}/resourcedistributiongenerator -v \
|
||||
${{ 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: Compress resourcedistribution-generator
|
||||
|
||||
- name: Package artifacts
|
||||
run: |
|
||||
cd _bin/resourcedistribution-generator && \
|
||||
${{ env.DIST_DIRS }} tar -zcf resourcedistribution-generator-{}.tar.gz {} \; && \
|
||||
cd .. && \
|
||||
sha256sum resourcedistribution-generator/resourcedistribution-generator-* >> sha256-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.txt \
|
||||
- name: Upload resourcedistribution-generator tar.gz
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
# 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/resourcedistribution-generator/resourcedistribution-generator-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
|
||||
asset_name: resourcedistribution-generator-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}-${{ steps.get_release.outputs.tag_name }}.tar.gz
|
||||
asset_content_type: binary/octet-stream
|
||||
- name: Post sha256
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sha256sums-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}
|
||||
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:
|
||||
|
||||
- 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: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Get release
|
||||
id: get_release
|
||||
uses: bruceadams/get-release@v1.2.2
|
||||
- name: Download artifacts
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4.1.7
|
||||
with:
|
||||
pattern: sha256sums-*
|
||||
pattern: "*"
|
||||
merge-multiple: true
|
||||
path: sha256sums
|
||||
- shell: bash
|
||||
path: artifacts
|
||||
|
||||
- name: Prepare release assets
|
||||
run: |
|
||||
cat sha256sums/*.txt > sha256sums.txt
|
||||
- name: Upload Checksums
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
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
|
||||
|
||||
# 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-${{ steps.get_release.outputs.tag_name }}.txt
|
||||
asset_content_type: text/plain
|
||||
files: release-assets/*
|
||||
fail_on_unmatched_files: true
|
||||
|
||||
- name: Update kubectl plugin version in krew-index
|
||||
uses: rajatjindal/krew-release-bot@v0.0.43
|
||||
uses: rajatjindal/krew-release-bot@v0.0.46
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
# Temporary exclusion - proxy/tokenizer vulnerabilities don't affect our usage
|
||||
CVE-2025-22870
|
||||
CVE-2025-22872
|
||||
57
README.md
57
README.md
|
|
@ -103,6 +103,9 @@ $ 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
|
||||
|
|
@ -195,6 +198,60 @@ kubectl kruise migrate CloneSet --from Deployment --src-name deployment-demo --d
|
|||
#### 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.
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ kubectl-kruise [flags]
|
|||
--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.
|
||||
|
|
@ -44,9 +45,11 @@ kubectl-kruise [flags]
|
|||
### 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
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ kubectl-kruise create -f FILENAME
|
|||
-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 Must be one of: strict (or true), warn, ignore (or false).
|
||||
--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")
|
||||
|
|
@ -61,6 +61,7 @@ kubectl-kruise create -f FILENAME
|
|||
--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
|
||||
|
|
@ -84,3 +85,4 @@ kubectl-kruise create -f FILENAME
|
|||
* [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
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ kubectl-kruise create ContainerRecreateRequest NAME --pod=podName [--containers=
|
|||
--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 Must be one of: strict (or true), warn, ignore (or false).
|
||||
--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")
|
||||
|
|
@ -63,6 +63,7 @@ kubectl-kruise create ContainerRecreateRequest NAME --pod=podName [--containers=
|
|||
--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
|
||||
|
|
@ -83,3 +84,4 @@ kubectl-kruise create ContainerRecreateRequest NAME --pod=podName [--containers=
|
|||
|
||||
* [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
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ kubectl-kruise create broadcastJob NAME --image=image [--from=cronjob/name] -- [
|
|||
--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 Must be one of: strict (or true), warn, ignore (or false).
|
||||
--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")
|
||||
|
|
@ -54,6 +54,7 @@ kubectl-kruise create broadcastJob NAME --image=image [--from=cronjob/name] -- [
|
|||
--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
|
||||
|
|
@ -74,3 +75,4 @@ kubectl-kruise create broadcastJob NAME --image=image [--from=cronjob/name] -- [
|
|||
|
||||
* [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
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ kubectl-kruise create job NAME --image=image [--from=cronjob/name] -- [COMMAND]
|
|||
--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 Must be one of: strict (or true), warn, ignore (or false).
|
||||
--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")
|
||||
|
|
@ -54,6 +54,7 @@ kubectl-kruise create job NAME --image=image [--from=cronjob/name] -- [COMMAND]
|
|||
--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
|
||||
|
|
@ -74,3 +75,4 @@ kubectl-kruise create job NAME --image=image [--from=cronjob/name] -- [COMMAND]
|
|||
|
||||
* [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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -85,6 +85,7 @@ kubectl-kruise expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UD
|
|||
--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
|
||||
|
|
@ -105,3 +106,4 @@ kubectl-kruise expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UD
|
|||
|
||||
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ kubectl-kruise migrate [DST_KIND] --from [SRC_KIND] [flags]
|
|||
--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
|
||||
|
|
@ -71,3 +72,4 @@ kubectl-kruise migrate [DST_KIND] --from [SRC_KIND] [flags]
|
|||
|
||||
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ kubectl-kruise rollout SUBCOMMAND
|
|||
--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
|
||||
|
|
@ -75,3 +76,4 @@ kubectl-kruise rollout SUBCOMMAND
|
|||
* [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
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ kubectl-kruise rollout approve RESOURCE
|
|||
```
|
||||
# approve a kruise rollout resource named "rollout-demo" in "ns-demo" namespace
|
||||
|
||||
kubectl-kruise rollout approve rollout-demo -n ns-demo
|
||||
kubectl-kruise rollout approve rollout/rollout-demo -n ns-demo
|
||||
```
|
||||
|
||||
### Options
|
||||
|
|
@ -45,6 +45,7 @@ kubectl-kruise rollout approve RESOURCE
|
|||
--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
|
||||
|
|
@ -65,3 +66,4 @@ kubectl-kruise rollout approve RESOURCE
|
|||
|
||||
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ kubectl-kruise rollout history (TYPE NAME | TYPE/NAME) [flags]
|
|||
--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
|
||||
|
|
@ -69,3 +70,4 @@ kubectl-kruise rollout history (TYPE NAME | TYPE/NAME) [flags]
|
|||
|
||||
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ kubectl-kruise rollout pause RESOURCE
|
|||
--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
|
||||
|
|
@ -67,3 +68,4 @@ kubectl-kruise rollout pause RESOURCE
|
|||
|
||||
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ Restart a resource
|
|||
|
||||
Restart a resource.
|
||||
|
||||
Resource will be rollout restarted.
|
||||
Resource will be rollout restarted. Supported kinds include:
|
||||
CloneSet, DaemonSet, Deployment, StatefulSet, and UnitedDeployment.
|
||||
|
||||
```
|
||||
kubectl-kruise rollout restart RESOURCE
|
||||
|
|
@ -21,6 +22,9 @@ kubectl-kruise rollout restart RESOURCE
|
|||
|
||||
# Restart a daemonset
|
||||
kubectl-kruise rollout restart daemonset/abc
|
||||
|
||||
# Restart a UnitedDeployment
|
||||
kubectl-kruise rollout restart uniteddeployment/my-app
|
||||
```
|
||||
|
||||
### Options
|
||||
|
|
@ -48,6 +52,7 @@ kubectl-kruise rollout restart RESOURCE
|
|||
--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
|
||||
|
|
@ -68,3 +73,4 @@ kubectl-kruise rollout restart RESOURCE
|
|||
|
||||
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ kubectl-kruise rollout resume RESOURCE
|
|||
--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
|
||||
|
|
@ -67,3 +68,4 @@ kubectl-kruise rollout resume RESOURCE
|
|||
|
||||
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ kubectl-kruise rollout status (TYPE NAME | TYPE/NAME) [flags]
|
|||
--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
|
||||
|
|
@ -70,3 +71,4 @@ kubectl-kruise rollout status (TYPE NAME | TYPE/NAME) [flags]
|
|||
|
||||
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ kubectl-kruise rollout undo (TYPE NAME | TYPE/NAME) [flags]
|
|||
|
||||
# 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
|
||||
|
|
@ -34,6 +37,7 @@ kubectl-kruise rollout undo (TYPE NAME | TYPE/NAME) [flags]
|
|||
```
|
||||
--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.
|
||||
|
|
@ -56,6 +60,7 @@ kubectl-kruise rollout undo (TYPE NAME | TYPE/NAME) [flags]
|
|||
--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
|
||||
|
|
@ -76,3 +81,4 @@ kubectl-kruise rollout undo (TYPE NAME | TYPE/NAME) [flags]
|
|||
|
||||
* [kubectl-kruise rollout](kubectl-kruise_rollout.md) - Manage the rollout of a resource
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ kubectl-kruise scaledown [CLONESET] --pods [POD1,POD2] -n [NAMESPACE]
|
|||
--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
|
||||
|
|
@ -58,3 +59,4 @@ kubectl-kruise scaledown [CLONESET] --pods [POD1,POD2] -n [NAMESPACE]
|
|||
|
||||
* [kubectl-kruise](kubectl-kruise.md) - kubectl-kruise controls the OpenKruise CRs
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ kubectl-kruise set SUBCOMMAND
|
|||
--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
|
||||
|
|
@ -56,3 +57,4 @@ kubectl-kruise set SUBCOMMAND
|
|||
* [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
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ kubectl-kruise set env RESOURCE/NAME KEY_1=VAL_1 ... KEY_N=VAL_N
|
|||
--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
|
||||
|
|
@ -113,3 +114,4 @@ kubectl-kruise set env RESOURCE/NAME KEY_1=VAL_1 ... KEY_N=VAL_N
|
|||
|
||||
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ kubectl-kruise set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IM
|
|||
--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
|
||||
|
|
@ -79,3 +80,4 @@ kubectl-kruise set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IM
|
|||
|
||||
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ kubectl-kruise set resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --re
|
|||
--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
|
||||
|
|
@ -84,3 +85,4 @@ kubectl-kruise set resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --re
|
|||
|
||||
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ kubectl-kruise set selector (-f FILENAME | TYPE NAME) EXPRESSIONS [--resource-ve
|
|||
--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
|
||||
|
|
@ -68,3 +69,4 @@ kubectl-kruise set selector (-f FILENAME | TYPE NAME) EXPRESSIONS [--resource-ve
|
|||
|
||||
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ kubectl-kruise set serviceaccount (-f FILENAME | TYPE NAME) SERVICE_ACCOUNT
|
|||
--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
|
||||
|
|
@ -72,3 +73,4 @@ kubectl-kruise set serviceaccount (-f FILENAME | TYPE NAME) SERVICE_ACCOUNT
|
|||
|
||||
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ kubectl-kruise set subject (-f FILENAME | TYPE NAME) [--user=username] [--group=
|
|||
--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
|
||||
|
|
@ -74,3 +75,4 @@ kubectl-kruise set subject (-f FILENAME | TYPE NAME) [--user=username] [--group=
|
|||
|
||||
* [kubectl-kruise set](kubectl-kruise_set.md) - Set specific features on objects
|
||||
|
||||
###### Auto generated by spf13/cobra on 12-Mar-2025
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@ options:
|
|||
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"
|
||||
|
|
@ -75,6 +79,7 @@ options:
|
|||
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
|
||||
|
|
|
|||
|
|
@ -98,6 +98,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -68,6 +68,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -68,6 +68,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -123,6 +123,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
@ -103,6 +107,6 @@ inherited_options:
|
|||
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-demo -n ns-demo"
|
||||
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
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ options:
|
|||
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: '[]'
|
||||
|
|
@ -66,6 +69,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
@ -107,6 +114,6 @@ inherited_options:
|
|||
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"
|
||||
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
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -114,6 +114,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -98,6 +98,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -80,6 +80,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@ inherited_options:
|
|||
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: |
|
||||
|
|
|
|||
51
go.mod
51
go.mod
|
|
@ -1,25 +1,27 @@
|
|||
module github.com/openkruise/kruise-tools
|
||||
|
||||
go 1.20
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.4
|
||||
|
||||
require (
|
||||
github.com/go-errors/errors v1.4.2
|
||||
github.com/lithammer/dedent v1.1.0
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587
|
||||
github.com/openkruise/kruise-api v1.7.1
|
||||
github.com/openkruise/kruise-rollout-api v0.5.1
|
||||
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.9.0
|
||||
k8s.io/api v0.28.9
|
||||
k8s.io/apimachinery v0.28.9
|
||||
k8s.io/cli-runtime v0.28.9
|
||||
k8s.io/client-go v0.28.9
|
||||
k8s.io/component-base v0.28.9
|
||||
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.28.9
|
||||
k8s.io/kubectl v0.30.11
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
|
||||
sigs.k8s.io/controller-runtime v0.16.6
|
||||
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
|
||||
)
|
||||
|
|
@ -33,23 +35,23 @@ require (
|
|||
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.6.0 // 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.1 // 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/golang-jwt/jwt/v4 v4.5.1 // 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
|
||||
|
|
@ -64,6 +66,7 @@ require (
|
|||
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
|
||||
|
|
@ -71,22 +74,30 @@ require (
|
|||
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.24.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/oauth2 v0.17.0 // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/term v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.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-20230717233707-2695361300d9 // indirect
|
||||
sigs.k8s.io/gateway-api v0.5.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
|
||||
)
|
||||
|
|
|
|||
154
go.sum
154
go.sum
|
|
@ -5,11 +5,14 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
|||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
|
||||
github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
|
|
@ -20,6 +23,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lV
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
@ -29,20 +33,20 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
|
|||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
|
||||
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
|
||||
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
|
||||
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
|
||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
|
||||
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
|
|
@ -50,13 +54,12 @@ github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En
|
|||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
|
@ -88,18 +91,20 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
|
|||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
|
|
@ -110,6 +115,7 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
|||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
|
|
@ -121,6 +127,7 @@ github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z
|
|||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
|
|
@ -136,28 +143,37 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/
|
|||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/openkruise/kruise-api v1.7.1 h1:pF+tPHWY1SS0X7sXTOIHZ5sNb5h5MBy1D7h6bJI5yW8=
|
||||
github.com/openkruise/kruise-api v1.7.1/go.mod h1:ZD94u+GSQGtKrDfFhMVpQhzjr7g7UlXhYfRoNp/EhJs=
|
||||
github.com/openkruise/kruise-rollout-api v0.5.1 h1:wZug9vIfkTjfGANEWX7//NhFLpsL4ZU3kZq8kFSYk7I=
|
||||
github.com/openkruise/kruise-rollout-api v0.5.1/go.mod h1:Db/+T+VaMtE++qTmBkW+lkBFO7zO5fgTZibfnKKfGaM=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||
github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
|
||||
github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
|
||||
github.com/openkruise/kruise-api v1.8.0 h1:DoUb873uuf2Bhoajim+9tb/X0eFpwIxRydc4Awfeeiw=
|
||||
github.com/openkruise/kruise-api v1.8.0/go.mod h1:XRpoTk7VFgh9r5HRUZurwhiC3cpCf5BX8X4beZLcIfA=
|
||||
github.com/openkruise/kruise-rollout-api v0.6.0 h1:pv8Y3UPCWqrZgOU5uzoEC0lSWfr+x0NSMfFhXJ9wLvg=
|
||||
github.com/openkruise/kruise-rollout-api v0.6.0/go.mod h1:qnSk54oRTv5JRp1m6fm5Qf+z1ClUhkGiKPtjP5Phtm8=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
||||
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
|
||||
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
||||
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
|
|
@ -166,6 +182,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
|
|
@ -181,11 +198,12 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
|
|||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
||||
|
|
@ -195,55 +213,25 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
|
|||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
|
||||
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
|
|
@ -252,12 +240,15 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
|
|
@ -294,29 +285,30 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.28.9 h1:E7VEXXCAlSrp+08zq4zgd+ko6Ttu0Mw+XoXlIkDTVW0=
|
||||
k8s.io/api v0.28.9/go.mod h1:AnCsDYf3SHjfa8mPG5LGYf+iF4mie+3peLQR51MMCgw=
|
||||
k8s.io/apiextensions-apiserver v0.28.9 h1:yzPHp+4IASHeu7XIPkAKJrY4UjWdjiAjOcQMd6oNKj0=
|
||||
k8s.io/apimachinery v0.28.9 h1:aXz4Zxsw+Pk4KhBerAtKRxNN1uSMWKfciL/iOdBfXvA=
|
||||
k8s.io/apimachinery v0.28.9/go.mod h1:zUG757HaKs6Dc3iGtKjzIpBfqTM4yiRsEe3/E7NX15o=
|
||||
k8s.io/cli-runtime v0.28.9 h1:TfEV/UgCiXewliUHOHsUMZ1bfENhqcqKkA/hqQ/HwvQ=
|
||||
k8s.io/cli-runtime v0.28.9/go.mod h1:PgxW97xCDbtWgsuo2nahMc2/MxcSDgscdwm8XZ7973A=
|
||||
k8s.io/client-go v0.28.9 h1:mmMvejwc/KDjMLmDpyaxkWNzlWRCJ6ht7Qsbsnwn39Y=
|
||||
k8s.io/client-go v0.28.9/go.mod h1:GFDy3rUNId++WGrr0hRaBrs+y1eZz5JtVZODEalhRMo=
|
||||
k8s.io/component-base v0.28.9 h1:ySM2PR8Z/xaUSG1Akd3yM6dqUezTltI7S5aV41MMuuc=
|
||||
k8s.io/component-base v0.28.9/go.mod h1:QtWzscEhCKRfHV24/S+11BwWjVxhC6fd3RYoEgZcWFU=
|
||||
k8s.io/api v0.30.11 h1:TpkiTTxQ6GSwHnqKOPeQRRFcBknTjOBwFYjWmn25Z1U=
|
||||
k8s.io/api v0.30.11/go.mod h1:DZzjCDcat14fMx/4Fm3h5lsbVStfHmgNzNDMy7JQMqU=
|
||||
k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws=
|
||||
k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4=
|
||||
k8s.io/apimachinery v0.30.11 h1:+qV/yXI2R7BxX1zeyELDFb0PopX22znfq5w+icav49k=
|
||||
k8s.io/apimachinery v0.30.11/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
|
||||
k8s.io/cli-runtime v0.30.11 h1:rJBIprFSmMX61uwFWv07C8+VVeEDRnxAwipP511iWGQ=
|
||||
k8s.io/cli-runtime v0.30.11/go.mod h1:yQ5Xh33U2NRdYvB3RBKBuLBHz7PrmGsnPSRFExsMnKg=
|
||||
k8s.io/client-go v0.30.11 h1:yamC5zf/g5ztZO3SELklaOSZKTOAL3Q0v0i6GBvq+Mg=
|
||||
k8s.io/client-go v0.30.11/go.mod h1:umPRna4oj2zLU03T1m7Cla+yMzRFyhuR+jAbDZNDqlM=
|
||||
k8s.io/component-base v0.30.11 h1:y0GDnKad+VFWKlfWqnu3oHKL5eRQ3AC8xBNwLGnMdyc=
|
||||
k8s.io/component-base v0.30.11/go.mod h1:JSQ3NPwvwGijXtApFqBYtsBitdbfXnwwLJkWuttRMV0=
|
||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
|
||||
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
|
||||
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
|
||||
k8s.io/kubectl v0.28.9 h1:FTf/aapuuFxPmt8gYUeqUmcsgG0gKC2ei6n+TO5sGOw=
|
||||
k8s.io/kubectl v0.28.9/go.mod h1:ip/zTUr1MM/H2M+YbPHnSKLt0x6kb85SJtRSjwEGDfs=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
|
||||
k8s.io/kubectl v0.30.11 h1:pBk1AzDpndHl9oBfqJS9J2CGYNyik+x/QanXSERM7gE=
|
||||
k8s.io/kubectl v0.30.11/go.mod h1:a8AoybYsyppPEctupfJk4uaSy9uUWdvNfqRmSzbPPCQ=
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/controller-runtime v0.16.6 h1:FiXwTuFF5ZJKmozfP2Z0j7dh6kmxP4Ou1KLfxgKKC3I=
|
||||
sigs.k8s.io/controller-runtime v0.16.6/go.mod h1:+dQzkZxnylD0u49e0a+7AR+vlibEBaThmPca7lTyUsI=
|
||||
sigs.k8s.io/gateway-api v0.5.1 h1:EqzgOKhChzyve9rmeXXbceBYB6xiM50vDfq0kK5qpdw=
|
||||
sigs.k8s.io/gateway-api v0.5.1/go.mod h1:x0AP6gugkFV8fC/oTlnOMU0pnmuzIR8LfIPRVUjxSqA=
|
||||
sigs.k8s.io/controller-runtime v0.18.6 h1:UnEoLBLDpQwzJ2jYh6aTdiMhGjNDR7IdFn9YEqHIccc=
|
||||
sigs.k8s.io/controller-runtime v0.18.6/go.mod h1:Dcsa9v8AEBWa3sQNJHsuWPT4ICv99irl5wj83NiC12U=
|
||||
sigs.k8s.io/gateway-api v0.7.1 h1:Tts2jeepVkPA5rVG/iO+S43s9n7Vp7jCDhZDQYtPigQ=
|
||||
sigs.k8s.io/gateway-api v0.7.1/go.mod h1:Xv0+ZMxX0lu1nSSDIIPEfbVztgNZ+3cfiYrJsa2Ooso=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0=
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ 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"
|
||||
|
|
@ -42,6 +43,7 @@ func init() {
|
|||
_ = kruiseappsv1beta1.AddToScheme(Scheme)
|
||||
_ = kruiserolloutsv1alpha1.AddToScheme(Scheme)
|
||||
_ = kruiserolloutsv1beta1.AddToScheme(Scheme)
|
||||
_ = kruisepolicyv1alpha1.AddToScheme(Scheme)
|
||||
}
|
||||
|
||||
func GetScheme() *runtime.Scheme {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,10 @@ import (
|
|||
"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"
|
||||
|
|
@ -443,6 +445,8 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||
cmds.AddCommand(alpha)
|
||||
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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ func (o *ApproveOptions) Validate() error {
|
|||
}
|
||||
|
||||
// RunApprove performs the execution of 'rollout approve' sub command
|
||||
func (o ApproveOptions) RunApprove() error {
|
||||
func (o *ApproveOptions) RunApprove() error {
|
||||
r := o.Builder().
|
||||
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
|
||||
NamespaceParam(o.Namespace).DefaultNamespace().
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -20,15 +20,19 @@ package rollout
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
rolloutsapi "github.com/openkruise/kruise-rollout-api/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"
|
||||
"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"
|
||||
|
|
@ -49,6 +53,8 @@ type UndoOptions struct {
|
|||
EnforceNamespace bool
|
||||
RESTClientGetter genericclioptions.RESTClientGetter
|
||||
|
||||
Fast bool // fast rollback for blue-green
|
||||
|
||||
resource.FilenameOptions
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
|
@ -71,7 +77,10 @@ var (
|
|||
kubectl-kruise rollout undo --dry-run=server deployment/abc
|
||||
|
||||
# Rollback to workload via rollout api object
|
||||
kubectl-kruise rollout undo rollout/abc`)
|
||||
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
|
||||
|
|
@ -98,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())
|
||||
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)
|
||||
|
|
@ -143,6 +157,76 @@ func (o *UndoOptions) Validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *UndoOptions) FastUndo() 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(), 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().
|
||||
|
|
@ -197,11 +281,10 @@ func (o *UndoOptions) RunUndo() error {
|
|||
if obj == nil {
|
||||
return fmt.Errorf("Rollout object not found")
|
||||
}
|
||||
ro, ok := obj.(*rolloutsapi.Rollout)
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported version of Rollout")
|
||||
workloadRef, err := getWorkloadRefFromRollout(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
workloadRef := ro.Spec.WorkloadRef
|
||||
gv, err := schema.ParseGroupVersion(workloadRef.APIVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -246,3 +329,19 @@ func (o *UndoOptions) RunUndo() error {
|
|||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package polymorphichelpers
|
||||
|
||||
import (
|
||||
rolloutschema "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type RolloutViewer func(obj runtime.Unstructured) (*rolloutschema.Rollout, error)
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
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 polymorphichelpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
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"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
)
|
||||
|
||||
// getViewer returns a printer for Kruise resources
|
||||
func getViewer(obj runtime.Object) (interface{}, error) {
|
||||
switch obj.(type) {
|
||||
case *kruiseappsv1alpha1.CloneSet,
|
||||
*kruiseappsv1beta1.StatefulSet,
|
||||
*kruiseappsv1alpha1.DaemonSet,
|
||||
*rolloutv1beta1.Rollout,
|
||||
*rolloutv1alpha1.Rollout,
|
||||
*kruiseappsv1alpha1.BroadcastJob,
|
||||
*kruiseappsv1alpha1.ContainerRecreateRequest,
|
||||
*kruiseappsv1alpha1.AdvancedCronJob,
|
||||
*kruiseappsv1alpha1.ResourceDistribution,
|
||||
*kruiseappsv1alpha1.UnitedDeployment,
|
||||
*kruiseappsv1alpha1.SidecarSet,
|
||||
*kruiseappsv1alpha1.PodProbeMarker,
|
||||
*kruiseappsv1alpha1.ImagePullJob,
|
||||
*kruisepolicyv1alpha1.PodUnavailableBudget:
|
||||
return printers.NewTablePrinter(printers.PrintOptions{
|
||||
WithKind: true,
|
||||
WithNamespace: true,
|
||||
}), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("no viewer has been implemented for %T", obj)
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/kubectl/pkg/cmd/set"
|
||||
)
|
||||
|
||||
// LogsForObjectFunc is a function type that can tell you how to get logs for a runtime.object
|
||||
|
|
@ -51,6 +52,10 @@ type StatusViewerFunc func(mapping *meta.RESTMapping) (StatusViewer, error)
|
|||
// StatusViewerFn gives a way to easily override the function for unit testing if needed
|
||||
var StatusViewerFn StatusViewerFunc = statusViewer
|
||||
|
||||
type RolloutViewerFunc func(obj runtime.Object) (interface{}, error)
|
||||
|
||||
var RolloutViewerFn RolloutViewerFunc = rolloutViewer
|
||||
|
||||
// UpdatePodSpecForObjectFunc will call the provided function on the pod spec this object supports,
|
||||
// return false if no pod spec is supported, or return an error.
|
||||
type UpdatePodSpecForObjectFunc func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error)
|
||||
|
|
@ -58,6 +63,10 @@ type UpdatePodSpecForObjectFunc func(obj runtime.Object, fn func(*v1.PodSpec) er
|
|||
// UpdatePodSpecForObjectFn gives a way to easily override the function for unit testing if needed
|
||||
var UpdatePodSpecForObjectFn UpdatePodSpecForObjectFunc = updatePodSpecForObject
|
||||
|
||||
type GetViewerFunc func(obj runtime.Object) (interface{}, error)
|
||||
|
||||
var GetViewerFn GetViewerFunc = getViewer
|
||||
|
||||
// MapBasedSelectorForObjectFunc will call the provided function on mapping the baesd selector for object,
|
||||
// return "" if object is not supported, or return an error.
|
||||
type MapBasedSelectorForObjectFunc func(object runtime.Object) (string, error)
|
||||
|
|
@ -120,3 +129,6 @@ type ObjectRestarterFunc func(runtime.Object) ([]byte, error)
|
|||
// ObjectRestarterFn gives a way to easily override the function for unit testing if needed.
|
||||
// Returns the patched object in bytes and any error that occurred during the encoding.
|
||||
var ObjectRestarterFn ObjectRestarterFunc = defaultObjectRestarter
|
||||
|
||||
// DefaultFastRollbackFunc is a function type that rollbacks a rollout process.
|
||||
var DefaultFastRollbackFunc set.PatchFn = defaultRolloutRollbackGetter(-1)
|
||||
|
|
|
|||
|
|
@ -36,10 +36,20 @@ func defaultObjectApprover(obj runtime.Object) ([]byte, error) {
|
|||
obj.Status.CanaryStatus.CurrentStepState = rolloutsapiv1alpha1.CanaryStepStateReady
|
||||
return runtime.Encode(scheme.Codecs.LegacyCodec(rolloutsapiv1alpha1.GroupVersion), obj)
|
||||
case *rolloutsapiv1beta1.Rollout:
|
||||
if obj.Status.CanaryStatus == nil || obj.Status.CanaryStatus.CurrentStepState != rolloutsapiv1beta1.CanaryStepStatePaused {
|
||||
return nil, errors.New("does not allow to approve, because current canary state is not 'StepPaused'")
|
||||
switch {
|
||||
case obj.Status.CanaryStatus != nil:
|
||||
if obj.Status.CanaryStatus.CurrentStepState != rolloutsapiv1beta1.CanaryStepStatePaused {
|
||||
return nil, fmt.Errorf("does not allow to approve, because current canary state is not '%s'", rolloutsapiv1beta1.CanaryStepStatePaused)
|
||||
}
|
||||
obj.Status.CanaryStatus.CurrentStepState = rolloutsapiv1beta1.CanaryStepStateReady
|
||||
case obj.Status.BlueGreenStatus != nil:
|
||||
if obj.Status.BlueGreenStatus.CurrentStepState != rolloutsapiv1beta1.CanaryStepStatePaused {
|
||||
return nil, fmt.Errorf("does not allow to approve, because current blue-green state is not '%s'", rolloutsapiv1beta1.CanaryStepStatePaused)
|
||||
}
|
||||
obj.Status.BlueGreenStatus.CurrentStepState = rolloutsapiv1beta1.CanaryStepStateReady
|
||||
default:
|
||||
return nil, fmt.Errorf("no need to approve: not in canary or blue-green progress")
|
||||
}
|
||||
return runtime.Encode(scheme.Codecs.LegacyCodec(rolloutsapiv1beta1.GroupVersion), obj)
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
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 polymorphichelpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
rolloutv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1"
|
||||
rolloutv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
|
||||
)
|
||||
|
||||
// statusViewer returns a StatusViewer for printing rollout status.
|
||||
func rolloutViewer(obj runtime.Object) (interface{}, error) {
|
||||
if rollout, ok := obj.(*rolloutv1beta1.Rollout); ok {
|
||||
return rollout, nil
|
||||
}
|
||||
if rollout, ok := obj.(*rolloutv1alpha1.Rollout); ok {
|
||||
return rollout, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unknown rollout type: %T", obj)
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package polymorphichelpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
)
|
||||
|
||||
func defaultRolloutRollbackGetter(targetStep int32) func(runtime.Object) ([]byte, error) {
|
||||
return func(obj runtime.Object) ([]byte, error) {
|
||||
switch rollout := obj.(type) {
|
||||
case *v1beta1.Rollout:
|
||||
steps := rollout.Spec.Strategy.GetSteps()
|
||||
curStep := rollout.Status.CurrentStepIndex
|
||||
if len(steps) < int(curStep) {
|
||||
return nil, fmt.Errorf("has %d steps, but current step is too large %d", len(steps), curStep)
|
||||
}
|
||||
if curStep <= 1 {
|
||||
return nil, fmt.Errorf("already at the first step")
|
||||
}
|
||||
if targetStep == -1 {
|
||||
s, err := findPreviousStepWithNoTrafficAndMostReplicas(steps, rollout.Status.CurrentStepIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
targetStep = s
|
||||
}
|
||||
if targetStep >= rollout.Status.CurrentStepIndex {
|
||||
return nil, fmt.Errorf("specified step %d is not a previous step (current step is %d)", targetStep, rollout.Status.CurrentStepIndex)
|
||||
}
|
||||
style := rollout.Spec.Strategy.GetRollingStyle()
|
||||
switch style {
|
||||
case v1beta1.BlueGreenRollingStyle:
|
||||
rollout.Status.BlueGreenStatus.NextStepIndex = targetStep
|
||||
default:
|
||||
// canary and partition
|
||||
rollout.Status.CanaryStatus.NextStepIndex = targetStep
|
||||
}
|
||||
return runtime.Encode(scheme.Codecs.LegacyCodec(v1beta1.GroupVersion), rollout)
|
||||
default:
|
||||
return nil, fmt.Errorf("rollback is not supported on given object")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func findPreviousStepWithNoTrafficAndMostReplicas(steps []v1beta1.CanaryStep, curStep int32) (int32, error) {
|
||||
maxReplicas := 0
|
||||
var targetStep int32 = -1
|
||||
for i := curStep - 2; i >= 0; i-- {
|
||||
step := steps[i]
|
||||
if hasTraffic(step) {
|
||||
klog.V(5).InfoS("has traffic", "step", i+1)
|
||||
continue
|
||||
}
|
||||
replicas, _ := intstr.GetScaledValueFromIntOrPercent(step.Replicas, 100, true)
|
||||
klog.V(5).InfoS("replicas percent", "percent", replicas, "step", i+1, "obj", step)
|
||||
if replicas > maxReplicas {
|
||||
maxReplicas = replicas
|
||||
targetStep = i + 1
|
||||
}
|
||||
}
|
||||
if targetStep == -1 {
|
||||
return 0, fmt.Errorf("no previous step with no traffic found")
|
||||
}
|
||||
return targetStep, nil
|
||||
}
|
||||
|
||||
func hasTraffic(step v1beta1.CanaryStep) bool {
|
||||
if step.Traffic == nil {
|
||||
return false
|
||||
}
|
||||
is := intstr.FromString(*step.Traffic)
|
||||
trafficPercent, _ := intstr.GetScaledValueFromIntOrPercent(&is, 100, true)
|
||||
return trafficPercent != 0
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
package polymorphichelpers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1"
|
||||
"github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
func init() {
|
||||
_ = v1beta1.AddToScheme(scheme.Scheme)
|
||||
}
|
||||
|
||||
func TestRolloutRollbackGetter(t *testing.T) {
|
||||
getRollout := func(currentIdx int32, steps []v1beta1.CanaryStep) []client.Object {
|
||||
canary := &v1beta1.Rollout{
|
||||
Status: v1beta1.RolloutStatus{
|
||||
CurrentStepIndex: currentIdx,
|
||||
},
|
||||
}
|
||||
canary.Spec.Strategy.Canary = &v1beta1.CanaryStrategy{
|
||||
Steps: steps,
|
||||
EnableExtraWorkloadForCanary: true,
|
||||
}
|
||||
canary.Status.CanaryStatus = &v1beta1.CanaryStatus{}
|
||||
|
||||
blueGreen := canary.DeepCopy()
|
||||
blueGreen.Spec.Strategy.BlueGreen = &v1beta1.BlueGreenStrategy{
|
||||
Steps: steps,
|
||||
}
|
||||
blueGreen.Status.BlueGreenStatus = &v1beta1.BlueGreenStatus{}
|
||||
|
||||
return []client.Object{canary, blueGreen}
|
||||
}
|
||||
newStep := func(replicas string, traffic string) v1beta1.CanaryStep {
|
||||
r := intstr.FromString(replicas)
|
||||
var trafficPtr *string
|
||||
if traffic != "" {
|
||||
trafficPtr = &traffic
|
||||
}
|
||||
return v1beta1.CanaryStep{
|
||||
Replicas: &r,
|
||||
TrafficRoutingStrategy: v1beta1.TrafficRoutingStrategy{
|
||||
Traffic: trafficPtr,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
rollout []client.Object
|
||||
targetStep int32
|
||||
expectedStep int32
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "valid rollback to previous step",
|
||||
rollout: getRollout(3, []v1beta1.CanaryStep{
|
||||
newStep("10%", ""),
|
||||
newStep("20%", ""),
|
||||
newStep("30%", ""),
|
||||
}),
|
||||
targetStep: 2,
|
||||
expectedStep: 2,
|
||||
},
|
||||
{
|
||||
name: "invalid rollback to same or future step",
|
||||
rollout: getRollout(3, []v1beta1.CanaryStep{
|
||||
newStep("10%", ""),
|
||||
newStep("20%", ""),
|
||||
newStep("30%", ""),
|
||||
}),
|
||||
targetStep: 3,
|
||||
expectedErr: "specified step 3 is not a previous step (current step is 3)",
|
||||
},
|
||||
{
|
||||
name: "rollback to previous step with no traffic and most replicas",
|
||||
rollout: getRollout(4, []v1beta1.CanaryStep{
|
||||
newStep("10%", ""),
|
||||
newStep("20%", ""),
|
||||
newStep("30%", "50%"),
|
||||
newStep("40%", "50%"),
|
||||
}),
|
||||
targetStep: -1,
|
||||
expectedStep: 2,
|
||||
},
|
||||
{
|
||||
name: "no previous step with no traffic found",
|
||||
rollout: getRollout(5, []v1beta1.CanaryStep{
|
||||
newStep("10%", "10%"),
|
||||
newStep("20%", "10%"),
|
||||
newStep("30%", "10%"),
|
||||
newStep("40%", "10%"),
|
||||
newStep("50%", "10%"),
|
||||
}),
|
||||
targetStep: -1,
|
||||
expectedErr: "no previous step with no traffic found",
|
||||
},
|
||||
{
|
||||
name: "already at the first step",
|
||||
rollout: getRollout(1, []v1beta1.CanaryStep{
|
||||
newStep("10%", ""),
|
||||
}),
|
||||
targetStep: 2,
|
||||
expectedErr: "already at the first step",
|
||||
},
|
||||
{
|
||||
name: "current step index out of range",
|
||||
rollout: getRollout(3, []v1beta1.CanaryStep{
|
||||
newStep("10%", ""),
|
||||
newStep("20%", ""),
|
||||
}),
|
||||
targetStep: 2,
|
||||
expectedErr: "has 2 steps, but current step is too large 3",
|
||||
},
|
||||
{
|
||||
name: "not supported object",
|
||||
rollout: []client.Object{&v1alpha1.Rollout{}},
|
||||
expectedErr: "rollback is not supported on given object",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
rollback := defaultRolloutRollbackGetter(tt.targetStep)
|
||||
for _, rollout := range tt.rollout {
|
||||
data, err := rollback(rollout)
|
||||
if tt.expectedErr != "" {
|
||||
if err == nil || err.Error() != tt.expectedErr {
|
||||
t.Errorf("expected error %v, got %v", tt.expectedErr, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
var updatedRollout v1beta1.Rollout
|
||||
if err := json.Unmarshal(data, &updatedRollout); err != nil {
|
||||
t.Errorf("failed to unmarshal updated rollout: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
var nextStepIndex int32
|
||||
if updatedRollout.Spec.Strategy.GetRollingStyle() == v1beta1.BlueGreenRollingStyle {
|
||||
nextStepIndex = updatedRollout.Status.BlueGreenStatus.NextStepIndex
|
||||
} else {
|
||||
nextStepIndex = updatedRollout.Status.CanaryStatus.NextStepIndex
|
||||
}
|
||||
|
||||
if nextStepIndex != tt.expectedStep {
|
||||
t.Errorf("expected next step index %d, got %d", tt.expectedStep, nextStepIndex)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -22,10 +22,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
|
||||
"github.com/openkruise/kruise-tools/pkg/api"
|
||||
"github.com/openkruise/kruise-tools/pkg/migration"
|
||||
"github.com/openkruise/kruise-tools/pkg/utils"
|
||||
"k8s.io/client-go/discovery"
|
||||
|
||||
apps "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -35,10 +32,15 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/restmapper"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
|
||||
"github.com/openkruise/kruise-tools/pkg/api"
|
||||
"github.com/openkruise/kruise-tools/pkg/migration"
|
||||
"github.com/openkruise/kruise-tools/pkg/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -81,10 +83,16 @@ func NewControl(cfg *rest.Config, stopChan <-chan struct{}) (migration.Control,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mapper, err := apiutil.NewDiscoveryRESTMapper(cfg, c)
|
||||
// Get a mapper
|
||||
dc, err := discovery.NewDiscoveryClientForConfigAndClient(cfg, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gr, err := restmapper.GetAPIGroupResources(dc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mapper := restmapper.NewDiscoveryRESTMapper(gr)
|
||||
|
||||
ctrl := &control{
|
||||
stopChan: stopChan,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
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 utils
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestInt32Min(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
a int32
|
||||
items []int32
|
||||
expected int32
|
||||
}{
|
||||
{
|
||||
name: "No extra items",
|
||||
a: 10,
|
||||
items: []int32{},
|
||||
expected: 10,
|
||||
},
|
||||
{
|
||||
name: "All positive numbers",
|
||||
a: 10,
|
||||
items: []int32{5, 20, 12},
|
||||
expected: 5,
|
||||
},
|
||||
{
|
||||
name: "With negative numbers",
|
||||
a: -5,
|
||||
items: []int32{10, -2, -10},
|
||||
expected: -10,
|
||||
},
|
||||
{
|
||||
name: "With zero",
|
||||
a: 1,
|
||||
items: []int32{5, 0, 2},
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
name: "All numbers are the same",
|
||||
a: 7,
|
||||
items: []int32{7, 7, 7},
|
||||
expected: 7,
|
||||
},
|
||||
{
|
||||
name: "Initial value 'a' is the minimum",
|
||||
a: 3,
|
||||
items: []int32{10, 5, 8},
|
||||
expected: 3,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got := Int32Min(tc.a, tc.items...); got != tc.expected {
|
||||
t.Errorf("Int32Min() = %v, want %v", got, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
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 utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Helper function for string pointers
|
||||
func strPtr(s string) *string { return &s }
|
||||
|
||||
func TestIsKruiseRolloutsAnnotation(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input *string
|
||||
expected bool
|
||||
}{
|
||||
{name: "Nil string", input: nil, expected: false},
|
||||
{name: "Kruise prefix", input: strPtr("rollouts.kruise.io/annotation"), expected: true},
|
||||
{name: "Non-matching string", input: strPtr("other.domain/key"), expected: false},
|
||||
{name: "Exact prefix", input: strPtr("rollouts.kruise.io/"), expected: true},
|
||||
{name: "Empty string", input: strPtr(""), expected: false},
|
||||
{name: "Substring match", input: strPtr("pre/rollouts.kruise.io/suffix"), expected: true},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got := IsKruiseRolloutsAnnotation(tc.input); got != tc.expected {
|
||||
t.Errorf("expected %v, got %v", tc.expected, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInCanaryProgress(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
deployment *appsv1.Deployment
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "Not paused",
|
||||
deployment: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{Paused: false},
|
||||
ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{InRolloutProgressingAnnotation: "true"}},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Missing progressing annotation",
|
||||
deployment: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{Paused: true},
|
||||
ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{}},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Has strategy annotation",
|
||||
deployment: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{Paused: true},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: map[string]string{
|
||||
InRolloutProgressingAnnotation: "true",
|
||||
DeploymentStrategyAnnotation: "partition",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Valid canary state",
|
||||
deployment: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{Paused: true},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: map[string]string{InRolloutProgressingAnnotation: "true"},
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "Nil annotations",
|
||||
deployment: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{Paused: true},
|
||||
ObjectMeta: metav1.ObjectMeta{},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Explicit empty annotations",
|
||||
deployment: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{Paused: true},
|
||||
ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{}},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Only strategy annotation present",
|
||||
deployment: &appsv1.Deployment{
|
||||
Spec: appsv1.DeploymentSpec{Paused: true},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: map[string]string{DeploymentStrategyAnnotation: "partition"},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got := InCanaryProgress(tc.deployment); got != tc.expected {
|
||||
t.Errorf("expected %v, got %v", tc.expected, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue