1

我正在尝试为 icinga2 实例编写一个包装器。配置文件中的对象如下所示;

object object_type "object_name" {
  some_property = "some_value"
}

例子;

object Host "server1" {
  import "generic-host"
  address = "192.168.0.1"
  vars.os = "Linux"
}

object Host "server2" {
  import "generic-host"
  address = "192.168.0.2"
  vars.os = "Linux"
}

我想做类似的事情:

icinga = icinga("/etc/icinga2/conf.d/hosts.conf")

print icinga.hosts_list()

icinga.hosts_add("server3","192.168.0.3")
icinga.hosts_remove("server1")

所以我尝试使用pynag,比如;

nc = Config('/etc/icinga2/conf.d/hosts.conf')
nc.parse()
print nc.get_host('server1')

但我得到了;

File "./icinga.py", line 51, in <module>
    print nc.get_host('server1')
  File "/Library/Python/2.7/site-packages/pynag/Parsers/__init__.py", line 1259, in get_host
    return self.get_object('host', object_name, user_key=user_key)
  File "/Library/Python/2.7/site-packages/pynag/Parsers/__init__.py", line 1238, in get_object
    for item in self.data['all_%s' % object_type]:
KeyError: 'all_host'

有没有一种简单的方法来处理这种形式?

4

3 回答 3

3

使用 pyparsing,处理这样的结构化文本格式并不难。

下面是解析器的样子:

from pyparsing import (Suppress, Keyword, Word, alphas, alphanums, Combine, 
    OneOrMore, quotedString, removeQuotes, Group, ZeroOrMore)

LBRACE,RBRACE,EQ = map(Suppress, "{}=")

OBJECT = Keyword("object")
IMPORT = Keyword("import")

ident = Word(alphas, alphanums)
dottedIdent = Combine(ident + OneOrMore("." + ident))

quotedString.setParseAction(removeQuotes)

propertyDefn = Group((dottedIdent | ident)("name") + EQ + quotedString("value"))

importDirective = Group(IMPORT + quotedString('source'))

objectBodyDefn = Group(ZeroOrMore(propertyDefn("properties*") | 
                                  importDirective("imports*")))

objectDefn = Group(OBJECT + ident("type") + quotedString("name") +
                    LBRACE + objectBodyDefn("body") + RBRACE)

parser = ZeroOrMore(objectDefn)

以下是应用解析器和访问解析数据的方法:

# parsing the sample, and accessing the parsed data fields
for obj in parser.parseString(sample):
    print(obj.dump())
    print("%(name)s (%(type)s)" % obj)
    print("imports:", ','.join(imp.source for imp in obj.body.imports))
    print("properties:")
    if obj.body.properties:
        for prop in obj.body.properties:
            print('-', prop.name, ':', prop.value)
    else:
        print(' ','<none>')
    print()

有了这个输出:

['object', 'Host', 'server1', [['import', 'generic-host'], ['address', '192.168.0.1'], ['vars.os', 'Linux']]]
- body: [['import', 'generic-host'], ['address', '192.168.0.1'], ['vars.os', 'Linux']]
  - imports: 
    [0]:
      ['import', 'generic-host']
      - source: generic-host
  - properties: 
    [0]:
      ['address', '192.168.0.1']
      - name: address
      - value: 192.168.0.1
    [1]:
      ['vars.os', 'Linux']
      - name: vars.os
      - value: Linux
- name: server1
- type: Host
server1 (Host)
imports: generic-host
properties:
- address : 192.168.0.1
- vars.os : Linux

['object', 'Host', 'server2', [['import', 'generic-host'], ['address', '192.168.0.2'], ['vars.os', 'Linux']]]
- body: [['import', 'generic-host'], ['address', '192.168.0.2'], ['vars.os', 'Linux']]
  - imports: 
    [0]:
      ['import', 'generic-host']
      - source: generic-host
  - properties: 
    [0]:
      ['address', '192.168.0.2']
      - name: address
      - value: 192.168.0.2
    [1]:
      ['vars.os', 'Linux']
      - name: vars.os
      - value: Linux
- name: server2
- type: Host
server2 (Host)
imports: generic-host
properties:
- address : 192.168.0.2
- vars.os : Linux
于 2015-06-01T00:32:10.127 回答
0

我像这样使用snipplet:

icinga_conf+='object Host "%s" {\n\timport "generic-LinuxHost"\n\t' \
                         'address = "%s"\n\t' \
                         'vars.http_vhost="%s"\n\t' \
                         '%s' \
                         '\n\t}' \
                         '\n\n' % (icinga_name,ip,name,backupvars)
于 2015-08-11T14:29:24.933 回答
0

我使用主机 conf 文件创建一个字典,如下所示:

import re
with open('hosts.conf', 'r') as f:
    lines = f.readlines()
    host=dict()
    add_attributes = False
    p= re.compile('obj[]\w\s]+"(.+)"')
    for line in lines:
        if '}' in line:
            add_attributes = False
        if  add_attributes and '=' in line:
            host[name][line.split('=')[0]]=line.split('=')[1]
        if p.search(line):
            name=p.search(line).group(1)
            add_attributes = True
            host[name]=dict()

然后,我有一个易于解析的字典。

于 2016-05-25T09:34:54.743 回答