You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:53:17