14

パペットが出力する 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: 

など...問題は、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 ... 
       ^

私の知る限り、この &id001 部分は yaml でサポートされています。

これを回避する方法はありますか?yaml パーサーにそれらを無視するように指示できますか? yaml ストリームからの数行だけが必要ですが、ここでは正規表現が私の友達でしょうか? 以前にyamlのクリーンアップ正規表現を行った人はいますか?

次のように curl を使用して yaml 出力を取得できます。

curl --cert /var/lib/puppet/ssl/certs/$(hostname).pem --key /var/lib/puppet/ssl/private_keys/$(hostname).pem --cacert /var/lib/puppet/ssl/certs/ca.pem -H 'Accept: yaml' https://puppet:8140/production/catalog/$(hostname)

puppet メーリングリスト @ http://www.mail-archive.com/puppet-users@googlegroups.com/msg24143.htmlでこれに関する情報も見つけました。しかし、私はそれを正しく動作させることができません...

4

4 に答える 4

24

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
于 2012-03-16T01:48:29.347 に答える
1

問題の核心は、puppetがruby-fuにyaml「タグ」を使用しているという事実であり、それがデフォルトのpythonローダーを混乱させていると思います。特に、PyYAMLはruby / object:Puppet :: Resource :: Catalogを構築する方法を知りません。これは、rubyオブジェクトであるため意味があります。

yamlタグのさまざまな使用法を示すリンクは次のとおりです: http ://www.yaml.org/spec/1.2/spec.html#id2761292

私は、次のようなことを行うだけで、ブルートフォースアプローチでこれを乗り越えました。

cat the_yaml | sed 's#\!ruby/object.*$##gm' > cleaner.yaml

しかし今、私は* resource_table *ブロックがPyYAMLをその複雑なキーと混同しているという問題に悩まされています(具体的には、複雑なキーの開始を示すために「?」を使用します)。

それを回避する良い方法を見つけたら、私に知らせてください...しかし、ヒップパペットがルビーにどれほど結びついているかを考えると、ルビーで直接スクリプトを作成する方が簡単かもしれません。

于 2011-12-02T19:46:20.957 に答える
1

クラスセクションだけが必要でした。だから私はそれを取り除くためにこの小さなpython関数を作成することになりました...

誰かに役立つことを願っています:)

#!/usr/bin/env python

import re

def getSingleYamlClass(className, yamlList):
    printGroup = False
    groupIndent = 0
    firstInGroup = False
    output = ''

    for line in yamlList:
        # Count how many spaces in the beginning of our line
        spaceCount = len(re.findall(r'^[ ]*', line)[0])
        cleanLine = line.strip()

        if cleanLine == className:
            printGroup = True
            groupIndent = spaceCount
            firstInGroup = True

        if printGroup and (spaceCount > groupIndent) or firstInGroup:
            # Strip away the X amount of spaces for this group, so we get valid yaml
            output += re.sub(r'^[ ]{%s}' % groupIndent, '', line) + '\n'
            firstInGroup = False # Reset this
        else:
            # End of our group, reset
            groupIndent = 0
            printGroup = False

    return output

getSingleYamlClass('classes:', open('puppet.yaml').readlines())
于 2011-12-05T15:04:39.887 に答える