Question

Je suis en train de créer un script qui ont besoin pour analyser la sortie de YAML que les sorties de marionnettes.

Quand je ne un exemple de agains demande https: // marionnettes: 8140 / production / catalogue / my.testserver.no Je vais récupérer une partie de YAML qui ressemble à quelque chose comme:

--- &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: 

et ainsi de suite ... Le problème est quand je fais un yaml.load (yamlstream), je vais faire une erreur comme:

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 ... 
       ^

Pour autant que je sache, ce ID001 et une partie est prise en charge en YAML.

Y at-il moyen de contourner cela? Puis-je dire l'analyseur YAML de les ignorer? Je ne ai besoin de quelques lignes du flux de YAML, est peut-être regex mon ami ici? Tout le monde fait des regexes de nettoyage de YAML avant?

Vous pouvez obtenir la sortie de YAML avec boucle comme:

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)

J'ai aussi trouvé quelques informations à ce sujet dans la marionnette @ liste de diffusion http: // www .mail-archive.com / marionnettes utilisateurs @ googlegroups.com / msg24143.html . Mais je ne peux pas le faire fonctionner correctement ...

Était-ce utile?

La solution

Je l'ai envoyé par courrier électronique Kirill Simonov, le créateur de PyYAML, pour obtenir de l'aide pour analyser le fichier de marionnettes YAML.

Il a aidé volontiers avec le code suivant. Ce code est pour l'analyse syntaxique journal de marionnettes, mais je suis sûr que vous pouvez le modifier pour analyser un autre fichier de marionnettes YAML.

L'idée est de créer le chargeur correct pour l'objet Ruby, PyYAML peut alors lire les données après.

Ici va:

#!/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

Autres conseils

Je crois que le nœud de la question est le fait que la marionnette utilise YAML « tags » pour Ruby-fu, et que le chargeur est déroutant de python par défaut. En particulier, PyYAML n'a aucune idée de la façon de construire un rubis / objet: Marionnettes :: ressources :: Catalogue, ce qui est logique, puisque c'est un objet rubis

.

Voici un lien montrant des différentes utilisations des balises YAML: http: // www .yaml.org / spec / 1.2 / spec.html # id2761292

J'ai eu passé cela dans une approche force brute simplement faire quelque chose comme:

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

mais maintenant je suis coincé sur une question où le bloc * resource_table * est source de confusion PyYAML avec ses clés complexes (l'utilisation de « ? » Pour indiquer le début d'une clé complexe, en particulier).

Si vous trouvez une belle façon autour de cela, s'il vous plaît laissez-moi savoir ... mais étant donné la façon liée à la marionnette de la hanche est de rubis, il peut être plus facile de vous faire directement le script en Ruby.

Je ne avais besoin de la section des classes. Donc, j'ai fini par créer cette petite fonction python pour dépouiller dehors ...

L'espoir pour quelqu'un de son UTILE:)

#!/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())

simple analyseur 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top