【问题标题】:Parse a puppet manifest with Python使用 Python 解析人偶清单
【发布时间】:2017-05-09 06:36:46
【问题描述】:

我有一个 puppet 清单文件 - 我的 puppet 模块的 init.pp 在这个文件中,有类的参数,在大多数情况下,它们的编写方式相同:

输入示例:

class test_module(
    $first_param = 'test',
    $second_param = 'new' )

我可以用 Python 解析这个文件并获得像这样的 dict 对象,其中包含所有类参数的最佳方法是什么?

示例输出:

param_dict = {'first_param':'test', 'second_param':'new'}

在此先感谢 :)

【问题讨论】:

    标签: python string file puppet


    【解决方案1】:

    Puppet Strings 是一个 ruby​​gem,可以安装在 Puppet 之上,并且可以输出包含类参数列表、文档等的 JSON 文档。

    安装后(参见上面的链接),在 shell 或 Python 程序中运行此命令以生成 JSON:

    puppet strings generate --emit-json-stdout init.pp
    

    这将生成:

    {
      "puppet_classes": [
        {
          "name": "test_module",
          "file": "init.pp",
          "line": 1,
          "docstring": {
            "text": "",
            "tags": [
              {
                "tag_name": "param",
                "text": "",
                "types": [
                  "Any"
                ],
                "name": "first_param"
              },
              {
                "tag_name": "param",
                "text": "",
                "types": [
                  "Any"
                ],
                "name": "second_param"
              }
            ]
          },
          "defaults": {
            "first_param": "'test'",
            "second_param": "'new'"
          },
          "source": "class test_module(\n    $first_param = 'test',\n    $second_param = 'new' ) {\n}"
        }
      ]
    }
    

    (为简洁起见,略微修剪了 JSON)

    您可以使用json.loads 在 Python 中加载 JSON,并从 root["puppet_classes"]["docstring"]["tags"](其中 tag_nameparam)中提取参数名称以及从 root["puppet_classes"]["defaults"] 中提取任何默认值。

    【讨论】:

      【解决方案2】:

      你可以使用正则表达式(简单但脆弱)

      import re
      def parse(data):
          mm = re.search('\((.*?)\)', data,re.MULTILINE)
          dd = {}
          if not mm:
              return dd
          matches = re.finditer("\s*\$(.*?)\s*=\s*'(.*?)'", mm.group(1), re.MULTILINE)
          for mm in matches:
              dd[mm.group(1)] = mm.group(2)
          return dd
      

      您可以按如下方式使用它:

      import codecs
      with codecs.open(filename,'r') as ff:
           dd = parse(ff.read())
      

      【讨论】:

      • 唯一的问题是,正则表达式还将捕获所有其他变量,并在赋值运算符之间假设一个空格(这对于 99% 的情况是正确的,但仍然如此)。否则,这很好用。
      • 嗯,这是脆弱的部分:-)
      • 别忘了忽略 cmets(以 # 开头的行)
      • 其实我试过了,还是不行。你能解释一下如何使用 re 或者你尝试做什么?
      • 您应该阅读文件的内容并为其提供功能。基本上,我们首先搜索 '(' 和 ')',然后在其中搜索 $var = 'value'
      【解决方案3】:

      我不知道“最佳”方式,但一种方式是:

      1) 设置 Rspec-puppet(请参阅 google 或 my blog post 了解如何执行此操作)。 2) 编译代码并生成 Puppet 目录。请参阅my other blog 帖子。

      现在,您编译的 Puppet 目录是一个 JSON 文档。

      3) 目视检查 JSON 文档以找到您要查找的数据。它在 JSON 文档中的准确位置取决于您使用的 Puppet 版本。

      4) 您现在可以使用 Python 从 JSON 文档中提取数据作为字典。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-17
        • 2017-03-12
        • 1970-01-01
        • 2014-12-17
        • 1970-01-01
        • 1970-01-01
        • 2014-03-03
        • 2021-11-15
        相关资源
        最近更新 更多