### Retrieve a Pod using get() Source: https://www.jspolicy.com/docs/functions/get This example demonstrates how to retrieve a specific Pod using the get() function. It checks if the Pod exists and prints a message accordingly. The function can also work with other CRDs. ```javascript // get() is able to retrieve any resource from the kubernetes cluster either cached or directly // get() takes parameters in the form of (Kind, apiVersion, Name, GetOptions?) // will also work with other CRDs, if the object cannot be found 'undefined' is returned. const pod = get("Pod", "v1", "my-namespace/my-pod"); if (!pod) { print("Pod not found"); } else { print("Pod found"); } ``` -------------------------------- ### Install jsPolicy SDK Development Dependencies Source: https://www.jspolicy.com/docs/writing-policies/policy-sdk Install the necessary development dependencies defined in the project's package.json file using npm. ```bash npm install ``` -------------------------------- ### JsPolicy Resource Configuration Example Source: https://www.jspolicy.com/docs/getting-started/work-with-policies This example demonstrates the configuration of a JsPolicy resource, including its type, trigger conditions (operations, resources, scope, selectors), and metadata. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "mutate-images.company.tld" spec: type: Mutating operations: ["CREATE", "UPDATE"] resources: ["pods", "deployments"] scope: Namespaced namespaceSelector: matchExpressions: # only trigger for namespaces with label "environment: prod" and/or label "environment: staging" - key: environment operator: In values: ["prod","staging"] objectSelector: # all trigger for objects with label "live: true" matchLabels: live: "true" # Optional javascript here if we choose to use inline vanilla JavaScript code # javascript: if ... ``` -------------------------------- ### Allow Request and Exit Source: https://www.jspolicy.com/docs/functions/allow Use allow() to permit a request and stop further policy execution. This example denies pod creation in the default namespace but allows it elsewhere. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "allow.resource.example" spec: operations: ["CREATE"] resources: ["pods"] javascript: | if (request.namespace !== "default") { allow(); // allow request and exit } deny("Do not create pods in the default namespace"); ``` -------------------------------- ### Retrieve Ingress with Cache Disabled Source: https://www.jspolicy.com/docs/functions/get This example demonstrates forcing the get() function to bypass the cache and make a direct call to the API server. This is useful when you need the most up-to-date information and cannot rely on cached data. ```javascript // you can also force cache behaviour by setting the 'cache' option to 'true' or 'false' const ingress = get("Ingress", "networking.k8s.io/v1", "my-namespace/my-config-map", {cache: false}) if (ingress) { print("Found ingress"); } ``` -------------------------------- ### Install jsPolicy with Helm Source: https://www.jspolicy.com/docs/getting-started/installation Use this command to install jsPolicy on your Kubernetes cluster. It creates the 'jspolicy' namespace if it doesn't exist. ```bash helm install jspolicy jspolicy -n jspolicy --create-namespace --repo https://charts.loft.sh ``` -------------------------------- ### Example of deny() Usage in JsPolicy Source: https://www.jspolicy.com/docs/functions/deny This example demonstrates how to use the deny() function to block requests based on namespace. It shows denying requests to 'kube-system' with a default message and to 'default' with a custom message, reason, and HTTP status code. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "deny.resource.example" spec: operations: ["CREATE"] resources: ["pods"] javascript: | // deny kube-system namespace if (request.namespace === "kube-system") { deny("No new pod allowed in kube-system"); } // deny default namespace with reason and code if (request.namespace === "default") { deny("No new pod allowed in default", "BadRequest", 400); } ``` -------------------------------- ### Using warn() to Print Client Warnings Source: https://www.jspolicy.com/docs/functions/warn This example demonstrates how to use the warn() function to display warnings to the client. It shows how to include dynamic information from the request object and how to print multiple warnings. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "warn.example.com" spec: operations: ["CREATE", "UPDATE"] resources: ["configmaps"] javascript: | // warn() will print a warning to the client. If warn() is called multiple times, it will print multiple warnings // Warnings are a feature of kubernetes since v1.19 and could look like this: // // kubectl create -f my-configmap.yaml // Warning: [warn.example.com]: Hello This Is A Warning for ConfigMap default/my-configmap // Warning: [warn.example.com]: Hello This Is Another Warning // configmap "my-configmap" created // warn(`Hello This Is A Warning for ConfigMap ${request.object.metadata.namespace}/${request.object.metadata.name}`); // print another warning to the client warn("Hello This Is Another Warning"); ``` -------------------------------- ### Validating Policy Examples in JavaScript Source: https://www.jspolicy.com/docs/why-jspolicy Demonstrates how to use allow(), deny(), and warn() for request validation in validating policies. Use these to enforce specific rules on Kubernetes API requests. ```javascript allow() ``` ```javascript deny("This is not allowed") ``` ```javascript warn("We\'ll let this one slip, but upgrade to the new ingress controller") ``` -------------------------------- ### Access Kubernetes API with readFileSync Source: https://www.jspolicy.com/docs/functions/readFileSync This example demonstrates reading the service account token using readFileSync to authenticate with the Kubernetes API. It then fetches namespaces and prints their names. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "read-file-policy.example.com" spec: operations: ["CREATE"] resources: ["pods"] javascript: | // read service account token. const token = readFileSync("/var/run/secrets/kubernetes.io/serviceaccount/token"); // retrieve all namespaces from the kube service directly, isn't that cool? const res = fetchSync("https://kubernetes.default/api/v1/namespaces", { "method": "GET", "insecure": true, "headers": { "Authorization": "bearer " + token } }) if (res.ok) { const namespaceList = res.json(); namespaceList.items.forEach(namespace => { print(namespace.metadata.name); }); } else { print("Something went wrong (" + res.status + "): " + res.text()); } ``` -------------------------------- ### Create a jsPolicy Resource Source: https://www.jspolicy.com/docs/quickstart Define a JsPolicy resource in a YAML file. This example denies the creation of any resources in the 'default' namespace. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "deny-default-namespace.company.tld" spec: operations: ["CREATE"] resources: ["*"] scope: Namespaced javascript: | if (request.namespace === "default") { deny("Creation of resources within the default namespace is not allowed!"); } ``` -------------------------------- ### Create a jsPolicy Resource Source: https://www.jspolicy.com/docs Define a JsPolicy resource in YAML format. This example denies the creation of any resources within the 'default' namespace. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "deny-default-namespace.company.tld" spec: operations: ["CREATE"] resources: ["*"] scope: Namespaced javascript: | if (request.namespace === "default") { deny("Creation of resources within the default namespace is not allowed!"); } ``` -------------------------------- ### Retrieve Namespace with Smart Caching Source: https://www.jspolicy.com/docs/functions/get This example shows how to retrieve a Namespace using 'smart' caching. It first attempts to find the resource in the cache and falls back to a direct API server call if not found. This can be useful when cache updates might lag behind actual changes. ```javascript // this will try to find the namespace first in the cache (fast) and if not found will // try to find it without cache (slow). Usually trying to get the resource from the cache // is enough, but there might be cases where some requests are faster than cache updates. const namespace = get("Namespace", "v1", request.namespace, {cache: 'smart'}); if (!namespace) { warn("Namespace not found"); } ``` -------------------------------- ### Cluster Access Functions in JavaScript Source: https://www.jspolicy.com/docs/why-jspolicy Illustrates how to interact with cluster resources using built-in functions like get(), list(), create(), update(), and remove(). These functions enable policies to read and modify cluster state. ```javascript get("Pod", "v1", "my-namespace/my-pod") ``` ```javascript list("Namespace", "v1") ``` ```javascript create(limitRange) ``` ```javascript update(mySecret) ``` ```javascript remove(configMap) ``` -------------------------------- ### Mutating Policy Example in JavaScript Source: https://www.jspolicy.com/docs/why-jspolicy Shows how to modify the Kubernetes request payload using mutate() in mutating policies. This allows for automatic adjustments to requests before they are processed. ```javascript mutate(modifiedObj) ``` -------------------------------- ### Clone jsPolicy SDK Template Project Source: https://www.jspolicy.com/docs/writing-policies/policy-sdk Clone the jsPolicy SDK GitHub repository to start a new policy project. Navigate into the cloned directory. ```bash git clone https://github.com/loft-sh/jspolicy-sdk mypolicies cd mypolicies ``` -------------------------------- ### Conditional Logging with env() Source: https://www.jspolicy.com/docs/functions/env This example demonstrates how to conditionally log messages based on an environment variable. The env() function retrieves the value of the DEBUG environment variable. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "env.example.com" spec: operations: ["CREATE"] resources: ["pods"] javascript: | // env() retrieves an environment variable from the jspolicy container if (env("DEBUG") === "true") { print("Log this Pod Creation to the console") } ``` -------------------------------- ### Importing Lodash in JsPolicy Source: https://www.jspolicy.com/docs/functions/import This example demonstrates how to import the 'lodash' library into a JsPolicy to utilize its utility functions, such as checking for label equality. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "dependency-policy.example.com" spec: operations: ["CREATE"] resources: ["pods"] dependencies: lodash: "^4.17.21" javascript: | import _ from 'lodash'; // check if forbidden label set is used if (_.isEqual(request.object.metadata?.labels, {"my-forbidden-label": "my-forbbiden-value"})) { deny("forbidden label set encountered"); // ends execution here } ``` -------------------------------- ### Synchronous HTTP Request with fetchSync Source: https://www.jspolicy.com/docs/functions/fetchSync Use fetchSync to make GET requests to backend servers and process the JSON response. Handles successful responses by printing the IP address. Requires the 'policy.jspolicy.com/v1beta1' API version and JsPolicy kind. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "fetch.example.com" spec: operations: ["CREATE"] resources: ["pods"] javascript: | // use fetchSync to make requests to backend servers const res = fetchSync("https://ip.seeip.org/jsonip", { method: "GET", headers: { "X-Custom-HTTP-Header": "test" }, }); if (res.ok) { print("jspolicy ip: " + res.json().ip); } // you can also use try catch to handle network errors try { fetchSync("https://this.will.not.exist.tld"); } catch(err) { print("Catched fetchSync: " + err); } ``` -------------------------------- ### Configure JsPolicy Trigger Source: https://www.jspolicy.com/docs/writing-policies/configuration Defines when a policy should trigger based on operations, resources, scope, and selectors. This example triggers for CREATE/UPDATE operations on namespaced pods or deployments in 'prod' or 'staging' namespaces with the label 'live: "true"'. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "mutate-images.company.tld" spec: type: Mutating operations: ["CREATE", "UPDATE"] resources: ["pods", "deployments"] scope: Namespaced namespaceSelector: matchExpressions: # only trigger for namespaces with label "environment: prod" and/or label "environment: staging" - key: environment operator: In values: ["prod","staging"] objectSelector: # all trigger for objects with label "live: true" matchLabels: live: "true" matchPolicy: "Equivalent" apiGroups: ["*"] apiVersions: ["*"] # Optional javascript here # javascript: if ... ``` -------------------------------- ### List Pods in Namespace with jsPolicy Source: https://www.jspolicy.com/docs/functions/list Lists all pods within the current request's namespace. Denies the operation if 10 or more pods are found. This example demonstrates basic usage with namespace filtering. ```javascript // list() can list any resource in the kubernetes cluster either from cache or directly // list() takes parameters in the form (Kind, apiVersion, ListOptions?) and returns an array // ListOptions can be 'namespace', 'labelSelector' and 'cache' // If no ListOptions are specified all resources from the cluster are listed const pods = list("Pod", "v1", { namespace: request.namespace }) if (pods.length >= 10) { deny("No more pods allowed in namespace " + request.namespace); } ``` -------------------------------- ### List Pods with Label Selector using jsPolicy Source: https://www.jspolicy.com/docs/functions/list Lists pods across the cluster that match a specific label selector ('my-label=my-value'). It checks if any such pods exist and prints a message if found. This example shows filtering by labels. ```javascript // list all pods in cluster with label selector from cache const myLabelPods = list("Pod", "v1", { labelSelector: "my-label=my-value" }) if (myLabelPods.length > 0) { print("Found pod with my-label=my-value"); } ``` -------------------------------- ### JsPolicyViolations CRD Example Source: https://www.jspolicy.com/docs/reference/policyviolations-crd This YAML defines a JsPolicyViolations resource, illustrating a typical policy violation report. It includes details like the action taken (deny), error code, a descriptive message, the reason for the violation, and information about the triggering request and user. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicyViolations metadata: name: "policy-name.company.tld" status: violations: - action: "deny" code: 500 message: "Namespace 'default' not allowed!" reason: "namespace_disallowed" requestInfo: operation: "" apiVersion: "v1" kind: "Pod" name: "nginx" namespace: "default" userInfo: uid: "uid" username: "admin" timestamp: "2021-05-05T00:32:02Z" ``` -------------------------------- ### Test jsPolicy by Creating a Deployment Source: https://www.jspolicy.com/docs Attempt to create a deployment in the 'default' namespace to verify that the jsPolicy is functioning as expected and denies the creation. ```bash kubectl create deployment nginx-deployment -n default --image=nginx ``` -------------------------------- ### Watch, Compile, and Apply Policies Source: https://www.jspolicy.com/docs/writing-policies/policy-sdk Combine the watch functionality with automatic application of compiled policies to the cluster using kubectl. This provides a seamless development and testing loop. ```bash npm run watch-apply ``` -------------------------------- ### Watch for Policy Changes and Compile Iteratively Source: https://www.jspolicy.com/docs/writing-policies/policy-sdk Enable a hot-reloading workflow that watches for file changes in the src/ directory and iteratively compiles policies. This speeds up the development cycle. ```bash npm run watch ``` -------------------------------- ### Stop Execution Immediately with exit() Source: https://www.jspolicy.com/docs/functions/exit Use exit() to immediately stop policy execution. Any subsequent code, including deny() calls, will not be reached. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "env.example.com" spec: operations: ["CREATE"] resources: ["pods"] javascript: | exit(); // this is never reached deny("I'm not executed"); ``` -------------------------------- ### Check for Ubuntu Pod using jsPolicy Source: https://www.jspolicy.com/docs/functions/list Iterates through a list of pods (previously fetched) to check if any pod is named 'ubuntu'. If an 'ubuntu' pod is found, the operation is denied. This demonstrates conditional logic after listing resources. ```javascript // deny if there is an ubuntu pod in the namespace pods.forEach(pod => pod.metadata.name === "ubuntu" && deny("there is an ubuntu pod in the namespace")); ``` -------------------------------- ### Run jsPolicy SDK Tests Source: https://www.jspolicy.com/docs/writing-policies/policy-sdk Execute all test suites located in the tests/ directory using Jest. This ensures the policy logic functions as expected. ```bash npm run test ``` -------------------------------- ### Create ConfigMap on Pod Creation with JsPolicy Source: https://www.jspolicy.com/docs/functions/create This JsPolicy creates a new ConfigMap in the same namespace as a new Pod. The ConfigMap's data includes a comma-separated list of the Pod's container names. It includes error handling for cases where the ConfigMap already exists or other creation errors occur. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "create.resource.example" spec: operations: ["CREATE"] resources: ["pods"] javascript: | // create() is able to create any resource in the kubernetes cluster // create() takes parameters in the form of (object) // this will create a new configmap in the namespace with the same name as // the pod and contains all the container names. const result = create({ kind: "ConfigMap", apiVersion: "v1", metadata: { "name": request.object.metadata.name, "namespace": request.object.metadata.namespace }, data: { containers: (request.object.spec?.containers || []).map(container => container.name).join(",") } }); if (!result.ok) { // check for a specific error type if (result.reason === "AlreadyExists") { warn(`ConfigMap already exists`) } else { warn(`Error creating ConfigMap (Reason ${result.reason}): ${result.message}`); } } else { print("Created ConfigMap", result.object); } ``` -------------------------------- ### Check JsPolicyBundle Source: https://www.jspolicy.com/docs/using-policies/basics Verify the creation of a JsPolicyBundle after applying a JsPolicy. The bundle contains the optimized, compressed, and base64 encoded JavaScript code. ```bash kubectl get jspolicybundle ``` -------------------------------- ### Apply JsPolicyBundle and JsPolicy as a Single File Source: https://www.jspolicy.com/docs/using-policies/basics Apply a JsPolicyBundle and its corresponding JsPolicy object combined into a single YAML file. Ensure the bundle is listed before the policy within the file. ```bash # Combo as single file: kubectl apply -f policy-and-bundle.yaml # should contain JsPolicyBundle + "---" + JsPolicy ``` -------------------------------- ### Publish Policy Logic to npm Source: https://www.jspolicy.com/docs/writing-policies/policy-sdk Export shared policy logic functions from src/index.ts and publish the project to npmjs.com to make them available for reuse by others. ```bash npm publish ``` -------------------------------- ### Apply jsPolicy to Kubernetes Source: https://www.jspolicy.com/docs Apply the created jsPolicy resource to your Kubernetes cluster using kubectl. ```bash kubectl apply -f policy.yaml ``` -------------------------------- ### Uninstall jsPolicy Helm Release Source: https://www.jspolicy.com/docs/getting-started/cleanup Use this command to uninstall the jsPolicy Helm release. This is the recommended first step for cleanup. ```bash helm delete -n jspolicy jspolicy ``` -------------------------------- ### Compile jsPolicy Policies Source: https://www.jspolicy.com/docs/writing-policies/policy-sdk Compile TypeScript policies located in src/policies into JavaScript and output them as YAML files in the policies/ directory. This prepares them for deployment. ```bash npm run compile ``` -------------------------------- ### Apply JsPolicyBundle and JsPolicy Separately Source: https://www.jspolicy.com/docs/using-policies/basics Apply a JsPolicyBundle and its corresponding JsPolicy object as separate files. It is recommended to apply the bundle first to ensure the policy has its code available immediately. ```bash # Combo as separate files: kubectl apply -f policy.bundle.yaml # apply JsPolicyBundle kubectl apply -f policy.yaml # apply JsPolicy ``` -------------------------------- ### Configure JsPolicy Runtime Settings Source: https://www.jspolicy.com/docs/writing-policies/configuration Define runtime behavior for JsPolicy, including violation and failure policies, reinvocation, and audit logging. Adjust timeoutSeconds to control execution duration. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "validate-images.company.tld" spec: operations: ["CREATE", "UPDATE"] resources: ["pods", "deployments"] violationPolicy: warn failurePolicy: Ignore reinvocationPolicy: IfNeeded auditPolicy: Skip timeoutSeconds: 30 ``` -------------------------------- ### Update Namespace with Pod Count Annotation Source: https://www.jspolicy.com/docs/functions/update This snippet demonstrates how to update a Namespace object by adding an annotation for the pod count. It retrieves the Namespace and a list of Pods, calculates the new pod count, updates the annotation, and then uses the update() function to apply the changes. Error handling is included to warn about conflicts or other update failures. ```javascript // update() is able to update any resource in the kubernetes cluster // update() takes parameters in the form of (newObject) // this will update the namespace and set the amount of pods in the namespace annotations const namespace = get("Namespace", "v1", request.namespace); const pods = list("Pod", "v1", {namespace: request.namespace}); // set annotation namespace.metadata.annotations = {...namespace.metadata.annotations, "pods-count": `${pods.length + 1}`}; const result = update(namespace); if (!result.ok) { // check for a specific error type if (result.reason === "Conflict") { warn(`Change conflicted with another change to the namespace`); } else { warn(`Error updating Namespace (Reason ${result.reason}): ${result.message}`); } } else { print("Updated Namespace", result.object); } ``` -------------------------------- ### Using sleep() in a JsPolicy Source: https://www.jspolicy.com/docs/functions/sleep Demonstrates how to use the sleep() function within a JsPolicy to pause execution. Avoid using sleep() in webhooks unless necessary; consider caching for timing-critical operations. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "pod-sleep.example.com" spec: operations: ["CREATE"] resources: ["pods"] javascript: | // you should usually never(!) sleep inside a webhook, // however there might be situations where you need to wait for // something to happen in the cluster, so this function exists // // remember you can use {cache: false} as well for get() and list() // if you need timing critical webhooks const before = new Date().getTime(); sleep(1000); // sleep for 1 second print(`Slept for ${(new Date().getTime() - before)}`); ``` -------------------------------- ### Delete a ConfigMap using remove() Source: https://www.jspolicy.com/docs/functions/remove Use the remove() function to delete a ConfigMap in the Kubernetes cluster. It checks if the ConfigMap exists before attempting deletion and logs warnings for errors or if the ConfigMap was not found. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "remove.resource.example" spec: operations: ["DELETE"] resources: ["pods"] javascript: | // remove() is able to delete any resource in the kubernetes cluster // remove() takes parameters in the form of (oldObject) // this will delete a configmap in the namespace with the same name as the pod const configMap = get("ConfigMap", "v1", request.namespace + "/" + request.name); if (configMap) { const result = remove(configMap); if (!result.ok) { // check for a specific error type if (result.reason === "NotFound") { warn(`ConfigMap was deleted by someone else`); } else { warn(`Error deleting ConfigMap (Reason ${result.reason}): ${result.message}`); } } else { print("Deleted ConfigMap", result.object); } } else { warn(`ConfigMap ${request.namespace}/${request.name} was not found`); } ``` -------------------------------- ### Set Annotation with mutate() Source: https://www.jspolicy.com/docs/functions/mutate This policy sets a required annotation on a pod during CREATE or UPDATE operations. It checks if the annotation exists and has the correct value, then modifies the object and calls mutate() to apply the change. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "set-annotation.example.com" spec: type: Mutating operations: ["CREATE", "UPDATE"] resources: ["pods"] javascript: | // This policy will set a required annotation on a pod during CREATE or UPDATE if (request.object.metadata.annotations?.["required-annotation"] !== "is-required") { // set annotation required-annotation=is-required request.object.metadata.annotations = {...request.object.metadata.annotations, 'required-annotation': 'is-required'}; // tell jspolicy to calc the patch and exit mutate(request.object); } // if execution reaches here, request is allowed and nothing happens ``` -------------------------------- ### Requeue on Create Error in jsPolicy Controller Source: https://www.jspolicy.com/docs/functions/requeue This snippet demonstrates how to use requeue() within a jsPolicy controller to handle errors during resource creation. If a ResourceQuota cannot be created and it's not due to the resource already existing, the policy is requeued with the error message. ```javascript // This policy will create a resource quota for each namespace that // has a label "create-rq": "true". Also works for already existing // namespaces that match these labels. // // You can test the policy with: // kubectl create ns test // kubectl label ns test create-rq=true // kubectl get resourcequotas -n test // find resource quota const resourceQuota = get("ResourceQuota", "v1", request.name + "/my-resource-quota"); if (!resourceQuota) { const createResult = create({ kind: "ResourceQuota", apiVersion: "v1", metadata: { "name": "my-resource-quota", "namespace": request.name }, spec: { hard: { "limits.cpu": "2" } } }); if (!createResult.ok && createResult.reason !== "AlreadyExists") { // This makes it possible to avoid loops and just tells jsPolicy to try again later requeue(createResult.message); } else { print(`created ResourceQuota ${request.name}/my-resource-quota`); } } ``` -------------------------------- ### Manually Delete jsPolicy Webhook Source: https://www.jspolicy.com/docs/getting-started/cleanup If the namespace was deleted before the Helm release, you must manually remove the validating webhook configuration to prevent cluster request failures. ```bash kubectl delete validatingwebhookconfiguration jspolicy ``` -------------------------------- ### Define JsPolicy with npm Dependency Source: https://www.jspolicy.com/docs/using-policies/basics Use this YAML structure to declare an npm package as a dependency for your JsPolicy. The package's functions can then be imported and used in the `spec.javascript` field. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "restrict-namespaces.company.tld" spec: operations: ["CREATE"] resources: ["*"] scope: Namespaced dependencies: "@jspolicy/policies": "^0.0.1" javascript: | import { disallowNamespaces } from "@jspolicy/policies"; disallowNamespaces(["default", "kube-system", /^prod-.*/]) ``` -------------------------------- ### Define JsPolicy Type Source: https://www.jspolicy.com/docs/writing-policies/configuration Specifies the type of policy. 'Validating' is the default and can be omitted. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "policy-name.company.tld" spec: type: Validating # other options: Mutating | Controller ``` -------------------------------- ### Delete jsPolicy Namespace Source: https://www.jspolicy.com/docs/getting-started/cleanup After deleting the Helm release, you can remove the jsPolicy namespace. Ensure the Helm release is deleted first to avoid potential issues. ```bash kubectl delete namespace jspolicy ``` -------------------------------- ### JsPolicy CRD Definition Source: https://www.jspolicy.com/docs/reference/policy-crd Defines a JsPolicy resource, specifying validation type, operations, resources, selectors, and JavaScript code. ```yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "policy-name.company.tld" spec: type: Validating operations: ["CREATE"] resources: ["*"] objectSelector: {} namespaceSelector: {} scope: Namespaced apiGroups: ["*"] apiVersions: ["*"] matchPolicy: "Equivalent" violationPolicy: "deny" failurePolicy: "" reinvocationPolicy: "Never" auditPolicy: "" auditLogSize: 10 dependencies: "@jspolicy/package-1": "^1.0.0" "@jspolicy/package-2": "~2.0.0" javascript: "/* JS CODE HERE */" timeoutSeconds: 10 status: phase: "Synced" message: "This is a human-readable error (if any)" reason: "error_reason_if_any" bundleHash: "" ``` -------------------------------- ### Delete jsPolicy CRDs Source: https://www.jspolicy.com/docs/getting-started/cleanup If the cluster fails to respond to API requests due to lingering CRDs, use this command to delete them. This action will also remove all jsPolicy objects. ```bash kubectl api-resources --api-group='policy.jspolicy.com' -o name | xargs kubectl delete crd ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.