<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>OPSaid – 策略治理</title><link>https://opsaid.net/docs/identity-security/policy-governance/</link><description>Recent content in 策略治理 on OPSaid</description><generator>Hugo -- gohugo.io</generator><atom:link href="https://opsaid.net/docs/identity-security/policy-governance/index.xml" rel="self" type="application/rss+xml"/><item><title>Docs: Rego 语言</title><link>https://opsaid.net/docs/identity-security/policy-governance/rego/</link><pubDate>Tue, 21 Nov 2023 16:18:29 +0800</pubDate><guid>https://opsaid.net/docs/identity-security/policy-governance/rego/</guid><description>
&lt;h2 id="简要概述">简要概述&lt;/h2>
&lt;p>这里做 Rego 的简要语法说明。&lt;/p>
&lt;h2 id="基础类型">基础类型&lt;/h2>
&lt;h3 id="scalar-values">Scalar Values&lt;/h3>
&lt;p>标量值是 Rego 中最简单的类型，可以是字符串、数字、布尔值或 null，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>greeting := &amp;#34;Hello&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>max_height := 42
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pi := 3.14159
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>allowed := true
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>location := null
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docs := [greeting, max_height, pi, allowed, location]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="strings">Strings&lt;/h3>
&lt;p>字符串支持两种声明方式，第一种通过双引号包含，如果有特殊字符需通过反斜杠转译，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;#34;[a-zA-Z_]\\w*&amp;#34;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>第二种声明方式是通过反引号(`)，对特殊字符既所见即所得，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>`[a-zA-Z_]\w*`
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这其实和 Go 语言字符串有相同申明方式。&lt;/p>
&lt;h3 id="composite-values">Composite Values&lt;/h3>
&lt;p>组合值包含两种类型：Objects（对象）、Sets（集合），在简单情况下，组合值可以像标量值一样被视为常量：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>cube := {&amp;#34;width&amp;#34;: 3, &amp;#34;height&amp;#34;: 4, &amp;#34;depth&amp;#34;: 5}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docs := [greeting, max_height, pi, allowed, location]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Objects（对象，也包含数组）键值可以是任意值：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>ips_by_port := {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 80: [&amp;#34;1.1.1.1&amp;#34;, &amp;#34;1.1.1.2&amp;#34;],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 443: [&amp;#34;2.2.2.1&amp;#34;],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;80&amp;#34;: [&amp;#34;1.1.1.3&amp;#34;],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这里 &lt;code>ips_by_port[80]&lt;/code> 与 &lt;code>ips_by_port[&amp;quot;80&amp;quot;]&lt;/code> 获取是不一样的结果，当需要把 &lt;code>ips_by_port&lt;/code> 输出 JSON 结构时，原先以 &lt;code>80&lt;/code> 为键名的内容会被 &lt;code>&amp;quot;80&amp;quot;&lt;/code> 所覆盖，因为 JSON 本身不支持以数字为属性，所以我们在定义 rego 变量是要避免使用数字类型键值，如 &lt;code>ips_by_port&lt;/code> 输出 JSON 结果集为：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">&amp;#34;443&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;2.2.2.1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">],&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">&amp;#34;80&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;1.1.1.3&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Sets（集合）是无序的唯一值的集合，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>{1,2,3} == {3,1,2}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="定义变量">定义变量&lt;/h2>
&lt;p>变量在 Rego 中与大部分编程语言不同，可同时是输入和输出。如果为变量提供了一个值，那么该变量是一个输入型，如果没有为变量提供值，那么该变量是一个输出型。&lt;/p>
&lt;h3 id="作为输入">作为输入&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>m := [10,6,9,8,15,3,12]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sites := [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&amp;#34;name&amp;#34;: &amp;#34;prod&amp;#34;},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&amp;#34;name&amp;#34;: &amp;#34;smoke1&amp;#34;},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&amp;#34;name&amp;#34;: &amp;#34;dev&amp;#34;}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>以上变量 &lt;code>m&lt;/code> 与 &lt;code>sites&lt;/code> 均作为输入型变量，这同其他语言定义。&lt;/p>
&lt;h3 id="作为输出">作为输出&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; m := [10,6,9,8,15,3,12]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;m&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 10,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 6,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 9,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 8,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 15,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 3,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 12
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; n
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>1 error occurred: 1:1: rego_unsafe_var_error: var n is unsafe
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m[n] == 3
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+---+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| n |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+---+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 5 |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+---+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>定义一个数组 &lt;code>m&lt;/code>，此时变量 &lt;code>n&lt;/code> 未定义，通过查询语句 &lt;code>m[n] == 3&lt;/code> 查找数组 &lt;code>m&lt;/code> 中值为 &amp;ldquo;3&amp;rdquo; 的结果并写入到变量 &lt;code>n&lt;/code> 中，此时变量 &lt;code>n&lt;/code> 作为输出型，在看另外一个示例：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import future.keywords.in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import future.keywords.contains
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sites := [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&amp;#34;name&amp;#34;: &amp;#34;prod&amp;#34;},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&amp;#34;name&amp;#34;: &amp;#34;smoke1&amp;#34;},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&amp;#34;name&amp;#34;: &amp;#34;dev&amp;#34;}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>q contains name if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> some site in sites
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name := site.name
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>此时变量 &lt;code>q&lt;/code> 的结果为：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>[
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;dev&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;prod&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;smoke1&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在使用一个未定义过的变量 &lt;code>x&lt;/code> 来评估 &lt;code>q&lt;/code>，此时 &lt;code>x&lt;/code> 为输出，如 &lt;code>q[x]&lt;/code> 结果为：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>+----------+----------+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| x | q[x] |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+----------+----------+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| &amp;#34;dev&amp;#34; | &amp;#34;dev&amp;#34; |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| &amp;#34;prod&amp;#34; | &amp;#34;prod&amp;#34; |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| &amp;#34;smoke1&amp;#34; | &amp;#34;smoke1&amp;#34; |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+----------+----------+
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这里由于 &lt;code>q&lt;/code> 是一个集合，所以它们结果相同。&lt;/p>
&lt;p>再比如 &lt;code>sites[i].name&lt;/code>，这样在遍历数组时会自动把变量 &lt;code>i&lt;/code> 赋值输出：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>+---+---------------+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| i | sites[i].name |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+---+---------------+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 0 | &amp;#34;prod&amp;#34; |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 1 | &amp;#34;smoke1&amp;#34; |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 2 | &amp;#34;dev&amp;#34; |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+---+---------------+
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>如果以上变量 &lt;code>i&lt;/code> 在下文中不会使用，我们可以用下划线代替 &lt;code>sites[_].name&lt;/code>，下划线在 Rego 中为特殊含义表示永不重复变量。&lt;/p>
&lt;h2 id="推导式">推导式&lt;/h2>
&lt;p>推导式，提供了一种从子查询构建复合值的简洁方式，主要有三种形式，这里通过以下示例说明：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>apps := [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;id&amp;#34;: &amp;#34;001&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;name&amp;#34;: &amp;#34;web&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;servers&amp;#34;: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-1&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-1000&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-1001&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-dev&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;id&amp;#34;: &amp;#34;002&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;name&amp;#34;: &amp;#34;mysql&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;servers&amp;#34;: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-1000&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;id&amp;#34;: &amp;#34;003&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;name&amp;#34;: &amp;#34;web&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;servers&amp;#34;: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-3&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-prod&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;id&amp;#34;: &amp;#34;004&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;name&amp;#34;: &amp;#34;mongodb&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;servers&amp;#34;: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-dev&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="数组推导式">数组推导式&lt;/h3>
&lt;p>Array Comprehensions&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>[ &amp;lt;term&amp;gt; | &amp;lt;body&amp;gt; ]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; comp := [ server | apps[i].name == &amp;#34;web&amp;#34;; server := apps[i].servers[0] ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; comp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-3&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="对象推导式">对象推导式&lt;/h3>
&lt;p>Object Comprehensions&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>{ &amp;lt;key&amp;gt;: &amp;lt;term&amp;gt; | &amp;lt;body&amp;gt; }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; comp := { key: server | key := apps[i].id; server := apps[i].servers[0] }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; comp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;001&amp;#34;: &amp;#34;web-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;002&amp;#34;: &amp;#34;db-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;003&amp;#34;: &amp;#34;web-3&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;004&amp;#34;: &amp;#34;db-dev&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="集合推导式">集合推导式&lt;/h3>
&lt;p>Set Comprehensions&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>{ &amp;lt;term&amp;gt; | &amp;lt;body&amp;gt; }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; comp := { name | name = apps[x].name }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; comp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;mongodb&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;mysql&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="根据已有数据生成变量">根据已有数据生成变量&lt;/h2>
&lt;p>在编写规则时，使用到的一些关键字需要自己引入下，如 &lt;code>if&lt;/code> &lt;code>contains&lt;/code> 等：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import futere.keywords.contains
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="通过规则生成数组">通过规则生成数组&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>comp[name] {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name := apps[_].servers[0]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; comp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-dev&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-3&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="通过规则生成对象">通过规则生成对象&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>comp[id] := server {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> some i
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> id := apps[i].id
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> server := apps[i].servers
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; comp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;001&amp;#34;: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-1&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-1000&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-1001&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-dev&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;002&amp;#34;: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-1000&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;003&amp;#34;: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-3&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-prod&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;004&amp;#34;: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-dev&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这里使用示例数据 &lt;code>apps&lt;/code> 生成一组对象 &lt;code>comp&lt;/code> 以 &amp;ldquo;id&amp;rdquo; 为键，以 &amp;ldquo;server&amp;rdquo; 为值，这个值来自后面的 {} 判断。&lt;/p>
&lt;h3 id="对已有数组的累加">对已有数组的累加&lt;/h3>
&lt;p>使用相同的变量 &lt;code>comp&lt;/code> 在通过多次规则时，它们的结果集是做增量，如下面两次叠加：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; comp[name] { name := apps[_].servers[0] }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; comp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-dev&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-3&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; comp[name] { name := apps[_].name }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; comp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;db-dev&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;mongodb&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;mysql&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-0&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;web-3&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="对变量的完整定义">对变量的完整定义&lt;/h3>
&lt;p>除了部分定义集合和对象的规则外，还支持任何类型文档的完整定义，通常用于常量：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>pi := 3.14159
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>由具有完整定义的规则生成的文档一次只能具有一个值，如果评估为同一文档生成多个值，将返回错误。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>package repl
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># 定义一个用户 &amp;#34;bob&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user := &amp;#34;bob&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># 定义两个用户组，分布表示管理员与受限用户组
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>power_users := {&amp;#34;alice&amp;#34;, &amp;#34;bob&amp;#34;, &amp;#34;fred&amp;#34;}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>restricted_users := {&amp;#34;bob&amp;#34;, &amp;#34;kim&amp;#34;}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># 管理员可拥有 32GB 内存
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>max_memory := 32 if power_users[user]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># 受限用户仅可有 4GB 内存
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>max_memory := 4 if restricted_users[user]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>TODO;&lt;/p>
&lt;p>这里注意下，官方文档是说无法更改，但实际测试中可以被变更：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Rule &amp;#39;max_memory&amp;#39; re-defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>需具体检查下原因。&lt;/p>
&lt;h3 id="用户自定义函数">用户自定义函数&lt;/h3>
&lt;p>支持用户自定定义函数，可以与内置函数相同的语义进行调用，它们可以访问数据文档和输入文档。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>trim_and_split(s) := x {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t := trim(s, &amp;#34; &amp;#34;)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x := split(t, &amp;#34;.&amp;#34;)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; trim_and_split(&amp;#34; foo.bar &amp;#34;)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;foo&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;bar&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>foo([x, {&amp;#34;bar&amp;#34;: y}]) := z {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> z := {x: y}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; foo([10, {&amp;#34;bar&amp;#34;: 30}])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;10&amp;#34;: 30
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="模块包与内置函数">模块、包与内置函数&lt;/h2>
&lt;h3 id="模块组成">模块组成&lt;/h3>
&lt;p>一个 Rego 的模块，由以下三部分组成：&lt;/p>
&lt;ol>
&lt;li>固定使用一个 &lt;code>package&lt;/code> 关键字申明包名称；&lt;/li>
&lt;li>零个或多个 &lt;code>import&lt;/code> 关键字语句导入外部模块；&lt;/li>
&lt;li>零个或多个规则定义。&lt;/li>
&lt;/ol>
&lt;h3 id="包名称">包名称&lt;/h3>
&lt;p>包名称仅能使用字符串，如需分割多个层级，则通过点号 &amp;ldquo;.&amp;quot;，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>package foo.bar.baz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pi := 3.14159
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>以上规则定义好后，会自动导出到 opa，可通过以下 api 查询：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>GET /v1/data/foo/bar/baz/pi
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>属于相同的包名称下的模块，可以分布在不同的目录。&lt;/p>
&lt;h3 id="导入模块">导入模块&lt;/h3>
&lt;p>如需复用第三方模块，使用关键字 &lt;code>import&lt;/code> 导入，这样即可在当前模块中引用该文档导出的标识符，如需使用关键字 &lt;code>if&lt;/code> 与 &lt;code>contains&lt;/code> 则：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>package foo.bar.baz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import future.keywords.contains
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>http_servers contains server if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> some server in servers
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;http&amp;#34; in server.protocols
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>TODO; 关键字 &lt;code>data&lt;/code> 与 &lt;code>input&lt;/code>&lt;/p>
&lt;h3 id="备注注解">备注注解&lt;/h3>
&lt;p>同其他语言一样，通过 &amp;ldquo;#&amp;rdquo; 实现注解。&lt;/p>
&lt;h3 id="内置函数">内置函数&lt;/h3>
&lt;p>OPA 本身提供了很多常用的函数，可直接调用，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; m := [6,9,8]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;m&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; max(m)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>9
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; min(m)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>6
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>具体列表查看&lt;a href="https://www.openpolicyagent.org/docs/latest/policy-reference/#built-in-functions">官方文档&lt;/a>。&lt;/p>
&lt;h2 id="内置关键字">内置关键字&lt;/h2>
&lt;h3 id="some">some&lt;/h3>
&lt;p>用于遍历数据或对象，显式声明键索引与键值局部变量，这些变量的作用范围仅限于该规则内，类似 go 语言的 for 循环，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; import future.keywords.in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m := [10,6,9,8,15,3,12]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;m&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; some k, v in m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+---+----+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| k | v |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+---+----+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 0 | 10 |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 1 | 6 |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 2 | 9 |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 3 | 8 |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 4 | 15 |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 5 | 3 |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 6 | 12 |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+---+----+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="with">with&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;lt;expr&amp;gt; with &amp;lt;target-1&amp;gt; as &amp;lt;value-1&amp;gt; [with &amp;lt;target-2&amp;gt; as &amp;lt;value-2&amp;gt; [...]]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>TODO;&lt;/p>
&lt;h3 id="default">default&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>default &amp;lt;name&amp;gt; := &amp;lt;term&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>为变量定义默认值，因为在判断规则不成立时，变量会被设置为 &lt;code>undefined&lt;/code>，这样在使用过程中不友好，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m if 3 &amp;gt; 10
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;m&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>undefined
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; default m := false
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;m&amp;#39; re-defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>false
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m if 3 &amp;gt; 10
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;m&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>false
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="else">else&lt;/h3>
&lt;p>基本的控制流构造，对一组规则按照顺序进行评估，一旦找到匹配项，就不会继续对后续规则评估，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>x := 10
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>y := 10
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>name := &amp;#34;user1&amp;#34; if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x &amp;gt; y
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>} else := &amp;#34;user2&amp;#34; {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x == y
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>} else := &amp;#34;user3&amp;#34; {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x &amp;lt; y
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="future">future&lt;/h3>
&lt;p>包含 &lt;code>in&lt;/code> &lt;code>every&lt;/code> &lt;code>if&lt;/code> &lt;code>contains&lt;/code> 在使用过程中可一次性导入 &lt;code>import futer.keyworks&lt;/code> 不过建议按需，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import future.keywords.every
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import future.keywords.contains
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="futurekeywordsin">future.keywords.in&lt;/h3>
&lt;p>对查找的内容是否在给定的对象或数组中，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; import future.keywords.in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m := [10,6,9,8,15,3,12]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;m&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 10,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 6,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 9,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 8,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 15,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 3,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 12
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; n := 3
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;n&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; n
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>3
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; n in m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>true
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="futurekeywordsevery">future.keywords.every&lt;/h3>
&lt;p>对遍历的对象或数组，在规则内必须每个都成立，此时结果才为真，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; import future.keywords.in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; import future.keywords.every
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m := [10,6,9,8,15,3,12]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;m&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; n := 3
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;n&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; n in m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>true
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; every x in m {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| x &amp;gt;= n
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>|
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>true
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="futurekeywordsif">future.keywords.if&lt;/h3>
&lt;p>如果规则判断为真，对前变量赋值，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>&amp;gt; import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; m := [10,6,9,8,15,3,12]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;m&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; n := 3
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;n&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; deny if n &amp;gt; m[0]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;deny&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; deny
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>undefined
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; deny if n &amp;lt; m[0]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rule &amp;#39;deny&amp;#39; defined in package repl. Type &amp;#39;show&amp;#39; to see rules.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; deny
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>true
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="futurekeywordscontains">future.keywords.contains&lt;/h3>
&lt;p>TODO;&lt;/p>
&lt;h2 id="运算符">运算符&lt;/h2>
&lt;h3 id="等号运算符">等号运算符&lt;/h3>
&lt;p>等号存在三种运算：赋值（:=）、相等（==）和对比赋值（=）。建议尽量使用赋值（:=）和比较（==），以便编写和阅读更容易理解的策略。&lt;/p>
&lt;p>赋值运算 &amp;ldquo;:=&amp;rdquo; 是将值分配给变量&lt;/p>
&lt;ol>
&lt;li>在规则内分配变量的作用域仅限于该规则内，并且会覆盖全局变量&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>x := 100
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>p if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 这里变量 &amp;#34;x&amp;#34; 仅在该规则内有效，并忽略上面的变量 &amp;#34;x&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x := 1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x != 100
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>以下均是错误的，变量赋值过不可重复&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>x := 100
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>p if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 这里变量 &amp;#34;x&amp;#34; 为以上定义的全局变量，不能在重复赋值，所以出错
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x != 100
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x := 1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>p if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x := 1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x := 2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="3">
&lt;li>从数组中提取值并将其赋值给变量&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>address := [&amp;#34;3 Abbey Road&amp;#34;, &amp;#34;NW8 9AY&amp;#34;, &amp;#34;London&amp;#34;, &amp;#34;England&amp;#34;]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>in_london if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [_, _, city, country] := address
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> city == &amp;#34;London&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> country == &amp;#34;England&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>相等运算 &amp;ldquo;==&amp;rdquo; 比较在规则内检查两个值是否相等&lt;/p>
&lt;ol>
&lt;li>比较两个变量值是否相等&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>p if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x := 100
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x == 100
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>两边对比的变量必须已经定义否则出错&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>p if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x == 100
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>对比赋值 &amp;ldquo;=&amp;rdquo; 用于比较两边规则如果为真则分别对其赋值&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>[x, &amp;#34;world&amp;#34;] = [&amp;#34;hello&amp;#34;, y]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>与单独赋值（:=）区别在他们规则内无需按照顺序&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>s if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 这个正常执行
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x &amp;gt; y
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> y = 41
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x = 42
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>import future.keywords.if
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>s if {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 这个会出错
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x &amp;gt; y
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> y := 41
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> x := 42
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="对比运算符">对比运算符&lt;/h3>
&lt;p>也就平常的大于、小于、等于等，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>a == b # `a` is equal to `b`.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>a != b # `a` is not equal to `b`.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>a &amp;lt; b # `a` is less than `b`.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>a &amp;lt;= b # `a` is less than or equal to `b`.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>a &amp;gt; b # `a` is greater than `b`.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>a &amp;gt;= b # `a` is greater than or equal to `b`.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs: Gatekeeper</title><link>https://opsaid.net/docs/identity-security/policy-governance/gatekeeper/</link><pubDate>Tue, 02 Jan 2024 17:38:16 +0800</pubDate><guid>https://opsaid.net/docs/identity-security/policy-governance/gatekeeper/</guid><description>
&lt;h2 id="简要概述">简要概述&lt;/h2>
&lt;p>各公司针对各自 K8S 集群都有一些合规政策，为了满足运维、安全、合规等要求。如果试图通过手动确保合规性就有可能会出现错误，所以需通过自动化方式执行确保一致性，即时反馈、并允许开发人员独立运作而无需牺牲合规性来提高灵活性。&lt;/p>
&lt;p>Kubernetes 是允许通过 &lt;a href="https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers/">Admission Controller Webhooks&lt;/a> 准入控制器将策略决策与 API Server 的内部工作解耦，这些 Webhooks 在每次创建、更新或删除资源时执行。如果各个规则均需要编写一个对应的准入控制器，难免有些复杂不够灵活，所以产生了通用的策略服务组件，也就是 Gatekeeper。&lt;/p>
&lt;h2 id="gatekeeper">Gatekeeper&lt;/h2>
&lt;p>它支持验证性质的准入 Webhook &lt;a href="https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook">ValidatingAdmissionWebhook&lt;/a> 与变更性质的准入 Webhook &lt;a href="https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook">MutatingAdmissionWebhook&lt;/a>，通过由 Open Policy Agent（OPA）执行预先编写的 rego 策略规则，基于 CRD 的方式数据持久存储在 etcd 中。而 OPA 是一个在云原生环境中执行的策略引擎，由 CNCF 作为一个已毕业项目进行托管。&lt;/p>
&lt;p>它的基础是基于 &lt;a href="https://github.com/open-policy-agent/frameworks/tree/master/constraint">OPA Constraint Framework&lt;/a> 框架实现，主要包含以下概念：&lt;/p>
&lt;ol>
&lt;li>ConstraintTemplate：是 Gatekeeper 中的一个自定义资源，用于定义一组策略规则，每个模版包含了用于验证和强制执行策略的 Rego 代码和相应的参数模式。&lt;/li>
&lt;li>Constraint：是 ConstraintTemplate 的实例，用于具体应用策略，每个对象定义了将被验证的 Kubernetes 对象类型、相应的参数和用于验证的 Rego 代码，当然必须遵循 ConstraintTemplate 中定义的 crd 属性与规则。&lt;/li>
&lt;/ol>
&lt;p>其中 Constraint 也是以 crd 在 k8s 集群中体现，它是由 ConstraintTemplate 模版自动创建的。待 Gatekeeper 安装后默认存在 crd 列表如下：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>assign.mutations.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>assignimage.mutations.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>assignmetadata.mutations.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>configs.config.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>constraintpodstatuses.status.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>constrainttemplatepodstatuses.status.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>constrainttemplates.templates.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>expansiontemplate.expansion.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>expansiontemplatepodstatuses.status.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>modifyset.mutations.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mutatorpodstatuses.status.gatekeeper.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>providers.externaldata.gatekeeper.sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>其中来自于 OPA Constraint Framework 框架有 &amp;ldquo;expansiontemplate.expansion.gatekeeper.sh&amp;rdquo; 以及使用 &amp;ldquo;constraints.gatekeeper.sh&amp;rdquo; 后缀的 crd，如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>k8srequiredlabels.constraints.gatekeeper.sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="配置示例">配置示例&lt;/h2>
&lt;h3 id="constrainttemplate">ConstraintTemplate&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">templates.gatekeeper.sh/v1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">ConstraintTemplate&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">foosystemrequiredlabels&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># 自动创建 foosystemrequiredlabels.constraints.gatekeeper.sh 类型&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">crd&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">names&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">FooSystemRequiredLabels&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">validation&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># 这里的属性会添加到自动创建 crd 的 parameters 参数下&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">openAPIV3Schema&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">object&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">properties&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">labels&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">array&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">items&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">string&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">targets&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">target&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">admission.k8s.gatekeeper.sh&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">libs&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000;font-weight:bold">|&lt;/span>&lt;span style="color:#8f5902;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> package lib.helpers
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> make_message(missing) = msg {
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> msg := sprintf(&amp;#34;you must provide labels: %v&amp;#34;, [missing])
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> }&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">rego&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">|&lt;/span>&lt;span style="color:#8f5902;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> package foosystemrequiredlabels
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> import data.lib.helpers
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> violation[{&amp;#34;msg&amp;#34;: msg, &amp;#34;details&amp;#34;: {&amp;#34;missing_labels&amp;#34;: missing}}] {
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> provided := {label | input.request.object.metadata.labels[label]}
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> required := {label | label := input.parameters.labels[_]}
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> missing := required - provided
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> count(missing) &amp;gt; 0
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> msg := helpers.make_message(missing)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> }&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="constraint">Constraint&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">constraints.gatekeeper.sh/v1beta1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">K8sRequiredLabels&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">ns-must-have-gk&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">match&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">kinds&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">apiGroups&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">kinds&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;Namespace&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">parameters&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">labels&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;gatekeeper&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">enforcementAction&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;deny&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="rego-引用变量">Rego 引用变量&lt;/h2>
&lt;h3 id="请求评估的对象">请求评估的对象&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>input.review
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>对象存储正在评估的 Admission 请求，数据结构可参考 &lt;a href="https://pkg.go.dev/k8s.io/kubernetes/pkg/apis/admission#AdmissionRequest">AdmissionRequest&lt;/a>。&lt;/p>
&lt;h3 id="用户自定义属性">用户自定义属性&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>input.parameters
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>对象存储了用户在 &amp;ldquo;ConstraintTemplate&amp;rdquo; 中定义的属性，既 &amp;ldquo;crd.spec.validation.openAPIV3Schema.properties&amp;rdquo; 这配置的值。&lt;/p>
&lt;h2 id="数据结构">数据结构&lt;/h2>
&lt;h3 id="constrainttemplate-1">ConstraintTemplate&lt;/h3>
&lt;p>在代码仓库 &lt;code>github.com/open-policy-agent/frameworks&lt;/code> 中定义：&lt;/p>
&lt;blockquote>
&lt;p>&lt;a href="https://github.com/open-policy-agent/frameworks/blob/master/constraint/pkg/apis/templates/v1/constrainttemplate_types.go">https://github.com/open-policy-agent/frameworks/blob/master/constraint/pkg/apis/templates/v1/constrainttemplate_types.go&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-golang" data-lang="golang">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// ConstraintTemplate is the Schema for the constrainttemplates API
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// +k8s:openapi-gen=true
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// +k8s:conversion-gen-external-types=github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">ConstraintTemplate&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">metav1&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">TypeMeta&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;,inline&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">metav1&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ObjectMeta&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;metadata,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Spec&lt;/span> &lt;span style="color:#000">ConstraintTemplateSpec&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;spec,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Status&lt;/span> &lt;span style="color:#000">ConstraintTemplateStatus&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;status,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// ConstraintTemplateSpec defines the desired state of ConstraintTemplate.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">ConstraintTemplateSpec&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">CRD&lt;/span> &lt;span style="color:#000">CRD&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;crd,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Targets&lt;/span> &lt;span style="color:#000;font-weight:bold">[]&lt;/span>&lt;span style="color:#000">Target&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;targets,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">CRD&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Spec&lt;/span> &lt;span style="color:#000">CRDSpec&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;spec,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">CRDSpec&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Names&lt;/span> &lt;span style="color:#000">Names&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;names,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:default={legacySchema: false}
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">Validation&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">*&lt;/span>&lt;span style="color:#000">Validation&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;validation,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">Names&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Kind&lt;/span> &lt;span style="color:#204a87;font-weight:bold">string&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;kind,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">ShortNames&lt;/span> &lt;span style="color:#000;font-weight:bold">[]&lt;/span>&lt;span style="color:#204a87;font-weight:bold">string&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;shortNames,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">Validation&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:validation:Schemaless
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:validation:Type=object
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:pruning:PreserveUnknownFields
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +k8s:conversion-gen=false
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">OpenAPIV3Schema&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">*&lt;/span>&lt;span style="color:#000">apiextensionsv1&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">JSONSchemaProps&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;openAPIV3Schema,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:default=false
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">LegacySchema&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">*&lt;/span>&lt;span style="color:#204a87;font-weight:bold">bool&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;legacySchema,omitempty&amp;#34;`&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// *bool allows for &amp;#34;unset&amp;#34; state which we need to apply appropriate defaults
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">Target&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Target&lt;/span> &lt;span style="color:#204a87;font-weight:bold">string&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;target,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Rego&lt;/span> &lt;span style="color:#204a87;font-weight:bold">string&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;rego,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Libs&lt;/span> &lt;span style="color:#000;font-weight:bold">[]&lt;/span>&lt;span style="color:#204a87;font-weight:bold">string&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;libs,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// The source code options for the constraint template. &amp;#34;Rego&amp;#34; can only
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// be specified in one place (either here or in the &amp;#34;rego&amp;#34; field)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +listType=map
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +listMapKey=engine
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:validation:Required
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">Code&lt;/span> &lt;span style="color:#000;font-weight:bold">[]&lt;/span>&lt;span style="color:#000">Code&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;code,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">Code&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// The engine used to evaluate the code. Example: &amp;#34;Rego&amp;#34;. Required.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:validation:Required
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">Engine&lt;/span> &lt;span style="color:#204a87;font-weight:bold">string&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;engine&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:validation:Required
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:validation:Schemaless
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:pruning:PreserveUnknownFields
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// The source code for the template. Required.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">Source&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">*&lt;/span>&lt;span style="color:#000">templates&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Anything&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;source&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="constraint-1">Constraint&lt;/h3>
&lt;p>是定义在 &amp;ldquo;ConstraintTemplate&amp;rdquo; 中自动生成的 CRD，查看该集群存在多少可通过以下指令：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>kubectl get constraints
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>创建该资源 crd 的逻辑在 &lt;code>github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/crds.go&lt;/code> 中 &amp;ldquo;CreateCRD“ 根据 &amp;ldquo;ConstraintTemplate&amp;rdquo; 中的 &amp;ldquo;openAPIV3Schema&amp;rdquo; 定义并把参数添加到 &amp;ldquo;parameters&amp;rdquo; 里面，然后在集群在把对应的 &amp;ldquo;Constraint&amp;rdquo; CRD 创建出来，大致设计以下代码片段：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/schema.go -&amp;gt; CreateSchema -&amp;gt; apiextensions.JSONSchemaProps
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/crds.go -&amp;gt; CreateCRD -&amp;gt; apiextensions.CustomResourceDefinition
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apiextensions.JSONSchemaProps -&amp;gt; apiextensions.CustomResourceDefinition
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>每个 &amp;ldquo;Constraint&amp;rdquo; CRD 都存在以下三个参数，在 &lt;code>CreateSchema&lt;/code> 方法中定义：&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>参数&lt;/th>
&lt;th>类型&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>match&lt;/td>
&lt;td>target.MatchSchema()&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>enforcementAction&lt;/td>
&lt;td>string&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>parameters&lt;/td>
&lt;td>ConstraintTemplate.Spec.CRD.Spec.Validation.OpenAPIV3Schema&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&amp;ldquo;match&amp;rdquo; 字段定义了约束将被应用于哪些资源，它支持以下类型的匹配器：&lt;/p>
&lt;ol>
&lt;li>&amp;ldquo;kinds&amp;rdquo; 接受一个包含 apiGroups 和 kinds 字段的对象列表，列出了约束将应用于的对象的组或种类。如果指定了多个组或种类，则只需要一个匹配项，资源就会处于范围内。&lt;/li>
&lt;li>&amp;ldquo;scope&amp;rdquo; 确定是否匹配集群范围或命名空间范围的资源。接受 *, Cluster 或 Namespaced。（默认为 *）&lt;/li>
&lt;li>&amp;ldquo;namespaces&amp;rdquo; 是一个命名空间名称的列表。如果定义了，约束仅适用于列出的命名空间中的资源。Namespaces 还支持基于前缀的通配符。例如，namespaces: [kube-*] 匹配 kube-system 和 kube-public。&lt;/li>
&lt;li>&amp;ldquo;excludedNamespaces&amp;rdquo; 是一个命名空间名称的列表。如果定义了，约束仅适用于不在列出的命名空间中的资源。excludedNamespaces 也支持基于前缀的通配符。例如，excludedNamespaces: [kube-*] 匹配不在 kube-system 和 kube-public 中的资源。&lt;/li>
&lt;li>&amp;ldquo;labelSelector&amp;rdquo; 是两个可选字段的组合：matchLabels 和 matchExpressions。这两个字段提供了基于对象元数据中包含的标签键和值选择或排除 Kubernetes 对象的不同方法。所有选择表达式都会进行 AND 运算，以确定对象是否符合选择器的累积要求。&lt;/li>
&lt;li>&amp;ldquo;namespaceSelector&amp;rdquo; 是针对对象所在的命名空间或对象本身（如果对象是一个命名空间）的标签选择器。&lt;/li>
&lt;li>&amp;ldquo;name&amp;rdquo; 是 Kubernetes 对象的名称。如果定义了，它将与具有指定名称的对象匹配。Name 也支持基于前缀的通配符。例如，name: pod-* 匹配 pod-a 和 pod-b。&lt;/li>
&lt;/ol>
&lt;p>&amp;ldquo;enforcementAction&amp;rdquo; 字段定义了处理约束违规的操作，支持 [deny, dryrun, warn] 三个取值，默认情况下被设置为 deny，因为默认行为是拒绝任何违规的 Admission 请求。&lt;/p>
&lt;p>&amp;ldquo;parameters&amp;rdquo; 字段描述了约束的意图，它可以被 &amp;ldquo;ConstraintTemplate&amp;rdquo; 的 Rego 源代码中 &lt;code>input.parameters&lt;/code> 引用。&lt;/p>
&lt;ul>
&lt;li>CreateSchema&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/schema.go&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-golang" data-lang="golang">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// CreateSchema combines the schema of the match target and the ConstraintTemplate parameters
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// to form the schema of the actual constraint resource.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">func&lt;/span> &lt;span style="color:#000">CreateSchema&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">templ&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">*&lt;/span>&lt;span style="color:#000">templates&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ConstraintTemplate&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">target&lt;/span> &lt;span style="color:#000">MatchSchemaProvider&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">*&lt;/span>&lt;span style="color:#000">apiextensions&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">JSONSchemaProps&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">props&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">map&lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#204a87;font-weight:bold">string&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#000">apiextensions&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">JSONSchemaProps&lt;/span>&lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;match&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000">target&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">MatchSchema&lt;/span>&lt;span style="color:#000;font-weight:bold">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;enforcementAction&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>&lt;span style="color:#000">Type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#34;string&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">if&lt;/span> &lt;span style="color:#000">templ&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Spec&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">CRD&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Spec&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Validation&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">!=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">nil&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">&amp;amp;&amp;amp;&lt;/span> &lt;span style="color:#000">templ&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Spec&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">CRD&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Spec&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Validation&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">OpenAPIV3Schema&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">!=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">nil&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">internalSchema&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">*&lt;/span>&lt;span style="color:#000">templ&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Spec&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">CRD&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Spec&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Validation&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">OpenAPIV3Schema&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">DeepCopy&lt;/span>&lt;span style="color:#000;font-weight:bold">()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">props&lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;parameters&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span> &lt;span style="color:#000;font-weight:bold">=&lt;/span> &lt;span style="color:#000">internalSchema&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">schema&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">&amp;amp;&lt;/span>&lt;span style="color:#000">apiextensions&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">JSONSchemaProps&lt;/span>&lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#34;object&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Properties&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#204a87;font-weight:bold">map&lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#204a87;font-weight:bold">string&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#000">apiextensions&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">JSONSchemaProps&lt;/span>&lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;metadata&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#34;object&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Properties&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#204a87;font-weight:bold">map&lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#204a87;font-weight:bold">string&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#000">apiextensions&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">JSONSchemaProps&lt;/span>&lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;name&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#34;string&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">MaxLength&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000">pointer&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Int64&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">63&lt;/span>&lt;span style="color:#000;font-weight:bold">),&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;spec&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#34;object&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Properties&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000">props&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;status&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">XPreserveUnknownFields&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#000">pointer&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Bool&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#000;font-weight:bold">),&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#000">schema&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>target.MatchSchema&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>github.com/open-policy-agent/gatekeeper/pkg/mutation/match/match_types.go
github.com/open-policy-agent/gatekeeper/pkg/target/matchcrd_constant.go&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-golang" data-lang="golang">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// Match selects which objects are in scope.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:object:generate=true
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">Match&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// Source determines whether generated or original resources are matched.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// Accepts `Generated`|`Original`|`All` (defaults to `All`). A value of
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// `Generated` will only match generated resources, while `Original` will only
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// match regular resources.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:validation:Enum=All;Generated;Original
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">Source&lt;/span> &lt;span style="color:#204a87;font-weight:bold">string&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;source,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Kinds&lt;/span> &lt;span style="color:#000;font-weight:bold">[]&lt;/span>&lt;span style="color:#000">Kinds&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;kinds,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// Scope determines if cluster-scoped and/or namespaced-scoped resources
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// are matched. Accepts `*`, `Cluster`, or `Namespaced`. (defaults to `*`)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">Scope&lt;/span> &lt;span style="color:#000">apiextensionsv1&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ResourceScope&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;scope,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// Namespaces is a list of namespace names. If defined, a constraint only
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// applies to resources in a listed namespace. Namespaces also supports a
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// `kube-system` and `gatekeeper-system`.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">Namespaces&lt;/span> &lt;span style="color:#000;font-weight:bold">[]&lt;/span>&lt;span style="color:#000">wildcard&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Wildcard&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;namespaces,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// ExcludedNamespaces is a list of namespace names. If defined, a
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// constraint only applies to resources not in a listed namespace.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// ExcludedNamespaces also supports a prefix or suffix based glob. For example,
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// `excludedNamespaces: [kube-*]` matches both `kube-system` and
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// `gatekeeper-system`.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">ExcludedNamespaces&lt;/span> &lt;span style="color:#000;font-weight:bold">[]&lt;/span>&lt;span style="color:#000">wildcard&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Wildcard&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;excludedNamespaces,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// LabelSelector is the combination of two optional fields: `matchLabels`
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// and `matchExpressions`. These two fields provide different methods of
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// selecting or excluding k8s objects based on the label keys and values
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// included in object metadata. All selection expressions from both
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// sections are ANDed to determine if an object meets the cumulative
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// requirements of the selector.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">LabelSelector&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">*&lt;/span>&lt;span style="color:#000">metav1&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">LabelSelector&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;labelSelector,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// NamespaceSelector is a label selector against an object&amp;#39;s containing
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// namespace or the object itself, if the object is a namespace.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">NamespaceSelector&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">*&lt;/span>&lt;span style="color:#000">metav1&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">LabelSelector&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;namespaceSelector,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// Name is the name of an object. If defined, it will match against objects with the specified
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">Name&lt;/span> &lt;span style="color:#000">wildcard&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Wildcard&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;name,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// Kinds accepts a list of objects with apiGroups and kinds fields
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// that list the groups/kinds of objects to which the mutation will apply.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// If multiple groups/kinds objects are specified,
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// only one match is needed for the resource to be in scope.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// +kubebuilder:object:generate=true
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span> &lt;span style="color:#000">Kinds&lt;/span> &lt;span style="color:#204a87;font-weight:bold">struct&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// APIGroups is the API groups the resources belong to. &amp;#39;*&amp;#39; is all groups.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// If &amp;#39;*&amp;#39; is present, the length of the slice must be one.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// Required.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span> &lt;span style="color:#000">APIGroups&lt;/span> &lt;span style="color:#000;font-weight:bold">[]&lt;/span>&lt;span style="color:#204a87;font-weight:bold">string&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;apiGroups,omitempty&amp;#34; protobuf:&amp;#34;bytes,1,rep,name=apiGroups&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Kinds&lt;/span> &lt;span style="color:#000;font-weight:bold">[]&lt;/span>&lt;span style="color:#204a87;font-weight:bold">string&lt;/span> &lt;span style="color:#4e9a06">`json:&amp;#34;kinds,omitempty&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="apiextensionsv1jsonschemaprops">apiextensionsv1.JSONSchemaProps&lt;/h3>
&lt;p>TODO;&lt;/p>
&lt;h3 id="templatesanything">templates.Anything&lt;/h3>
&lt;p>TODO;&lt;/p></description></item></channel></rss>