Jinja2渲染Virtual Service YAML失败,报UndefinedError错误求助
Jinja2渲染Virtual Service YAML文件失败,报UndefinedError错误
在使用Jinja2模板渲染Virtual Service YAML文件时无法正常完成渲染,报错提示jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'destination',相关代码及配置如下:
Jinja2模板内容
serviceRoutes: gateways: {% for gateway in gateways %} - {{ gateway }} {% endfor %} hosts: {% for host in hosts %} - {{ host }} {% endfor %} http: {% for item in http %} - match: - uri: prefix: {{ item.match.prefix }} {% if item.get('rewrite') %} rewrite: uri: {{ item.rewrite.uri }} {% endif %} route: - destination: host: "{{ item['destination']['host'] }}" port: number: {{ item['destination']['port']['number'] }} weight: {{ item['weight'] }} {% endfor %}
对应的YAML值文件
serviceRoutes: - sr: name: sr1 gateways: - mesh - "test.usnabk.com" hosts: - "1.one.bank-dns.com" - "tes.one.bank-dns.com" http: - match: prefix: "base_path" route: - destination: host: "one.bank-dns.com" port: number: 8080 weight: 100 - match: prefix: "base_path" rewrite: uri: "base_path" route: - destination: host: "one.bank-dns.com" port: number: 8080 weight: 100
使用的Python脚本
import yaml from jinja2 import Environment, FileSystemLoader import os if __name__ == "__main__": # Load values from YAML file with open('./test.yaml', 'r') as f: values = yaml.safe_load(f) # Load Jinja environment env = Environment(loader=FileSystemLoader('./template'), trim_blocks=True, lstrip_blocks=True) template = env.get_template('template.j2') # Iterate over each service route for service in values["serviceRoutes"]: # Render the template for each service route rendered = template.render(service) # Write the rendered content to a YAML file with open("abc.yaml", "w") as output_file: output_file.write(rendered)
错误信息
jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'destination'
问题原因及修复方案
错误根源是模板中对字段的路径访问错误:YAML值文件里,http数组的每个元素中,destination和weight是嵌套在route数组的子元素里的,但模板直接从item根节点获取这些字段,导致Jinja无法找到对应属性。
修改模板中的http循环部分,调整字段访问路径即可解决:
修复后的模板片段
http: {% for item in http %} - match: - uri: prefix: {{ item.match.prefix }} {% if item.get('rewrite') %} rewrite: uri: {{ item.rewrite.uri }} {% endif %} route: {% for route_item in item.route %} - destination: host: "{{ route_item['destination']['host'] }}" port: number: {{ route_item['destination']['port']['number'] }} weight: {{ route_item['weight'] }} {% endfor %} {% endfor %}
如果确定每个item.route只会有一个元素,也可以简化为直接访问索引:
http: {% for item in http %} - match: - uri: prefix: {{ item.match.prefix }} {% if item.get('rewrite') %} rewrite: uri: {{ item.rewrite.uri }} {% endif %} route: - destination: host: "{{ item.route[0]['destination']['host'] }}" port: number: {{ item.route[0]['destination']['port']['number'] }} weight: {{ item.route[0]['weight'] }} {% endfor %}
内容的提问来源于stack exchange,提问作者Rajendar T
相关产品推荐
相关产品推荐

