使用走走以rego递归聚合处于地形状态的资源

如何解决使用走走以rego递归聚合处于地形状态的资源

我正在使用Open Policy Agent针对我的Terraform状态的JSON输出编写策略。

这是状态文件的结构:

wrapRootElement

我定义了这个讨厌的规则来实现我想要的,但是显然这不是聚集这些资源的理想方法。

{
  "format_version": "0.1","terraform_version": "0.12.28","values": {
    "root_module": {
      "resources": [],"child_modules": [
        {
          "resources": [],"address": "","child_modules": [
            {
              "resources": [],"child_modules": [
                {}
              ]
            }
          ]
        }
      ]
    }
  }
}

我已经阅读了内置函数resources[resource_type] = all { some resource_type resource_types[resource_type] rm := tfstate.values.root_module # I think the below can be simplified with the built in "walk" function TODO: do that. root_resources := [name | name := rm.resources[_] name.type == resource_type ] cmone_resources = [name | name := rm.child_modules[_].resources[_] name.type == resource_type ] cmtwo_resources = [name | name := rm.child_modules[_].child_modules[_].resources[_] name.type == resource_type ] cm := array.concat(cmone_resources,cmtwo_resources) all := array.concat(cm,root_resources) } 的文档。文档here。我相信此功能可以实现我想要的功能,但是根据我在其他地方提供的文档以及稀疏的示例,我无法弄清楚如何使其按预期运行。

我包括了一个非常基本的设置和我定义的当前规则的playground。任何帮助将不胜感激。

解决方法

您处在正确的轨道上,使用walk绝对是收集任意嵌套的子资源的好方法。

首先,我们将探索步行的功能。它实际上将遍历我们要遍历的对象中的所有节点,并为每个节点提供“路径”和当前节点值。路径将是一个键数组,就像对象:

{"a": {"b": {"c": 123}}}

如果我们走过去(以下示例,使用opa run REPL:

> [path,value] = walk({"a": {"b": {"c": 123}}})
+---------------+-----------------------+
|     path      |         value         |
+---------------+-----------------------+
| []            | {"a":{"b":{"c":123}}} |
| ["a"]         | {"b":{"c":123}}       |
| ["a","b"]     | {"c":123}             |
| ["a","b","c"] | 123                   |
+---------------+-----------------------+

我们看到pathvalue的值具有每种路径和值的组合。您可以在部分规则(例如resources规则)或理解中进行迭代时捕获任何这些值。

所以..把它交给了terraform的东西。如果我们修改操场示例以遍历示例输入(对示例输入进行了稍微修改以赋予事物一些唯一的名称),则会得到:

walk_example[path] = value {
    [path,value] := walk(tfstate)
}

https://play.openpolicyagent.org/p/2u5shGbrV2

如果查看walk_example的结果值,我们会看到我们期望必须处理的所有路径和值。

从那里开始,就需要对resources进行过滤(类似于您在resource_types规则中所做的操作)。与其对集合进行迭代,我们将使用它作为查询来检查每个确定的类型,然后我们将首先构建完整的 all 资源集(不按类型对它们进行分组)。原因是遍历输入json的所有节点非常昂贵,因此我们只想执行一次。随后,我们可以通过第二遍按类型分组(根据需要)来更快地遍历每个资源的完整列表。

更新后的版本如下:

walk_resources[resource] {  
    [path,value] := walk(tfstate)

    # Attempt to iterate over "resources" of the value,if the key doesn't
    # exist its OK,this iteration for walk will be undefined,and excluded
    # from the results.
    # Note: If you needed to be sure it was a "real" resource,and not some
    # key you can perform additional validation on the path here!
    resource := value.resources[_]
    
    # check if the resource type was contained in the set of desired resource types
    resource_types[resource.type]
}

https://play.openpolicyagent.org/p/TyqMKDyWyh

^游乐场输入已更新,以在示例中包括另一级嵌套和类型。您可以看到原始的resources输出缺少该深度3资源,但是walk_resources集包含了所有预期的资源。

最后一部分,如果您想按类型对它们进行分组,请添加完整的规则,例如:

# list of all resources of a given type. given type must be defined in the resource_types variable above
resources = { resource_type: resources |
    some resource_type
    resource_types[resource_type]
    resources := { resource | 
        walk_resources[resource]
        resource.type == resource_type
    }
}

https://play.openpolicyagent.org/p/RlRZwibij9

使用一种理解来替换原始的resources规则,该规则将遍历每种资源类型,然后收集与该类型匹配的资源。

我在这些terraform资源帮助程序规则中发现了一个额外的指针,那就是您将要引用该“完全”规则,有关其含义的详细信息,请参见https://www.openpolicyagent.org/docs/latest/policy-language/#complete-definitions比“部分”规则(在这种情况下,是建立一组资源而不是将值分配给理解结果的规则)。问题在于,在编写本文时,OPA将在内部缓存“完整”规则的值,而部分规则则不会。因此,如果您去编写一堆规则,例如:

deny[msg] {
    r := resources["foo"]
    # enforce something for resources of type "foo"...
    ...
}

deny[msg] {
    r := resources["bar"]
    # enforce something for resources of type "bar"...
    ...
}

您要确保它每次都使用resources的缓存值,并且不重新计算集合。您的resources规则的原始版本以及使用我在这些示例中显示的walk_resources规则都会遇到该问题。需要注意的是,如果您输入的tfplan很大,它可能会对性能产生极大的影响。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-