【问题标题】:Is it possible to use a Jinja2 template to reverse engineer the parameters from a document?是否可以使用 Jinja2 模板对文档中的参数进行逆向工程?
【发布时间】:2016-10-15 06:38:33
【问题描述】:

Jinja2 的一般工作流程是 params + Jinja2 模板 = 生成的文档

from jinja2 import Template
t = Template("Hello {{ something }}!")
t.render(something="World")
>>> u'Hello World!'

是否可以使用 Jinja2 模板对文档中的参数进行逆向工程?换句话说,我正在寻找以下内容:Jinja2 模板 + 生成的文档 = 参数

from jinja2 import Template
t = Template("Hello {{ something }}!")
t.reverse("Hello World!")
>>> {"something" : "World"}

json 输出不是必需的,但它会很方便。

如果不是这样创建逻辑的好方法是什么?

上下文: 我使用 Jinja2 生成 Cisco Switch 配置文件,能够提取过去生成的文档将是一个不错的功能,我不想显示超过 1000 行的配置脚本,而只想列出参数。我知道可以通过将所有参数存储在一个简单的数据库中来解决它,但目前我没有设置数据库,如果可能的话我会避免它。

【问题讨论】:

  • 查看thisthis 线程。这是您要搜索的内容吗?
  • @vrs 感谢您的快速回复,我已经看过这些帖子了。我已经用一些示例编辑了我的问题,这可能有助于理解我的具体案例。
  • 我认为这通常是不可能的。你的用例是什么?
  • 模板上的diff 和呈现的模板将显示替换。
  • 我使用 Jinja2 生成 Cisco Switch 配置文件,能够提取过去生成的文档将是一个不错的功能,而不是显示 1000 多行配置脚本,我会喜欢只列出参数。我知道可以通过将所有参数存储在一个简单的数据库中来解决它,但目前我没有设置数据库,我会避免它。

标签: python jinja2


【解决方案1】:

这可行,但不能提供所有信息

import textfsm
import tempfile
import re
import pprint

j2template = open(<template_file_path>)

find_txt = '(\{\{.+?\}\})'
all_variables = re.findall(find_txt, j2template.read())
variable_set = set()

for variable in all_variables:
    variable_set.add( variable )

value_block_txt = ''
for value in variable_set:
    value = value.replace('.', '')
    value_block_txt += "Value List {val_text} (\S+)\n".format(val_text = value.strip('{}\ '))

fsm_regex_block = '''
Start
'''
j2template = open(<filepath>)
for line in j2template.readlines():
    replace_list = [var for var in variable_set if(var in line)]
    if len(replace_list) > 0: 
        for string in replace_list:
                line = line.replace(string, "${"+string.replace('.', '').strip('{}. ')+"}") 
        line = "  ^"+line
        fsm_regex_block += line

textfsm_template = value_block_txt
textfsm_template += fsm_regex_block

f = open(<temp_file_path>, 'w+')
f.write(textfsm_template)
f.close()

fsm = textfsm.TextFSM(open(<temp_file_path>))
original_variables_list_of_lists = fsm.ParseText(jinja_device_config_output)

print(original_variables_list_of_lists)

os.unlink(f)
Outputs a list of lists like: [[['1', '1', '1'], ['12'], ['abcd.1234.0000'], ['1', '1', '12'], ['CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V', 'CGNLTEST123V'], ['fe81:::::/127']]]

然后我将删除每个变量的输入参数列表以获取 og 值。

【讨论】:

    【解决方案2】:

    这可行,但它只是提取所有参数。它没有给你顺序,或者它们是如何相关的:

    import textfsm
    import tempfile
    import re
    import pprint
    
    j2template = open(<template_file_path>)
    
    find_txt = '(\{\{.+?\}\})'
    all_variables = re.findall(find_txt, j2template.read())
    variable_set = set()
    
    for variable in all_variables:
        variable_set.add( variable )
        
    value_block_txt = ''
    for value in variable_set:
        value = value.replace('.', '')
        value_block_txt += "Value List {val_text} (\S+)\n".format(val_text = value.strip('{}\ '))
    
    fsm_regex_block = '''
    Start
    '''
    j2template = open(<filepath>)
    for line in j2template.readlines():
        replace_list = [var for var in variable_set if(var in line)]
        if len(replace_list) > 0: 
            for string in replace_list:
                    line = line.replace(string, "${"+string.replace('.', '').strip('{}. ')+"}") 
            line = "  ^"+line
            fsm_regex_block += line
            
    textfsm_template = value_block_txt
    textfsm_template += fsm_regex_block
    
    f = open(<temp_file_path>, 'w+')
    f.write(textfsm_template)
    f.close()
    
    fsm = textfsm.TextFSM(open(<temp_file_path>))
    original_variables_list_of_lists = fsm.ParseText(jinja_device_config_output)
    
    print(original_variables_list_of_lists)
    
    os.unlink(f)
    

    输出一个列表,如:

    [
        [
            ['1', '1', '1'],
            ['12'],
            ['abcd.1234.0000'],
            ['1', '1', '12'],
            [
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V', 
                'CGNLTEST123V'
                ],
            [
                'fe81:::::/127'
            ]
        ]
    ]
    

    然后您可以对每个变量的输入参数列表进行重复数据删除以获得原始值。

    【讨论】:

      【解决方案3】:

      这个开源项目似乎提供了所需的功能: https://github.com/yvdlima/pytemplate-reverse

      使用示例:

      from template_reverse import ReverseTemplate
      
      segments = [
          "shrek3_0_600.avi",
          "shrek3_1_560.avi",
          "shrek3_2_780.avi"
      ]
      rt = ReverseTemplate("{video_name}_{segment_id}_{segment_duration_in_secs}.avi")
      
      total_duration = 0
      
      for segment in segments:
          values = rt.reverse(segment)
          print("Checking out movie", values["video_name"], "part ", values["segment_id"])
          total_duration += int(values["segment_duration_in_secs"])
      
      print("Total video duration so far", total_duration)
      

      【讨论】:

        猜你喜欢
        • 2010-10-23
        • 1970-01-01
        • 1970-01-01
        • 2016-09-28
        • 2021-09-11
        • 1970-01-01
        • 2013-06-28
        • 1970-01-01
        • 2014-06-06
        相关资源
        最近更新 更多