用python解析puppet api yaml

用python解析puppet api yaml,python,yaml,puppet,Python,Yaml,Puppet,我正在创建一个脚本,它需要解析木偶输出的yaml输出 当我对一个示例执行请求时https://puppet:8140/production/catalog/my.testserver.no 我会取回一些yaml,看起来像: --- &id001 !ruby/object:Puppet::Resource::Catalog aliases: {} applying: false classes: - s_baseconfig ... edges:

我正在创建一个脚本,它需要解析木偶输出的yaml输出

当我对一个示例执行请求时https://puppet:8140/production/catalog/my.testserver.no 我会取回一些yaml,看起来像:

--- &id001 !ruby/object:Puppet::Resource::Catalog
  aliases: {}
  applying: false
  classes: 
    - s_baseconfig
    ...
  edges: 
    - &id111 !ruby/object:Puppet::Relationship
      source: &id047 !ruby/object:Puppet::Resource
        catalog: *id001
        exported: 
cat the_yaml | sed 's#\!ruby/object.*$##gm' > cleaner.yaml
等等。。。问题是,当我执行yaml.load(yamlstream)时,会出现如下错误:

yaml.constructor.ConstructorError: could not determine a constructor for the tag '!ruby/object:Puppet::Resource::Catalog'
 in "<string>", line 1, column 5:
   --- &id001 !ruby/object:Puppet::Reso ... 
       ^

我在puppet mailinglist@中也找到了一些相关信息。但是我不能让它正常工作…

我相信问题的关键是puppet在ruby fu中使用yaml“标记”,这让默认的python加载程序很混乱。尤其是,PyYAML不知道如何构造ruby/object:Puppet::Resource::Catalog,这很有意义,因为这是一个ruby对象

下面的链接显示了yaml标记的一些不同用途:

我已经用蛮力的方法克服了这一问题,只需做如下事情:

--- &id001 !ruby/object:Puppet::Resource::Catalog
  aliases: {}
  applying: false
  classes: 
    - s_baseconfig
    ...
  edges: 
    - &id111 !ruby/object:Puppet::Relationship
      source: &id047 !ruby/object:Puppet::Resource
        catalog: *id001
        exported: 
cat the_yaml | sed 's#\!ruby/object.*$##gm' > cleaner.yaml
但现在我陷入了一个问题,*resource_table*块将PyYAML与其复杂键混淆(特别是使用“?”表示复杂键的开始)


如果你能找到一个好办法,请让我知道。。。但是考虑到hip puppet与ruby的关系,直接用ruby编写脚本可能更容易。

我只需要类部分。所以我最终创建了这个小python函数来去掉它

希望对某人有用:)


我已经给PyYAML的创建者Kirill Simonov发了电子邮件,请求帮助解析Puppet YAML文件

他很乐意帮助编写以下代码。这段代码用于解析Puppet日志,但我相信您可以修改它来解析其他Puppet YAML文件

其思想是为Ruby对象创建正确的加载程序,然后PyYAML可以读取之后的数据

下面是:

#!/usr/bin/env python

import yaml

def construct_ruby_object(loader, suffix, node):
    return loader.construct_yaml_map(node)

def construct_ruby_sym(loader, node):
    return loader.construct_yaml_str(node)

yaml.add_multi_constructor(u"!ruby/object:", construct_ruby_object)
yaml.add_constructor(u"!ruby/sym", construct_ruby_sym)


stream = file('201203130939.yaml','r')
mydata = yaml.load(stream)
print mydata
简单YAML解析器:

with open("file","r") as file:
    for line in file:
        re= yaml.load('\n'.join(line.split('?')[1:-1]).replace('?','\n').replace('""','\'').replace('"','\''))
        # print '\n'.join(line.split('?')[1:-1])
        # print '\n'.join(line.split('?')[1:-1]).replace('?','\n').replace('""','\'').replace('"','\'')
        print line
        print re

谢谢你的信息。我将在星期一试一试。因为我实际上需要的信息不多,所以我可能可以去掉很多。。Ruby不是选项,抱歉..=)如果我发现一些聪明的东西,我会对这个问题进行评论。我还没有机会尝试,但它看起来很有希望,我认为这正是我需要的。我将尝试将当前代码更改为类似这样的代码,而不是删除不可解析的yaml代码。谢谢