File kubectl-view-allocations-0.22.1.obscpio of Package kubectl-view-allocations
07070100000000000041ED000000000000000000000002685BA88A00000000000000000000000000000000000000000000002800000000kubectl-view-allocations-0.22.1/.github07070100000001000081A4000000000000000000000001685BA88A00000282000000000000000000000000000000000000003400000000kubectl-view-allocations-0.22.1/.github/FUNDING.yml# These are supported funding model platforms
github: [davidB]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
07070100000002000081A4000000000000000000000001685BA88A0000014D000000000000000000000000000000000000003700000000kubectl-view-allocations-0.22.1/.github/dependabot.ymlversion: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
allow:
- dependency-type: "direct"
- package-ecosystem: "github-actions"
# Workflow files stored in the
# default location of `.github/workflows`
directory: "/"
schedule:
interval: "weekly"
07070100000003000041ED000000000000000000000002685BA88A00000000000000000000000000000000000000000000003200000000kubectl-view-allocations-0.22.1/.github/workflows07070100000004000081A4000000000000000000000001685BA88A00000B8E000000000000000000000000000000000000003A00000000kubectl-view-allocations-0.22.1/.github/workflows/ci.yamlname: ci-flow
on:
pull_request:
push:
branches:
- master
- "releases/*"
# tags-ignore:
# - "[0-9]+.[0-9]+.[0-9]+*"
permissions:
contents: read
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
jobs:
build:
runs-on: ${{ matrix.os.imageName }}
strategy:
matrix:
rust_toolchain: ["stable"]
os:
- imageName: ubuntu-latest
profile_rustup: default
profile_ci_flow: ci-static-code-analysis-tasks
target_platform: x86_64-unknown-linux-gnu
- target_platform: x86_64-apple-darwin
imageName: "macOS-latest"
profile_rustup: minimal
profile_ci_flow: none
# - imageName: "macOS-latest"
# profile_rustup: minimal
# profile_ci_flow: none
# target_platform: aarch64-apple-darwin
# - imageName: windows-latest
# profile_rustup: minimal
# profile_ci_flow: none
# target_platform:
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust_toolchain }}
targets: ${{ matrix.os.target_platform }}
- uses: mozilla-actions/sccache-action@v0.0.9
- uses: davidB/rust-cargo-make@v1
- name: Run tests
run: cargo make --disable-check-for-updates --profile "${{ matrix.os.profile_ci_flow }}" ci-flow
env:
TARGET: ${{ matrix.os.target_paddlatform }}
# for list of xcode sdk see https://help.github.com/en/actions/automating-your-workflow-with-github-actions/software-installed-on-github-hosted-runners#xcode
# DEVELOPER_DIR: "/Applications/Xcode_11.app/Contents/Developer"
CARGO_MAKE_RUN_CODECOV: "false"
# to have CODECOV_TOKEN go to https://codecov.io/gh/${GITHUB_USER}/${GITHUB_REPO}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- run: ${SCCACHE_PATH} --show-stats
shell: bash
integration:
# Integration tests are linux only
runs-on: ubuntu-latest
steps:
- uses: nolar/setup-k3d-k3s@v1
with:
# version: v1.20
# k3d-kube
k3d-name: kube
# Used to avoid rate limits when fetching the releases from k3s repo.
# Anonymous access is limited to 60 requests / hour / worker
# github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: mozilla-actions/sccache-action@v0.0.9
- name: Run on k3d
run: cargo run
- run: ${SCCACHE_PATH} --show-stats
shell: bash
07070100000005000081A4000000000000000000000001685BA88A000009EE000000000000000000000000000000000000003F00000000kubectl-view-allocations-0.22.1/.github/workflows/release.yamlname: release-flow
# https://help.github.com/en/articles/events-that-trigger-workflows#release-event-release
# on: release
on:
workflow_dispatch:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+*"
permissions:
contents: write
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
jobs:
build:
runs-on: ${{ matrix.os.imageName }}
strategy:
matrix:
rust_toolchain: ["stable"]
os:
- target_platform: x86_64-unknown-linux-gnu
imageName: ubuntu-latest
cross: "true"
- target_platform: x86_64-unknown-linux-musl
imageName: ubuntu-latest
cross: "true"
- target_platform: aarch64-unknown-linux-musl
imageName: ubuntu-latest
cross: "true"
- target_platform: x86_64-apple-darwin
imageName: "macOS-latest"
- target_platform: aarch64-apple-darwin
imageName: "macOS-latest"
- target_platform: x86_64-pc-windows-msvc
imageName: windows-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust_toolchain }}
targets: ${{ matrix.os.target_platform }}
- uses: mozilla-actions/sccache-action@v0.0.9
- uses: davidB/rust-cargo-make@v1
- name: Make zip-release-ci-flow
id: zip-release-ci-flow
run: cargo make --disable-check-for-updates zip-release-ci-flow
env:
TARGET: ${{ matrix.os.target_platform }}
CROSS: ${{ matrix.os.cross }}
# DEVELOPER_DIR: "/Applications/Xcode_11.app/Contents/Developer"
- name: Upload binaries to release
# if: startsWith(github.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ steps.zip-release-ci-flow.outputs.dist_file_path }}
# asset_name: ${{ steps.zip-release-ci-flow.outputs.dist_file_name }}
# tag: ${{ github.ref }}
tag: ${{ steps.zip-release-ci-flow.outputs.dist_version }}
prerelease: false # ${{ github.ref == format('refs/tags/{0}', steps.zip-release-ci-flow.outputs.dist_version) }}
overwrite: true
- run: ${SCCACHE_PATH} --show-stats
shell: bash
krew-update:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Update new version in krew-index
uses: rajatjindal/krew-release-bot@v0.0.47
07070100000006000081A4000000000000000000000001685BA88A000005BC000000000000000000000000000000000000002B00000000kubectl-view-allocations-0.22.1/.gitignore# Created by https://www.gitignore.io/api/git,rust,macos,visualstudiocode
# Edit at https://www.gitignore.io/?templates=git,rust,macos,visualstudiocode
### Git ###
# Created by git for backups. To disable backups in Git:
# $ git config --global mergetool.keepBackup false
*.orig
# Created by git when using merge tools for conflicts
*.BACKUP.*
*.BASE.*
*.LOCAL.*
*.REMOTE.*
*_BACKUP_*.txt
*_BASE_*.txt
*_LOCAL_*.txt
*_REMOTE_*.txt
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Rust ###
# Generated by Cargo
# will have compiled files and executables
/target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
# End of https://www.gitignore.io/api/git,rust,macos,visualstudiocode
!Cargo.lock
07070100000007000081A4000000000000000000000001685BA88A00000871000000000000000000000000000000000000002B00000000kubectl-view-allocations-0.22.1/.krew.yamlapiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: view-allocations
spec:
version: "v{{ .TagName }}"
platforms:
- selector:
matchLabels:
os: darwin
arch: amd64
{{addURIAndSha "https://github.com/davidB/kubectl-view-allocations/releases/download/{{ .TagName }}/kubectl-view-allocations_{{ .TagName }}-x86_64-apple-darwin.tar.gz" .TagName | indent 6 }}
bin: "./kubectl-view-allocations"
- selector:
matchLabels:
os: darwin
arch: arm64
{{addURIAndSha "https://github.com/davidB/kubectl-view-allocations/releases/download/{{ .TagName }}/kubectl-view-allocations_{{ .TagName }}-aarch64-apple-darwin.tar.gz" .TagName | indent 6}}
bin: "./kubectl-view-allocations"
- selector:
matchLabels:
os: linux
arch: amd64
{{addURIAndSha "https://github.com/davidB/kubectl-view-allocations/releases/download/{{ .TagName }}/kubectl-view-allocations_{{ .TagName }}-x86_64-unknown-linux-musl.tar.gz" .TagName | indent 6}}
bin: "./kubectl-view-allocations"
- selector:
matchLabels:
os: linux
arch: arm64
{{addURIAndSha "https://github.com/davidB/kubectl-view-allocations/releases/download/{{ .TagName }}/kubectl-view-allocations_{{ .TagName }}-aarch64-unknown-linux-musl.tar.gz" .TagName | indent 6}}
bin: "./kubectl-view-allocations"
- selector:
matchLabels:
os: windows
arch: amd64
{{addURIAndSha "https://github.com/davidB/kubectl-view-allocations/releases/download/{{ .TagName }}/kubectl-view-allocations_{{ .TagName }}-x86_64-pc-windows-msvc.zip" .TagName | indent 6}}
bin: "./kubectl-view-allocations.exe"
shortDescription: List allocations per resources, nodes, pods.
homepage: https://github.com/davidB/kubectl-view-allocations
description: |
This plugin lists resources (cpu, memory, gpu,...) allocations (requested,
limit, allocatable) as defined in the manifest of nodes and running pods,
and utilization from metrics-server.
try `kubectl view-allocations -h`, `kubectl view-allocations`
07070100000008000081A4000000000000000000000001685BA88A00000157000000000000000000000000000000000000002B00000000kubectl-view-allocations-0.22.1/.mise.toml[env]
CLUSTER_NAME = "demo-kube"
DOCKER_BUILDKIT = "1"
# BP_RUST_TOOLCHAIN = "1.86"
# KIND_EXPERIMENTAL_PROVIDER = "podman" # to use podman and podman-docker
[tools]
# docker (or podman + some config) should be available for some of thoses tools
# helm = '3.12'
kubectl = '1.24'
# helmfile = '0.155'
kind = '0.20'
just = '1.14'
rust = '1.86'
07070100000009000041ED000000000000000000000002685BA88A00000000000000000000000000000000000000000000002800000000kubectl-view-allocations-0.22.1/.vscode0707010000000A000081A4000000000000000000000001685BA88A0000006F000000000000000000000000000000000000003600000000kubectl-view-allocations-0.22.1/.vscode/settings.json{
"spellright.language": [],
"spellright.documentTypes": [
"latex",
"plaintext"
]
}0707010000000B000081A4000000000000000000000001685BA88A0000FF05000000000000000000000000000000000000002B00000000kubectl-view-allocations-0.22.1/Cargo.lock# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "addr2line"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
"gimli",
]
[[package]]
name = "adler2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "ahash"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [
"cfg-if",
"getrandom 0.3.3",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "async-compression"
version = "0.4.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d615619615a650c571269c00dca41db04b9210037fa76ed8239f70404ab56985"
dependencies = [
"flate2",
"futures-core",
"memchr",
"pin-project-lite",
"tokio",
]
[[package]]
name = "async-socks5"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da2537846e16b96d2972ee52a3b355663872a1a687ce6d57a3b6f6b6a181c89"
dependencies = [
"thiserror 1.0.69",
"tokio",
]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "backtrace"
version = "0.3.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
"windows-targets",
]
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee"
[[package]]
name = "bytes"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
version = "1.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]]
name = "chrono"
version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-link",
]
[[package]]
name = "clap"
version = "4.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
[[package]]
name = "color-eyre"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d"
dependencies = [
"backtrace",
"color-spantrace",
"eyre",
"indenter",
"once_cell",
"owo-colors",
"tracing-error",
]
[[package]]
name = "color-spantrace"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427"
dependencies = [
"once_cell",
"owo-colors",
"tracing-core",
"tracing-error",
]
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "data-encoding"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
[[package]]
name = "deranged"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
dependencies = [
"powerfmt",
]
[[package]]
name = "derive_more"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "displaydoc"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "eyre"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
dependencies = [
"indenter",
"once_cell",
]
[[package]]
name = "flate2"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]]
name = "futures"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-executor"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-macro"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-sink"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
[[package]]
name = "futures-task"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
[[package]]
name = "futures-util"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "gethostname"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
"wasi 0.11.1+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
]
[[package]]
name = "gimli"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "hashbrown"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
[[package]]
name = "headers"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
dependencies = [
"base64",
"bytes",
"headers-core",
"http",
"httpdate",
"mime",
"sha1",
]
[[package]]
name = "headers-core"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
dependencies = [
"http",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]]
name = "home"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "http"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "httpdate"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http",
"http-body",
"httparse",
"itoa",
"pin-project-lite",
"smallvec",
"tokio",
"want",
]
[[package]]
name = "hyper-http-proxy"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ad4b0a1e37510028bc4ba81d0e38d239c39671b0f0ce9e02dfa93a8133f7c08"
dependencies = [
"bytes",
"futures-util",
"headers",
"http",
"hyper",
"hyper-rustls",
"hyper-util",
"pin-project-lite",
"rustls-native-certs 0.7.3",
"tokio",
"tokio-rustls",
"tower-service",
]
[[package]]
name = "hyper-rustls"
version = "0.27.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
dependencies = [
"http",
"hyper",
"hyper-util",
"log",
"rustls",
"rustls-native-certs 0.8.1",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
"webpki-roots",
]
[[package]]
name = "hyper-socks2"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51c227614c208f7e7c2e040526912604a1a957fe467c9c2f5b06c5d032337dab"
dependencies = [
"async-socks5",
"http",
"hyper",
"hyper-util",
"thiserror 1.0.69",
"tokio",
"tower-service",
]
[[package]]
name = "hyper-timeout"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
dependencies = [
"hyper",
"hyper-util",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http",
"http-body",
"hyper",
"libc",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
]
[[package]]
name = "iana-time-zone"
version = "0.1.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "icu_collections"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
dependencies = [
"displaydoc",
"potential_utf",
"yoke",
"zerofrom",
"zerovec",
]
[[package]]
name = "icu_locale_core"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
dependencies = [
"displaydoc",
"litemap",
"tinystr",
"writeable",
"zerovec",
]
[[package]]
name = "icu_normalizer"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
dependencies = [
"displaydoc",
"icu_collections",
"icu_normalizer_data",
"icu_properties",
"icu_provider",
"smallvec",
"zerovec",
]
[[package]]
name = "icu_normalizer_data"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
[[package]]
name = "icu_properties"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
dependencies = [
"displaydoc",
"icu_collections",
"icu_locale_core",
"icu_properties_data",
"icu_provider",
"potential_utf",
"zerotrie",
"zerovec",
]
[[package]]
name = "icu_properties_data"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
[[package]]
name = "icu_provider"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
dependencies = [
"displaydoc",
"icu_locale_core",
"stable_deref_trait",
"tinystr",
"writeable",
"yoke",
"zerofrom",
"zerotrie",
"zerovec",
]
[[package]]
name = "idna"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
dependencies = [
"idna_adapter",
"smallvec",
"utf8_iter",
]
[[package]]
name = "idna_adapter"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
dependencies = [
"icu_normalizer",
"icu_properties",
]
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indexmap"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "is-terminal"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi",
"libc",
"windows-sys 0.59.0",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "js-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "jsonpath-rust"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c00ae348f9f8fd2d09f82a98ca381c60df9e0820d8d79fce43e649b4dc3128b"
dependencies = [
"pest",
"pest_derive",
"regex",
"serde_json",
"thiserror 2.0.12",
]
[[package]]
name = "k8s-openapi"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa60a41b57ae1a0a071af77dbcf89fc9819cfe66edaf2beeb204c34459dcf0b2"
dependencies = [
"base64",
"chrono",
"serde",
"serde_json",
]
[[package]]
name = "kube"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778f98664beaf4c3c11372721e14310d1ae00f5e2d9aabcf8906c881aa4e9f51"
dependencies = [
"k8s-openapi",
"kube-client",
"kube-core",
]
[[package]]
name = "kube-client"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cb276b85b6e94ded00ac8ea2c68fcf4697ea0553cb25fddc35d4a0ab718db8d"
dependencies = [
"base64",
"bytes",
"chrono",
"either",
"form_urlencoded",
"futures",
"home",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-http-proxy",
"hyper-rustls",
"hyper-socks2",
"hyper-timeout",
"hyper-util",
"jsonpath-rust",
"k8s-openapi",
"kube-core",
"pem",
"rustls",
"secrecy",
"serde",
"serde_json",
"serde_yaml",
"tame-oauth",
"thiserror 2.0.12",
"tokio",
"tokio-util",
"tower",
"tower-http",
"tracing",
]
[[package]]
name = "kube-core"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c56ff45deb0031f2a476017eed60c06872251f271b8387ad8020b8fef60960"
dependencies = [
"chrono",
"derive_more",
"form_urlencoded",
"http",
"k8s-openapi",
"serde",
"serde-value",
"serde_json",
"thiserror 2.0.12",
]
[[package]]
name = "kubectl-view-allocations"
version = "0.22.1"
dependencies = [
"anyhow",
"chrono",
"clap",
"color-eyre",
"futures",
"itertools",
"k8s-openapi",
"kube",
"pretty_assertions",
"prettytable-rs",
"serde",
"serde_json",
"thiserror 2.0.12",
"tokio",
"tracing",
"tracing-bunyan-formatter",
"tracing-error",
"tracing-subscriber",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.173"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "litemap"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
[[package]]
name = "lock_api"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "memchr"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "miniz_oxide"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [
"adler2",
]
[[package]]
name = "mio"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
dependencies = [
"libc",
"wasi 0.11.1+wasi-snapshot-preview1",
"windows-sys 0.59.0",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "object"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "openssl-probe"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "ordered-float"
version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
dependencies = [
"num-traits",
]
[[package]]
name = "owo-colors"
version = "4.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26995317201fa17f3656c36716aed4a7c81743a9634ac4c99c0eeda495db0cec"
[[package]]
name = "parking_lot"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets",
]
[[package]]
name = "pem"
version = "3.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3"
dependencies = [
"base64",
"serde",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323"
dependencies = [
"memchr",
"thiserror 2.0.12",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5"
dependencies = [
"pest",
"sha2",
]
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "potential_utf"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
dependencies = [
"zerovec",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "pretty_assertions"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
dependencies = [
"diff",
"yansi",
]
[[package]]
name = "prettytable-rs"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a"
dependencies = [
"encode_unicode",
"is-terminal",
"lazy_static",
"term",
"unicode-width",
]
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "redox_syscall"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom 0.2.16",
"libredox",
"thiserror 1.0.69",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.9",
"regex-syntax 0.8.5",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax 0.6.29",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.5",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.16",
"libc",
"untrusted",
"windows-sys 0.52.0",
]
[[package]]
name = "rustc-demangle"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
[[package]]
name = "rustls"
version = "0.23.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643"
dependencies = [
"log",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5"
dependencies = [
"openssl-probe",
"rustls-pemfile",
"rustls-pki-types",
"schannel",
"security-framework 2.11.1",
]
[[package]]
name = "rustls-native-certs"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3"
dependencies = [
"openssl-probe",
"rustls-pki-types",
"schannel",
"security-framework 3.2.0",
]
[[package]]
name = "rustls-pemfile"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
dependencies = [
"zeroize",
]
[[package]]
name = "rustls-webpki"
version = "0.103.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "rustversion"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "schannel"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "secrecy"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a"
dependencies = [
"zeroize",
]
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags",
"core-foundation 0.9.4",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316"
dependencies = [
"bitflags",
"core-foundation 0.10.1",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
dependencies = [
"ordered-float",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook-registry"
version = "1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
dependencies = [
"libc",
]
[[package]]
name = "slab"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "socket2"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
[[package]]
name = "synstructure"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tame-oauth"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c206bbecfbc0aea8bf35f57bf34e8be060d2cf7efe3937f8d0bdfdd4205ed771"
dependencies = [
"data-encoding",
"http",
"ring",
"serde",
"serde_json",
"twox-hash",
"url",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl 2.0.12",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thiserror-impl"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
"cfg-if",
]
[[package]]
name = "time"
version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
[[package]]
name = "time-macros"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "tinystr"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
dependencies = [
"displaydoc",
"zerovec",
]
[[package]]
name = "tokio"
version = "1.45.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
dependencies = [
"backtrace",
"bytes",
"libc",
"mio",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys 0.52.0",
]
[[package]]
name = "tokio-macros"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-rustls"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"
dependencies = [
"rustls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tower"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-http"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
dependencies = [
"async-compression",
"base64",
"bitflags",
"bytes",
"futures-core",
"http",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-bunyan-formatter"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d637245a0d8774bd48df6482e086c59a8b5348a910c3b0579354045a9d82411"
dependencies = [
"ahash",
"gethostname",
"log",
"serde",
"serde_json",
"time",
"tracing",
"tracing-core",
"tracing-log",
"tracing-subscriber",
]
[[package]]
name = "tracing-core"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-error"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db"
dependencies = [
"tracing",
"tracing-subscriber",
]
[[package]]
name = "tracing-log"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
dependencies = [
"matchers",
"once_cell",
"regex",
"sharded-slab",
"thread_local",
"tracing",
"tracing-core",
]
[[package]]
name = "try-lock"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "twox-hash"
version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if",
"static_assertions",
]
[[package]]
name = "typenum"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "unicode-width"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "utf8_iter"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "want"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[package]]
name = "webpki-roots"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-result"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
[[package]]
name = "writeable"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
[[package]]
name = "yansi"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "yoke"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
dependencies = [
"serde",
"stable_deref_trait",
"yoke-derive",
"zerofrom",
]
[[package]]
name = "yoke-derive"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]]
name = "zerocopy"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zerofrom"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
dependencies = [
"zerofrom-derive",
]
[[package]]
name = "zerofrom-derive"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
[[package]]
name = "zerotrie"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
dependencies = [
"displaydoc",
"yoke",
"zerofrom",
]
[[package]]
name = "zerovec"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
dependencies = [
"yoke",
"zerofrom",
"zerovec-derive",
]
[[package]]
name = "zerovec-derive"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
0707010000000C000081A4000000000000000000000001685BA88A0000079D000000000000000000000000000000000000002B00000000kubectl-view-allocations-0.22.1/Cargo.toml[package]
name = "kubectl-view-allocations"
version = "0.22.1"
authors = ["David Bernard"]
edition = "2024"
description = "kubectl plugin to list allocations (cpu, memory, gpu,...) X (utilization, requested, limit, allocatable,...)"
readme = "README.md"
license = "CC0-1.0"
keywords = ["kubectl", "k8s"]
repository = "https://github.com/davidB/kubectl-view-allocations"
homepage = "https://github.com/davidB/kubectl-view-allocations"
exclude = ["/.github", ".gitignore"]
[dependencies]
chrono = "0.4"
clap = { version = "4.5", features = ["derive"] }
color-eyre = "0.6"
futures = "0.3"
itertools = "0.14"
k8s-openapi = { version = "0.25", default-features = false }
kube = { version = "1", features = [
"ring", # or "aws-lc-rs" for rustls-tls, "ring" is also a dependency of tame-oauth
"client",
"gzip",
"http-proxy",
"oauth",
"oidc",
"rustls-tls",
"socks5",
"webpki-roots",
], default-features = false }
prettytable-rs = { version = "0.10", default-features = false, optional = true }
serde = "1.0"
serde_json = "1.0"
thiserror = "2.0"
tokio = { version = "1", features = ["full"], optional = true }
tracing = "0.1"
tracing-bunyan-formatter = { version = "0.3", optional = true }
tracing-error = "0.2"
tracing-subscriber = { version = "0.3", optional = true, default-features = false, features = [
"env-filter",
] }
[features]
default = ["cli"]
cli = [
"dep:tokio",
"k8s-openapi/earliest",
"dep:tracing-subscriber",
"prettytable",
]
prettytable = ["dep:prettytable-rs"]
[[bin]]
name = "kubectl-view-allocations"
path = "src/main.rs"
doc = false
# HACK to define dependencies only for cli
# see https://github.com/rust-lang/cargo/issues/1982
required-features = ["cli"]
[dev-dependencies]
anyhow = "1"
pretty_assertions = "1"
[profile.release]
lto = true
panic = 'abort'
opt-level = 'z' # Optimize for size.
codegen-units = 1
strip = true
[profile.dev.package.backtrace]
opt-level = 3
0707010000000D000081A4000000000000000000000001685BA88A00001BD3000000000000000000000000000000000000002C00000000kubectl-view-allocations-0.22.1/LICENSE.txtCreative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.
0707010000000E000081A4000000000000000000000001685BA88A000016D4000000000000000000000000000000000000002E00000000kubectl-view-allocations-0.22.1/Makefile.toml# see https://crates.io/crates/cargo-make
[env]
RUST_TEST_THREADS = "1"
CARGO_MAKE_TEST_COVERAGE_BINARY_FILTER = "cli-[a-z0-9]*$\\|makers-[a-z0-9]*$\\|${CARGO_MAKE_TEST_COVERAGE_DEFAULT_BINARY_FILTER}"
# TARGET is {arch}-{vendor}-{sys}-{abi} the output of rustc --print target-list
TARGET_AUTO = { source = "${CARGO_MAKE_RUST_TARGET_ARCH}-${CARGO_MAKE_RUST_TARGET_VENDOR}-${CARGO_MAKE_RUST_TARGET_OS}-${CARGO_MAKE_RUST_TARGET_ENV}", mapping = { x86_64-apple-macos- = "x86_64-apple-darwin" } }
TARGET = { condition = { env_not_set = ["TARGET"] }, value = "${TARGET_AUTO}" }
LIBZ_SYS_STATIC = "1"
PKG_CONFIG_ALLOW_CROSS = "1"
# see https://github.com/naftulikay/rust-openssl-static-example
OPENSSL_STATIC = "1"
# OPENSSL_LIB_DIR="/usr/lib64"
# OPENSSL_INCLUDE_DIR="/usr/include/openssl"
CARGO_BUILD_CMD = { source = "${CROSS}", default_value = "cargo", mapping = { true = "cross" } }
[tasks.init.mac.env]
# workaround for "____chkstk_darwin ... which was built for Mac OS X 10.15 /usr/lib/libSystem.B.dylib"
# see https://github.com/sharkdp/bat/issues/680
# if DevelopmentTools.clang_build_version >= 1010
CFLAGS = "-fno-stack-check"
#RUSTFLAGS = "-Clink-args=-Wl,-bind_at_load"
# XCode --mmacosx-version-min=10.9 ?
MACOSX_DEPLOYMENT_TARGET = "10.9"
[tasks.dist_env.env]
DIST_VERSION = "${CARGO_MAKE_CRATE_VERSION}"
DIST_NAME = "${CARGO_MAKE_CRATE_NAME}_${DIST_VERSION}-${TARGET}"
DIST_EXT = { source = "${CARGO_MAKE_RUST_TARGET_OS}", default_value = "tar.gz", mapping = { windows = "zip" } }
DIST_PATH = "target/dist/${DIST_NAME}"
[tasks.debug]
dependencies = ["dist_env"]
script_runner = "@duckscript"
script = ['''
echo "PROFILE=${PROFILE}"
echo "MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET}"
echo "FILE=${DIST_PATH}.${DIST_EXT}"
echo "TARGET=${TARGET}"
echo "DIST_VERSION=${DIST_VERSION}"
echo "TAG=${TAG}"
echo "GITHUB_REF=${GITHUB_REF}"
echo "CARGO_BUILD_CMD=${CARGO_BUILD_CMD}"
echo ${CARGO_MAKE_PROFILE} : ${DIST_PATH} : ${platform}
''']
[tasks.zip-release-ci-flow]
description = "Compiles the binary in release mode and zips it up"
windows_alias = "zip-release-ci-flow_windows"
category = "CI"
condition = { env_set = ["TARGET"] }
dependencies = [
# "clean",
"dist_env",
"build-release-for-target",
"zip-release-binary-for-target",
]
script_runner = "@shell"
script = ['''
echo "dist_file_path=${DIST_PATH}.${DIST_EXT}" >> $GITHUB_OUTPUT
echo "dist_file_name=${DIST_NAME}.${DIST_EXT}" >> $GITHUB_OUTPUT
echo "dist_version=${DIST_VERSION}" >> $GITHUB_OUTPUT
''']
[tasks.zip-release-ci-flow_windows]
description = "Compiles the binary in release mode and zips it up"
category = "CI"
condition = { env_set = ["TARGET"] }
dependencies = [
# "clean",
"dist_env",
"build-release-for-target",
"zip-release-binary-for-target",
]
script_runner = "powershell"
script_extension = "ps1"
script = ['''
echo "dist_file_path=${env:DIST_PATH}.${env:DIST_EXT}" >> $env:GITHUB_OUTPUT
echo "dist_file_name=${env:DIST_NAME}.${env:DIST_EXT}" >> $env:GITHUB_OUTPUT
echo "dist_version=${env:DIST_VERSION}" >> $env:GITHUB_OUTPUT
''']
[tasks.setup-cross]
description = "Install cross from https://github.com/cross-rs/cross"
condition = { env_set = ["TARGET", "CROSS"] }
install_crate = { crate_name = "cross", binary = "cross", test_arg = "--help" }
[tasks.build-release-for-target]
description = "Makes a release build for a given target"
condition = { env_set = ["TARGET"] }
dependencies = ["setup-cross"]
command = "${CARGO_BUILD_CMD}"
args = ["build", "--release", "--all-features", "--target", "${TARGET}"]
[tasks.zip-release-binary-for-target]
windows_alias = "zip-release-binary-for-target_windows"
description = "Zips up the release binary, README, and license(s)"
category = "Publish"
condition = { env_set = ["TARGET"] }
# env = { "LIBZ_SYS_STATIC" = "1", "PKG_CONFIG_ALLOW_CROSS" = "1" }
script_runner = "@shell"
script = [
'''
rm -Rf ${DIST_PATH}*
mkdir -p ${DIST_PATH}
cp target/${TARGET}/release/${CARGO_MAKE_CRATE_NAME} ${DIST_PATH}/
cp LICENSE* ${DIST_PATH}/ || echo "ignore if no LICENSE"
# "cp README* ${DIST_PATH}/
tar -czvf "${DIST_PATH}.${DIST_EXT}" -C "${DIST_PATH}" "${CARGO_MAKE_CRATE_NAME}" "LICENSE.txt"
''',
]
[tasks.zip-release-binary-for-target_windows]
script_runner = "powershell"
script_extension = "ps1"
script = [
'''
Set-PSDebug -Strict # -Trace 1
$ErrorActionPreference = "Stop"
Remove-Item -Recurse -Force "${env:DIST_PATH}" -ErrorAction SilentlyContinue
New-Item -ItemType directory -Path "${env:DIST_PATH}"
Copy-Item -Path "target\\${env:TARGET}\\release\\${env:CARGO_MAKE_CRATE_NAME}.exe" -Destination "${env:DIST_PATH}"
Copy-Item -Path "LICENSE*" -Destination "${env:DIST_PATH}"
# Copy-Item -Path "README*" -Destination "${env:DIST_PATH}"
Compress-Archive -Path "${env:DIST_PATH}\\*" -DestinationPath "${env:DIST_PATH}.${env:DIST_EXT}" -CompressionLevel Optimal -Force
''',
]
[tasks.update-changelog]
category = "Publish"
install_crate = { crate_name = "gitmoji-changelog", binary = "gitmoji-changelog", test_arg = "--help" }
script = ['''
rm -Rf CHANGELOG.md
gitmoji-changelog -r x.y.z-dev -o CHANGELOG.md .
''']
[tasks.update-book]
category = "Publish"
install_crate = { crate_name = "mdbook", binary = "mdbook", test_arg = "--help" }
script = ['''
cd docs
mdbook clean
mdbook build
''']
[tasks.update-bom]
category = "Publish"
install_crate = { crate_name = "cargo-bom", binary = "cargo", test_arg = "bom" }
script = ["cargo bom > BOM.txt"]
[tasks.pre-publish]
dependencies = ["update-docs"]
[tasks.update-docs]
env = { COMMIT_MSG = ":pencil: pre-publish update book, changelog" }
run_task = "_update-docs-do"
[tasks._update-docs-do]
dependencies = [
"update-changelog",
"update-bom",
"git-add",
"git-commit-message",
]
[tasks.publish]
command = "cargo"
args = ["release", "${@}"]
0707010000000F000081A4000000000000000000000001685BA88A000030E3000000000000000000000000000000000000002A00000000kubectl-view-allocations-0.22.1/README.md# kubectl-view-allocations
[](http://creativecommons.org/publicdomain/zero/1.0/)
[](https://crates.io/crates/kubectl-view-allocations)
[](https://www.repostatus.org/#wip)
[](https://github.com/davidB/kubectl-view-allocations/actions)
[](https://docs.rs/kubectl-view-allocations/)
[](https://crates.io/crates/kubectl-view-allocations)

`kubectl` plugin lists allocations for resources (cpu, memory, gpu,...) as defined into the manifest of nodes and running pods. It doesn't list usage like `kubectl top`. It can provide result grouped by namespaces, nodes, pods and filtered by resources'name.
Columns displayed :
- `Requested` : Quantity of resources requested by the container in the pod's manifest. It's the sum group by pod, namespace, node where container is running. With percentage of resources requested over what is allocatable in the group.
- `Limit` : Quantity of resources max (limit) requestable by the container in the pod's manifest. It's the sum group by pod, namespace, node where container is running. With percentage of resources max / limit over what is allocatable in the group.
- `Allocatable` : Allocatable resources defined (or detected) on nodes.
- `Free` : `Allocatable - max (Limit, Requested)` (by default, see options `--used-mode`)
- `Utilization` : Quantity of resources (cpu & memory only) used as reported by Metrics API. It's disable by default, [metrics-server](https://github.com/kubernetes-incubator/metrics-server) is optional and should be setup into the cluster.
## Install
### Via download binary
Download from [github's release](https://github.com/davidB/kubectl-view-allocations/releases/latest) or use script
```sh
curl https://raw.githubusercontent.com/davidB/kubectl-view-allocations/master/scripts/getLatest.sh | bash
```
### Via krew (kubectl plugin manager)
[Krew – kubectl plugin manager](https://krew.sigs.k8s.io/)
```sh
kubectl krew install view-allocations
```
### Via cargo
```sh
cargo install kubectl-view-allocations
```
### As lib in Cargo.toml
If you want to embed some function or struct of the plugin into an other rust code:
```toml
[dependencies]
kubectl-view-allocations = { version = "0.14", default-features = false }
[features]
default = ["k8s-openapi/v1_20"]
```
## Usage
### Show help
```sh
> kubectl-view-allocations -h
kubectl plugin to list allocations (cpu, memory, gpu,...) X (utilization, requested, limit, allocatable,...)
Usage: kubectl-view-allocations [OPTIONS]
Options:
--context <CONTEXT>
The name of the kubeconfig context to use
-n, --namespace <NAMESPACE>...
Filter pods by namespace(s), by default pods in all namespaces are listed (comma separated list or multiple calls)
-l, --selector <SELECTOR>
Show only nodes match this label selector
-u, --utilization
Force to retrieve utilization (for cpu and memory), requires having metrics-server https://github.com/kubernetes-sigs/metrics-server
-z, --show-zero
Show lines with zero requested AND zero limit AND zero allocatable, OR pods with unset requested AND limit for `cpu` and `memory`
--used-mode <USED_MODE>
The way to compute the `used` part for free (`allocatable - used`) [default: max-request-limit] [possible values: max-request-limit, only-request]
--precheck
Pre-check access and refresh token on kubeconfig by running `kubectl cluster-info`
--accept-invalid-certs
Accept invalid certificates (dangerous)
-r, --resource-name <RESOURCE_NAME>...
Filter resources shown by name(s), by default all resources are listed (comma separated list or multiple calls)
-g, --group-by <GROUP_BY>...
Group information in a hierarchical manner; defaults to `-g resource,node,pod` (comma-separated list or multiple calls) [possible values: resource, node, pod, namespace]
-o, --output <OUTPUT>
Output format [default: table] [possible values: table, csv]
-h, --help
Print help
-V, --version
Print version
https://github.com/davidB/kubectl-view-allocations
```
### Show gpu allocation
```sh
> kubectl-view-allocations -r gpu
Resource Requested Limit Allocatable Free
nvidia.com/gpu (71%) 10.0 (71%) 10.0 14.0 4.0
├─ node-gpu1 (0%) __ (0%) __ 2.0 2.0
├─ node-gpu2 (0%) __ (0%) __ 2.0 2.0
├─ node-gpu3 (100%) 2.0 (100%) 2.0 2.0 __
│ └─ fah-gpu-cpu-d29sc 2.0 2.0 __ __
├─ node-gpu4 (100%) 2.0 (100%) 2.0 2.0 __
│ └─ fah-gpu-cpu-hkg59 2.0 2.0 __ __
├─ node-gpu5 (100%) 2.0 (100%) 2.0 2.0 __
│ └─ fah-gpu-cpu-nw9fc 2.0 2.0 __ __
├─ node-gpu6 (100%) 2.0 (100%) 2.0 2.0 __
│ └─ fah-gpu-cpu-gtwsf 2.0 2.0 __ __
└─ node-gpu7 (100%) 2.0 (100%) 2.0 2.0 __
└─ fah-gpu-cpu-x7zfb 2.0 2.0 __ __
```
### Overview only
```sh
> kubectl-view-allocations -g resource
Resource Requested Limit Allocatable Free
cpu (21%) 56.7 (65%) 176.1 272.0 95.9
ephemeral-storage (0%) __ (0%) __ 38.4T 38.4T
memory (8%) 52.7Gi (15%) 101.3Gi 675.6Gi 574.3Gi
nvidia.com/gpu (71%) 10.0 (71%) 10.0 14.0 4.0
pods (9%) 147.0 (9%) 147.0 1.6k 1.5k
```
### Show utilization
- Utilization information are retrieve from [metrics-server](https://github.com/kubernetes-incubator/metrics-server) (should be setup on your cluster).
- Only report cpu and memory utilization
```sh
> kubectl-view-allocations -u
Resource Utilization Requested Limit Allocatable Free
cpu (0%) 9.0m (10%) 200.0m __ 2.0 1.8
└─ lima-rancher-desktop (0%) 9.0m (10%) 200.0m __ 2.0 1.8
├─ coredns-96cc4f57d-57cj9 1.0m 100.0m __ __ __
├─ local-path-provisioner-84bb864455-czzcg 1.0m __ __ __ __
├─ metrics-server-ff9dbcb6c-kb7x9 4.0m 100.0m __ __ __
├─ svclb-traefik-ggd2q 2.0m __ __ __ __
└─ traefik-55fdc6d984-sqp57 1.0m __ __ __ __
ephemeral-storage __ __ __ 99.8G __
└─ lima-rancher-desktop __ __ __ 99.8G __
memory (1%) 51.0Mi (2%) 140.0Mi (3%) 170.0Mi 5.8Gi 5.6Gi
└─ lima-rancher-desktop (1%) 51.0Mi (2%) 140.0Mi (3%) 170.0Mi 5.8Gi 5.6Gi
├─ coredns-96cc4f57d-57cj9 11.5Mi 70.0Mi 170.0Mi __ __
├─ local-path-provisioner-84bb864455-czzcg 6.2Mi __ __ __ __
├─ metrics-server-ff9dbcb6c-kb7x9 14.9Mi 70.0Mi __ __ __
├─ svclb-traefik-ggd2q 548.0Ki __ __ __ __
└─ traefik-55fdc6d984-sqp57 17.9Mi __ __ __ __
pods __ (5%) 5.0 (5%) 5.0 110.0 105.0
└─ lima-rancher-desktop __ (5%) 5.0 (5%) 5.0 110.0 105.0
```
### Group by namespaces
```sh
> kubectl-view-allocations -g namespace
Resource Requested Limit Allocatable Free
cpu (10%) 200.0m __ 2.0 1.8
└─ kube-system 200.0m __ __ __
ephemeral-storage __ __ 99.8G __
memory (2%) 140.0Mi (3%) 170.0Mi 5.8Gi 5.6Gi
└─ kube-system 140.0Mi 170.0Mi __ __
pods (5%) 5.0 (5%) 5.0 110.0 105.0
└─ kube-system 5.0 5.0 __ __
```
### Show as csv
In this case value as expanded as float (with 2 decimal)
```sh
kubectl-view-allocations -o csv
Date,Kind,resource,node,pod,Requested,%Requested,Limit,%Limit,Allocatable,Free
2020-08-19T19:12:48.326605746+00:00,resource,cpu,,,59.94,22%,106.10,39%,272.00,165.90
2020-08-19T19:12:48.326605746+00:00,node,cpu,node-gpu1,,2.31,19%,4.47,37%,12.00,7.53
2020-08-19T19:12:48.326605746+00:00,pod,cpu,node-gpu1,yyy-b8bd56fbd-5x8vq,1.00,,2.00,,,
2020-08-19T19:12:48.326605746+00:00,pod,cpu,node-gpu1,kube-flannel-ds-amd64-7dz9z,0.10,,0.10,,,
2020-08-19T19:12:48.326605746+00:00,pod,cpu,node-gpu1,node-exporter-gpu-b4w7s,0.11,,0.22,,,
2020-08-19T19:12:48.326605746+00:00,pod,cpu,node-gpu1,xxx-backend-7d84544458-46qnh,1.00,,2.00,,,
2020-08-19T19:12:48.326605746+00:00,pod,cpu,node-gpu1,weave-scope-agent-bbdnz,0.10,,0.15,,,
2020-08-19T19:12:48.326605746+00:00,node,cpu,node-gpu2,,0.31,1%,0.47,2%,24.00,23.53
2020-08-19T19:12:48.326605746+00:00,pod,cpu,node-gpu2,kube-flannel-ds-amd64-b5b4v,0.10,,0.10,,,
2020-08-19T19:12:48.326605746+00:00,pod,cpu,node-gpu2,node-exporter-gpu-796jz,0.11,,0.22,,,
2020-08-19T19:12:48.326605746+00:00,pod,cpu,node-gpu2,weave-scope-agent-8rhnd,0.10,,0.15,,,
2020-08-19T19:12:48.326605746+00:00,node,cpu,node-gpu3,,3.41,11%,6.67,21%,32.00,25.33
...
```
It can be combined with "group-by" options.
```sh
kubectl-view-allocations -g resource -o csv
Date,Kind,resource,Requested,%Requested,Limit,%Limit,Allocatable,Free
2020-08-19T19:11:49.630864028+00:00,resource,cpu,59.94,22%,106.10,39%,272.00,165.90
2020-08-19T19:11:49.630864028+00:00,resource,ephemeral-storage,0.00,0%,0.00,0%,34462898618662.00,34462898618662.00
2020-08-19T19:11:49.630864028+00:00,resource,hugepages-1Gi,0.00,,0.00,,,
2020-08-19T19:11:49.630864028+00:00,resource,hugepages-2Mi,0.00,,0.00,,,
2020-08-19T19:11:49.630864028+00:00,resource,memory,69063409664.00,10%,224684670976.00,31%,722318667776.00,497633996800.00
2020-08-19T19:11:49.630864028+00:00,resource,nvidia.com/gpu,3.00,27%,3.00,27%,11.00,8.00
2020-08-19T19:11:49.630864028+00:00,resource,pods,0.00,0%,0.00,0%,1540.00,1540.00
```
## Alternatives & Similars
- see the discussion [Need simple kubectl command to see cluster resource usage · Issue #17512 · kubernetes/kubernetes](https://github.com/kubernetes/kubernetes/issues/17512)
- For CPU & Memory only
- [ahmetb/kubectl-node\_resource: Query node allocations/utilization in kubectl](https://github.com/ahmetb/kubectl-node_resource)
- [robscott/kube-capacity: A simple CLI that provides an overview of the resource requests, limits, and utilization in a Kubernetes cluster](https://github.com/robscott/kube-capacity),
- [hjacobs/kube-resource-report: Report Kubernetes cluster and pod resource requests vs usage and generate static HTML](https://github.com/hjacobs/kube-resource-report)
- [etopeter/kubectl-view-utilization: kubectl plugin to show cluster CPU and Memory requests utilization](https://github.com/etopeter/kubectl-view-utilization)
- For CPU & Memory utilization only
- `kubectl top pods`
- [LeastAuthority/kubetop: A top(1)-like tool for Kubernetes.](https://github.com/LeastAuthority/kubetop)
07070100000010000041ED000000000000000000000002685BA88A00000000000000000000000000000000000000000000002900000000kubectl-view-allocations-0.22.1/examples07070100000011000081A4000000000000000000000001685BA88A00000219000000000000000000000000000000000000003400000000kubectl-view-allocations-0.22.1/examples/pod_api.rsuse k8s_openapi::api::core::v1::Pod;
use kube::{
Client,
api::{Api, ListParams},
};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
//std::env::set_var("RUST_LOG", "info,kube=debug");
tracing_subscriber::fmt::init();
let client = Client::try_default().await?;
let pods: Api<Pod> = Api::all(client);
// let pods: Api<Pod> = Api::namespaced(client, "kube-system");
let lp = ListParams::default().timeout(10);
let pods = pods.list(&lp).await?;
eprintln!("pods: {:?}", pods);
Ok(())
}
07070100000012000081A4000000000000000000000001685BA88A000004CC000000000000000000000000000000000000002900000000kubectl-view-allocations-0.22.1/justfiledefault:
just --list
k8s_create_kind:
# k3d cluster create "$CLUSTER_NAME" --agents 2
sudo systemctl start docker
kind create cluster --name "$CLUSTER_NAME"
kubectl cluster-info --context kind-"$CLUSTER_NAME"
kubectl apply -f tests/metrics-server-components.yaml
sleep 5
kubectl top node
cargo run
k8s_delete_kind:
# k3d cluster delete "$CLUSTER_NAME"
kind delete cluster --name "$CLUSTER_NAME"
# k8s_create_kwok_in_container:
# cp tests/kube_config-kwokcontainer.yaml $HOME/.kube/config-kwokcontainer.yaml
# kubectl config --kubeconfig=config-kwokcontainer use-context kwok
# podman run --rm -it -p 8080:8080 registry.k8s.io/kwok/cluster:v0.4.0-k8s.v1.28.0
k8s_create_kwok:
# echo "require docker, with podman I got timeout on my machine"
kwokctl create cluster --name="$CLUSTER_NAME"
kwokctl get clusters
kubectl cluster-info --context kwok-"$CLUSTER_NAME"
kwokctl scale node --replicas 2 --name="$CLUSTER_NAME"
kubectl get node
kubectl create deployment pod --image=pod --replicas=5
kubectl get pods -o wide
echo "use '--accept-invalid-certs' with kube view-allocations"
cargo run -- --accept-invalid-certs
k8s_delete_kwok:
kwokctl delete cluster --name="$CLUSTER_NAME"
07070100000013000081A4000000000000000000000001685BA88A000001EF000000000000000000000000000000000000002D00000000kubectl-view-allocations-0.22.1/release.tomlpre-release-commit-message = "🚀 (cargo-release) version {{version}}"
# post-release-commit-message = ":construction: (cargo-release) start next development iteration {{next_version}}"
tag-prefix = ""
tag-name = "{{prefix}}{{version}}"
tag-message = "🔖 {{version}}"
# dev-version-ext = "dev"
# dev-version = true
# pre-release-replacements = [
# {file="CHANGELOG.md", search="x.y.z-dev", replace="{{version}}"},
# {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}"}
# ]
07070100000014000041ED000000000000000000000002685BA88A00000000000000000000000000000000000000000000002800000000kubectl-view-allocations-0.22.1/scripts07070100000015000081ED000000000000000000000001685BA88A00000D19000000000000000000000000000000000000003500000000kubectl-view-allocations-0.22.1/scripts/getLatest.sh#!/bin/bash
# The install script is licensed under the CC-0 1.0 license.
# See https://github.com/davidB/kubectl-view-allocations/blob/master/LICENSE for more details.
#
# To run this script execute:
# `curl https://raw.githubusercontent.com/davidB/kubectl-view-allocations/master/scripts/getLatest.sh | sh`
GITHUB_REPO="kubectl-view-allocations"
GITHUB_USER="davidB"
EXE_FILENAME="kubectl-view-allocations"
bye() {
result=$?
if [ "$result" != "0" ]; then
echo "Fail to install ${GITHUB_USER}/${GITHUB_REPO}"
fi
exit $result
}
fail() {
echo "$1"
exit 1
}
find_download_url() {
local SUFFIX=$1
URL=$(curl -s https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/releases/latest |
grep "browser_download_url.*${SUFFIX}" |
cut -d : -f 2,3 |
tr -d \" |
head -n 1)
echo "${URL//[[:space:]]/}"
}
find_arch() {
ARCH=$(uname -m)
case $ARCH in
armv5*) ARCH="armv5" ;;
armv6*) ARCH="armv6" ;;
armv7*) ARCH="armv7" ;;
aarch64) ARCH="arm64" ;;
x86) ARCH="386" ;;
# x86_64) ARCH="amd64";;
i686) ARCH="386" ;;
i386) ARCH="386" ;;
esac
echo $ARCH
}
find_os() {
UNAME=$(uname)
OS=$(echo "$UNAME" | tr '[:upper:]' '[:lower:]')
case "$OS" in
# Minimalist GNU for Windows
mingw*) OS='windows' ;;
msys*) OS='windows' ;;
esac
echo "$OS"
}
find_suffix() {
local ARCH=$1
local OS=$2
local SUFFIX="$ARCH-$OS.tar.gz"
case "$SUFFIX" in
"x86_64-darwin.tar.gz") SUFFIX='x86_64-apple-darwin.tar.gz' ;;
"arm64-darwin.tar.gz") SUFFIX='aarch64-apple-darwin.tar.gz' ;;
"x86_64-linux.tar.gz") SUFFIX='x86_64-unknown-linux-musl.tar.gz' ;;
"arm64-linux.tar.gz") SUFFIX='aarch64-unknown-linux-musl.tar.gz' ;;
# "x86_64-windows.tar.gz") SUFFIX='x86_64-pc-windows-msvc.zip';;
esac
echo "$SUFFIX"
}
download_file() {
local FILE_URL="$1"
local FILE_PATH="$2"
echo "Getting $FILE_URL"
httpStatusCode=$(curl -s -w '%{http_code}' -L "$FILE_URL" -o "$FILE_PATH")
if [ "$httpStatusCode" != 200 ]; then
echo "failed to download '${URL}'"
fail "Request fail with http status code $httpStatusCode"
fi
}
find_exec_dest_path() {
local DEST_DIR="/usr/local/bin"
if [ ! -w $DEST_DIR ]; then
DEST_DIR=$(pwd)
fi
echo "${DEST_DIR}"
}
install_file() {
local FILE_PATH=$1
local EXE_DEST_FILE=$2
TMP_DIR="/tmp/${GITHUB_USER}_${GITHUB_REPO}"
mkdir -p "$TMP_DIR" || true
tar xf "$FILE_PATH" -C "$TMP_DIR"
if [ -f "$TMP_DIR/${EXE_FILENAME}" ]; then
cp "$TMP_DIR/${EXE_FILENAME}" "${EXE_DEST_FILE}"
else
for dir in "$TMP_DIR"/*/; do
if [ -f "$dir${EXE_FILENAME}" ]; then
cp "$dir${EXE_FILENAME}" "${EXE_DEST_FILE}"
break
fi
done
fi
chmod +x "${EXE_DEST_FILE}"
rm -rf "$TMP_DIR"
}
main() {
EXE_DEST_DIR=$(find_exec_dest_path)
EXE_DEST_FILE="${EXE_DEST_DIR}/${EXE_FILENAME}"
ARCH=$(find_arch)
OS=$(find_os)
SUFFIX=$(find_suffix "$ARCH" "$OS")
FILE_URL=$(find_download_url "$SUFFIX")
FILE_PATH="/tmp/${GITHUB_USER}-${GITHUB_REPO}-latest-${SUFFIX}"
if [ -z "${FILE_URL}" ]; then
fail "Did not find a release for your system: $OS $ARCH"
fi
download_file "${FILE_URL}" "${FILE_PATH}"
install_file "${FILE_PATH}" "${EXE_DEST_FILE}"
rm -Rf "${FILE_PATH}"
echo "executable installed at ${EXE_DEST_FILE}"
bye
}
#Stop execution on any error
trap "bye" EXIT
set -e
# set -x
main
07070100000016000041ED000000000000000000000002685BA88A00000000000000000000000000000000000000000000002400000000kubectl-view-allocations-0.22.1/src07070100000017000081A4000000000000000000000001685BA88A00007E71000000000000000000000000000000000000002B00000000kubectl-view-allocations-0.22.1/src/lib.rspub mod metrics;
pub mod qty;
pub mod tree;
// mod human_format;
use chrono::prelude::*;
use clap::{Parser, ValueEnum};
use core::convert::TryFrom;
use futures::future::try_join_all;
use itertools::Itertools;
use k8s_openapi::api::core::v1::{Node, Pod};
use kube::api::{Api, ListParams, ObjectList};
#[cfg(feature = "prettytable")]
use prettytable::{Cell, Row, Table, format, row};
use qty::Qty;
use std::collections::BTreeMap;
use std::str::FromStr;
use tracing::{info, instrument, warn};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Failed to run '{cmd}'")]
CmdError {
cmd: String,
output: Option<std::process::Output>,
source: Option<std::io::Error>,
},
#[error("Failed to read Qty of location {location:?} / {qualifier:?} {kind}={input}")]
ResourceQtyParseError {
location: Location,
qualifier: ResourceQualifier,
kind: String,
input: String,
source: qty::Error,
},
#[error("Failed to process Qty")]
QtyError {
#[from]
source: qty::Error,
},
#[error("Failed to {context}")]
KubeError {
context: String,
source: kube::Error,
},
#[error("Failed to {context}")]
KubeConfigError {
context: String,
source: kube::config::KubeconfigError,
},
#[error("Failed to {context}")]
KubeInferConfigError {
context: String,
source: kube::config::InferConfigError,
},
}
#[derive(Debug, Clone, Default)]
pub struct Location {
pub node_name: String,
pub namespace: Option<String>,
pub pod_name: Option<String>,
}
#[derive(Debug, Clone)]
pub struct Resource {
pub kind: String,
pub quantity: Qty,
pub location: Location,
pub qualifier: ResourceQualifier,
}
#[derive(Debug, Clone)]
pub enum ResourceQualifier {
Limit,
Requested,
Allocatable,
Utilization,
// HACK special qualifier, used to show zero/undef cpu & memory
Present,
}
#[derive(Debug, Clone, Default)]
pub struct QtyByQualifier {
pub limit: Option<Qty>,
pub requested: Option<Qty>,
pub allocatable: Option<Qty>,
pub utilization: Option<Qty>,
pub present: Option<Qty>,
}
fn add(lhs: Option<Qty>, rhs: &Qty) -> Option<Qty> {
lhs.map(|l| &l + rhs).or_else(|| Some(rhs.clone()))
}
impl QtyByQualifier {
pub fn calc_free(&self, used_mode: UsedMode) -> Option<Qty> {
let total_used = match used_mode {
UsedMode::max_request_limit => {
std::cmp::max(self.limit.as_ref(), self.requested.as_ref())
}
UsedMode::only_request => self.requested.as_ref(),
};
self.allocatable
.as_ref()
.zip(total_used)
.map(|(allocatable, total_used)| {
if allocatable > total_used {
allocatable - total_used
} else {
Qty::default()
}
})
}
}
pub fn sum_by_qualifier(rsrcs: &[&Resource]) -> Option<QtyByQualifier> {
if !rsrcs.is_empty() {
let kind = rsrcs
.first()
.expect("group contains at least 1 element")
.kind
.clone();
if rsrcs.iter().all(|i| i.kind == kind) {
let sum = rsrcs.iter().fold(QtyByQualifier::default(), |mut acc, v| {
match &v.qualifier {
ResourceQualifier::Limit => acc.limit = add(acc.limit, &v.quantity),
ResourceQualifier::Requested => acc.requested = add(acc.requested, &v.quantity),
ResourceQualifier::Allocatable => {
acc.allocatable = add(acc.allocatable, &v.quantity)
}
ResourceQualifier::Utilization => {
acc.utilization = add(acc.utilization, &v.quantity)
}
ResourceQualifier::Present => acc.present = add(acc.present, &v.quantity),
};
acc
});
Some(sum)
} else {
None
}
} else {
None
}
}
pub fn make_qualifiers(
rsrcs: &[Resource],
group_by: &[GroupBy],
resource_names: &[String],
) -> Vec<(Vec<String>, Option<QtyByQualifier>)> {
let group_by_fct = group_by.iter().map(GroupBy::to_fct).collect::<Vec<_>>();
let mut out = make_group_x_qualifier(
&(rsrcs
.iter()
.filter(|a| accept_resource(&a.kind, resource_names))
.collect::<Vec<_>>()),
&[],
&group_by_fct,
0,
);
out.sort_by_key(|i| i.0.clone());
out
}
fn make_group_x_qualifier(
rsrcs: &[&Resource],
prefix: &[String],
group_by_fct: &[fn(&Resource) -> Option<String>],
group_by_depth: usize,
) -> Vec<(Vec<String>, Option<QtyByQualifier>)> {
// Note: The `&` is significant here, `GroupBy` is iterable
// only by reference. You can also call `.into_iter()` explicitly.
let mut out = vec![];
if let Some(group_by) = group_by_fct.get(group_by_depth) {
for (key, group) in rsrcs
.iter()
.filter_map(|e| group_by(e).map(|k| (k, *e)))
.into_group_map()
{
let mut key_full = prefix.to_vec();
key_full.push(key);
let children =
make_group_x_qualifier(&group, &key_full, group_by_fct, group_by_depth + 1);
out.push((key_full, sum_by_qualifier(&group)));
out.extend(children);
}
}
// let kg = &rsrcs.into_iter().group_by(|v| v.kind);
// kg.into_iter().map(|(key, group)| ).collect()
out
}
fn accept_resource(name: &str, resource_filter: &[String]) -> bool {
resource_filter.is_empty() || resource_filter.iter().any(|x| name.contains(x))
}
#[instrument(skip(client, resources))]
pub async fn collect_from_nodes(
client: kube::Client,
resources: &mut Vec<Resource>,
selector: &Option<String>,
) -> Result<Vec<String>, Error> {
let api_nodes: Api<Node> = Api::all(client);
let mut lp = ListParams::default();
if let Some(labels) = &selector {
lp = lp.labels(labels);
}
let nodes = api_nodes
.list(&lp)
.await
.map_err(|source| Error::KubeError {
context: "list nodes".to_string(),
source,
})?
.items;
let node_names = nodes
.iter()
.filter_map(|node| node.metadata.name.clone())
.collect();
extract_allocatable_from_nodes(nodes, resources).await?;
Ok(node_names)
}
#[instrument(skip(node_list, resources))]
pub async fn extract_allocatable_from_nodes(
node_list: Vec<Node>,
resources: &mut Vec<Resource>,
) -> Result<(), Error> {
for node in node_list {
let location = Location {
node_name: node.metadata.name.unwrap_or_default(),
..Location::default()
};
if let Some(als) = node.status.and_then(|v| v.allocatable) {
// add_resource(resources, &location, ResourceUsage::Allocatable, &als)?
for (kind, value) in als.iter() {
let quantity =
Qty::from_str(&(value).0).map_err(|source| Error::ResourceQtyParseError {
location: location.clone(),
qualifier: ResourceQualifier::Allocatable,
kind: kind.to_string(),
input: value.0.to_string(),
source,
})?;
resources.push(Resource {
kind: kind.clone(),
qualifier: ResourceQualifier::Allocatable,
quantity,
location: location.clone(),
});
}
}
}
Ok(())
}
/*
The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle. The conditions array, the reason and message fields, and the individual container status arrays contain more detail about the pod's status.
There are five possible phase values:
Pending: The pod has been accepted by the Kubernetes system, but one or more of the container images has not been created. This includes time before being scheduled as well as time spent downloading images over the network, which could take a while.
Running: The pod has been bound to a node, and all of the containers have been created. At least one container is still running, or is in the process of starting or restarting.
Succeeded: All containers in the pod have terminated in success, and will not be restarted.
Failed: All containers in the pod have terminated, and at least one container has terminated in failure. The container either exited with non-zero status or was terminated by the system.
Unknown: For some reason the state of the pod could not be obtained, typically due to an error in communicating with the host of the pod.
More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase
*/
pub fn is_scheduled(pod: &Pod) -> bool {
pod.status
.as_ref()
.and_then(|ps| {
ps.phase.as_ref().and_then(|phase| {
match &phase[..] {
"Succeeded" | "Failed" => Some(false),
"Running" => Some(true),
"Unknown" => None, // this is the case when a node is down (kubelet is not responding)
"Pending" => ps.conditions.as_ref().map(|o| {
o.iter()
.any(|c| c.type_ == "PodScheduled" && c.status == "True")
}),
&_ => None, // should not happen
}
})
})
.unwrap_or(false)
}
#[allow(clippy::result_large_err)]
fn push_resources(
resources: &mut Vec<Resource>,
location: &Location,
qualifier: ResourceQualifier,
resource_list: &BTreeMap<String, Qty>,
) -> Result<(), Error> {
for (key, quantity) in resource_list.iter() {
resources.push(Resource {
kind: key.clone(),
qualifier: qualifier.clone(),
quantity: quantity.clone(),
location: location.clone(),
});
}
// add a "pods" resource as well
resources.push(Resource {
kind: "pods".to_string(),
qualifier,
quantity: Qty::from_str("1")?,
location: location.clone(),
});
Ok(())
}
#[allow(clippy::result_large_err)]
fn process_resources<F>(
effective_resources: &mut BTreeMap<String, Qty>,
resource_list: &BTreeMap<String, k8s_openapi::apimachinery::pkg::api::resource::Quantity>,
op: F,
) -> Result<(), Error>
where
F: Fn(Qty, Qty) -> Qty,
{
for (key, value) in resource_list.iter() {
let quantity = Qty::from_str(&(value).0)?;
if let Some(current_quantity) = effective_resources.get_mut(key) {
*current_quantity = op(current_quantity.clone(), quantity).clone();
} else {
effective_resources.insert(key.clone(), quantity.clone());
}
}
Ok(())
}
#[instrument(skip(client, resources))]
pub async fn collect_from_pods(
client: kube::Client,
resources: &mut Vec<Resource>,
namespace: &[String],
selected_node_names: &[String],
) -> Result<(), Error> {
let mut apis: Vec<Api<Pod>> = vec![];
if namespace.is_empty() {
apis.push(Api::all(client))
} else {
for ns in namespace {
apis.push(Api::namespaced(client.clone(), ns))
}
}
// Call `list` concurrently on every apis
let pods: Vec<Pod> = try_join_all(
apis.iter()
.map(|api| async { api.list(&ListParams::default()).await }),
)
.await
.map_err(|source| Error::KubeError {
context: "list pods".to_string(),
source,
})?
.into_iter()
.flat_map(|list| list.items)
.collect();
extract_allocatable_from_pods(pods, resources, selected_node_names).await?;
Ok(())
}
#[instrument(skip(pod_list, resources))]
pub async fn extract_allocatable_from_pods(
pod_list: Vec<Pod>,
resources: &mut Vec<Resource>,
selected_node_names: &[String],
) -> Result<(), Error> {
for pod in pod_list.into_iter().filter(is_scheduled) {
let spec = pod.spec.as_ref();
let node_name = spec.and_then(|s| s.node_name.clone()).unwrap_or_default();
if !selected_node_names.contains(&node_name) {
continue;
}
let metadata = &pod.metadata;
let location = Location {
node_name: node_name.clone(),
namespace: metadata.namespace.clone(),
pod_name: metadata.name.clone(),
};
// compute the effective resource qualifier
// see https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#resources
let mut resource_requests: BTreeMap<String, Qty> = BTreeMap::new();
let mut resource_limits: BTreeMap<String, Qty> = BTreeMap::new();
// handle regular containers
let containers = spec.map(|s| s.containers.clone()).unwrap_or_default();
for container in containers.into_iter() {
if let Some(requirements) = container.resources {
if let Some(r) = requirements.requests {
process_resources(&mut resource_requests, &r, std::ops::Add::add)?;
}
if let Some(r) = requirements.limits {
process_resources(&mut resource_limits, &r, std::ops::Add::add)?;
}
}
}
// handle initContainers
let init_containers = spec
.and_then(|s| s.init_containers.clone())
.unwrap_or_default();
for container in init_containers.into_iter() {
if let Some(requirements) = container.resources {
if let Some(r) = requirements.requests {
process_resources(&mut resource_requests, &r, std::cmp::max)?;
}
if let Some(r) = requirements.limits {
process_resources(&mut resource_limits, &r, std::cmp::max)?;
}
}
}
// handler overhead (add to both requests and limits)
if let Some(ref overhead) = spec.and_then(|s| s.overhead.clone()) {
process_resources(&mut resource_requests, overhead, std::ops::Add::add)?;
process_resources(&mut resource_limits, overhead, std::ops::Add::add)?;
}
// push these onto resources
push_resources(
resources,
&location,
ResourceQualifier::Requested,
&resource_requests,
)?;
push_resources(
resources,
&location,
ResourceQualifier::Limit,
&resource_limits,
)?;
// HACK add zero/None cpu & memory, to allow show-zero to display them
resources.push(Resource {
kind: "cpu".to_string(),
qualifier: ResourceQualifier::Present,
quantity: Qty::zero(),
location: location.clone(),
});
resources.push(Resource {
kind: "memory".to_string(),
qualifier: ResourceQualifier::Present,
quantity: Qty::zero(),
location: location.clone(),
});
}
Ok(())
}
pub fn extract_locations(
resources: &[Resource],
) -> std::collections::HashMap<(String, String), Location> {
resources
.iter()
.filter_map(|resource| {
let loc = &resource.location;
loc.pod_name.as_ref().map(|n| {
(
(loc.namespace.clone().unwrap_or_default(), n.to_owned()),
loc.clone(),
)
})
})
.collect()
}
//TODO need location of pods (aka node because its not part of metrics)
//TODO filter to only retreive info from node's selector
#[instrument(skip(client, resources))]
pub async fn collect_from_metrics(
client: kube::Client,
resources: &mut Vec<Resource>,
) -> Result<(), Error> {
let api_pod_metrics: Api<metrics::PodMetrics> = Api::all(client);
let pod_metrics = api_pod_metrics
.list(&ListParams::default())
.await
.map_err(|source| Error::KubeError {
context: "list podmetrics, maybe Metrics API not available".to_string(),
source,
})?;
extract_utilizations_from_pod_metrics(pod_metrics, resources).await?;
Ok(())
}
#[instrument(skip(pod_metrics, resources))]
pub async fn extract_utilizations_from_pod_metrics(
pod_metrics: ObjectList<metrics::PodMetrics>,
resources: &mut Vec<Resource>,
) -> Result<(), Error> {
let cpu_kind = "cpu";
let memory_kind = "memory";
let locations = extract_locations(resources);
for pod_metric in pod_metrics.items {
let metadata = &pod_metric.metadata;
let key = (
metadata.namespace.clone().unwrap_or_default(),
metadata.name.clone().unwrap_or_default(),
);
let location = locations.get(&key).cloned().unwrap_or_else(|| Location {
// node_name: node_name.clone(),
namespace: metadata.namespace.clone(),
pod_name: metadata.name.clone(),
..Location::default()
});
let mut cpu_utilization = Qty::default();
let mut memory_utilization = Qty::default();
for container in pod_metric.containers.into_iter() {
cpu_utilization += &Qty::from_str(&container.usage.cpu)
.map_err(|source| Error::ResourceQtyParseError {
location: location.clone(),
qualifier: ResourceQualifier::Utilization,
kind: cpu_kind.to_string(),
input: container.usage.cpu.clone(),
source,
})?
.max(Qty::lowest_positive());
memory_utilization += &Qty::from_str(&container.usage.memory)
.map_err(|source| Error::ResourceQtyParseError {
location: location.clone(),
qualifier: ResourceQualifier::Utilization,
kind: memory_kind.to_string(),
input: container.usage.memory.clone(),
source,
})?
.max(Qty::lowest_positive());
}
resources.push(Resource {
kind: cpu_kind.to_string(),
qualifier: ResourceQualifier::Utilization,
quantity: cpu_utilization,
location: location.clone(),
});
resources.push(Resource {
kind: memory_kind.to_string(),
qualifier: ResourceQualifier::Utilization,
quantity: memory_utilization,
location: location.clone(),
});
}
Ok(())
}
#[derive(Debug, Eq, PartialEq, ValueEnum, Clone)]
#[allow(non_camel_case_types)]
pub enum GroupBy {
resource,
node,
pod,
namespace,
}
impl GroupBy {
pub fn to_fct(&self) -> fn(&Resource) -> Option<String> {
match self {
Self::resource => Self::extract_kind,
Self::node => Self::extract_node_name,
Self::pod => Self::extract_pod_name,
Self::namespace => Self::extract_namespace,
}
}
fn extract_kind(e: &Resource) -> Option<String> {
Some(e.kind.clone())
}
fn extract_node_name(e: &Resource) -> Option<String> {
Some(e.location.node_name.to_string()).filter(|s| !s.is_empty())
}
fn extract_pod_name(e: &Resource) -> Option<String> {
// We do not need to display "pods" resource types when grouping by pods
if e.kind == "pods" {
return None;
}
e.location.pod_name.clone()
}
fn extract_namespace(e: &Resource) -> Option<String> {
e.location.namespace.clone()
}
}
impl std::fmt::Display for GroupBy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::resource => "resource",
Self::node => "node",
Self::pod => "pod",
Self::namespace => "namespace",
};
f.write_str(s)
}
}
#[derive(Debug, Eq, PartialEq, ValueEnum, Clone, Copy, Default)]
#[allow(non_camel_case_types)]
pub enum Output {
#[default]
table,
csv,
}
#[derive(Debug, Eq, PartialEq, ValueEnum, Clone, Copy, Default)]
#[allow(non_camel_case_types)]
pub enum UsedMode {
#[default]
max_request_limit,
only_request,
}
#[derive(Parser, Debug)]
#[command(
version, about,
after_help(env!("CARGO_PKG_HOMEPAGE")),
propagate_version = true
)]
pub struct CliOpts {
/// The name of the kubeconfig context to use
#[arg(long, value_parser)]
pub context: Option<String>,
/// Filter pods by namespace(s), by default pods in all namespaces are listed (comma separated list or multiple calls)
#[arg(short, long, value_parser, value_delimiter= ',', num_args = 1..)]
pub namespace: Vec<String>,
/// Show only nodes match this label selector
#[arg(short = 'l', long, value_parser)]
pub selector: Option<String>,
/// Force to retrieve utilization (for cpu and memory), requires
/// having metrics-server https://github.com/kubernetes-sigs/metrics-server
#[arg(short = 'u', long, value_parser)]
pub utilization: bool,
/// Show lines with zero requested AND zero limit AND zero allocatable,
/// OR pods with unset requested AND limit for `cpu` and `memory`
#[arg(short = 'z', long, value_parser)]
pub show_zero: bool,
/// The way to compute the `used` part for free (`allocatable - used`)
#[arg(
long,
value_enum,
ignore_case = true,
default_value = "max-request-limit",
value_parser
)]
pub used_mode: UsedMode,
/// Pre-check access and refresh token on kubeconfig by running `kubectl cluster-info`
#[arg(long, value_parser)]
pub precheck: bool,
/// Accept invalid certificates (dangerous)
#[arg(long, value_parser)]
pub accept_invalid_certs: bool,
/// Filter resources shown by name(s), by default all resources are listed (comma separated list or multiple calls)
#[arg(short, long, value_parser, value_delimiter= ',', num_args = 1..)]
pub resource_name: Vec<String>,
/// Group information in a hierarchical manner; defaults to `-g resource,node,pod` (comma-separated list or multiple calls)
#[arg(short, long, value_enum, ignore_case = true, value_parser, value_delimiter= ',', num_args = 1..)]
pub group_by: Vec<GroupBy>,
/// Output format
#[arg(
short,
long,
value_enum,
ignore_case = true,
default_value = "table",
value_parser
)]
pub output: Output,
}
pub async fn refresh_kube_config(cli_opts: &CliOpts) -> Result<(), Error> {
//HACK force refresh token by calling "kubectl cluster-info before loading configuration"
use std::process::Command;
let mut cmd = Command::new("kubectl");
cmd.arg("cluster-info");
if let Some(ref context) = cli_opts.context {
cmd.arg("--context").arg(context);
}
let output = cmd.output().map_err(|source| Error::CmdError {
cmd: "kubectl cluster-info".to_owned(),
output: None,
source: Some(source),
})?;
if !output.status.success() {
return Err(Error::CmdError {
cmd: "kubectl cluster-info".to_owned(),
output: Some(output),
source: None,
});
}
Ok(())
}
pub async fn new_client(cli_opts: &CliOpts) -> Result<kube::Client, Error> {
if cli_opts.precheck {
refresh_kube_config(cli_opts).await?;
}
let mut client_config = match cli_opts.context {
Some(ref context) => kube::Config::from_kubeconfig(&kube::config::KubeConfigOptions {
context: Some(context.clone()),
..Default::default()
})
.await
.map_err(|source| Error::KubeConfigError {
context: "create the kube client config".to_string(),
source,
})?,
None => kube::Config::infer()
.await
.map_err(|source| Error::KubeInferConfigError {
context: "create the kube client config".to_string(),
source,
})?,
};
info!(cluster_url = client_config.cluster_url.to_string().as_str());
client_config.accept_invalid_certs = client_config.accept_invalid_certs || cli_opts.accept_invalid_certs;
kube::Client::try_from(client_config).map_err(|source| Error::KubeError {
context: "create the kube client".to_string(),
source,
})
}
#[instrument]
pub async fn do_main(cli_opts: &CliOpts) -> Result<(), Error> {
let client = new_client(cli_opts).await?;
let mut resources: Vec<Resource> = vec![];
let node_names = collect_from_nodes(client.clone(), &mut resources, &cli_opts.selector).await?;
collect_from_pods(
client.clone(),
&mut resources,
&cli_opts.namespace,
&node_names,
)
.await?;
let show_utilization = if cli_opts.utilization {
match collect_from_metrics(client.clone(), &mut resources).await {
Ok(_) => true,
Err(err) => {
warn!(?err);
false
}
}
} else {
false
};
let res = make_qualifiers(&resources, &cli_opts.group_by, &cli_opts.resource_name);
match &cli_opts.output {
Output::table => display_with_prettytable(
&res,
!&cli_opts.show_zero,
show_utilization,
cli_opts.used_mode,
),
Output::csv => display_as_csv(
&res,
&cli_opts.group_by,
show_utilization,
cli_opts.used_mode,
),
}
Ok(())
}
pub fn display_as_csv(
data: &[(Vec<String>, Option<QtyByQualifier>)],
group_by: &[GroupBy],
show_utilization: bool,
used_mode: UsedMode,
) {
// print header
println!(
"Date,Kind,{}{},Requested,%Requested,Limit,%Limit,Allocatable,Free",
group_by.iter().map(|x| x.to_string()).join(","),
if show_utilization {
",Utilization,%Utilization"
} else {
""
}
);
// print data
let empty = "".to_string();
let datetime = Utc::now().to_rfc3339();
for (k, oqtys) in data {
if let Some(qtys) = oqtys {
let mut row = vec![
datetime.clone(),
group_by
.get(k.len() - 1)
.map(|x| x.to_string())
.unwrap_or_else(|| empty.clone()),
];
for i in 0..group_by.len() {
row.push(k.get(i).cloned().unwrap_or_else(|| empty.clone()));
}
if show_utilization {
add_cells_for_cvs(&mut row, &qtys.utilization, &qtys.allocatable);
}
add_cells_for_cvs(&mut row, &qtys.requested, &qtys.allocatable);
add_cells_for_cvs(&mut row, &qtys.limit, &qtys.allocatable);
row.push(
qtys.allocatable
.as_ref()
.map(|qty| format!("{:.2}", f64::from(qty)))
.unwrap_or_else(|| empty.clone()),
);
row.push(
qtys.calc_free(used_mode)
.as_ref()
.map(|qty| format!("{:.2}", f64::from(qty)))
.unwrap_or_else(|| empty.clone()),
);
println!("{}", &row.join(","));
}
}
}
fn add_cells_for_cvs(row: &mut Vec<String>, oqty: &Option<Qty>, o100: &Option<Qty>) {
match oqty {
None => {
row.push("".to_string());
row.push("".to_string());
}
Some(qty) => {
row.push(format!("{:.2}", f64::from(qty)));
row.push(match o100 {
None => "".to_string(),
Some(q100) => format!("{:.0}%", qty.calc_percentage(q100)),
});
}
};
}
#[cfg(not(feature = "prettytable"))]
pub fn display_with_prettytable(
_data: &[(Vec<String>, Option<QtyByQualifier>)],
_filter_full_zero: bool,
_show_utilization: bool,
_used_mode: UsedMode,
) {
warn!("feature 'prettytable' not enabled");
}
#[cfg(feature = "prettytable")]
pub fn display_with_prettytable(
data: &[(Vec<String>, Option<QtyByQualifier>)],
filter_full_zero: bool,
show_utilization: bool,
used_mode: UsedMode,
) {
// Create the table
let mut table = Table::new();
let format = format::FormatBuilder::new()
// .column_separator('|')
// .borders('|')
// .separators(&[format::LinePosition::Top,
// format::LinePosition::Bottom],
// format::LineSeparator::new('-', '+', '+', '+'))
.separators(&[], format::LineSeparator::new('-', '+', '+', '+'))
.padding(1, 1)
.build();
table.set_format(format);
let mut row_titles = row![bl->"Resource", br->"Utilization", br->"Requested", br->"Limit", br->"Allocatable", br->"Free"];
if !show_utilization {
row_titles.remove_cell(1);
}
table.set_titles(row_titles);
let data2 = data
.iter()
.filter(|d| {
!filter_full_zero
|| !d
.1
.as_ref()
.map(|x| {
x.utilization.is_none()
&& is_empty(&x.requested)
&& is_empty(&x.limit)
&& is_empty(&x.allocatable)
})
.unwrap_or(false)
})
.collect::<Vec<_>>();
let prefixes = tree::provide_prefix(&data2, |parent, item| parent.0.len() + 1 == item.0.len());
for ((k, oqtys), prefix) in data2.iter().zip(prefixes.iter()) {
let column0 = format!(
"{} {}",
prefix,
k.last().map(|x| x.as_str()).unwrap_or("???")
);
if let Some(qtys) = oqtys {
let style = if qtys.requested > qtys.limit
|| qtys.utilization > qtys.limit
|| is_empty(&qtys.requested)
|| is_empty(&qtys.limit)
{
"rFy"
} else {
"rFg"
};
let mut row = Row::new(vec![
Cell::new(&column0),
make_cell_for_prettytable(&qtys.utilization, &qtys.allocatable).style_spec(style),
make_cell_for_prettytable(&qtys.requested, &qtys.allocatable).style_spec(style),
make_cell_for_prettytable(&qtys.limit, &qtys.allocatable).style_spec(style),
make_cell_for_prettytable(&qtys.allocatable, &None).style_spec(style),
make_cell_for_prettytable(&qtys.calc_free(used_mode), &None).style_spec(style),
]);
if !show_utilization {
row.remove_cell(1);
}
table.add_row(row);
} else {
table.add_row(Row::new(vec![Cell::new(&column0)]));
}
}
// Print the table to stdout
table.printstd();
}
#[cfg(feature = "prettytable")]
fn is_empty(oqty: &Option<Qty>) -> bool {
match oqty {
Some(qty) => qty.is_zero(),
None => true,
}
}
#[cfg(feature = "prettytable")]
fn make_cell_for_prettytable(oqty: &Option<Qty>, o100: &Option<Qty>) -> Cell {
let txt = match oqty {
None => "__".to_string(),
Some(qty) => match o100 {
None => format!("{}", qty.adjust_scale()),
Some(q100) => format!("({:.0}%) {}", qty.calc_percentage(q100), qty.adjust_scale()),
},
};
Cell::new(&txt)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_accept_resource() {
assert!(accept_resource("cpu", &[]));
assert!(accept_resource("cpu", &["c".to_string()]));
assert!(accept_resource("cpu", &["cpu".to_string()]));
assert!(!accept_resource("cpu", &["cpu3".to_string()]));
assert!(accept_resource("gpu", &["gpu".to_string()]));
assert!(accept_resource("nvidia.com/gpu", &["gpu".to_string()]));
}
}
07070100000018000081A4000000000000000000000001685BA88A00000503000000000000000000000000000000000000002C00000000kubectl-view-allocations-0.22.1/src/main.rsuse clap::Parser;
use color_eyre::eyre::Result;
use kubectl_view_allocations::{CliOpts, GroupBy, do_main};
fn init_tracing() {
use tracing_error::ErrorLayer;
use tracing_subscriber::prelude::*;
use tracing_subscriber::{EnvFilter, fmt};
let fmt_layer = fmt::layer().with_target(false);
let filter_layer = EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new("warn"))
.unwrap();
tracing_subscriber::registry()
.with(filter_layer)
.with(fmt_layer)
.with(ErrorLayer::default())
.init();
}
#[tokio::main]
async fn main() -> Result<()> {
init_tracing();
color_eyre::config::HookBuilder::default()
.panic_section("consider reporting the bug on github")
.install()?;
let mut cli_opts = CliOpts::parse();
//HACK because I didn't find how to default a multiple opts
if cli_opts.group_by.is_empty() {
cli_opts.group_by.push(GroupBy::resource);
cli_opts.group_by.push(GroupBy::node);
cli_opts.group_by.push(GroupBy::pod);
}
if !cli_opts.group_by.contains(&GroupBy::resource) {
cli_opts.group_by.insert(0, GroupBy::resource)
}
cli_opts.group_by.dedup();
// dbg!(&cli_opts);
do_main(&cli_opts).await?;
Ok(())
}
07070100000019000081A4000000000000000000000001685BA88A00000566000000000000000000000000000000000000002F00000000kubectl-view-allocations-0.22.1/src/metrics.rsuse serde::{Deserialize, Serialize};
// kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods | jq .
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Usage {
pub cpu: String,
pub memory: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Container {
pub name: String,
pub usage: Usage,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PodMetrics {
pub metadata: kube::api::ObjectMeta,
pub containers: Vec<Container>,
pub timestamp: String,
pub window: String,
}
// custom impl since metrics API doesn't exist on kube-rs
impl k8s_openapi::Resource for PodMetrics {
const GROUP: &'static str = "metrics.k8s.io";
const KIND: &'static str = "pod";
const VERSION: &'static str = "v1beta1";
const API_VERSION: &'static str = "metrics.k8s.io/v1beta1";
const URL_PATH_SEGMENT: &'static str = "pods";
type Scope = k8s_openapi::NamespaceResourceScope;
}
impl k8s_openapi::Metadata for PodMetrics {
type Ty = kube::api::ObjectMeta;
fn metadata(&self) -> &Self::Ty {
&self.metadata
}
fn metadata_mut(&mut self) -> &mut Self::Ty {
&mut self.metadata
}
}
// #[derive(Debug, Clone, Serialize, Deserialize)]
// struct PodMetricsList {
// metadata: kube::api::ObjectMeta,
// api_version: String,
// kind: String,
// items: Vec<PodMetrics>,
// }
0707010000001A000081A4000000000000000000000001685BA88A00002DB8000000000000000000000000000000000000002B00000000kubectl-view-allocations-0.22.1/src/qty.rs// see [Definitions of the SI units: The binary prefixes](https://physics.nist.gov/cuu/Units/binary.html)
// see [Managing Compute Resources for Containers - Kubernetes](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/)
//TODO rewrite to support exponent, ... see [apimachinery/quantity.go at master · kubernetes/apimachinery](https://github.com/kubernetes/apimachinery/blob/master/pkg/api/resource/quantity.go)
use std::cmp::Ordering;
use std::str::FromStr;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Failed to parse scale in '{0}'")]
ScaleParseError(String),
#[error("Failed to read Qty (num) from '{input}'")]
QtyNumberParseError {
input: String,
#[source] // optional if field name is `source`
source: std::num::ParseFloatError,
},
}
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub struct Scale {
label: &'static str,
base: u32,
pow: i32,
}
// should be sorted in DESC
#[rustfmt::skip]
static SCALES: [Scale;15] = [
Scale{ label:"Pi", base: 2, pow: 50},
Scale{ label:"Ti", base: 2, pow: 40},
Scale{ label:"Gi", base: 2, pow: 30},
Scale{ label:"Mi", base: 2, pow: 20},
Scale{ label:"Ki", base: 2, pow: 10},
Scale{ label:"P", base: 10, pow: 15},
Scale{ label:"T", base: 10, pow: 12},
Scale{ label:"G", base: 10, pow: 9},
Scale{ label:"M", base: 10, pow: 6},
Scale{ label:"k", base: 10, pow: 3},
Scale{ label:"", base: 10, pow: 0},
Scale{ label:"m", base: 10, pow: -3},
Scale{ label:"u", base: 10, pow: -6},
Scale{ label:"μ", base: 10, pow: -6},
Scale{ label:"n", base: 10, pow: -9},
];
impl FromStr for Scale {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
SCALES
.iter()
.find(|v| v.label == s)
.cloned()
.ok_or_else(|| Error::ScaleParseError(s.to_owned()))
}
}
impl From<&Scale> for f64 {
fn from(v: &Scale) -> f64 {
if v.pow == 0 || v.base == 0 {
1.0
} else {
f64::from(v.base).powf(f64::from(v.pow))
}
}
}
impl PartialOrd for Scale {
//TODO optimize accuracy with big number
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let v1 = f64::from(self);
let v2 = f64::from(other);
if v1 > v2 {
Some(Ordering::Greater)
} else if v1 < v2 {
Some(Ordering::Less)
} else if (v1 - v2).abs() < f64::EPSILON {
Some(Ordering::Equal)
} else {
None
}
}
}
impl Scale {
pub fn min(&self, other: &Scale) -> Scale {
if self < other {
self.clone()
} else {
other.clone()
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub struct Qty {
pub value: i64,
pub scale: Scale,
}
impl From<&Qty> for f64 {
fn from(v: &Qty) -> f64 {
(v.value as f64) * 0.001
}
}
impl Qty {
pub fn zero() -> Self {
Self {
value: 0,
scale: Scale::from_str("").unwrap(),
}
}
pub fn lowest_positive() -> Self {
Self {
value: 1,
scale: Scale::from_str("m").unwrap(),
}
}
pub fn is_zero(&self) -> bool {
self.value == 0
}
pub fn calc_percentage(&self, base100: &Self) -> f64 {
if base100.value != 0 {
f64::from(self) * 100f64 / f64::from(base100)
} else {
f64::NAN
}
}
pub fn adjust_scale(&self) -> Self {
let valuef64 = f64::from(self);
let scale = SCALES
.iter()
.filter(|s| s.base == self.scale.base || self.scale.base == 0)
.find(|s| f64::from(*s) <= valuef64);
match scale {
Some(scale) => Self {
value: self.value,
scale: scale.clone(),
},
None => self.clone(),
}
}
}
impl FromStr for Qty {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (num_str, scale_str): (&str, &str) = match s.find(|c: char| {
!c.is_ascii_digit() && c != 'E' && c != 'e' && c != '+' && c != '-' && c != '.'
}) {
Some(pos) => (&s[..pos], &s[pos..]),
None => (s, ""),
};
let scale = Scale::from_str(scale_str.trim())?;
let num = f64::from_str(num_str).map_err(|source| Error::QtyNumberParseError {
input: num_str.to_owned(),
source,
})?;
let value = (num * f64::from(&scale) * 1000f64) as i64;
Ok(Qty { value, scale })
}
}
impl std::fmt::Display for Qty {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{:.1}{}",
(self.value as f64 / (f64::from(&self.scale) * 1000f64)),
self.scale.label
)
}
}
impl PartialOrd for Qty {
//TODO optimize accuracy with big number
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Qty {
//TODO optimize accuracy with big number
fn cmp(&self, other: &Self) -> Ordering {
let v1 = self.value; // f64::from(self);
let v2 = other.value; // f64::from(other);
v1.partial_cmp(&v2).unwrap() // i64 should always be comparable (no NaNs or anything crazy like that)
}
}
pub fn select_scale_for_add(v1: &Qty, v2: &Qty) -> Scale {
if v2.value == 0 {
v1.scale.clone()
} else if v1.value == 0 {
v2.scale.clone()
} else {
v1.scale.min(&v2.scale)
}
}
impl std::ops::Add for Qty {
type Output = Qty;
fn add(self, other: Self) -> Qty {
&self + &other
}
}
impl std::ops::Add for &Qty {
type Output = Qty;
fn add(self, other: Self) -> Qty {
Qty {
value: self.value + other.value,
scale: select_scale_for_add(self, other),
}
}
}
impl<'b> std::ops::AddAssign<&'b Qty> for Qty {
fn add_assign(&mut self, other: &'b Self) {
*self = Qty {
value: self.value + other.value,
scale: select_scale_for_add(self, other),
}
}
}
impl std::ops::Sub for Qty {
type Output = Qty;
fn sub(self, other: Self) -> Qty {
&self - &other
}
}
impl std::ops::Sub for &Qty {
type Output = Qty;
fn sub(self, other: Self) -> Qty {
Qty {
value: self.value - other.value,
scale: select_scale_for_add(self, other),
}
}
}
impl<'b> std::ops::SubAssign<&'b Qty> for Qty {
fn sub_assign(&mut self, other: &'b Self) {
*self = Qty {
value: self.value - other.value,
scale: select_scale_for_add(self, other),
};
}
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
macro_rules! assert_is_close {
($x:expr, $y:expr, $range:expr) => {
assert!($x >= ($y - $range));
assert!($x <= ($y + $range));
};
}
#[test]
fn test_to_base() -> Result<(), Box<dyn std::error::Error>> {
assert_is_close!(
f64::from(&Qty::from_str("1k")?),
f64::from(&Qty::from_str("1000000m")?),
0.01
);
assert_eq!(
Qty::from_str("1Ki")?,
Qty {
value: 1024000,
scale: Scale {
label: "Ki",
base: 2,
pow: 10,
},
}
);
Ok(())
}
#[test]
fn expectation_ok_for_adjust_scale() -> Result<(), Box<dyn std::error::Error>> {
let cases = vec![
("1k", "1.0k"),
("10k", "10.0k"),
("100k", "100.0k"),
("999k", "999.0k"),
("1000k", "1.0M"),
("1999k", "2.0M"), //TODO 1.9M should be better ?
("1Ki", "1.0Ki"),
("10Ki", "10.0Ki"),
("100Ki", "100.0Ki"),
("1000Ki", "1000.0Ki"),
("1024Ki", "1.0Mi"),
("25641877504", "25.6G"),
("1770653738944", "1.8T"),
("1000m", "1.0"),
("100m", "100.0m"),
("1m", "1.0m"),
];
for (input, expected) in cases {
assert_eq!(
format!("{}", &Qty::from_str(input)?.adjust_scale()),
expected.to_string()
);
}
Ok(())
}
#[test]
fn test_display() -> Result<(), Box<dyn std::error::Error>> {
let cases = vec![
("1k", "1.0k"),
("10k", "10.0k"),
("100k", "100.0k"),
("999k", "999.0k"),
("1000k", "1000.0k"),
("1999k", "1999.0k"),
("1Ki", "1.0Ki"),
("10Ki", "10.0Ki"),
("100Ki", "100.0Ki"),
("1000Ki", "1000.0Ki"),
("1024Ki", "1024.0Ki"),
("25641877504", "25641877504.0"),
("1000m", "1000.0m"),
("100m", "100.0m"),
("1m", "1.0m"),
("1000000n", "1000000.0n"),
// lowest precision is m, under 1m value is trunked
("1u", "0.0u"),
("1μ", "0.0μ"),
("1n", "0.0n"),
("999999n", "0.0n"),
];
for input in cases {
assert_eq!(format!("{}", &Qty::from_str(input.0)?), input.1.to_string());
assert_eq!(format!("{}", &Qty::from_str(input.1)?), input.1.to_string());
}
Ok(())
}
#[test]
fn test_f64_from_scale() -> Result<(), Box<dyn std::error::Error>> {
assert_is_close!(f64::from(&Scale::from_str("m")?), 0.001, 0.00001);
Ok(())
}
#[test]
fn test_f64_from_qty() -> Result<(), Box<dyn std::error::Error>> {
assert_is_close!(f64::from(&Qty::from_str("20m")?), 0.020, 0.00001);
assert_is_close!(f64::from(&Qty::from_str("300m")?), 0.300, 0.00001);
assert_is_close!(f64::from(&Qty::from_str("1000m")?), 1.000, 0.00001);
assert_is_close!(f64::from(&Qty::from_str("+1000m")?), 1.000, 0.00001);
assert_is_close!(f64::from(&Qty::from_str("-1000m")?), -1.000, 0.00001);
assert_is_close!(
f64::from(&Qty::from_str("3145728e3")?),
3145728000.000,
0.00001
);
Ok(())
}
#[test]
fn test_add() -> Result<(), Box<dyn std::error::Error>> {
assert_eq!(
(Qty::from_str("1")?
+ Qty::from_str("300m")?
+ Qty::from_str("300m")?
+ Qty::from_str("300m")?
+ Qty::from_str("300m")?),
Qty::from_str("2200m")?
);
assert_eq!(
Qty::default() + Qty::from_str("300m")?,
Qty::from_str("300m")?
);
assert_eq!(
Qty::default() + Qty::from_str("16Gi")?,
Qty::from_str("16Gi")?
);
assert_eq!(
Qty::from_str("20m")? + Qty::from_str("300m")?,
Qty::from_str("320m")?
);
assert_eq!(
&(Qty::from_str("1k")? + Qty::from_str("300m")?),
&Qty::from_str("1000300m")?
);
assert_eq!(
&(Qty::from_str("1Ki")? + Qty::from_str("1Ki")?),
&Qty::from_str("2Ki")?
);
assert_eq!(
&(Qty::from_str("1Ki")? + Qty::from_str("1k")?),
&Qty {
value: 2024000,
scale: Scale {
label: "k",
base: 10,
pow: 3,
},
}
);
Ok(())
}
}
0707010000001B000081A4000000000000000000000001685BA88A000011F9000000000000000000000000000000000000002C00000000kubectl-view-allocations-0.22.1/src/tree.rs//! module to make tree-table or tree from a list,
//! by computing the string prefix that contains line of to link item of the list
//! like a tree (multi-root)
//!
//! ```rust
//! use kubectl_view_allocations::tree::provide_prefix;
//!
//! let items = vec![
//! "1/2",
//! "1/2/3",
//! "1/2/3/4",
//! "1/2/5",
//! "6",
//! "7",
//! "7/8",
//! "7/9",
//! ];
//!
//! let prefixes = provide_prefix(&items, |parent, item| {
//! let pi = item.split("/");
//! let pp = parent.split("/");
//! (pi.count() == pp.count() + 1) && item.starts_with(parent)
//! });
//!
//! let mut actual = String::new();
//! prefixes.iter().zip(items).for_each(|(p, i)|
//! actual.push_str(&format!("{} {}\n", p, i))
//! );
//!
//! let expected = r#" 1/2
//! ├─ 1/2/3
//! │ └─ 1/2/3/4
//! └─ 1/2/5
//! 6
//! 7
//! ├─ 7/8
//! └─ 7/9
//! "#;
//! //dbg!(&actual);
//! assert_eq!(actual, expected);
//! ```
//!
#[derive(Debug, Clone)]
struct TreeNode {
parent: Option<usize>,
level: Vec<bool>,
children: Vec<usize>,
}
fn level_to_string(level: &[bool]) -> String {
const EMPTY: &str = " ";
const EDGE: &str = " └─";
const PIPE: &str = " │ ";
const BRANCH: &str = " ├─";
let mut prefix = String::new();
if !level.is_empty() {
let last_col = level.len() - 1;
for (col, is_last_child) in level.iter().enumerate() {
let is_last_col = col == last_col;
let s = match (*is_last_child, is_last_col) {
(true, false) => EMPTY,
(true, true) => EDGE,
(false, false) => PIPE,
(false, true) => BRANCH,
};
prefix.push_str(s);
}
}
prefix
}
fn write_tree_level_of_children(nodes: &mut [TreeNode], idx: usize) {
if let Some(node) = nodes.get(idx) {
let treenode = node.clone();
let mut d = treenode.children.len();
for s in treenode.children.iter() {
if let Some(child) = nodes.get_mut(*s) {
let mut lnext = treenode.level.clone();
lnext.push(d == 1);
d -= 1;
child.level = lnext;
}
}
}
}
fn make_tree_by_reverse_depth_first<I, F>(items: &[I], is_parent_of: F) -> Vec<TreeNode>
where
F: Fn(&I, &I) -> bool,
{
let mut current: Option<usize> = None;
let mut nodes: Vec<TreeNode> = vec![];
for (i, item) in items.iter().enumerate() {
while current.is_some() && !is_parent_of(&items[current.unwrap()], item) {
current = nodes.get_mut(current.unwrap()).and_then(|n| n.parent);
}
let treenode = TreeNode {
parent: current,
level: vec![],
children: vec![],
};
if let Some(parent) = current {
if let Some(node) = nodes.get_mut(parent) {
node.children.push(i);
}
}
nodes.push(treenode);
current = Some(i);
}
nodes
}
/// Generate a list of prefix to display items as a tree (multi-root)
/// - the input should be sorted in the target display order
/// - the input order of ìtems is preserved into output
/// - the input order is used to ask for parent of item (parent should be before child)
/// - output as the same number of element than input `items`
/// - output can be zipped with input ìtems
/// - is_parent_of(maybe_parent, item)
pub fn provide_prefix<I, F>(items: &[I], is_parent_of: F) -> Vec<String>
where
F: Fn(&I, &I) -> bool,
{
let mut nodes: Vec<TreeNode> = make_tree_by_reverse_depth_first(items, is_parent_of);
//dbg!(&nodes);
for i in 0..nodes.len() {
write_tree_level_of_children(&mut nodes, i);
}
//dbg!(&nodes);
nodes.iter().map(|n| level_to_string(&n.level)).collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_() {
let items = vec!["1/2", "1/2/3", "1/2/3/4", "1/2/5", "6", "7", "7/8", "7/9"];
let prefixes = provide_prefix(&items, |parent, item| {
let pi = item.split('/');
let pp = parent.split('/');
(pi.count() == pp.count() + 1) && item.starts_with(parent)
});
let mut actual = String::new();
prefixes
.iter()
.zip(items)
.for_each(|(p, i)| actual.push_str(&format!("{} {}\n", p, i)));
let expected = r#" 1/2
├─ 1/2/3
│ └─ 1/2/3/4
└─ 1/2/5
6
7
├─ 7/8
└─ 7/9
"#;
//dbg!(&actual);
assert_eq!(actual, expected);
}
}
0707010000001C000041ED000000000000000000000002685BA88A00000000000000000000000000000000000000000000002600000000kubectl-view-allocations-0.22.1/tests0707010000001D000081A4000000000000000000000001685BA88A00000F9B000000000000000000000000000000000000004500000000kubectl-view-allocations-0.22.1/tests/metrics-server-components.yamlapiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-view: "true"
name: system:aggregated-metrics-reader
rules:
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
rules:
- apiGroups:
- ""
resources:
- pods
- nodes
- nodes/stats
- namespaces
- configmaps
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server-auth-reader
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:metrics-server
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
ports:
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: metrics-server
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
k8s-app: metrics-server
spec:
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --kubelet-insecure-tls
image: k8s.gcr.io/metrics-server/metrics-server:v0.4.2
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /livez
port: https
scheme: HTTPS
periodSeconds: 10
name: metrics-server
ports:
- containerPort: 4443
name: https
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /readyz
port: https
scheme: HTTPS
periodSeconds: 10
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- mountPath: /tmp
name: tmp-dir
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
serviceAccountName: metrics-server
volumes:
- emptyDir: {}
name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
labels:
k8s-app: metrics-server
name: v1beta1.metrics.k8s.io
spec:
group: metrics.k8s.io
groupPriorityMinimum: 100
insecureSkipTLSVerify: true
service:
name: metrics-server
namespace: kube-system
version: v1beta1
versionPriority: 100
0707010000001E000081ED000000000000000000000001685BA88A000001A2000000000000000000000000000000000000003700000000kubectl-view-allocations-0.22.1/tests/run_ubuntu_16.sh#!/bin/bash
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
docker build -t ubuntu_curl:16.04 -f "${DIR}/ubuntu_16.dockerfile" "${DIR}"
docker run --rm \
-v ${DIR}/..:/prj \
-v $HOME/.kube:/root/.kube \
-w /tmp \
ubuntu_curl:16.04 \
/prj/tests/test_first_run.sh
# docker run --rm -it \
# -v ${DIR}/..:/prj \
# -v $HOME/.kube:/root/.kube \
# -w /tmp \
# ubuntu:16.04 \
# bash
0707010000001F000081ED000000000000000000000001685BA88A0000010E000000000000000000000000000000000000003800000000kubectl-view-allocations-0.22.1/tests/test_first_run.sh#!/bin/bash
#set -ex
# apt-get update && apt-get install -y curl
#curl https://raw.githubusercontent.com/davidB/kubectl-view-allocations/master/scripts/getLatest.sh | sh
#sh /prj/scripts/getLatest.sh
bash /prj/scripts/getLatest.sh
ls -l /tmp
kubectl-view-allocations
07070100000020000081A4000000000000000000000001685BA88A00000068000000000000000000000000000000000000003B00000000kubectl-view-allocations-0.22.1/tests/ubuntu_16.dockerfileFROM ubuntu:16.04
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!333 blocks