Jinja模板列表和dict解析

时间:2017-05-25 19:03:08

标签: jinja2 haproxy salt salt-stack

我正在尝试使用此模板来创建HAProxy配置文件。它几乎就在那里,但我似乎无法正确地获取这里的列表。我想保存密钥并将其添加到项目列表中,例如:

此:

acl:
  - host_static hdr_beg(host) -i static
  - url_static path_beg static

应该是:

acl host_static hdr_beg(host) -i static
acl url_static path_beg static

这将是任何具有其值列表的dict键。

结转是因为可能存在多个前端和后端,而这些将是前端下的一个字典。

我能够更新它,可能是更好的方法,但似乎工作正常:

编辑(更新的工作代码)

{%- set key = 0 -%}
{%- set value = 1 -%}
{%- set carryovers = ['frontend', 'backend','listen'] -%}
{%- macro haproxy_config(data, carryover='', listkey='', recurse=-1, indent=0) -%}
  {%- set recurse = recurse + 1 -%}
  {%- if data is none -%}
    {{- '\n' -}}
  {%- elif data is string or data is number -%}
    {{- '%s %s'|format(listkey,data)|string|indent(indent, True) }}{{ '\n' -}}
  {%- else -%}
    {%- if recurse > 0 -%}
      {{- '\n' -}}
      {%- set indent = indent + 2 -%}
    {%- endif -%}
    {%- if data is mapping -%}
      {%- for item in data|dictsort -%}
        {%- if item[key] in carryovers -%}
          {{- haproxy_config(item[value], carryover=item[key], indent=indent) -}}
        {%- else -%}
          {%- set carryIndent = indent -%}
          {%- set forwardIndent = indent -%}
          {%- if carryover -%}
            {{- carryover|indent(indent, True) }}{{ ' ' -}}
            {%- set carryIndent = 0 -%}
          {%- endif -%}
          {%- if item[value] is string or item[value] is not iterable -%}
            {%- set forwardIndent = 0 -%}
          {%- endif -%}
          {%- if item[value] is not string and item[value] is iterable and item[value] is not mapping -%}
            {%- set forwardIndent = 0 -%}
            {{ haproxy_config(item[value], listkey=item[key], recurse=recurse, indent=forwardIndent) -}}
          {%- else -%}
            {{- item[key]|indent(carryIndent, True) }} {{ haproxy_config(item[value], recurse=recurse, indent=forwardIndent) -}}
          {%- endif -%}
        {%- endif -%}
      {%- endfor -%}
    {%- else -%}
      {%- for item in data -%}
        {{- haproxy_config(item, listkey=listkey, indent=indent) -}}
      {%- endfor -%}
    {%- endif -%}
    {%- if recurse > 0 -%}
      {{ '\n' }}
    {%- endif -%}
  {%- endif -%}
{%- endmacro -%}

=============================================== ========================

模板:

{%- set key = 0 -%}
{%- set value = 1 -%}
{%- set carryovers = ['frontend', 'backend',
      'listen'] -%}
{%- macro haproxy_config(data, carryover='', recurse=-1, indent=0) -%}
  {%- set recurse = recurse + 1 -%}
  {%- if data is none -%}
    {{- '\n' -}}
  {%- elif data is string or data is number -%}
    {{- data|string|indent(indent, True) }}{{ '\n' -}}
  {%- else -%}
    {%- if recurse > 0 -%}
      {{- '\n' -}}
      {%- set indent = indent + 2 -%}
    {%- endif -%}
    {%- if data is mapping -%}
      {%- for item in data|dictsort -%}
        {%- if item[key] in carryovers -%}
          {{- haproxy_config(item[value], carryover=item[key], indent=indent) -}}
        {%- else -%}
          {%- set carryIndent = indent -%}
          {%- set forwardIndent = indent -%}
          {%- if carryover -%}
            {{- carryover|indent(indent, True) }}{{ ' ' -}}
            {%- set carryIndent = 0 -%}
          {%- endif -%}
          {%- if item[value] is string or item[value] is not iterable -%}
            {%- set forwardIndent = 0 -%}
          {%- endif -%}
          {{- item[key]|indent(carryIndent, True) }} {{ haproxy_config(item[value], recurse=recurse, indent=forwardIndent) -}}
        {%- endif -%}
      {%- endfor -%}
    {%- else -%}
      {%- for item in data -%}
        {{- haproxy_config(item, indent=indent) -}}
      {%- endfor -%}
    {%- endif -%}
    {%- if recurse > 0 -%}
      {{ '\n' }}
    {%- endif -%}
  {%- endif -%}
{%- endmacro -%}

