├── CODEOWNERS ├── .gitignore ├── crates ├── versions │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── serde_helpers.rs │ │ ├── lib.rs │ │ └── deprecations.rs └── policy-metadata-helper │ ├── .gitignore │ ├── Cargo.toml │ └── src │ ├── cli.rs │ ├── policy_metadata.rs │ └── main.rs ├── CONTRIBUTING.md ├── artifacthub-repo.yml ├── renovate.json ├── .github ├── workflows │ ├── open-release-pr.yml │ ├── release-tag.yml │ ├── test.yml │ ├── check-versions-updates-cron.yml │ ├── release-drafter.yml │ └── release.yml └── release-drafter.yml ├── Cargo.toml ├── updatecli-manifest.yaml ├── questions-ui.yml ├── test_data └── ingress_creation.json ├── Makefile ├── src ├── settings.rs └── lib.rs ├── e2e.bats ├── README.md ├── metadata.yml ├── artifacthub-pkg.yml ├── LICENSE ├── versions.yaml └── Cargo.lock /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @kubewarden/kubewarden-developers 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | *.wasm 3 | 4 | 5 | # Added by cargo 6 | # 7 | # already existing elements were commented out 8 | 9 | #/target 10 | -------------------------------------------------------------------------------- /crates/versions/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | *.wasm 3 | 4 | 5 | # Added by cargo 6 | # 7 | # already existing elements were commented out 8 | 9 | #/target 10 | -------------------------------------------------------------------------------- /crates/policy-metadata-helper/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | *.wasm 3 | 4 | 5 | # Added by cargo 6 | # 7 | # already existing elements were commented out 8 | 9 | #/target 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Code conventions 2 | 3 | Check out our global [CONTRIBUTING guidelines](https://github.com/kubewarden/.github/blob/main/CONTRIBUTING.md) for Rust code conventions 4 | -------------------------------------------------------------------------------- /artifacthub-repo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | repositoryID: 42c39ebd-5522-4947-8f3e-5f1f13a3f761 3 | owners: 4 | - name: Kubewarden developers 5 | email: cncf-kubewarden-maintainers@lists.cncf.io 6 | -------------------------------------------------------------------------------- /crates/policy-metadata-helper/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "policy-metadata-helper" 3 | version = "1.0.5" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | clap = { version = "4.5", features = ["derive"] } 8 | serde = { version = "1.0", features = ["derive"] } 9 | serde_yaml = "0.9" 10 | versions = { path = "../versions" } 11 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "github>kubewarden/github-actions//renovate-config/policies" 4 | ], 5 | "packageRules": [ 6 | { 7 | "description": "Update GitHub Actions", 8 | "matchManagers": ["github-actions"], 9 | "groupName": "github-actions", 10 | "groupSlug": "github-actions", 11 | "pinDigests": true 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.github/workflows/open-release-pr.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: 3 | schedule: 4 | - cron: "30 3 12 * *" # At 03:30 on day-of-month 12 5 | 6 | name: Open release PR 7 | 8 | jobs: 9 | test: 10 | name: open-release-pr 11 | uses: kubewarden/github-actions/.github/workflows/reusable-release-pr.yml@247608f0b5a1562a6fd2576e5b2e6cbe62551baf # v4.5.15 12 | secrets: 13 | APP_ID: ${{ secrets.APP_ID }} 14 | APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} 15 | -------------------------------------------------------------------------------- /.github/workflows/release-tag.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | types: 4 | - closed 5 | workflow_dispatch: 6 | inputs: 7 | trigger_release: 8 | description: "Tag and trigger release manually" 9 | required: false 10 | default: true 11 | 12 | name: Tag and Release on PR Merge 13 | 14 | jobs: 15 | test: 16 | name: release-tag 17 | uses: kubewarden/github-actions/.github/workflows/reusable-release-tag.yml@247608f0b5a1562a6fd2576e5b2e6cbe62551baf # v4.5.15 18 | -------------------------------------------------------------------------------- /crates/versions/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "versions" 3 | version = "1.0.5" 4 | authors = ["Flavio Castelli "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | anyhow = "1.0" 11 | kubewarden-policy-sdk = { version = "0.15.0", default-features = false } 12 | lazy_static = "1.4" 13 | serde = { version = "1.0", features = ["derive"] } 14 | serde_json = "1.0" 15 | serde_yaml = "0.9" 16 | semver = "1.0" 17 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | name: Continuous integration 3 | jobs: 4 | test: 5 | name: run tests and linters 6 | uses: kubewarden/github-actions/.github/workflows/reusable-test-policy-rust.yml@247608f0b5a1562a6fd2576e5b2e6cbe62551baf # v4.5.15 7 | 8 | check-metadata: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 12 | - id: check-policy-metadata 13 | shell: bash 14 | run: | 15 | make check-policy-metadata 16 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "deprecated-api-versions" 3 | version = "1.0.5" 4 | authors = ["Flavio Castelli "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [workspace] 10 | members = ["crates/versions", "crates/policy-metadata-helper"] 11 | 12 | [lib] 13 | crate-type = ["cdylib"] 14 | 15 | [dependencies] 16 | anyhow = "1.0" 17 | lazy_static = "1.4" 18 | kubewarden-policy-sdk = { version = "0.15.0", default-features = false } 19 | serde = { version = "1.0", features = ["derive"] } 20 | serde_json = "1.0" 21 | serde_yaml = "0.9" 22 | semver = "1.0" 23 | versions = { path = "crates/versions" } 24 | -------------------------------------------------------------------------------- /.github/workflows/check-versions-updates-cron.yml: -------------------------------------------------------------------------------- 1 | name: Check for updates to versions.yaml file cron job 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' 5 | 6 | permissions: 7 | contents: write 8 | pull-requests: write 9 | 10 | jobs: 11 | audit: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 15 | - name: Install Updatecli in the runner 16 | uses: updatecli/updatecli-action@9a21b6911fe58865c8346d4fde3470010f49bf31 # v2.97.0 17 | 18 | - name: Run Updatecli in Apply mode 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | run: | 22 | updatecli apply --config updatecli-manifest.yaml 23 | -------------------------------------------------------------------------------- /crates/policy-metadata-helper/src/cli.rs: -------------------------------------------------------------------------------- 1 | use clap::{Parser, Subcommand}; 2 | 3 | /// Find the most recent Kubernetes version mentioned inside of `versions.yml` 4 | #[derive(Parser, Debug)] 5 | #[command(author, version, about, long_about = None)] 6 | pub(crate) struct Cli { 7 | /// Path to the metadata.yml of the policy 8 | #[arg(short, long)] 9 | pub metadata_path: String, 10 | 11 | #[command(subcommand)] 12 | pub command: Option, 13 | } 14 | 15 | impl Cli { 16 | pub(crate) fn new() -> Self { 17 | Self::parse() 18 | } 19 | } 20 | 21 | #[derive(Subcommand, Debug)] 22 | pub enum Commands { 23 | /// Propose the rules to be used inside of the policy metadata 24 | Build {}, 25 | /// Check if the rules defined inside of the metadata are correct 26 | Check {}, 27 | } 28 | -------------------------------------------------------------------------------- /updatecli-manifest.yaml: -------------------------------------------------------------------------------- 1 | title: Update versions.yaml file 2 | 3 | scms: 4 | pluto-git: 5 | kind: git 6 | spec: 7 | url: https://github.com/FairwindsOps/pluto.git 8 | branch: master 9 | 10 | policy-git: 11 | kind: github 12 | spec: 13 | owner: "kubewarden" 14 | repository: "deprecated-api-versions-policy" 15 | token: '{{ requiredEnv "GITHUB_TOKEN" }}' 16 | username: '{{ requiredEnv "GITHUB_ACTOR" }}' 17 | branch: "main" 18 | 19 | pullrequests: 20 | helm-charts: 21 | kind: "github" 22 | scmid: policy-git 23 | spec: 24 | description: "Update deprecation definitions" 25 | draft: false 26 | title: "Update versions.yaml file" 27 | 28 | sources: 29 | upstreamVersions: 30 | name: versions.yaml 31 | kind: file 32 | scmid: pluto-git 33 | spec: 34 | file: versions.yaml 35 | transformers: 36 | - addprefix: "# File taken from https://github.com/FairwindsOps/pluto\n" 37 | 38 | targets: 39 | versionsYaml: 40 | name: "versions.yaml" 41 | kind: file 42 | scmid: policy-git 43 | spec: 44 | file: versions.yaml 45 | -------------------------------------------------------------------------------- /crates/policy-metadata-helper/src/policy_metadata.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | // This is a stripped down copy of `policy_evaluator::policy_metadata` 4 | // We could introduce policy_evaluator as a dependency, but that would 5 | // cause the whole wapc environment to be built for this tiny cli program :/ 6 | 7 | #[derive(Deserialize, Serialize, Debug, Clone)] 8 | #[serde(rename_all = "camelCase")] 9 | pub struct MetadataLite { 10 | pub rules: Vec, 11 | } 12 | 13 | #[derive(Deserialize, Serialize, Debug, Clone, Hash, Eq, PartialEq)] 14 | pub enum Operation { 15 | #[serde(rename = "CREATE")] 16 | Create, 17 | #[serde(rename = "UPDATE")] 18 | Update, 19 | #[serde(rename = "DELETE")] 20 | Delete, 21 | #[serde(rename = "CONNECT")] 22 | Connect, 23 | #[serde(rename = "*")] 24 | All, 25 | } 26 | 27 | #[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq)] 28 | #[serde(rename_all = "camelCase")] 29 | pub struct Rule { 30 | pub api_groups: Vec, 31 | pub api_versions: Vec, 32 | pub resources: Vec, 33 | pub operations: Vec, 34 | } 35 | -------------------------------------------------------------------------------- /questions-ui.yml: -------------------------------------------------------------------------------- 1 | questions: 2 | - default: null 3 | description: >- 4 | This policy detects usage of Kubernetes resources that have been deprecated 5 | or removed. At deployment time, the operator must provide a Kubernetes 6 | version to use when looking for deprecation/removal objects. This is done 7 | via the kubernetes_version attribute. 8 | group: Settings 9 | label: Description 10 | required: false 11 | hide_input: true 12 | type: string 13 | variable: description 14 | - default: '' 15 | tooltip: >- 16 | The policy will detect all the Kubernetes resources that are deprecated or 17 | removed starting from the Kubernetes version. 18 | group: Settings 19 | label: Kubernetes Version 20 | placeholder: '1.24.2' 21 | required: true 22 | type: string 23 | variable: kubernetes_version 24 | - default: true 25 | tooltip: >- 26 | By default the policy will prevent the usage of Kubernetes resources that 27 | are already deprecated, but not yet removed. This setting will change that 28 | behavior. 29 | group: Settings 30 | label: Deny on Deprecation 31 | required: false 32 | type: boolean 33 | variable: deny_on_deprecation 34 | -------------------------------------------------------------------------------- /test_data/ingress_creation.json: -------------------------------------------------------------------------------- 1 | { 2 | "uid": "1299d386-525b-4032-98ae-1949f69f9cfc", 3 | "kind": { 4 | "group": "extensions", 5 | "kind": "Ingress", 6 | "version": "v1beta1" 7 | }, 8 | "resource": { 9 | "group": "extensions", 10 | "version": "v1beta1", 11 | "resource": "ingresses" 12 | }, 13 | "operation": "CREATE", 14 | "requestKind": { 15 | "group": "extensions", 16 | "version": "v1beta1", 17 | "kind": "Ingress" 18 | }, 19 | "userInfo": { 20 | "username": "alice", 21 | "uid": "alice-uid", 22 | "groups": [ 23 | "system:authenticated" 24 | ] 25 | }, 26 | "object": { 27 | "metadata": { 28 | "name": "prod" 29 | }, 30 | "spec": { 31 | "tls": [ 32 | { 33 | "hosts": [ 34 | "some-host.com" 35 | ], 36 | "secretName": "secret-name-tls" 37 | } 38 | ], 39 | "rules": [ 40 | { 41 | "host": "some-host.com", 42 | "http": { 43 | "paths": [ 44 | { 45 | "path": "/", 46 | "backend": { 47 | "service": { 48 | "name": "service", 49 | "port": 443 50 | } 51 | } 52 | } 53 | ] 54 | } 55 | } 56 | ] 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | # branches to consider in the event; optional, defaults to all 7 | branches: 8 | - main 9 | # pull_request event is required only for autolabeler 10 | pull_request: 11 | # Only following types are handled by the action, but one can default to all as well 12 | types: [opened, reopened, synchronize, edited] 13 | # pull_request_target event is required for autolabeler to support PRs from forks 14 | pull_request_target: 15 | types: [opened, reopened, synchronize, edited] 16 | 17 | permissions: 18 | contents: read 19 | 20 | jobs: 21 | update_release_draft: 22 | permissions: 23 | # write permission is required to create a github release 24 | contents: write 25 | # write permission is required for autolabeler 26 | # otherwise, read permission is required at least 27 | pull-requests: write 28 | runs-on: ubuntu-latest 29 | steps: 30 | # Drafts your next Release notes as Pull Requests are merged into "master" 31 | - uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0 32 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml 33 | # with: 34 | # config-name: my-config.yml 35 | # disable-autolabeler: true 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SOURCE_FILES := $(shell test -e src/ && find src -type f) 2 | VERSION := $(shell sed --posix -n 's,^version = \"\(.*\)\",\1,p' Cargo.toml) 3 | 4 | policy.wasm: $(SOURCE_FILES) Cargo.* 5 | cargo build --target=wasm32-wasip1 --release 6 | cp target/wasm32-wasip1/release/*.wasm policy.wasm 7 | 8 | artifacthub-pkg.yml: metadata.yml Cargo.toml 9 | kwctl scaffold artifacthub --metadata-path metadata.yml --version $(VERSION) \ 10 | --questions-path questions-ui.yml --output artifacthub-pkg.yml 11 | 12 | annotated-policy.wasm: policy.wasm metadata.yml 13 | kwctl annotate -m metadata.yml -u README.md -o annotated-policy.wasm policy.wasm 14 | 15 | .PHONY: fmt 16 | fmt: 17 | cargo fmt --all -- --check 18 | 19 | .PHONY: lint 20 | lint: 21 | cargo clippy --workspace -- -D warnings 22 | 23 | .PHONY: e2e-tests 24 | e2e-tests: annotated-policy.wasm 25 | bats e2e.bats 26 | 27 | .PHONY: test 28 | test: check-policy-metadata check-policy-version fmt lint 29 | cargo test --workspace 30 | 31 | .PHONY: expected-policy-metadata 32 | expected-policy-metadata: 33 | cargo run --quiet --manifest-path crates/policy-metadata-helper/Cargo.toml -- --metadata-path metadata.yml build 34 | 35 | .PHONY: check-policy-metadata 36 | check-policy-metadata: 37 | cargo run --quiet --manifest-path crates/policy-metadata-helper/Cargo.toml -- --metadata-path metadata.yml check 38 | 39 | .PHONY: clean 40 | clean: 41 | cargo clean 42 | cargo clean --manifest-path crates/policy-metadata-helper/Cargo.toml 43 | cargo clean --manifest-path crates/versions/Cargo.toml 44 | rm -f policy.wasm annotated-policy.wasm artifacthub-pkg.yml 45 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: 3 | push: 4 | branches: 5 | - main 6 | tags: 7 | - "v*" 8 | 9 | name: Release policy 10 | 11 | jobs: 12 | test: 13 | name: run tests and linters 14 | uses: kubewarden/github-actions/.github/workflows/reusable-test-policy-rust.yml@247608f0b5a1562a6fd2576e5b2e6cbe62551baf # v4.5.15 15 | 16 | check-policy-metadata: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 20 | - id: check-policy-metadata 21 | shell: bash 22 | run: | 23 | make check-policy-metadata 24 | 25 | release: 26 | needs: 27 | - test 28 | - check-policy-metadata 29 | permissions: 30 | # Required to create GH releases 31 | contents: write 32 | # Required to push to GHCR 33 | packages: write 34 | # Required by cosign keyless signing 35 | id-token: write 36 | uses: kubewarden/github-actions/.github/workflows/reusable-release-policy-rust.yml@247608f0b5a1562a6fd2576e5b2e6cbe62551baf # v4.5.15 37 | with: 38 | oci-target: ghcr.io/${{ github.repository_owner }}/policies/deprecated-api-versions 39 | 40 | release-catalog: 41 | needs: release 42 | uses: kubewarden/github-actions/.github/workflows/reusable-release-policy-catalog.yml@247608f0b5a1562a6fd2576e5b2e6cbe62551baf # v4.5.15 43 | secrets: 44 | # Required to dispatch the release event to the policy-catalog repository 45 | APP_ID: ${{ secrets.APP_ID }} 46 | APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} 47 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | categories: 2 | - title: "⚠️ Breaking changes" 3 | labels: 4 | - "kind/major" 5 | - "kind/breaking-change" 6 | - title: "🚀 Features" 7 | labels: 8 | - "kind/enhancement" 9 | - "kind/feature" 10 | - title: "🐛 Bug Fixes" 11 | labels: 12 | - "kind/bug" 13 | - title: "🧰 Maintenance" 14 | labels: 15 | - "kind/chore" 16 | - "area/dependencies" 17 | 18 | exclude-labels: 19 | - duplicate 20 | - invalid 21 | - later 22 | - wontfix 23 | - kind/question 24 | - release/skip-changelog 25 | 26 | change-template: "- $TITLE (#$NUMBER)" 27 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. 28 | name-template: "v$RESOLVED_VERSION" 29 | template: | 30 | $CHANGES 31 | 32 | autolabeler: 33 | # Tag any PR with "!" in the subject as major update. In other words, breaking change 34 | - label: "kind/breaking-change" 35 | title: "/.*!:.*/" 36 | - label: "area/dependencies" 37 | title: "chore(deps)" 38 | - label: "area/dependencies" 39 | title: "fix(deps)" 40 | - label: "area/dependencies" 41 | title: "build(deps)" 42 | - label: "kind/feature" 43 | title: "feat" 44 | - label: "kind/bug" 45 | title: "fix" 46 | - label: "kind/chore" 47 | title: "chore" 48 | 49 | version-resolver: 50 | major: 51 | labels: 52 | - "kind/major" 53 | - "kind/breaking-change" 54 | minor: 55 | labels: 56 | - "kind/minor" 57 | - "kind/feature" 58 | - "kind/enhancement" 59 | patch: 60 | labels: 61 | - "kind/patch" 62 | - "kind/fix" 63 | - "kind/bug" 64 | - "kind/chore" 65 | - "area/dependencies" 66 | default: patch 67 | -------------------------------------------------------------------------------- /src/settings.rs: -------------------------------------------------------------------------------- 1 | use lazy_static::lazy_static; 2 | use semver::Version; 3 | use serde::{Deserialize, Serialize}; 4 | 5 | use versions::serde_helpers::semver_serde; 6 | 7 | lazy_static! { 8 | static ref DEFAULT_KUBERNETES_VERSION: Version = Version::parse("0.0.1").unwrap(); 9 | } 10 | 11 | #[derive(Deserialize, Serialize, Debug)] 12 | #[serde(rename_all = "snake_case")] 13 | pub(crate) struct Settings { 14 | #[serde(with = "semver_serde")] 15 | pub kubernetes_version: Version, 16 | #[serde(default = "deny_on_deprecation_default")] 17 | pub deny_on_deprecation: bool, 18 | } 19 | 20 | fn deny_on_deprecation_default() -> bool { 21 | true 22 | } 23 | 24 | impl Default for Settings { 25 | fn default() -> Self { 26 | Settings { 27 | kubernetes_version: DEFAULT_KUBERNETES_VERSION.clone(), 28 | deny_on_deprecation: true, 29 | } 30 | } 31 | } 32 | 33 | impl kubewarden::settings::Validatable for Settings { 34 | fn validate(&self) -> Result<(), String> { 35 | if self.kubernetes_version == *DEFAULT_KUBERNETES_VERSION { 36 | Err("Please provide a kubernetes version".to_string()) 37 | } else { 38 | Ok(()) 39 | } 40 | } 41 | } 42 | 43 | #[cfg(test)] 44 | mod tests { 45 | use super::*; 46 | 47 | use kubewarden_policy_sdk::settings::Validatable; 48 | 49 | #[test] 50 | fn validate_settings() { 51 | let settings = Settings { 52 | kubernetes_version: Version::parse("1.25.0").unwrap(), 53 | deny_on_deprecation: true, 54 | }; 55 | 56 | assert!(settings.validate().is_ok()); 57 | 58 | let settings = Settings { 59 | kubernetes_version: Version::parse("0.0.1").unwrap(), 60 | deny_on_deprecation: true, 61 | }; 62 | 63 | assert!(settings.validate().is_err()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /crates/versions/src/serde_helpers.rs: -------------------------------------------------------------------------------- 1 | pub mod semver_serde { 2 | use semver::Version; 3 | use serde::{self, Deserialize, Deserializer, Serializer}; 4 | 5 | pub fn serialize(version: &Version, s: S) -> Result 6 | where 7 | S: Serializer, 8 | { 9 | s.serialize_str(&version.to_string()) 10 | } 11 | 12 | pub fn deserialize<'de, D>(deserializer: D) -> Result 13 | where 14 | D: Deserializer<'de>, 15 | { 16 | let s: String = String::deserialize(deserializer)?; 17 | let version_str = if s.starts_with('v') { 18 | s.strip_prefix('v').unwrap().to_string() 19 | } else { 20 | s 21 | }; 22 | Version::parse(&version_str).map_err(serde::de::Error::custom) 23 | } 24 | } 25 | 26 | pub mod option_semver_serde { 27 | use semver::Version; 28 | use serde::{self, Deserialize, Deserializer, Serializer}; 29 | 30 | pub fn serialize(version: &Option, s: S) -> Result 31 | where 32 | S: Serializer, 33 | { 34 | if let Some(ref v) = *version { 35 | return s.serialize_str(&v.to_string()); 36 | } 37 | s.serialize_none() 38 | } 39 | 40 | pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> 41 | where 42 | D: Deserializer<'de>, 43 | { 44 | let s: Option = Option::deserialize(deserializer)?; 45 | if let Some(s) = s { 46 | if s.is_empty() { 47 | return Ok(None); 48 | } 49 | 50 | let version_str = if s.starts_with('v') { 51 | s.strip_prefix('v').unwrap().to_string() 52 | } else { 53 | s 54 | }; 55 | 56 | return Ok(Some( 57 | Version::parse(&version_str).map_err(serde::de::Error::custom)?, 58 | )); 59 | } 60 | 61 | Ok(None) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /e2e.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | @test "Reject because deprecated" { 4 | run kwctl run \ 5 | --request-path test_data/ingress_creation.json \ 6 | --settings-json '{ "kubernetes_version" : "1.19.0", "deny_on_deprecation_default": true }' \ 7 | annotated-policy.wasm 8 | 9 | # this prints the output when one the checks below fails 10 | echo "output = ${output}" 11 | 12 | [ "$status" -eq 0 ] 13 | [ $(expr "$output" : '.*"allowed":false.*') -ne 0 ] 14 | } 15 | 16 | @test "By default deny_on_deprecation is enabled" { 17 | run kwctl run \ 18 | --request-path test_data/ingress_creation.json \ 19 | --settings-json '{ "kubernetes_version" : "1.19.0" }' \ 20 | annotated-policy.wasm 21 | 22 | # this prints the output when one the checks below fails 23 | echo "output = ${output}" 24 | 25 | [ "$status" -eq 0 ] 26 | [ $(expr "$output" : '.*"allowed":false.*') -ne 0 ] 27 | } 28 | 29 | @test "Handle deny_on_deprecation set to false" { 30 | run kwctl run \ 31 | --request-path test_data/ingress_creation.json \ 32 | --settings-json '{ "kubernetes_version" : "1.19.0", "deny_on_deprecation": false }' \ 33 | annotated-policy.wasm 34 | 35 | # this prints the output when one the checks below fails 36 | echo "output = ${output}" 37 | 38 | [ "$status" -eq 0 ] 39 | [ $(expr "$output" : '.*"allowed":true.*') -ne 0 ] 40 | } 41 | 42 | @test "Reject because dropped" { 43 | run kwctl run \ 44 | --request-path test_data/ingress_creation.json \ 45 | --settings-json '{ "kubernetes_version" : "1.25.0" }' \ 46 | annotated-policy.wasm 47 | 48 | # this prints the output when one the checks below fails 49 | echo "output = ${output}" 50 | 51 | [ "$status" -eq 0 ] 52 | [ $(expr "$output" : '.*"allowed":false.*') -ne 0 ] 53 | } 54 | 55 | @test "Accept on a really old version of kubernetes" { 56 | run kwctl run \ 57 | --request-path test_data/ingress_creation.json \ 58 | --settings-json '{ "kubernetes_version" : "1.10.0" }' \ 59 | annotated-policy.wasm 60 | 61 | # this prints the output when one the checks below fails 62 | echo "output = ${output}" 63 | 64 | [ "$status" -eq 0 ] 65 | [ $(expr "$output" : '.*"allowed":true.*') -ne 0 ] 66 | } 67 | 68 | 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Kubewarden Policy Repository](https://github.com/kubewarden/community/blob/main/badges/kubewarden-policies.svg)](https://github.com/kubewarden/community/blob/main/REPOSITORIES.md#policy-scope) 2 | [![Stable](https://img.shields.io/badge/status-stable-brightgreen?style=for-the-badge)](https://github.com/kubewarden/community/blob/main/REPOSITORIES.md#stable) 3 | 4 | # Kubewarden policy deprecated-api-versions 5 | 6 | ## Description 7 | 8 | This policy detects usage of Kubernetes resources that have been deprecated 9 | or removed. 10 | 11 | At deployment time, the operator must provide a Kubernetes version to use when 12 | looking for deprecation/removal objects. 13 | This is done via the `kubernetes_version` attribute. 14 | 15 | For example, given the following configuration: 16 | 17 | ```yaml 18 | kubernetes_version: "1.24.2" 19 | ``` 20 | 21 | The policy will detect all the Kubernetes resources that are deprecated or removed 22 | starting from the Kubernetes version `1.24.2`. 23 | 24 | ## Keeping up with Kubernetes deprecations 25 | 26 | Kubernetes deprecation evolve over the time. As soon as new deprecations are 27 | added this policy will be updated. 28 | 29 | Currently, this policy is aware of deprecations introduced up to the Kubernetes **1.32.0** release. 30 | 31 | ## Deprecated but not yet removed resources 32 | 33 | By default the policy will prevent the usage of Kubernetes resources that are 34 | already deprecated, but not yet removed. 35 | 36 | This behaviour can be changed via the `deny_on_deprecation` setting. 37 | 38 | For example, let's assume we are using an old version of Kubernetes like 39 | `1.19.3` and someone is attempting to create a `extensions/v1beta1/Ingress` 40 | object. 41 | 42 | This kind of resource has been deprecated starting from `v1.14.0` of Kubernetes, 43 | but it has been removed starting from version `v1.22.0`. 44 | 45 | Given the following configuration: 46 | 47 | ```yaml 48 | kubernetes_version: "1.19.0" 49 | deny_on_deprecation: false 50 | ``` 51 | 52 | The `extensions/v1beta1/Ingress` object will be accepted inside of the cluster. 53 | 54 | On the other hand, it would be blocked with this configuration: 55 | 56 | ```yaml 57 | kubernetes_version: "1.19.0" 58 | deny_on_deprecation: true # note: this is set to true by default 59 | ``` 60 | -------------------------------------------------------------------------------- /crates/policy-metadata-helper/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::collections::{HashMap, HashSet}; 2 | use versions::Versions; 3 | 4 | mod cli; 5 | mod policy_metadata; 6 | use policy_metadata::{MetadataLite as PolicyMetadata, Operation, Rule as PolicyMetadataRule}; 7 | 8 | const K8S_COMPONENT: &str = "k8s"; 9 | 10 | fn generate_metadata_rules() -> Vec { 11 | let mut metadata_rules: Vec = vec![]; 12 | 13 | let mut relevant_versions: HashMap> = HashMap::new(); 14 | 15 | let versions: Versions = serde_yaml::from_slice(include_bytes!("../../../versions.yaml")) 16 | .expect("Cannot decode versions.yml"); 17 | 18 | for rule in &versions.deprecated_versions { 19 | if rule.component != K8S_COMPONENT { 20 | continue; 21 | } 22 | let buffer: Vec<&str> = rule.version.splitn(2, '/').collect(); 23 | let (api_group, api_version) = if buffer.len() != 2 { 24 | ("", buffer[0]) 25 | } else { 26 | (buffer[0], buffer[1]) 27 | }; 28 | 29 | let mut api_versions: HashSet = if relevant_versions.contains_key(api_group) { 30 | relevant_versions[api_group].clone() 31 | } else { 32 | HashSet::new() 33 | }; 34 | api_versions.insert(api_version.to_string()); 35 | relevant_versions.insert(api_group.to_string(), api_versions); 36 | } 37 | 38 | let mut api_groups: Vec = relevant_versions.keys().map(|k| k.to_string()).collect(); 39 | api_groups.sort(); 40 | 41 | for api_group in &api_groups { 42 | let mut api_versions: Vec = relevant_versions[api_group].iter().cloned().collect(); 43 | api_versions.sort(); 44 | 45 | metadata_rules.push(PolicyMetadataRule { 46 | api_groups: vec![api_group.to_owned()], 47 | api_versions, 48 | resources: vec!["*".to_string()], 49 | operations: vec![Operation::Create], 50 | }); 51 | } 52 | 53 | metadata_rules 54 | } 55 | 56 | pub fn main() { 57 | let cli = cli::Cli::new(); 58 | if cli.metadata_path.is_empty() { 59 | eprintln!("You must provide the path to the metadata.yml file of the policy"); 60 | std::process::exit(1); 61 | } 62 | 63 | let metadata_raw = std::fs::read(cli.metadata_path).expect("Error reading metadata file"); 64 | let metadata: PolicyMetadata = 65 | serde_yaml::from_slice(&metadata_raw).expect("Cannot deserialize PolicyMetadata"); 66 | 67 | let expected_rules = generate_metadata_rules(); 68 | 69 | match &cli.command { 70 | Some(cli::Commands::Build {}) => { 71 | println!("{}", serde_yaml::to_string(&expected_rules).unwrap()); 72 | } 73 | Some(cli::Commands::Check {}) => { 74 | if metadata.rules != expected_rules { 75 | eprintln!("Current rules are not correct."); 76 | std::process::exit(1); 77 | } 78 | } 79 | None => {} 80 | }; 81 | } 82 | -------------------------------------------------------------------------------- /crates/versions/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate kubewarden_policy_sdk as kubewarden; 2 | use kubewarden::request::GroupVersionKind; 3 | 4 | use anyhow::Result; 5 | use lazy_static::lazy_static; 6 | use serde::Deserialize; 7 | use std::collections::HashMap; 8 | 9 | pub mod serde_helpers; 10 | 11 | mod deprecations; 12 | use deprecations::{DeprecationRule, DeprecationRules}; 13 | 14 | lazy_static! { 15 | pub static ref DEPRECATION_CHECKER: DeprecationChecker = { 16 | DeprecationChecker::from_yaml(include_bytes!("../../../versions.yaml")).expect( 17 | "Cannot deserialize the embedded versions. Check the 'versions.yaml' file for errors", 18 | ) 19 | }; 20 | } 21 | 22 | #[derive(Deserialize, Debug)] 23 | #[serde(rename_all = "kebab-case")] 24 | pub struct Versions { 25 | pub deprecated_versions: DeprecationRules, 26 | } 27 | 28 | pub struct DeprecationChecker { 29 | deprecated_versions_map: HashMap, 30 | } 31 | 32 | impl DeprecationChecker { 33 | pub fn from_yaml(data: &[u8]) -> Result { 34 | let versions: Versions = serde_yaml::from_slice(data)?; 35 | let mut deprecated_versions_map: HashMap = HashMap::new(); 36 | 37 | for deprecation in &versions.deprecated_versions { 38 | let deprecations = if deprecated_versions_map.contains_key(&deprecation.version) { 39 | let mut deprecations = deprecated_versions_map[&deprecation.version].clone(); 40 | deprecations.push(deprecation.to_owned()); 41 | deprecations 42 | } else { 43 | vec![deprecation.to_owned()] 44 | }; 45 | deprecated_versions_map.insert(deprecation.version.clone(), deprecations); 46 | } 47 | 48 | Ok(DeprecationChecker { 49 | deprecated_versions_map, 50 | }) 51 | } 52 | 53 | pub fn check( 54 | &self, 55 | obj: &GroupVersionKind, 56 | kubernetes_version: &semver::Version, 57 | ) -> Option { 58 | if let Some(deprecations) = self 59 | .deprecated_versions_map 60 | .get(format!("{}/{}", obj.group, obj.version).as_str()) 61 | { 62 | deprecations 63 | .iter() 64 | .find(move |&deprecation| { 65 | deprecation.kind == obj.kind && deprecation.includes(kubernetes_version) 66 | }) 67 | .cloned() 68 | } else { 69 | None 70 | } 71 | } 72 | } 73 | 74 | #[cfg(test)] 75 | mod tests { 76 | use super::*; 77 | use semver::Version; 78 | 79 | #[test] 80 | fn check_deprecations() { 81 | let yaml_data = r#" 82 | deprecated-versions: 83 | - version: extensions/v1beta1 84 | kind: ReplicaSet 85 | deprecated-in: "" 86 | removed-in: v1.16.0 87 | replacement-api: apps/v1 88 | component: k8s 89 | - version: extensions/v1beta1 90 | kind: PodSecurityPolicy 91 | deprecated-in: v1.10.0 92 | removed-in: v1.16.0 93 | replacement-api: policy/v1beta1 94 | component: k8s 95 | "#; 96 | 97 | let deprecated_versions = 98 | DeprecationChecker::from_yaml(yaml_data.as_bytes()).expect("Cannot parse yaml"); 99 | 100 | let obj = GroupVersionKind { 101 | group: "extensions".to_string(), 102 | version: "v1beta1".to_string(), 103 | kind: "ReplicaSet".to_string(), 104 | }; 105 | 106 | let kubernetes_version = Version::parse("1.24.0").expect("Cannot parse version"); 107 | let deprecation = deprecated_versions.check(&obj, &kubernetes_version); 108 | assert!(deprecation.is_some()); 109 | 110 | let kubernetes_version = Version::parse("1.14.0").expect("Cannot parse version"); 111 | let deprecation = deprecated_versions.check(&obj, &kubernetes_version); 112 | assert!(deprecation.is_none()); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use guest::prelude::*; 2 | use kubewarden_policy_sdk::wapc_guest as guest; 3 | 4 | extern crate kubewarden_policy_sdk as kubewarden; 5 | use kubewarden::{protocol_version_guest, request::ValidationRequest, validate_settings}; 6 | 7 | mod settings; 8 | use settings::Settings; 9 | 10 | use versions::DEPRECATION_CHECKER; 11 | 12 | #[no_mangle] 13 | pub extern "C" fn wapc_init() { 14 | register_function("validate", validate); 15 | register_function("validate_settings", validate_settings::); 16 | register_function("protocol_version", protocol_version_guest); 17 | } 18 | 19 | fn validate(payload: &[u8]) -> CallResult { 20 | let validation_request: ValidationRequest = ValidationRequest::new(payload)?; 21 | let obj = validation_request.request.kind; 22 | let kubernetes_version = validation_request.settings.kubernetes_version; 23 | 24 | match DEPRECATION_CHECKER.check(&obj, &kubernetes_version) { 25 | Some(deprecation_rule) => { 26 | if !validation_request.settings.deny_on_deprecation 27 | && deprecation_rule.is_only_deprecated(&kubernetes_version)? 28 | { 29 | return kubewarden::accept_request(); 30 | } 31 | kubewarden::reject_request(Some(deprecation_rule.to_string()), None, None, None) 32 | } 33 | None => kubewarden::accept_request(), 34 | } 35 | } 36 | 37 | #[cfg(test)] 38 | mod tests { 39 | use super::*; 40 | 41 | use kubewarden_policy_sdk::test::Testcase; 42 | 43 | #[test] 44 | fn eval_extensions_v1beta1_ingress() -> Result<(), ()> { 45 | // This is the deprecation rule: 46 | // 47 | // version: extensions/v1beta1 48 | // kind: Ingress 49 | // deprecated-in: v1.14.0 50 | // removed-in: v1.22.0 51 | // replacement-api: networking.k8s.io/v1 52 | // component: k8s 53 | 54 | let request_file = "test_data/ingress_creation.json"; 55 | let test_cases = vec![ 56 | Testcase { 57 | name: String::from("Reject because it has been dropped from kubernetes 1.25.0"), 58 | fixture_file: String::from(request_file), 59 | expected_validation_result: false, 60 | settings: Settings { 61 | kubernetes_version: semver::Version::parse("1.25.0").unwrap(), 62 | deny_on_deprecation: true, 63 | }, 64 | }, 65 | Testcase { 66 | name: String::from("Reject because it has been deprected startiong from 1.14.0"), 67 | fixture_file: String::from(request_file), 68 | expected_validation_result: false, 69 | settings: Settings { 70 | kubernetes_version: semver::Version::parse("1.19.0").unwrap(), 71 | deny_on_deprecation: true, 72 | }, 73 | }, 74 | Testcase { 75 | name: String::from( 76 | "Do not reject despite being deprected because of user settings", 77 | ), 78 | fixture_file: String::from(request_file), 79 | expected_validation_result: true, 80 | settings: Settings { 81 | kubernetes_version: semver::Version::parse("1.19.0").unwrap(), 82 | deny_on_deprecation: false, 83 | }, 84 | }, 85 | Testcase { 86 | name: String::from("Accept on a really old version of kubernetes"), 87 | fixture_file: String::from(request_file), 88 | expected_validation_result: true, 89 | settings: Settings { 90 | kubernetes_version: semver::Version::parse("1.10.0").unwrap(), 91 | deny_on_deprecation: false, 92 | }, 93 | }, 94 | ]; 95 | 96 | for tc in &test_cases { 97 | let res = tc.eval(validate).unwrap(); 98 | assert!( 99 | res.mutated_object.is_none(), 100 | "Something mutated with test case: {}", 101 | tc.name, 102 | ); 103 | } 104 | 105 | Ok(()) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /metadata.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - apiGroups: 3 | - admissionregistration.k8s.io 4 | apiVersions: 5 | - v1beta1 6 | resources: 7 | - "*" 8 | operations: 9 | - CREATE 10 | - apiGroups: 11 | - apiextensions.k8s.io 12 | apiVersions: 13 | - v1beta1 14 | resources: 15 | - "*" 16 | operations: 17 | - CREATE 18 | - apiGroups: 19 | - apiregistration.k8s.io 20 | apiVersions: 21 | - v1beta1 22 | resources: 23 | - "*" 24 | operations: 25 | - CREATE 26 | - apiGroups: 27 | - apps 28 | apiVersions: 29 | - v1beta1 30 | - v1beta2 31 | resources: 32 | - "*" 33 | operations: 34 | - CREATE 35 | - apiGroups: 36 | - audit.k8s.io 37 | apiVersions: 38 | - v1alpha1 39 | - v1beta1 40 | resources: 41 | - "*" 42 | operations: 43 | - CREATE 44 | - apiGroups: 45 | - authentication.k8s.io 46 | apiVersions: 47 | - v1beta1 48 | resources: 49 | - "*" 50 | operations: 51 | - CREATE 52 | - apiGroups: 53 | - autoscaling 54 | apiVersions: 55 | - v2beta1 56 | - v2beta2 57 | resources: 58 | - "*" 59 | operations: 60 | - CREATE 61 | - apiGroups: 62 | - batch 63 | apiVersions: 64 | - v1beta1 65 | resources: 66 | - "*" 67 | operations: 68 | - CREATE 69 | - apiGroups: 70 | - certificates.k8s.io 71 | apiVersions: 72 | - v1beta1 73 | resources: 74 | - "*" 75 | operations: 76 | - CREATE 77 | - apiGroups: 78 | - coordination.k8s.io 79 | apiVersions: 80 | - v1beta1 81 | resources: 82 | - "*" 83 | operations: 84 | - CREATE 85 | - apiGroups: 86 | - discovery.k8s.io 87 | apiVersions: 88 | - v1beta1 89 | resources: 90 | - "*" 91 | operations: 92 | - CREATE 93 | - apiGroups: 94 | - events.k8s.io 95 | apiVersions: 96 | - v1beta1 97 | resources: 98 | - "*" 99 | operations: 100 | - CREATE 101 | - apiGroups: 102 | - extensions 103 | apiVersions: 104 | - v1beta1 105 | resources: 106 | - "*" 107 | operations: 108 | - CREATE 109 | - apiGroups: 110 | - flowcontrol.apiserver.k8s.io 111 | apiVersions: 112 | - v1beta1 113 | - v1beta2 114 | - v1beta3 115 | resources: 116 | - "*" 117 | operations: 118 | - CREATE 119 | - apiGroups: 120 | - networking.k8s.io 121 | apiVersions: 122 | - v1beta1 123 | resources: 124 | - "*" 125 | operations: 126 | - CREATE 127 | - apiGroups: 128 | - node.k8s.io 129 | apiVersions: 130 | - v1beta1 131 | resources: 132 | - "*" 133 | operations: 134 | - CREATE 135 | - apiGroups: 136 | - policy 137 | apiVersions: 138 | - v1beta1 139 | resources: 140 | - "*" 141 | operations: 142 | - CREATE 143 | - apiGroups: 144 | - rbac.authorization.k8s.io 145 | apiVersions: 146 | - v1alpha1 147 | - v1beta1 148 | resources: 149 | - "*" 150 | operations: 151 | - CREATE 152 | - apiGroups: 153 | - scheduling.k8s.io 154 | apiVersions: 155 | - v1alpha1 156 | - v1beta1 157 | resources: 158 | - "*" 159 | operations: 160 | - CREATE 161 | - apiGroups: 162 | - storage.k8s.io 163 | apiVersions: 164 | - v1beta1 165 | resources: 166 | - "*" 167 | operations: 168 | - CREATE 169 | mutating: false 170 | contextAware: false 171 | executionMode: kubewarden-wapc 172 | backgroundAudit: false 173 | annotations: 174 | # artifacthub specific 175 | io.artifacthub.displayName: Deprecated API Versions 176 | io.artifacthub.resources: "*" 177 | io.artifacthub.keywords: compliance, deprecated API 178 | io.kubewarden.policy.ociUrl: ghcr.io/kubewarden/policies/deprecated-api-versions 179 | # kubewarden specific 180 | io.kubewarden.policy.title: deprecated-api-versions 181 | io.kubewarden.policy.description: Find deprecated and removed Kubernetes resources 182 | io.kubewarden.policy.version: 1.0.5 183 | io.kubewarden.policy.author: Kubewarden developers 184 | io.kubewarden.policy.url: https://github.com/kubewarden/deprecated-api-versions-policy 185 | io.kubewarden.policy.source: https://github.com/kubewarden/deprecated-api-versions-policy 186 | io.kubewarden.policy.license: Apache-2.0 187 | io.kubewarden.policy.category: Kubernetes API Versions 188 | io.kubewarden.policy.severity: low 189 | -------------------------------------------------------------------------------- /crates/versions/src/deprecations.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{anyhow, Result}; 2 | use serde::{Deserialize, Serialize}; 3 | use std::fmt; 4 | 5 | use crate::serde_helpers::option_semver_serde; 6 | 7 | pub type DeprecationRules = Vec; 8 | 9 | #[derive(Deserialize, Serialize, Debug, Clone)] 10 | #[serde(rename_all = "kebab-case")] 11 | pub struct DeprecationRule { 12 | pub version: String, 13 | pub kind: String, 14 | #[serde(with = "option_semver_serde")] 15 | pub deprecated_in: Option, 16 | #[serde(default)] 17 | #[serde(with = "option_semver_serde")] 18 | pub removed_in: Option, 19 | pub replacement_api: String, 20 | pub component: String, 21 | } 22 | 23 | impl DeprecationRule { 24 | pub fn includes(&self, kubernetes_version: &semver::Version) -> bool { 25 | if let Some(removed_in) = &self.removed_in { 26 | if kubernetes_version >= removed_in { 27 | return true; 28 | } 29 | } 30 | if let Some(deprecated_in) = &self.deprecated_in { 31 | if kubernetes_version >= deprecated_in { 32 | return true; 33 | } 34 | } 35 | 36 | false 37 | } 38 | 39 | pub fn is_only_deprecated(&self, kubernetes_version: &semver::Version) -> Result { 40 | if let Some(removed_in) = &self.removed_in { 41 | if kubernetes_version >= removed_in { 42 | return Ok(false); 43 | } 44 | } 45 | if let Some(deprecated_in) = &self.deprecated_in { 46 | if kubernetes_version >= deprecated_in { 47 | return Ok(true); 48 | } 49 | } 50 | 51 | Err(anyhow!( 52 | "The deprecation rule '{}' does not apply to kubernetes version: {}", 53 | self, 54 | kubernetes_version 55 | )) 56 | } 57 | } 58 | 59 | impl fmt::Display for DeprecationRule { 60 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 61 | let mut msgs = vec![format!("{} {} cannot be used.", self.version, self.kind,)]; 62 | if let Some(deprecated_in) = &self.deprecated_in { 63 | msgs.push(format!( 64 | "It has been deprecated starting from {deprecated_in}." 65 | )); 66 | } 67 | 68 | if let Some(removed_in) = &self.removed_in { 69 | msgs.push(format!("It has been removed starting from {removed_in}.")); 70 | } 71 | msgs.push(format!("It has been replaced by {}.", self.replacement_api)); 72 | 73 | write!(f, "{}", msgs.join(" ")) 74 | } 75 | } 76 | 77 | #[cfg(test)] 78 | mod tests { 79 | use super::*; 80 | use semver::Version; 81 | 82 | #[test] 83 | fn deserialize_deprecation() { 84 | let yaml_data = vec![ 85 | r#" 86 | version: extensions/v1beta1 87 | kind: ReplicaSet 88 | deprecated-in: "" 89 | removed-in: v1.16.0 90 | replacement-api: apps/v1 91 | component: k8s"#, 92 | r#" 93 | version: extensions/v1beta1 94 | kind: PodSecurityPolicy 95 | deprecated-in: v1.10.0 96 | removed-in: v1.16.0 97 | replacement-api: policy/v1beta1 98 | component: k8s"#, 99 | ]; 100 | 101 | for yaml in &yaml_data { 102 | let deprecation: Result = 103 | serde_yaml::from_str(yaml); 104 | assert!(deprecation.is_ok()); 105 | } 106 | } 107 | 108 | #[test] 109 | fn deprecation_applies_to_kubernetes_release() { 110 | let deprecation: DeprecationRule = serde_yaml::from_str( 111 | r#" 112 | version: extensions/v1beta1 113 | kind: PodSecurityPolicy 114 | deprecated-in: v1.10.0 115 | removed-in: v1.16.0 116 | replacement-api: policy/v1beta1 117 | component: k8s"#, 118 | ) 119 | .expect("cannot deserialize"); 120 | 121 | let matching_versions = vec!["1.10.0", "1.12.0", "1.16.0", "1.23.0"]; 122 | for v in &matching_versions { 123 | let kubernetes_version = 124 | Version::parse(v).unwrap_or_else(|_| panic!("cannot parse version {}", v)); 125 | assert!( 126 | deprecation.includes(&kubernetes_version), 127 | "{} should cause a match", 128 | v 129 | ); 130 | } 131 | 132 | let matching_versions = vec!["1.0.0", "1.9.99"]; 133 | for v in &matching_versions { 134 | let kubernetes_version = 135 | Version::parse(v).unwrap_or_else(|_| panic!("cannot parse version {}", v)); 136 | assert!( 137 | !deprecation.includes(&kubernetes_version), 138 | "{} should not cause a match", 139 | v 140 | ); 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /artifacthub-pkg.yml: -------------------------------------------------------------------------------- 1 | # Kubewarden Artifacthub Package config 2 | # 3 | # Use this config to submit the policy to https://artifacthub.io. 4 | # 5 | # This config can be saved to its default location with: 6 | # kwctl scaffold artifacthub > artifacthub-pkg.yml 7 | version: 0.2.0 8 | name: deprecated-api-versions 9 | displayName: Deprecated API Versions 10 | createdAt: 2025-03-19T09:27:52.338863758Z 11 | description: Find deprecated and removed Kubernetes resources 12 | license: Apache-2.0 13 | homeURL: https://github.com/kubewarden/deprecated-api-versions-policy 14 | containersImages: 15 | - name: policy 16 | image: ghcr.io/kubewarden/policies/deprecated-api-versions:v0.2.0 17 | keywords: 18 | - compliance 19 | - deprecated API 20 | links: 21 | - name: policy 22 | url: https://github.com/kubewarden/deprecated-api-versions-policy/releases/download/v0.2.0/policy.wasm 23 | - name: source 24 | url: https://github.com/kubewarden/deprecated-api-versions-policy 25 | install: | 26 | The policy can be obtained using [`kwctl`](https://github.com/kubewarden/kwctl): 27 | ```console 28 | kwctl pull ghcr.io/kubewarden/policies/deprecated-api-versions:v0.2.0 29 | ``` 30 | Then, generate the policy manifest and tune it to your liking. For example: 31 | ```console 32 | kwctl scaffold manifest -t ClusterAdmissionPolicy registry://ghcr.io/kubewarden/policies/deprecated-api-versions:v0.2.0 33 | ``` 34 | maintainers: 35 | - name: Kubewarden developers 36 | email: cncf-kubewarden-maintainers@lists.cncf.io 37 | provider: 38 | name: kubewarden 39 | recommendations: 40 | - url: https://artifacthub.io/packages/helm/kubewarden/kubewarden-controller 41 | annotations: 42 | kubewarden/mutation: 'false' 43 | kubewarden/questions-ui: | 44 | questions: 45 | - default: null 46 | description: >- 47 | This policy detects usage of Kubernetes resources that have been deprecated 48 | or removed. At deployment time, the operator must provide a Kubernetes 49 | version to use when looking for deprecation/removal objects. This is done 50 | via the kubernetes_version attribute. 51 | group: Settings 52 | label: Description 53 | required: false 54 | hide_input: true 55 | type: string 56 | variable: description 57 | - default: '' 58 | tooltip: >- 59 | The policy will detect all the Kubernetes resources that are deprecated or 60 | removed starting from the Kubernetes version. 61 | group: Settings 62 | label: Kubernetes Version 63 | placeholder: '1.24.2' 64 | required: true 65 | type: string 66 | variable: kubernetes_version 67 | - default: true 68 | tooltip: >- 69 | By default the policy will prevent the usage of Kubernetes resources that 70 | are already deprecated, but not yet removed. This setting will change that 71 | behavior. 72 | group: Settings 73 | label: Deny on Deprecation 74 | required: false 75 | type: boolean 76 | variable: deny_on_deprecation 77 | kubewarden/resources: '*' 78 | kubewarden/rules: | 79 | - apiGroups: 80 | - admissionregistration.k8s.io 81 | apiVersions: 82 | - v1beta1 83 | resources: 84 | - '*' 85 | operations: 86 | - CREATE 87 | - apiGroups: 88 | - apiextensions.k8s.io 89 | apiVersions: 90 | - v1beta1 91 | resources: 92 | - '*' 93 | operations: 94 | - CREATE 95 | - apiGroups: 96 | - apiregistration.k8s.io 97 | apiVersions: 98 | - v1beta1 99 | resources: 100 | - '*' 101 | operations: 102 | - CREATE 103 | - apiGroups: 104 | - apps 105 | apiVersions: 106 | - v1beta1 107 | - v1beta2 108 | resources: 109 | - '*' 110 | operations: 111 | - CREATE 112 | - apiGroups: 113 | - audit.k8s.io 114 | apiVersions: 115 | - v1alpha1 116 | - v1beta1 117 | resources: 118 | - '*' 119 | operations: 120 | - CREATE 121 | - apiGroups: 122 | - authentication.k8s.io 123 | apiVersions: 124 | - v1beta1 125 | resources: 126 | - '*' 127 | operations: 128 | - CREATE 129 | - apiGroups: 130 | - autoscaling 131 | apiVersions: 132 | - v2beta1 133 | - v2beta2 134 | resources: 135 | - '*' 136 | operations: 137 | - CREATE 138 | - apiGroups: 139 | - batch 140 | apiVersions: 141 | - v1beta1 142 | resources: 143 | - '*' 144 | operations: 145 | - CREATE 146 | - apiGroups: 147 | - certificates.k8s.io 148 | apiVersions: 149 | - v1beta1 150 | resources: 151 | - '*' 152 | operations: 153 | - CREATE 154 | - apiGroups: 155 | - coordination.k8s.io 156 | apiVersions: 157 | - v1beta1 158 | resources: 159 | - '*' 160 | operations: 161 | - CREATE 162 | - apiGroups: 163 | - discovery.k8s.io 164 | apiVersions: 165 | - v1beta1 166 | resources: 167 | - '*' 168 | operations: 169 | - CREATE 170 | - apiGroups: 171 | - events.k8s.io 172 | apiVersions: 173 | - v1beta1 174 | resources: 175 | - '*' 176 | operations: 177 | - CREATE 178 | - apiGroups: 179 | - extensions 180 | apiVersions: 181 | - v1beta1 182 | resources: 183 | - '*' 184 | operations: 185 | - CREATE 186 | - apiGroups: 187 | - flowcontrol.apiserver.k8s.io 188 | apiVersions: 189 | - v1beta1 190 | - v1beta2 191 | - v1beta3 192 | resources: 193 | - '*' 194 | operations: 195 | - CREATE 196 | - apiGroups: 197 | - networking.k8s.io 198 | apiVersions: 199 | - v1beta1 200 | resources: 201 | - '*' 202 | operations: 203 | - CREATE 204 | - apiGroups: 205 | - node.k8s.io 206 | apiVersions: 207 | - v1beta1 208 | resources: 209 | - '*' 210 | operations: 211 | - CREATE 212 | - apiGroups: 213 | - policy 214 | apiVersions: 215 | - v1beta1 216 | resources: 217 | - '*' 218 | operations: 219 | - CREATE 220 | - apiGroups: 221 | - rbac.authorization.k8s.io 222 | apiVersions: 223 | - v1alpha1 224 | - v1beta1 225 | resources: 226 | - '*' 227 | operations: 228 | - CREATE 229 | - apiGroups: 230 | - scheduling.k8s.io 231 | apiVersions: 232 | - v1alpha1 233 | - v1beta1 234 | resources: 235 | - '*' 236 | operations: 237 | - CREATE 238 | - apiGroups: 239 | - storage.k8s.io 240 | apiVersions: 241 | - v1beta1 242 | resources: 243 | - '*' 244 | operations: 245 | - CREATE 246 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /versions.yaml: -------------------------------------------------------------------------------- 1 | # File taken from https://github.com/FairwindsOps/pluto 2 | deprecated-versions: 3 | - version: extensions/v1beta1 4 | kind: Deployment 5 | deprecated-in: v1.9.0 6 | removed-in: v1.16.0 7 | replacement-api: apps/v1 8 | replacement-available-in: v1.9.0 9 | component: k8s 10 | - version: apps/v1beta2 11 | kind: Deployment 12 | deprecated-in: v1.9.0 13 | removed-in: v1.16.0 14 | replacement-api: apps/v1 15 | replacement-available-in: v1.9.0 16 | component: k8s 17 | - version: apps/v1beta1 18 | kind: Deployment 19 | deprecated-in: v1.9.0 20 | removed-in: v1.16.0 21 | replacement-api: apps/v1 22 | replacement-available-in: v1.9.0 23 | component: k8s 24 | - version: apps/v1beta1 25 | kind: StatefulSet 26 | deprecated-in: v1.9.0 27 | removed-in: v1.16.0 28 | replacement-api: apps/v1 29 | replacement-available-in: v1.9.0 30 | component: k8s 31 | - version: apps/v1beta2 32 | kind: StatefulSet 33 | deprecated-in: v1.9.0 34 | removed-in: v1.16.0 35 | replacement-api: apps/v1 36 | replacement-available-in: v1.9.0 37 | component: k8s 38 | - version: extensions/v1beta1 39 | kind: NetworkPolicy 40 | deprecated-in: v1.9.0 41 | removed-in: v1.16.0 42 | replacement-api: networking.k8s.io/v1 43 | replacement-available-in: v1.8.0 44 | component: k8s 45 | - version: extensions/v1beta1 46 | kind: Ingress 47 | deprecated-in: v1.14.0 48 | removed-in: v1.22.0 49 | replacement-api: networking.k8s.io/v1 50 | replacement-available-in: v1.19.0 51 | component: k8s 52 | - version: networking.k8s.io/v1beta1 53 | kind: Ingress 54 | deprecated-in: v1.19.0 55 | removed-in: v1.22.0 56 | replacement-api: networking.k8s.io/v1 57 | replacement-available-in: v1.19.0 58 | component: k8s 59 | - version: networking.k8s.io/v1beta1 60 | kind: IngressClass 61 | deprecated-in: v1.19.0 62 | removed-in: v1.22.0 63 | replacement-api: networking.k8s.io/v1 64 | replacement-available-in: v1.19.0 65 | component: k8s 66 | - version: apps/v1beta2 67 | kind: DaemonSet 68 | deprecated-in: v1.9.0 69 | removed-in: v1.16.0 70 | replacement-api: apps/v1 71 | replacement-available-in: v1.9.0 72 | component: k8s 73 | - version: extensions/v1beta1 74 | kind: DaemonSet 75 | deprecated-in: v1.9.0 76 | removed-in: v1.16.0 77 | replacement-api: apps/v1 78 | replacement-available-in: v1.9.0 79 | component: k8s 80 | - version: extensions/v1beta1 81 | kind: PodSecurityPolicy 82 | deprecated-in: v1.10.0 83 | removed-in: v1.16.0 84 | replacement-api: policy/v1beta1 85 | replacement-available-in: v1.10.0 86 | component: k8s 87 | - version: policy/v1beta1 88 | kind: PodSecurityPolicy 89 | deprecated-in: v1.21.0 90 | removed-in: v1.25.0 91 | replacement-api: "" 92 | component: k8s 93 | - version: extensions/v1beta1 94 | kind: ReplicaSet 95 | deprecated-in: "" 96 | removed-in: v1.16.0 97 | replacement-api: apps/v1 98 | replacement-available-in: v1.9.0 99 | component: k8s 100 | - version: apps/v1beta1 101 | kind: ReplicaSet 102 | deprecated-in: "" 103 | removed-in: v1.16.0 104 | replacement-api: apps/v1 105 | replacement-available-in: v1.9.0 106 | component: k8s 107 | - version: apps/v1beta2 108 | kind: ReplicaSet 109 | deprecated-in: "" 110 | removed-in: v1.16.0 111 | replacement-api: apps/v1 112 | replacement-available-in: v1.9.0 113 | component: k8s 114 | - version: scheduling.k8s.io/v1beta1 115 | kind: PriorityClass 116 | deprecated-in: v1.14.0 117 | removed-in: v1.22.0 118 | replacement-api: scheduling.k8s.io/v1 119 | replacement-available-in: v1.14.0 120 | component: k8s 121 | - version: scheduling.k8s.io/v1alpha1 122 | kind: PriorityClass 123 | deprecated-in: v1.14.0 124 | removed-in: v1.17.0 125 | replacement-api: scheduling.k8s.io/v1 126 | component: k8s 127 | - version: apiextensions.k8s.io/v1beta1 128 | kind: CustomResourceDefinition 129 | deprecated-in: v1.16.0 130 | removed-in: v1.22.0 131 | replacement-api: apiextensions.k8s.io/v1 132 | replacement-available-in: v1.16.0 133 | component: k8s 134 | - version: admissionregistration.k8s.io/v1beta1 135 | kind: MutatingWebhookConfiguration 136 | deprecated-in: v1.16.0 137 | removed-in: v1.22.0 138 | replacement-api: admissionregistration.k8s.io/v1 139 | replacement-available-in: v1.16.0 140 | component: k8s 141 | - version: admissionregistration.k8s.io/v1beta1 142 | kind: ValidatingWebhookConfiguration 143 | deprecated-in: v1.16.0 144 | removed-in: v1.22.0 145 | replacement-api: admissionregistration.k8s.io/v1 146 | replacement-available-in: v1.16.0 147 | component: k8s 148 | - version: rbac.authorization.k8s.io/v1alpha1 149 | kind: ClusterRoleBinding 150 | deprecated-in: v1.17.0 151 | removed-in: v1.22.0 152 | replacement-api: rbac.authorization.k8s.io/v1 153 | replacement-available-in: v1.8.0 154 | component: k8s 155 | - version: rbac.authorization.k8s.io/v1alpha1 156 | kind: ClusterRole 157 | deprecated-in: v1.17.0 158 | removed-in: v1.22.0 159 | replacement-api: rbac.authorization.k8s.io/v1 160 | replacement-available-in: v1.8.0 161 | component: k8s 162 | - version: rbac.authorization.k8s.io/v1alpha1 163 | kind: ClusterRoleBindingList 164 | deprecated-in: v1.17.0 165 | removed-in: v1.22.0 166 | replacement-api: rbac.authorization.k8s.io/v1 167 | component: k8s 168 | - version: rbac.authorization.k8s.io/v1alpha1 169 | kind: ClusterRoleList 170 | deprecated-in: v1.17.0 171 | removed-in: v1.22.0 172 | replacement-api: rbac.authorization.k8s.io/v1 173 | component: k8s 174 | - version: rbac.authorization.k8s.io/v1alpha1 175 | kind: Role 176 | deprecated-in: v1.17.0 177 | removed-in: v1.22.0 178 | replacement-api: rbac.authorization.k8s.io/v1 179 | replacement-available-in: v1.8.0 180 | component: k8s 181 | - version: rbac.authorization.k8s.io/v1alpha1 182 | kind: RoleBinding 183 | deprecated-in: v1.17.0 184 | removed-in: v1.22.0 185 | replacement-api: rbac.authorization.k8s.io/v1 186 | replacement-available-in: v1.8.0 187 | component: k8s 188 | - version: rbac.authorization.k8s.io/v1alpha1 189 | kind: RoleList 190 | deprecated-in: v1.17.0 191 | removed-in: v1.22.0 192 | replacement-api: rbac.authorization.k8s.io/v1 193 | component: k8s 194 | - version: rbac.authorization.k8s.io/v1alpha1 195 | kind: RoleBindingList 196 | deprecated-in: v1.17.0 197 | removed-in: v1.22.0 198 | replacement-api: rbac.authorization.k8s.io/v1 199 | component: k8s 200 | - version: rbac.authorization.k8s.io/v1beta1 201 | kind: ClusterRoleBinding 202 | deprecated-in: v1.17.0 203 | removed-in: v1.22.0 204 | replacement-api: rbac.authorization.k8s.io/v1 205 | component: k8s 206 | - version: rbac.authorization.k8s.io/v1beta1 207 | kind: ClusterRole 208 | deprecated-in: v1.17.0 209 | removed-in: v1.22.0 210 | replacement-api: rbac.authorization.k8s.io/v1 211 | component: k8s 212 | - version: rbac.authorization.k8s.io/v1beta1 213 | kind: ClusterRoleBindingList 214 | deprecated-in: v1.17.0 215 | removed-in: v1.22.0 216 | replacement-api: rbac.authorization.k8s.io/v1 217 | component: k8s 218 | - version: rbac.authorization.k8s.io/v1beta1 219 | kind: ClusterRoleList 220 | deprecated-in: v1.17.0 221 | removed-in: v1.22.0 222 | replacement-api: rbac.authorization.k8s.io/v1 223 | component: k8s 224 | - version: rbac.authorization.k8s.io/v1beta1 225 | kind: Role 226 | deprecated-in: v1.17.0 227 | removed-in: v1.22.0 228 | replacement-api: rbac.authorization.k8s.io/v1 229 | component: k8s 230 | - version: rbac.authorization.k8s.io/v1beta1 231 | kind: RoleBinding 232 | deprecated-in: v1.17.0 233 | removed-in: v1.22.0 234 | replacement-api: rbac.authorization.k8s.io/v1 235 | component: k8s 236 | - version: rbac.authorization.k8s.io/v1beta1 237 | kind: RoleList 238 | deprecated-in: v1.17.0 239 | removed-in: v1.22.0 240 | replacement-api: rbac.authorization.k8s.io/v1 241 | component: k8s 242 | - version: rbac.authorization.k8s.io/v1beta1 243 | kind: RoleBindingList 244 | deprecated-in: v1.17.0 245 | removed-in: v1.22.0 246 | replacement-api: rbac.authorization.k8s.io/v1 247 | component: k8s 248 | - version: node.k8s.io/v1beta1 249 | kind: RuntimeClass 250 | deprecated-in: v1.22.0 251 | removed-in: v1.25.0 252 | replacement-api: node.k8s.io/v1 253 | replacement-available-in: v1.20.0 254 | component: k8s 255 | - version: policy/v1beta1 256 | kind: PodDisruptionBudget 257 | deprecated-in: v1.21.0 258 | removed-in: v1.25.0 259 | replacement-api: policy/v1 260 | replacement-available-in: v1.21.0 261 | component: k8s 262 | - version: policy/v1beta1 263 | kind: PodDisruptionBudgetList 264 | deprecated-in: v1.21.0 265 | removed-in: v1.25.0 266 | replacement-api: policy/v1 267 | component: k8s 268 | - version: autoscaling/v2beta1 269 | kind: HorizontalPodAutoscaler 270 | deprecated-in: v1.22.0 271 | removed-in: v1.25.0 272 | replacement-api: autoscaling/v2 273 | replacement-available-in: v1.23.0 274 | component: k8s 275 | - version: autoscaling/v2beta1 276 | kind: HorizontalPodAutoscalerList 277 | deprecated-in: v1.22.0 278 | removed-in: v1.25.0 279 | replacement-api: autoscaling/v2 280 | component: k8s 281 | - version: autoscaling/v2beta2 282 | kind: HorizontalPodAutoscaler 283 | deprecated-in: v1.23.0 284 | removed-in: v1.26.0 285 | replacement-api: autoscaling/v2 286 | component: k8s 287 | - version: autoscaling/v2beta2 288 | kind: HorizontalPodAutoscalerList 289 | deprecated-in: v1.23.0 290 | removed-in: v1.26.0 291 | replacement-api: autoscaling/v2 292 | component: k8s 293 | - version: batch/v1beta1 294 | kind: CronJob 295 | replacement-api: batch/v1 296 | replacement-available-in: v1.21.0 297 | deprecated-in: v1.21.0 298 | removed-in: v1.25.0 299 | component: k8s 300 | - version: batch/v1beta1 301 | kind: CronJobList 302 | replacement-api: batch/v1 303 | deprecated-in: v1.21.0 304 | removed-in: v1.25.0 305 | component: k8s 306 | - version: storage.k8s.io/v1beta1 307 | kind: CSINode 308 | deprecated-in: v1.17.0 309 | removed-in: v1.22.0 310 | replacement-api: storage.k8s.io/v1 311 | replacement-available-in: v1.17.0 312 | component: k8s 313 | - version: storage.k8s.io/v1beta1 314 | kind: CSIDriver 315 | deprecated-in: v1.19.0 316 | removed-in: v1.22.0 317 | replacement-api: storage.k8s.io/v1 318 | replacement-available-in: v1.19.0 319 | component: k8s 320 | - version: storage.k8s.io/v1beta1 321 | kind: CSIStorageCapacity 322 | deprecated-in: v1.24.0 323 | removed-in: v1.27.0 324 | replacement-api: storage.k8s.io/v1 325 | replacement-available-in: v1.24.0 326 | component: k8s 327 | - version: storage.k8s.io/v1beta1 328 | kind: StorageClass 329 | deprecated-in: v1.6.0 330 | removed-in: v1.22.0 331 | replacement-api: storage.k8s.io/v1 332 | replacement-available-in: v1.6.0 333 | component: k8s 334 | - version: storage.k8s.io/v1beta1 335 | kind: VolumeAttachment 336 | deprecated-in: v1.13.0 337 | removed-in: v1.22.0 338 | replacement-api: storage.k8s.io/v1 339 | replacement-available-in: v1.13.0 340 | component: k8s 341 | - version: apiregistration.k8s.io/v1beta1 342 | kind: APIService 343 | removed-in: v1.22.0 344 | deprecated-in: v1.10.0 345 | replacement-api: apiregistration.k8s.io/v1 346 | replacement-available-in: v1.10.0 347 | component: k8s 348 | - version: authentication.k8s.io/v1beta1 349 | kind: TokenReview 350 | replacement-api: authentication.k8s.io/v1 351 | replacement-available-in: v1.6.0 352 | deprecated-in: v1.6.0 353 | removed-in: v1.22.0 354 | component: k8s 355 | - version: certificates.k8s.io/v1beta1 356 | kind: CertificateSigningRequest 357 | deprecated-in: v1.19.0 358 | removed-in: v1.22.0 359 | replacement-api: certificates.k8s.io/v1 360 | replacement-available-in: v1.19.0 361 | component: k8s 362 | - version: coordination.k8s.io/v1beta1 363 | kind: Lease 364 | replacement-api: coordination.k8s.io/v1 365 | replacement-available-in: v1.14.0 366 | deprecated-in: v1.14.0 367 | removed-in: v1.22.0 368 | component: k8s 369 | - version: events.k8s.io/v1beta1 370 | kind: Event 371 | replacement-api: events.k8s.io/v1 372 | replacement-available-in: v1.19.0 373 | deprecated-in: v1.19.0 374 | removed-in: v1.25.0 375 | component: k8s 376 | - version: discovery.k8s.io/v1beta1 377 | kind: EndpointSlice 378 | replacement-api: discovery.k8s.io/v1 379 | replacement-available-in: v1.21.0 380 | deprecated-in: v1.21.0 381 | removed-in: v1.25.0 382 | component: k8s 383 | - version: flowcontrol.apiserver.k8s.io/v1beta1 384 | kind: FlowControl 385 | replacement-api: flowcontrol.apiserver.k8s.io/v1beta2 386 | deprecated-in: v1.23.0 387 | removed-in: v1.26.0 388 | component: k8s 389 | - version: rbac.istio.io 390 | kind: AuthorizationPolicies 391 | deprecated-in: v1.4.0 392 | removed-in: v1.4.0 393 | replacement-api: security.istio.io/v1beta1 394 | component: istio 395 | - version: authentication.istio.io/v1alpha1 396 | kind: "" 397 | deprecated-in: v1.5.0 398 | removed-in: v1.6.0 399 | replacement-api: security.istio.io/v1beta1 400 | component: istio 401 | - version: certmanager.k8s.io/v1alpha1 402 | kind: Certificate 403 | deprecated-in: v0.11.0 404 | removed-in: v0.11.0 405 | replacement-api: cert-manager.io/v1alpha2 406 | component: cert-manager 407 | - version: certmanager.k8s.io/v1alpha1 408 | kind: Issuer 409 | deprecated-in: v0.11.0 410 | removed-in: v0.11.0 411 | replacement-api: cert-manager.io/v1alpha2 412 | component: cert-manager 413 | - version: certmanager.k8s.io/v1alpha1 414 | kind: ClusterIssuer 415 | deprecated-in: v0.11.0 416 | removed-in: v0.11.0 417 | replacement-api: cert-manager.io/v1alpha2 418 | component: cert-manager 419 | - version: certmanager.k8s.io/v1alpha1 420 | kind: CertificateRequest 421 | deprecated-in: v0.11.0 422 | removed-in: v0.11.0 423 | replacement-api: cert-manager.io/v1alpha2 424 | component: cert-manager 425 | - version: certmanager.k8s.io/v1alpha1 426 | kind: Order 427 | deprecated-in: v0.11.0 428 | removed-in: v0.11.0 429 | replacement-api: cert-manager.io/v1alpha2 430 | component: cert-manager 431 | - version: certmanager.k8s.io/v1alpha1 432 | kind: Challenge 433 | deprecated-in: v0.11.0 434 | removed-in: v0.11.0 435 | replacement-api: cert-manager.io/v1alpha2 436 | component: cert-manager 437 | - version: cert-manager.io/v1alpha2 438 | kind: Certificate 439 | deprecated-in: v1.4.0 440 | removed-in: v1.6.0 441 | replacement-api: cert-manager.io/v1 442 | component: cert-manager 443 | - version: cert-manager.io/v1alpha3 444 | kind: Certificate 445 | deprecated-in: v1.4.0 446 | removed-in: v1.6.0 447 | replacement-api: cert-manager.io/v1 448 | component: cert-manager 449 | - version: cert-manager.io/v1beta1 450 | kind: Certificate 451 | deprecated-in: v1.4.0 452 | removed-in: v1.6.0 453 | replacement-api: cert-manager.io/v1 454 | component: cert-manager 455 | - version: cert-manager.io/v1alpha2 456 | kind: Issuer 457 | deprecated-in: v1.4.0 458 | removed-in: v1.6.0 459 | replacement-api: cert-manager.io/v1 460 | component: cert-manager 461 | - version: cert-manager.io/v1alpha3 462 | kind: Issuer 463 | deprecated-in: v1.4.0 464 | removed-in: v1.6.0 465 | replacement-api: cert-manager.io/v1 466 | component: cert-manager 467 | - version: cert-manager.io/v1beta1 468 | kind: Issuer 469 | deprecated-in: v1.4.0 470 | removed-in: v1.6.0 471 | replacement-api: cert-manager.io/v1 472 | component: cert-manager 473 | - version: cert-manager.io/v1alpha2 474 | kind: ClusterIssuer 475 | deprecated-in: v1.4.0 476 | removed-in: v1.6.0 477 | replacement-api: cert-manager.io/v1 478 | component: cert-manager 479 | - version: cert-manager.io/v1alpha3 480 | kind: ClusterIssuer 481 | deprecated-in: v1.4.0 482 | removed-in: v1.6.0 483 | replacement-api: cert-manager.io/v1 484 | component: cert-manager 485 | - version: cert-manager.io/v1beta1 486 | kind: ClusterIssuer 487 | deprecated-in: v1.4.0 488 | removed-in: v1.6.0 489 | replacement-api: cert-manager.io/v1 490 | component: cert-manager 491 | - version: cert-manager.io/v1alpha2 492 | kind: CertificateRequest 493 | deprecated-in: v1.4.0 494 | removed-in: v1.6.0 495 | replacement-api: cert-manager.io/v1 496 | component: cert-manager 497 | - version: cert-manager.io/v1alpha3 498 | kind: CertificateRequest 499 | deprecated-in: v1.4.0 500 | removed-in: v1.6.0 501 | replacement-api: cert-manager.io/v1 502 | component: cert-manager 503 | - version: cert-manager.io/v1beta1 504 | kind: CertificateRequest 505 | deprecated-in: v1.4.0 506 | removed-in: v1.6.0 507 | replacement-api: cert-manager.io/v1 508 | component: cert-manager 509 | - version: acme.cert-manager.io/v1alpha2 510 | kind: Order 511 | deprecated-in: v1.4.0 512 | removed-in: v1.6.0 513 | replacement-api: cert-manager.io/v1 514 | component: cert-manager 515 | - version: acme.cert-manager.io/v1alpha3 516 | kind: Order 517 | deprecated-in: v1.4.0 518 | removed-in: v1.6.0 519 | replacement-api: cert-manager.io/v1 520 | component: cert-manager 521 | - version: acme.cert-manager.io/v1beta1 522 | kind: Order 523 | deprecated-in: v1.4.0 524 | removed-in: v1.6.0 525 | replacement-api: cert-manager.io/v1 526 | component: cert-manager 527 | - version: acme.cert-manager.io/v1alpha2 528 | kind: Challenge 529 | deprecated-in: v1.4.0 530 | removed-in: v1.6.0 531 | replacement-api: cert-manager.io/v1 532 | component: cert-manager 533 | - version: acme.cert-manager.io/v1alpha3 534 | kind: Challenge 535 | deprecated-in: v1.4.0 536 | removed-in: v1.6.0 537 | replacement-api: cert-manager.io/v1 538 | component: cert-manager 539 | - version: acme.cert-manager.io/v1beta1 540 | kind: Challenge 541 | deprecated-in: v1.4.0 542 | removed-in: v1.6.0 543 | replacement-api: cert-manager.io/v1 544 | component: cert-manager 545 | - version: flowcontrol.apiserver.k8s.io/v1beta2 546 | kind: FlowSchema 547 | deprecated-in: v1.24.0 548 | removed-in: v1.29.0 549 | replacement-api: flowcontrol.apiserver.k8s.io/v1beta3 550 | component: k8s 551 | - version: flowcontrol.apiserver.k8s.io/v1beta2 552 | kind: PriorityLevelConfiguration 553 | deprecated-in: v1.24.0 554 | removed-in: v1.29.0 555 | replacement-api: flowcontrol.apiserver.k8s.io/v1beta3 556 | component: k8s 557 | - version: flowcontrol.apiserver.k8s.io/v1beta1 558 | kind: PriorityLevelConfiguration 559 | deprecated-in: v1.24.0 560 | removed-in: v1.29.0 561 | replacement-api: flowcontrol.apiserver.k8s.io/v1beta3 562 | component: k8s 563 | - version: flowcontrol.apiserver.k8s.io/v1beta1 564 | kind: FlowSchema 565 | deprecated-in: v1.24.0 566 | removed-in: v1.29.0 567 | replacement-api: flowcontrol.apiserver.k8s.io/v1beta3 568 | component: k8s 569 | - version: audit.k8s.io/v1alpha1 570 | kind: Policy 571 | deprecated-in: v1.21.0 572 | removed-in: v1.24.0 573 | replacement-api: audit.k8s.io/v1 574 | component: k8s 575 | - version: audit.k8s.io/v1alpha1 576 | kind: Policy 577 | deprecated-in: v1.21.0 578 | removed-in: v1.24.0 579 | replacement-api: audit.k8s.io/v1 580 | component: k8s 581 | - version: audit.k8s.io/v1alpha1 582 | kind: PolicyList 583 | deprecated-in: v1.21.0 584 | removed-in: v1.24.0 585 | replacement-api: audit.k8s.io/v1 586 | component: k8s 587 | - version: audit.k8s.io/v1alpha1 588 | kind: Event 589 | deprecated-in: v1.21.0 590 | removed-in: v1.24.0 591 | replacement-api: audit.k8s.io/v1 592 | component: k8s 593 | - version: audit.k8s.io/v1alpha1 594 | kind: EventList 595 | deprecated-in: v1.21.0 596 | removed-in: v1.24.0 597 | replacement-api: audit.k8s.io/v1 598 | component: k8s 599 | - version: audit.k8s.io/v1beta1 600 | kind: Policy 601 | deprecated-in: v1.21.0 602 | removed-in: v1.24.0 603 | replacement-api: audit.k8s.io/v1 604 | component: k8s 605 | - version: audit.k8s.io/v1beta1 606 | kind: PolicyList 607 | deprecated-in: v1.21.0 608 | removed-in: v1.24.0 609 | replacement-api: audit.k8s.io/v1 610 | component: k8s 611 | - version: audit.k8s.io/v1beta1 612 | kind: Event 613 | deprecated-in: v1.21.0 614 | removed-in: v1.24.0 615 | replacement-api: audit.k8s.io/v1 616 | component: k8s 617 | - version: audit.k8s.io/v1beta1 618 | kind: EventList 619 | deprecated-in: v1.21.0 620 | removed-in: v1.24.0 621 | replacement-api: audit.k8s.io/v1 622 | component: k8s 623 | - version: flowcontrol.apiserver.k8s.io/v1beta3 624 | kind: FlowSchema 625 | deprecated-in: v1.24.0 626 | removed-in: v1.32.0 627 | replacement-api: flowcontrol.apiserver.k8s.io/v1 628 | component: k8s 629 | - version: flowcontrol.apiserver.k8s.io/v1beta3 630 | kind: PriorityLevelConfiguration 631 | deprecated-in: v1.31.0 632 | removed-in: v1.32.0 633 | replacement-api: flowcontrol.apiserver.k8s.io/v1 634 | component: k8s 635 | target-versions: 636 | cert-manager: v1.5.3 637 | istio: v1.11.0 638 | k8s: v1.25.0 639 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.4" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "anstream" 16 | version = "0.6.21" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" 19 | dependencies = [ 20 | "anstyle", 21 | "anstyle-parse", 22 | "anstyle-query", 23 | "anstyle-wincon", 24 | "colorchoice", 25 | "is_terminal_polyfill", 26 | "utf8parse", 27 | ] 28 | 29 | [[package]] 30 | name = "anstyle" 31 | version = "1.0.13" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" 34 | 35 | [[package]] 36 | name = "anstyle-parse" 37 | version = "0.2.7" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 40 | dependencies = [ 41 | "utf8parse", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle-query" 46 | version = "1.1.5" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" 49 | dependencies = [ 50 | "windows-sys", 51 | ] 52 | 53 | [[package]] 54 | name = "anstyle-wincon" 55 | version = "3.0.11" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" 58 | dependencies = [ 59 | "anstyle", 60 | "once_cell_polyfill", 61 | "windows-sys", 62 | ] 63 | 64 | [[package]] 65 | name = "anyhow" 66 | version = "1.0.100" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" 69 | 70 | [[package]] 71 | name = "autocfg" 72 | version = "1.5.0" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" 75 | 76 | [[package]] 77 | name = "bitflags" 78 | version = "2.10.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" 81 | 82 | [[package]] 83 | name = "cfg-if" 84 | version = "1.0.4" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" 87 | 88 | [[package]] 89 | name = "chrono" 90 | version = "0.4.42" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" 93 | dependencies = [ 94 | "num-traits", 95 | ] 96 | 97 | [[package]] 98 | name = "clap" 99 | version = "4.5.53" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" 102 | dependencies = [ 103 | "clap_builder", 104 | "clap_derive", 105 | ] 106 | 107 | [[package]] 108 | name = "clap_builder" 109 | version = "4.5.53" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" 112 | dependencies = [ 113 | "anstream", 114 | "anstyle", 115 | "clap_lex", 116 | "strsim", 117 | ] 118 | 119 | [[package]] 120 | name = "clap_derive" 121 | version = "4.5.49" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" 124 | dependencies = [ 125 | "heck", 126 | "proc-macro2", 127 | "quote", 128 | "syn", 129 | ] 130 | 131 | [[package]] 132 | name = "clap_lex" 133 | version = "0.7.6" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" 136 | 137 | [[package]] 138 | name = "colorchoice" 139 | version = "1.0.4" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 142 | 143 | [[package]] 144 | name = "const_format" 145 | version = "0.2.35" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" 148 | dependencies = [ 149 | "const_format_proc_macros", 150 | ] 151 | 152 | [[package]] 153 | name = "const_format_proc_macros" 154 | version = "0.2.34" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" 157 | dependencies = [ 158 | "proc-macro2", 159 | "quote", 160 | "unicode-xid", 161 | ] 162 | 163 | [[package]] 164 | name = "darling" 165 | version = "0.20.11" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" 168 | dependencies = [ 169 | "darling_core", 170 | "darling_macro", 171 | ] 172 | 173 | [[package]] 174 | name = "darling_core" 175 | version = "0.20.11" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" 178 | dependencies = [ 179 | "fnv", 180 | "ident_case", 181 | "proc-macro2", 182 | "quote", 183 | "strsim", 184 | "syn", 185 | ] 186 | 187 | [[package]] 188 | name = "darling_macro" 189 | version = "0.20.11" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" 192 | dependencies = [ 193 | "darling_core", 194 | "quote", 195 | "syn", 196 | ] 197 | 198 | [[package]] 199 | name = "deprecated-api-versions" 200 | version = "1.0.5" 201 | dependencies = [ 202 | "anyhow", 203 | "kubewarden-policy-sdk", 204 | "lazy_static", 205 | "semver", 206 | "serde", 207 | "serde_json", 208 | "serde_yaml", 209 | "versions", 210 | ] 211 | 212 | [[package]] 213 | name = "derive_builder" 214 | version = "0.20.2" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" 217 | dependencies = [ 218 | "derive_builder_macro", 219 | ] 220 | 221 | [[package]] 222 | name = "derive_builder_core" 223 | version = "0.20.2" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" 226 | dependencies = [ 227 | "darling", 228 | "proc-macro2", 229 | "quote", 230 | "syn", 231 | ] 232 | 233 | [[package]] 234 | name = "derive_builder_macro" 235 | version = "0.20.2" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" 238 | dependencies = [ 239 | "derive_builder_core", 240 | "syn", 241 | ] 242 | 243 | [[package]] 244 | name = "displaydoc" 245 | version = "0.2.5" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 248 | dependencies = [ 249 | "proc-macro2", 250 | "quote", 251 | "syn", 252 | ] 253 | 254 | [[package]] 255 | name = "equivalent" 256 | version = "1.0.2" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 259 | 260 | [[package]] 261 | name = "erased-serde" 262 | version = "0.3.31" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" 265 | dependencies = [ 266 | "serde", 267 | ] 268 | 269 | [[package]] 270 | name = "fnv" 271 | version = "1.0.7" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 274 | 275 | [[package]] 276 | name = "form_urlencoded" 277 | version = "1.2.2" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" 280 | dependencies = [ 281 | "percent-encoding", 282 | ] 283 | 284 | [[package]] 285 | name = "getset" 286 | version = "0.1.6" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912" 289 | dependencies = [ 290 | "proc-macro-error2", 291 | "proc-macro2", 292 | "quote", 293 | "syn", 294 | ] 295 | 296 | [[package]] 297 | name = "hashbrown" 298 | version = "0.16.1" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" 301 | 302 | [[package]] 303 | name = "heck" 304 | version = "0.5.0" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 307 | 308 | [[package]] 309 | name = "hex" 310 | version = "0.4.3" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 313 | 314 | [[package]] 315 | name = "icu_collections" 316 | version = "2.1.1" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" 319 | dependencies = [ 320 | "displaydoc", 321 | "potential_utf", 322 | "yoke", 323 | "zerofrom", 324 | "zerovec", 325 | ] 326 | 327 | [[package]] 328 | name = "icu_locale_core" 329 | version = "2.1.1" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" 332 | dependencies = [ 333 | "displaydoc", 334 | "litemap", 335 | "tinystr", 336 | "writeable", 337 | "zerovec", 338 | ] 339 | 340 | [[package]] 341 | name = "icu_normalizer" 342 | version = "2.1.1" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" 345 | dependencies = [ 346 | "icu_collections", 347 | "icu_normalizer_data", 348 | "icu_properties", 349 | "icu_provider", 350 | "smallvec", 351 | "zerovec", 352 | ] 353 | 354 | [[package]] 355 | name = "icu_normalizer_data" 356 | version = "2.1.1" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" 359 | 360 | [[package]] 361 | name = "icu_properties" 362 | version = "2.1.1" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" 365 | dependencies = [ 366 | "icu_collections", 367 | "icu_locale_core", 368 | "icu_properties_data", 369 | "icu_provider", 370 | "zerotrie", 371 | "zerovec", 372 | ] 373 | 374 | [[package]] 375 | name = "icu_properties_data" 376 | version = "2.1.1" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" 379 | 380 | [[package]] 381 | name = "icu_provider" 382 | version = "2.1.1" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" 385 | dependencies = [ 386 | "displaydoc", 387 | "icu_locale_core", 388 | "writeable", 389 | "yoke", 390 | "zerofrom", 391 | "zerotrie", 392 | "zerovec", 393 | ] 394 | 395 | [[package]] 396 | name = "ident_case" 397 | version = "1.0.1" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 400 | 401 | [[package]] 402 | name = "idna" 403 | version = "1.1.0" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" 406 | dependencies = [ 407 | "idna_adapter", 408 | "smallvec", 409 | "utf8_iter", 410 | ] 411 | 412 | [[package]] 413 | name = "idna_adapter" 414 | version = "1.2.1" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" 417 | dependencies = [ 418 | "icu_normalizer", 419 | "icu_properties", 420 | ] 421 | 422 | [[package]] 423 | name = "indexmap" 424 | version = "2.12.1" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" 427 | dependencies = [ 428 | "equivalent", 429 | "hashbrown", 430 | ] 431 | 432 | [[package]] 433 | name = "is_terminal_polyfill" 434 | version = "1.70.2" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" 437 | 438 | [[package]] 439 | name = "itoa" 440 | version = "1.0.15" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 443 | 444 | [[package]] 445 | name = "kubewarden-policy-sdk" 446 | version = "0.15.0" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "3fe5786acb75fb7744b3b57ee517f72a4e614a0b62a15bb6a44765cb8a8f9163" 449 | dependencies = [ 450 | "anyhow", 451 | "cfg-if", 452 | "chrono", 453 | "hex", 454 | "num", 455 | "num-derive", 456 | "num-traits", 457 | "oci-spec", 458 | "serde", 459 | "serde_json", 460 | "serde_yaml", 461 | "slog", 462 | "url", 463 | "wapc-guest", 464 | ] 465 | 466 | [[package]] 467 | name = "lazy_static" 468 | version = "1.5.0" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 471 | 472 | [[package]] 473 | name = "libc" 474 | version = "0.2.178" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" 477 | 478 | [[package]] 479 | name = "litemap" 480 | version = "0.8.1" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" 483 | 484 | [[package]] 485 | name = "lock_api" 486 | version = "0.4.14" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" 489 | dependencies = [ 490 | "scopeguard", 491 | ] 492 | 493 | [[package]] 494 | name = "memchr" 495 | version = "2.7.6" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" 498 | 499 | [[package]] 500 | name = "num" 501 | version = "0.4.3" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" 504 | dependencies = [ 505 | "num-bigint", 506 | "num-complex", 507 | "num-integer", 508 | "num-iter", 509 | "num-rational", 510 | "num-traits", 511 | ] 512 | 513 | [[package]] 514 | name = "num-bigint" 515 | version = "0.4.6" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" 518 | dependencies = [ 519 | "num-integer", 520 | "num-traits", 521 | ] 522 | 523 | [[package]] 524 | name = "num-complex" 525 | version = "0.4.6" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" 528 | dependencies = [ 529 | "num-traits", 530 | ] 531 | 532 | [[package]] 533 | name = "num-derive" 534 | version = "0.4.2" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" 537 | dependencies = [ 538 | "proc-macro2", 539 | "quote", 540 | "syn", 541 | ] 542 | 543 | [[package]] 544 | name = "num-integer" 545 | version = "0.1.46" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 548 | dependencies = [ 549 | "num-traits", 550 | ] 551 | 552 | [[package]] 553 | name = "num-iter" 554 | version = "0.1.45" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" 557 | dependencies = [ 558 | "autocfg", 559 | "num-integer", 560 | "num-traits", 561 | ] 562 | 563 | [[package]] 564 | name = "num-rational" 565 | version = "0.4.2" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" 568 | dependencies = [ 569 | "num-bigint", 570 | "num-integer", 571 | "num-traits", 572 | ] 573 | 574 | [[package]] 575 | name = "num-traits" 576 | version = "0.2.19" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 579 | dependencies = [ 580 | "autocfg", 581 | ] 582 | 583 | [[package]] 584 | name = "oci-spec" 585 | version = "0.8.3" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "2eb4684653aeaba48dea019caa17b2773e1212e281d50b6fa759f36fe032239d" 588 | dependencies = [ 589 | "const_format", 590 | "derive_builder", 591 | "getset", 592 | "regex", 593 | "serde", 594 | "serde_json", 595 | "strum", 596 | "strum_macros", 597 | "thiserror", 598 | ] 599 | 600 | [[package]] 601 | name = "once_cell" 602 | version = "1.21.3" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 605 | 606 | [[package]] 607 | name = "once_cell_polyfill" 608 | version = "1.70.2" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" 611 | 612 | [[package]] 613 | name = "parking_lot" 614 | version = "0.12.5" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" 617 | dependencies = [ 618 | "lock_api", 619 | "parking_lot_core", 620 | ] 621 | 622 | [[package]] 623 | name = "parking_lot_core" 624 | version = "0.9.12" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" 627 | dependencies = [ 628 | "cfg-if", 629 | "libc", 630 | "redox_syscall", 631 | "smallvec", 632 | "windows-link", 633 | ] 634 | 635 | [[package]] 636 | name = "percent-encoding" 637 | version = "2.3.2" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" 640 | 641 | [[package]] 642 | name = "policy-metadata-helper" 643 | version = "1.0.5" 644 | dependencies = [ 645 | "clap", 646 | "serde", 647 | "serde_yaml", 648 | "versions", 649 | ] 650 | 651 | [[package]] 652 | name = "potential_utf" 653 | version = "0.1.4" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" 656 | dependencies = [ 657 | "zerovec", 658 | ] 659 | 660 | [[package]] 661 | name = "proc-macro-error-attr2" 662 | version = "2.0.0" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" 665 | dependencies = [ 666 | "proc-macro2", 667 | "quote", 668 | ] 669 | 670 | [[package]] 671 | name = "proc-macro-error2" 672 | version = "2.0.1" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" 675 | dependencies = [ 676 | "proc-macro-error-attr2", 677 | "proc-macro2", 678 | "quote", 679 | "syn", 680 | ] 681 | 682 | [[package]] 683 | name = "proc-macro2" 684 | version = "1.0.103" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" 687 | dependencies = [ 688 | "unicode-ident", 689 | ] 690 | 691 | [[package]] 692 | name = "quote" 693 | version = "1.0.42" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" 696 | dependencies = [ 697 | "proc-macro2", 698 | ] 699 | 700 | [[package]] 701 | name = "redox_syscall" 702 | version = "0.5.18" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" 705 | dependencies = [ 706 | "bitflags", 707 | ] 708 | 709 | [[package]] 710 | name = "regex" 711 | version = "1.12.2" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" 714 | dependencies = [ 715 | "aho-corasick", 716 | "memchr", 717 | "regex-automata", 718 | "regex-syntax", 719 | ] 720 | 721 | [[package]] 722 | name = "regex-automata" 723 | version = "0.4.13" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" 726 | dependencies = [ 727 | "aho-corasick", 728 | "memchr", 729 | "regex-syntax", 730 | ] 731 | 732 | [[package]] 733 | name = "regex-syntax" 734 | version = "0.8.8" 735 | source = "registry+https://github.com/rust-lang/crates.io-index" 736 | checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" 737 | 738 | [[package]] 739 | name = "rustversion" 740 | version = "1.0.22" 741 | source = "registry+https://github.com/rust-lang/crates.io-index" 742 | checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" 743 | 744 | [[package]] 745 | name = "ryu" 746 | version = "1.0.20" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 749 | 750 | [[package]] 751 | name = "scopeguard" 752 | version = "1.2.0" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 755 | 756 | [[package]] 757 | name = "semver" 758 | version = "1.0.27" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" 761 | 762 | [[package]] 763 | name = "serde" 764 | version = "1.0.228" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" 767 | dependencies = [ 768 | "serde_core", 769 | "serde_derive", 770 | ] 771 | 772 | [[package]] 773 | name = "serde_core" 774 | version = "1.0.228" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" 777 | dependencies = [ 778 | "serde_derive", 779 | ] 780 | 781 | [[package]] 782 | name = "serde_derive" 783 | version = "1.0.228" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" 786 | dependencies = [ 787 | "proc-macro2", 788 | "quote", 789 | "syn", 790 | ] 791 | 792 | [[package]] 793 | name = "serde_json" 794 | version = "1.0.145" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" 797 | dependencies = [ 798 | "itoa", 799 | "memchr", 800 | "ryu", 801 | "serde", 802 | "serde_core", 803 | ] 804 | 805 | [[package]] 806 | name = "serde_yaml" 807 | version = "0.9.34+deprecated" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" 810 | dependencies = [ 811 | "indexmap", 812 | "itoa", 813 | "ryu", 814 | "serde", 815 | "unsafe-libyaml", 816 | ] 817 | 818 | [[package]] 819 | name = "slog" 820 | version = "2.8.2" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "9b3b8565691b22d2bdfc066426ed48f837fc0c5f2c8cad8d9718f7f99d6995c1" 823 | dependencies = [ 824 | "anyhow", 825 | "erased-serde", 826 | "rustversion", 827 | "serde_core", 828 | ] 829 | 830 | [[package]] 831 | name = "smallvec" 832 | version = "1.15.1" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 835 | 836 | [[package]] 837 | name = "stable_deref_trait" 838 | version = "1.2.1" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" 841 | 842 | [[package]] 843 | name = "strsim" 844 | version = "0.11.1" 845 | source = "registry+https://github.com/rust-lang/crates.io-index" 846 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 847 | 848 | [[package]] 849 | name = "strum" 850 | version = "0.27.2" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" 853 | 854 | [[package]] 855 | name = "strum_macros" 856 | version = "0.27.2" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" 859 | dependencies = [ 860 | "heck", 861 | "proc-macro2", 862 | "quote", 863 | "syn", 864 | ] 865 | 866 | [[package]] 867 | name = "syn" 868 | version = "2.0.111" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" 871 | dependencies = [ 872 | "proc-macro2", 873 | "quote", 874 | "unicode-ident", 875 | ] 876 | 877 | [[package]] 878 | name = "synstructure" 879 | version = "0.13.2" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" 882 | dependencies = [ 883 | "proc-macro2", 884 | "quote", 885 | "syn", 886 | ] 887 | 888 | [[package]] 889 | name = "thiserror" 890 | version = "2.0.17" 891 | source = "registry+https://github.com/rust-lang/crates.io-index" 892 | checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" 893 | dependencies = [ 894 | "thiserror-impl", 895 | ] 896 | 897 | [[package]] 898 | name = "thiserror-impl" 899 | version = "2.0.17" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" 902 | dependencies = [ 903 | "proc-macro2", 904 | "quote", 905 | "syn", 906 | ] 907 | 908 | [[package]] 909 | name = "tinystr" 910 | version = "0.8.2" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" 913 | dependencies = [ 914 | "displaydoc", 915 | "zerovec", 916 | ] 917 | 918 | [[package]] 919 | name = "unicode-ident" 920 | version = "1.0.22" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" 923 | 924 | [[package]] 925 | name = "unicode-xid" 926 | version = "0.2.6" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" 929 | 930 | [[package]] 931 | name = "unsafe-libyaml" 932 | version = "0.2.11" 933 | source = "registry+https://github.com/rust-lang/crates.io-index" 934 | checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" 935 | 936 | [[package]] 937 | name = "url" 938 | version = "2.5.7" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" 941 | dependencies = [ 942 | "form_urlencoded", 943 | "idna", 944 | "percent-encoding", 945 | "serde", 946 | ] 947 | 948 | [[package]] 949 | name = "utf8_iter" 950 | version = "1.0.4" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 953 | 954 | [[package]] 955 | name = "utf8parse" 956 | version = "0.2.2" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 959 | 960 | [[package]] 961 | name = "versions" 962 | version = "1.0.5" 963 | dependencies = [ 964 | "anyhow", 965 | "kubewarden-policy-sdk", 966 | "lazy_static", 967 | "semver", 968 | "serde", 969 | "serde_json", 970 | "serde_yaml", 971 | ] 972 | 973 | [[package]] 974 | name = "wapc-guest" 975 | version = "1.2.0" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "680cefee82217e1c312bdbc21789a33a168038b64f715621cdb780cf7946c82d" 978 | dependencies = [ 979 | "once_cell", 980 | "parking_lot", 981 | ] 982 | 983 | [[package]] 984 | name = "windows-link" 985 | version = "0.2.1" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 988 | 989 | [[package]] 990 | name = "windows-sys" 991 | version = "0.61.2" 992 | source = "registry+https://github.com/rust-lang/crates.io-index" 993 | checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" 994 | dependencies = [ 995 | "windows-link", 996 | ] 997 | 998 | [[package]] 999 | name = "writeable" 1000 | version = "0.6.2" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" 1003 | 1004 | [[package]] 1005 | name = "yoke" 1006 | version = "0.8.1" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" 1009 | dependencies = [ 1010 | "stable_deref_trait", 1011 | "yoke-derive", 1012 | "zerofrom", 1013 | ] 1014 | 1015 | [[package]] 1016 | name = "yoke-derive" 1017 | version = "0.8.1" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" 1020 | dependencies = [ 1021 | "proc-macro2", 1022 | "quote", 1023 | "syn", 1024 | "synstructure", 1025 | ] 1026 | 1027 | [[package]] 1028 | name = "zerofrom" 1029 | version = "0.1.6" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 1032 | dependencies = [ 1033 | "zerofrom-derive", 1034 | ] 1035 | 1036 | [[package]] 1037 | name = "zerofrom-derive" 1038 | version = "0.1.6" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 1041 | dependencies = [ 1042 | "proc-macro2", 1043 | "quote", 1044 | "syn", 1045 | "synstructure", 1046 | ] 1047 | 1048 | [[package]] 1049 | name = "zerotrie" 1050 | version = "0.2.3" 1051 | source = "registry+https://github.com/rust-lang/crates.io-index" 1052 | checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" 1053 | dependencies = [ 1054 | "displaydoc", 1055 | "yoke", 1056 | "zerofrom", 1057 | ] 1058 | 1059 | [[package]] 1060 | name = "zerovec" 1061 | version = "0.11.5" 1062 | source = "registry+https://github.com/rust-lang/crates.io-index" 1063 | checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" 1064 | dependencies = [ 1065 | "yoke", 1066 | "zerofrom", 1067 | "zerovec-derive", 1068 | ] 1069 | 1070 | [[package]] 1071 | name = "zerovec-derive" 1072 | version = "0.11.2" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" 1075 | dependencies = [ 1076 | "proc-macro2", 1077 | "quote", 1078 | "syn", 1079 | ] 1080 | --------------------------------------------------------------------------------