PageSourceSearch

https://flanksource.com/assets/js/e872018a.5140722c.js

js flanksource.com collected 2026-09-25 15:26:39 UTC 9,429 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkmission_control=globalThis.webpackChunkmission_control||[]).push([[3671],{64732(e,n,s){s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"guide/playbooks/concepts/expression","title":"Expressions","description":"Playbook event filters use Common Expression Language (CEL).","source":"@site/docs/guide/playbooks/concepts/expression.mdx","sourceDirName":"guide/playbooks/concepts","slug":"/guide/playbooks/concepts/expression","permalink":"/docs/guide/playbooks/concepts/expression","draft":false,"unlisted":false,"editUrl":"https://github.com/flanksource/docs/tree/main/docs/guide/playbooks/concepts/expression.mdx","tags":[],"version":"current","frontMatter":{"title":"Expressions","sidebar_custom_props":{"icon":"hugeicons:code"}},"sidebar":"guide","previous":{"title":"Cancel Runs","permalink":"/docs/guide/playbooks/concepts/cancellation"},"next":{"title":"Runners","permalink":"/docs/guide/playbooks/concepts/runners"}}');var t=s(74848),c=s(28453);const o={title:"Expressions",sidebar_custom_props:{icon:"hugeicons:code"}},r=void 0,d={},l=[{value:"Conditionally running actions",id:"conditionally-running-actions",level:2},{value:"Context",id:"context",level:2}];function a(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,c.R)(),...e.components},{CommonLink:s,Fields:i}=n;return s||x("CommonLink",!0),i||x("Fields",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["Playbook event filters use ",(0,t.jsx)(n.a,{href:"https://github.com/google/cel-go",children:"Common Expression Language (CEL)"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"The Common Expression Language (CEL) is a non-Turing complete language designed for simplicity, speed, safety, and portability. CEL's C-like syntax is similar to expressions in C++, Go, Java, and TypeScript."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="notify-with-filter.yaml"',children:'---\napiVersion: mission-control.flanksource.com/v1\nkind: Playbook\nmetadata:\n  name: notify-with-filter\nspec:\n  on:\n    config:\n      - event: created\n  configs:\n    - type: Kubernetes::Pod\n  actions:\n    - name: Send notification\n      exec:\n        script: notify-send "{{.config.name}} was created"\n    - name: Bad script to create a failing action\n      exec:\n        script: non-existing-command\n    - name: Send all success notification\n      if: success() # this filter practically skips this action as the second action above always fail
1s\n      exec:\n        script: notify-send "Everything went successfully"\n    - name: Send notification regardless\n      if: always()\n      exec:\n        script: notify-send "a config was created"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"conditionally-running-actions",children:"Conditionally running actions"}),"\n",(0,t.jsxs)(n.p,{children:["Playbook actions can be conditionally executed using CEL expressions. These expressions must return a ",(0,t.jsx)(n.code,{children:"bool"})," value (return ",(0,t.jsx)(n.code,{children:"false"})," to skip the action)."]}),"\n",(0,t.jsxs)(n.p,{children:["Expressions support the following functions in addition to the standard ",(0,t.jsx)(s,{to:"cel",children:"CEL"})," functions."]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Function"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"always()"})}),(0,t.jsx)(n.td,{children:"Execute regardless of playbook state (cancelled/failed)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"failure()"})}),(0,t.jsx)(n.td,{children:"Execute if any previous actions failed"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"skip()"})}),(0,t.jsx)(n.td,{children:"Skip execution of this action"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"success()"})}),(0,t.jsx)(n.td,{children:"Execute only if all previous actions succeeded (default)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"timeout()"})}),(0,t.jsx)(n.td,{children:"Execute only if any previous actions timed out"})]})]})]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Examples"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"if: config.deleted_at ? true: false"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"if: always()"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"context",children:"Context"}),"\n",(0,t.jsx)(n.p,{children:"Expressions have access to the following variables and functions:"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Field"}),(0,t.jsx)(n.th,{children:"Description"}),(0,t.jsx)(n.th,{children:"Schema"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"config"})}),(0,t.jsx)(n.td,{children:"Configuration object passed to the playbook"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/docs/reference/config-db",children:(0,t.jsx)(n.code,{children:"ConfigItem"})})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"check"})}),(0,t.jsx)(n.td,{children:"Canary Check object passed to the playbook"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/docs/reference/canary-checker/check",children:(0,t.jsx)(n.code,{children:"Check"})})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"params"})}),(0,t.jsx)(n.td,{children:"User-provided parameters for the playbook"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"map[string]string"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"user.id"})}),(0,t.jsx)(n.td,{children:"Unique identifier of the user who triggered the action"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"string"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"user.name"})}),(0,t.jsx)(n.td,{children:"Full name of the user who triggered the action"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"string"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"user.email"})}),(0,t.jsx)(n.td,{children:"Email address of the user who triggered the action"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"string"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"action.name"})}),(0,t.jsx)(n.td,{children:"Name of the current action"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"string"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"action.status"})}),(0,t.jsxs)(n.td,{children:["Current status of the action (",(0,t.jsx)(n.code,{children:"scheduled"}),", ",(0,t.jsx)(n.code,{children:"running"}),", ",(0,t.jsx)(n.code,{children:"succeeded"}),", ",(0,t.jsx)(n.code,{children:"failed"}),", ",(0,t.jsx)(n.code,{children:"skipped"}),", or ",(0,t.jsx)(n.code,{children:"cancelled"}),")"]}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"string"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"action.scheduled_time"})}),(0,t.jsx)(n.td,{children:"Timestamp when the action was scheduled"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"string"})})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"action.start_time"})}),(0,t.jsx)(n.td,{children:"Timestamp when the action execution began"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"string"})})]})]})]}),"\n",(0,t.jsx)(n.p,{children:"For playbooks triggered via webhooks, the following additional fields are available:"}),"\n",(0,t.jsx)(i,{rows:[{field:"request.url",description:"Endpoint of the webhook. Example `/playbook/webhook/test-webhook`",scheme:"string"},{field:"request.headers",description:"Headers sent on the webhook request",scheme:"`map[string]string`"},{field:"request.params",description:"Query parameters sent on the webhook request",scheme:"`map[string]string`"},{field:"request.content",description:"Content sent on the webhook request",scheme:"string"},{field:"request.json",description:"JSON content if the webhook content is JSON",scheme:"`map[string]any`"}]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}function x(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453(e,n,s){s.d(n,{R:()=>o,x:()=>r});var i=s(96540);const t={}
1,c=i.createContext(t);function o(e){const n=i.useContext(c);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.