haproxy:
  global:
    stats: socket /var/lib/haproxy/stats mode 660 level admin
    ssl-default-bind-ciphers: "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384"
    ssl-default-bind-options: "no-sslv3 no-tlsv10 no-tlsv11"
    user: haproxy
    group: haproxy
    chroot: /var/lib/haproxy
    tune.something.else: 2048
  frontend:
    http:
      bind: 0.0.0.0:80
      option: http-server-close
      acl:
        - host_static hdr_beg(host) -i static
        - url_static path_beg static
      #use_backend: static if host_static
      #use_backend: static if url_static
      default_backend: www
  backend:
    www:
      balance: roundrobin
      #server: www1 www1 check port 80
      #server: www2 www2 check port 80
#      server: www3 www3 check port 80
#      server: load1 localhost:8080 backup
#    static:
#      server: media1 media1 check port 80
#      server: media2 media2 check port 80
#      server: load1 localhost:8080 backup

输出

backend www
  balance roundrobin

frontend http
  host_static hdr_beg(host) -i static
  url_static path_beg static
  bind 0.0.0.0:80
  default_backend www
  option http-server-close

global
  chroot /var/lib/haproxy
  daemon True
  group haproxy
  log
    /dev/log local0
    /dev/log local1 notice

  ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384
  ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
  stats socket /var/lib/haproxy/stats mode 660 level admin
  tune.something.else 2048
  user haproxy

我想要什么

backend www
  balance roundrobin

frontend http
  acl host_static hdr_beg(host) -i static
  acl url_static path_beg static
  bind 0.0.0.0:80
  default_backend www
  option http-server-close

global
  chroot /var/lib/haproxy
  daemon True
  group haproxy
  log /dev/log local0
  log /dev/log local1 notice

  ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384
  ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
  stats socket /var/lib/haproxy/stats mode 660 level admin
  tune.something.else 2048
  user haproxy

由于

1 个答案:

答案 0 :(得分:0)

我认为你需要if else块{%- if data is mapping -%}中的另一个部分来检查它是否是一个列表并使用以下内容。

{%- for key, value in data.items() %}
{{key}} {{value}}
{%- endfor %}

可能这个

{%- set key = 0 -%}
{%- set value = 1 -%}
{%- set carryovers = ['frontend', 'backend',
      'listen'] -%}
{%- macro haproxy_config(data, carryover='', recurse=-1, indent=0) -%}
  {%- set recurse = recurse + 1 -%}
  {%- if data is none -%}
    {{- '\n' -}}
  {%- elif data is string or data is number -%}
    {{- data|string|indent(indent, True) }}{{ '\n' -}}
  {%- else -%}
    {%- if recurse > 0 -%}
      {{- '\n' -}}
      {%- set indent = indent + 2 -%}
    {%- endif -%}
    {%- if data is mapping -%}
      {%- for item in data|dictsort -%}
        {%- if item[key] in carryovers -%}
          {{- haproxy_config(item[value], carryover=item[key], indent=indent) -}}
        {%- else -%}
          {%- set carryIndent = indent -%}
          {%- set forwardIndent = indent -%}
          {%- if carryover -%}
            {{- carryover|indent(indent, True) }}{{ ' ' -}}
            {%- set carryIndent = 0 -%}
          {%- endif -%}
          {%- if item[value] is string or item[value] is not iterable -%}
            {%- set forwardIndent = 0 -%}
          {%- endif -%}
          {{- item[key]|indent(carryIndent, True) }} {{ haproxy_config(item[value], recurse=recurse, indent=forwardIndent) -}}
        {%- endif -%}
      {%- endfor -%}
    {%- elif data is iterable and data is not string %}
      {%- for key, value in data.items() %}
        {{- '%s %s'|format(key, value)|indent(indent, True) }}
      {%- endfor %}
    {%- else -%}
      {%- for item in data -%}
        {{- haproxy_config(item, indent=indent) -}}
      {%- endfor -%}
    {%- endif -%}
    {%- if recurse > 0 -%}