{"id":13788093,"url":"https://github.com/anderseknert/kube-review","last_synced_at":"2025-10-23T02:35:58.761Z","repository":{"id":109367112,"uuid":"436233464","full_name":"anderseknert/kube-review","owner":"anderseknert","description":"Create Kubernetes AdmissionReview requests from Kubernetes resource manifests","archived":false,"fork":false,"pushed_at":"2025-03-13T11:37:17.000Z","size":180,"stargazers_count":139,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-29T20:09:41.428Z","etag":null,"topics":["admission-controller","admission-review","admission-webhook","k8s","kube-review","kubectl","kubernetes","mutating-admission-webhook","opa","open-policy-agent","policy-as-code","validating-admission-webhook"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anderseknert.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-08T12:07:29.000Z","updated_at":"2025-03-29T10:04:02.000Z","dependencies_parsed_at":"2024-02-09T09:45:13.929Z","dependency_job_id":"432e0a4b-8b29-4707-ae3b-8a6a7511ce4f","html_url":"https://github.com/anderseknert/kube-review","commit_stats":{"total_commits":66,"total_committers":4,"mean_commits":16.5,"dds":0.3787878787878788,"last_synced_commit":"b209b1d906cada3d5c5f9f4e68639462e4811343"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anderseknert%2Fkube-review","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anderseknert%2Fkube-review/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anderseknert%2Fkube-review/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anderseknert%2Fkube-review/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anderseknert","download_url":"https://codeload.github.com/anderseknert/kube-review/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247399885,"owners_count":20932880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admission-controller","admission-review","admission-webhook","k8s","kube-review","kubectl","kubernetes","mutating-admission-webhook","opa","open-policy-agent","policy-as-code","validating-admission-webhook"],"created_at":"2024-08-03T21:00:36.734Z","updated_at":"2025-10-23T02:35:53.724Z","avatar_url":"https://github.com/anderseknert.png","language":"Go","funding_links":[],"categories":["Tools and Utilities","Testing","Go"],"sub_categories":["Serverless Blogs and Articles"],"readme":"# kube-review\n\nSimple command line utility to transform a provided Kubernetes resource into a Kubernetes AdmissionReview request, as\nsent from the Kubernetes API server when [dynamic admission control](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/)\n(i.e. webhook) is configured.\n\n**deployment.yaml**\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: nginx\n  labels:\n    app: nginx\nspec:\n  selector:\n    matchLabels:\n      app: nginx\n  template:\n    metadata:\n      labels:\n        app: nginx\n    spec:\n      containers:\n      - image: nginx\n        name: nginx\n        ports:\n        - containerPort: 8080\n```\n**Command**\n```shell\n$ kube-review create deployment.yaml\n```\n**Output**\n```json\n{\n  \"kind\": \"AdmissionReview\",\n  \"apiVersion\": \"admission.k8s.io/v1\",\n  \"request\": {\n    \"uid\": \"2024ee9c-c374-413c-838d-e62bcb4826be\",\n    \"kind\": {\n      \"group\": \"apps\",\n      \"version\": \"v1\",\n      \"kind\": \"Deployment\"\n    },\n    \"resource\": {\n      \"group\": \"apps\",\n      \"version\": \"v1\",\n      \"resource\": \"deployments\"\n    },\n    \"requestKind\": {\n      \"group\": \"apps\",\n      \"version\": \"v1\",\n      \"kind\": \"Deployment\"\n    },\n    \"requestResource\": {\n      \"group\": \"apps\",\n      \"version\": \"v1\",\n      \"resource\": \"deployments\"\n    },\n    \"name\": \"nginx\",\n    \"operation\": \"CREATE\",\n    \"userInfo\": {\n      \"username\": \"kube-review\",\n      \"uid\": \"611a19d7-6aa5-47d2-bba3-8c5df2bffbc7\"\n    },\n    \"object\": {\n      \"kind\": \"Deployment\",\n      \"apiVersion\": \"apps/v1\",\n      \"metadata\": {\n        \"name\": \"nginx\",\n        \"creationTimestamp\": null,\n        \"labels\": {\n          \"app\": \"nginx\"\n        }\n      },\n      \"spec\": {\n        \"selector\": {\n          \"matchLabels\": {\n            \"app\": \"nginx\"\n          }\n        },\n        \"template\": {\n          \"metadata\": {\n            \"creationTimestamp\": null,\n            \"labels\": {\n              \"app\": \"nginx\"\n            }\n          },\n          \"spec\": {\n            \"containers\": [\n              {\n                \"name\": \"nginx\",\n                \"image\": \"nginx\",\n                \"ports\": [\n                  {\n                    \"containerPort\": 8080\n                  }\n                ],\n                \"resources\": {}\n              }\n            ]\n          }\n        },\n        \"strategy\": {}\n      },\n      \"status\": {}\n    },\n    \"oldObject\": null,\n    \"dryRun\": true,\n    \"options\": {\n      \"kind\": \"CreateOptions\",\n      \"apiVersion\": \"meta.k8s.io/v1\"\n    }\n  }\n}\n```\n\n## Why?\n\n* Testing Kubernetes admission webhook receivers without Kubernetes (CI/CD pipelines, faster integration tests, etc.)\n* Quickly be able to author, and test, admission control policies with tools like [Open Policy Agent](https://www.openpolicyagent.org/)\n\n## Installation\n\nFind the latest release for your platform at the [release page](https://github.com/anderseknert/kube-review/releases/latest).\nOnce downloaded, rename it to `kube-review` (or `kube-review.exe` for Windows if not using WSL),\nallow it to be executed, and put it somewhere on your `$PATH`.\n\n## Running kube-review\n\n`kube-review create` can either be provided a filename with a resource to create an admission review for, or can read\ndata from stdin. This allows easily piping resources from a kube cluster and into kube-review.\n\n**Command**\n```shell\n$ kubectl get service gatekeeper-webhook-service -o yaml | kube-review create --action update\n```\n**Output**\n```json\n{\n    \"kind\": \"AdmissionReview\",\n    \"apiVersion\": \"admission.k8s.io/v1\",\n    \"request\": {\n        \"uid\": \"b42420d7-5cc2-4644-992f-72ff67dc2889\",\n        \"kind\": {\n            \"group\": \"\",\n            \"version\": \"v1\",\n            \"kind\": \"Service\"\n        },\n        \"name\": \"gatekeeper-webhook-service\",\n        \"namespace\": \"gatekeeper-system\",\n        \"operation\": \"UPDATE\",\n        \"userInfo\": {\n            \"username\": \"kube-review\",\n            \"uid\": \"42eac911-a8ec-4d72-9eb1-e6c466328085\"\n        },\n        \"...\": \"...\"\n    }\n}\n```\n## Command line options\n\n| Name         | Type   | Default     | Description                                                                                |\n|--------------|--------|-------------|--------------------------------------------------------------------------------------------|\n| `--action`   | string | create      | Type of operation to apply in admission review (create, update, delete, connect)           |\n| `--as`       | string | kube-review | Name of user or service account for userInfo attributes                                    |\n| `--as-group` | string | none        | Name of group this user or service account belongs to. May be repeated for multiple groups |\n| `--indent`   | int    | 2           | Number of spaces to indent JSON output                                                     |\n\nThe `action` provided has the following effects on the produced `AdmissionReview` object:\n\n* `create` and `connect`: `request.oldObject` is `null`\n* `delete`: `request.object` is `null`\n* All actions change the value of `request.operation` and `request.options`\n\n## Using with Open Policy Agent\n\nAssuming we have a policy that denies any deployment where the number of replicas is either undefined or below two:\n\n```rego\npackage admission\n\ndeny contains \"Deployment must have at least 2 replicas\" if {\n    input.request.object.spec.replicas \u003c 2\n}\n\ndeny contains \"Deployment must define number of replicas explicitly\" if {\n    not input.request.object.spec.replicas\n}\n```\n\nWe could either run kube-review with a deployment from disk, and pipe the output into `opa eval`:\n\n**Command**\n```shell\n$ kube-review create deployment.yaml \\\n| opa eval --format pretty --stdin-input --data policy.rego data.admission.deny\n```\n**Output**\n```json\n[\n  \"Deployment must define number of replicas explicitly\"\n]\n```\nOr we could run the policy against any resource in our cluster in the same manner:\n\n**Command**\n```shell\n$ kubectl get deployment my-microservice -o yaml \\\n| kube-review create \\\n| opa eval --format pretty --stdin-input --data policy.rego data.admission.deny\n```\n**Output**\n```json\n[\n  \"Deployment must have at least 2 replicas\"\n]\n```\nAlternatively, we could use `curl` to send the data into a running OPA server:\n\n**Command**\n```shell\n$ kubectl get deployment my-microservice -o yaml \\\n| kube-review create \\\n| curl --data-binary \"@-\" http://localhost:8181/v0/data/admission/deny\n```\n**Output**\n```json\n[\n    \"Deployment must define number of replicas explicitly\"\n]\n```\n\nIf your policies are written for [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper), simply rename the\n`request` object in the admission request to `review`:\n\n```shell\n$ kube-review create deployment.yaml \\\n| opa eval --format pretty --stdin-input '{\"review\": input.request}' \\\n| opa eval --format pretty --stdin-input --data policy.rego data.admission.deny\n```\n\n## Limitations\n\n* kube-review can create `AdmissionReview` objects from CRDs, or any \"Kubernetes-like\" manifest, but it makes no attempt\n  to verify that they conform to the schema of the corresponding `CustomResourceDefinition`.\n* Currently, kube-review doesn't handle subresource requests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanderseknert%2Fkube-review","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanderseknert%2Fkube-review","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanderseknert%2Fkube-review/lists"}