AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题

问题[jinja2](server)

Martin Hope
dutsnekcirf
Asked: 2022-02-01 15:57:41 +0800 CST

使用 Jinja2 模板遍历嵌套列表/字典

  • 3

我正在尝试通过使用 Ansible 生成 /etc/exports 文件来动态配置系统中的多个 NFS 服务器。我希望能够使用 jinja2 模板来做到这一点。这是我根据导出列表无法确定的 jinja2 模板。

我在我的 nfs 角色中定义了以下变量:

site_nfs_servers: ['ansibletarget1', 'ansibletarget2']

exports:
  - server: "ansibletarget1"
    shares:
      - path: "/my/first/share/path"
        client: "*"
        options: "rw,sync"
      - path: "/my/second/share/path"
        client: "*"
        options: "rw,sync,root_squash"
  - server: "ansibletarget2"
    shares:
      - path: "/another/shared/path/different/server"
        client: "*"
        options: "ro,sync"

然后我有以下 ansible play 来生成模板:

- name: Generate the exports file.
  template:
    src: exports.j2
    dest: /etc/exports
    owner: root
    group: root
    mode: '0750'

我的模板目前看起来像这样:

{% for export in exports %}
{% if ansible_hostname in export.server %}
{% for share in shares %}
{{ share.path }} {{ share.client }} {{ share.options }}
{% endfor %}
{% endif %}
{% endfor %}

我认为我离正确的模板结构还差得很远。到底是如何遍历这个列表的?

ansible ansible-playbook jinja2
  • 2 个回答
  • 3575 Views
Martin Hope
Bogdan Stoica
Asked: 2021-10-07 22:11:37 +0800 CST

来自 JSON 格式的 Ansible jinja2 模板作为额外变量提供

  • 0

我有这个 jinja2 模板:

# {{ ansible_managed }}

{% for vhost in nginx_vhosts %}
{%- if vhost.name == item.name -%}

# redirect www to non-www
server {
    listen {{ nginx_port }};
    listen [::]:{{ nginx_port }};
    port_in_redirect off;

    server_name www.{{ vhost.name }};
    return 301 http://{{ vhost.name }}$request_uri;
}
{%- endif -%}
{%- endfor -%}

一个带有 yaml 文件vhosts.ym l 的 ansible 角色,其中包含如下定义:

nginx_vhosts:
      - name: "test1.com"
        repo: "git1"
        branch: master
        state: present
      - name: "test2.com"
        repo: "git2"
        branch: master
        state: present
...
      - name: "test101.com"
        repo: "git101"
        branch: master
        state: present

playbook.yml中的一个任务:

- name: "Generate nginx vhost configuration file"
  template:
    src: templates/nginx-vhost-template.j2
    dest: "{{ nginx_vhosts_dir }}/{{ item.name }}.conf"
    owner: "{{ nginx_user }}"
    group: "{{ nginx_group }}"
    mode: 0640
  with_items:
    - "{{ nginx_vhosts }}"
  when:
    - item.state == 'present'
  notify:
    - nginx-restart

我跑了一个像这样的任务:

ansible-playbook -l web1 playbook.yml --tags=nginx-vhost-config

这工作正常,它将从模板在远程服务器上创建一个 nginx vhost 配置文件,如 domain1.com.conf 等,用于所有找到的定义。

假设在 vhosts.yml 文件中我有 test1.com 到 test100.com,我将添加假设 test101.com 并且我想严格为该 test101.com 而不是所有以前的主机运行任务。所以我尝试了这样的事情:

ansible-playbook -l web1 playbook.yml --tags=nginx-vhost-config -e "{ 'nginx_vhosts': { 'name': 'test101.com', 'state': 'present', 'repo': 'git101', 'branch': 'master' }}"

这样做的问题是在尝试替换 jinja2 模板中的值时会导致错误。

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ansible.errors.AnsibleUndefinedVariable: 'ansible.parsing.yaml.objects.AnsibleUnicode object' has no attribute 'name'

我也尝试过使用循环而不是with_items但没有运气。

我知道在使用额外变量时,提供的内容是 JSON 格式,但我无法找到另一种方法将 vhosts.yml 中的内容作为单个条目的额外变量传递。有什么办法可以使它起作用吗?

也许有更好的方法吗?

ansible ansible-playbook jinja jinja2
  • 1 个回答
  • 2491 Views
Martin Hope
Andrew Lamarra
Asked: 2021-09-24 07:31:05 +0800 CST

从 Ansible 中的同一列表项访问变量中的 dict 值

  • 1

我正在使用 Ansible 部署一些虚拟机,并且我有一个定义虚拟机的列表变量。我想知道是否可以让其中一个 dict 项目在同一个列表元素中使用另一个作为变量。例如,假设我定义了以下变量:

nodes:
  - name: vm1
    aliases:
      - vm1
      - vm1.local
  - name: vm2
    aliases:
      - vm2
      - vm2.local

相反,我可以做这样的事情吗?

nodes:
  - name: vm1
    aliases:
      - "{{ name }}"
      - "{{ name }}.local"
  - name: vm2
    aliases:
      - "{{ name }}"
      - "{{ name }}.local"

我试过了,我尝试使用"{{ nodes.0.name }}".

ansible jinja jinja2
  • 1 个回答
  • 291 Views
Martin Hope
Sandeep
Asked: 2021-06-25 04:23:13 +0800 CST

Ansible 根据特定条件更新字典列表

  • 1

我想用 ansible 更新列表,其中包含基于某些条件的字典项

例如:

list1:
  - {"name": "test1", "uid": 100, "gid": 250}
  - {"name": "test2", "uid": 101, "gid": 250}
  - {"name": "test3", "uid": 103, "gid": 250}
  - {"name": "test4", "uid": 104, "gid": 250}

list2: [100, 101]

list3: [102,103]

如果 uid 与 list2 中的项目匹配,它将更改 gid=300,如果与 list3 匹配,则将其更新为 400,其余项目在 list1 中保持不变

请建议我如何在上述条件下生成 list1

python ansible jinja2
  • 1 个回答
  • 1645 Views
Martin Hope
Lethargos
Asked: 2021-04-06 23:48:22 +0800 CST

ansible - docker 容器中环境变量的模板 json

  • 0

我正在尝试将单行 json 字符串分配给 docker 容器中的环境变量。这是json的样子:

{"ip_access": {"IP_whitelist": {"192.168.99.19/32": "grafana/status (Provider)"}}, "vhosts": {"prometheus1": {"dns_names": ["prometheus1.company.internal"], "add_lines_443": ["include IP_whitelist;", "set $prometheus http://prometheus:9090;", "location / { proxy_pass $prometheus; }"], "options": {"cert_path": "/etc/ssl/certs/prometheus1.crt", "key_path": "/etc/ssl/private/prometheus1.key"}}}}

因此,["prometheus1.company.internal"]我不想拥有["{{ inventory_hostname }} .company.internal"](以及其他prometheus1.

我正在使用 docker_container 如下:

- name: create nginx reverse proxy container
  docker_container:
    image: registry.company.com/devops/nginx-reverseproxy:{{ nginx_version }}
    name: nginx-reverseproxy
    labels:
      role=metrics
    volumes:
      - /etc/ssl/certs/{{ inventory_hostname }}.crt:/etc/ssl/certs/{{ inventory_hostname }}.crt
      - /etc/ssl/private/{{ inventory_hostname }}.key:/etc/ssl/private/{{ inventory_hostname }}.key
    container_default_behavior: compatibility
    networks_cli_compatible: yes
    network_mode: default
    purge_networks: yes
    networks:
      - name: metrics-net
      - name: proxy-net
    env:
      STAGING_ENVIRONMENT: 'production'
      NGINX_VHOSTS_JSON: '{{ lookup("template", "rproxy/nginx_vhosts_prometheus_develop.j2") }}'

不幸的是,我不断得到:

TASK [prometheus : create nginx reverse proxy container] **********************************************
fatal: [prometheus_vag]: FAILED! => {"changed": false, "msg": "Non-string value found for env option. Ambiguous env options must be wrapped in quotes to avoid them being interpreted. Key: NGINX_VHOSTS_JSON"}

奇怪的是,如果我只是使用模板模块,它会按预期工作:

  template:
    src: rproxy/nginx_vhosts_prometheus_develop.j2
    dest: /tmp/tempo.json
  when: "prometheus_host in inventory_hostname"
  tags:
    - copytmp

inventory_hostname将被库存中的实际价值取代,我得到了正确的东西。此外,如果我将这个确切的结果作为 yaml playbook 中 NGINX_VHOSTS_JSON 的值粘贴到 playbook 中,它也可以正常工作。

但是查找模板似乎没有提供预期的字符串。

有什么想法可以解决这个问题吗?

json ansible jinja2
  • 2 个回答
  • 811 Views
Martin Hope
Lethargos
Asked: 2021-03-28 10:38:51 +0800 CST

使用 ansible 模板文件以获取不同主机的不同变量部分(通过其索引)

  • 0

我正在尝试将证书分发到其相应的主机(我将仅给出私钥任务的示例):

- name: create certificate private key
  community.crypto.openssl_privatekey:
    path: "/root/client/{{ item }}.key"
    type: Ed25519
    backup: yes
    return_content: yes
  register: privatekey
  loop: "{{ ansible_play_hosts_all }}"
  when: "'prometheus1' in inventory_hostname"

我可以像这样为其他主机调用变量:

{{ hostvars['prometheus1']['privatekey']['results'][0]['privatekey'] }}

索引指向某个键,因此 0 将是第一个主机 ( prometheus1),1 将是第二个主机,依此类推。

我想模板化是要走的路,但我根本不知道如何编写模板。我认为ansible_play_hosts_all是解决方案的关键,因为它的索引对应于私钥的索引,例如: ansible_play_hosts_all[2]-->hostvars['prometheus1']['privatekey']['results'][2]['privatekey']

但逻辑是:

for i in index of ansible_play_hosts_all
add the  hostvars['prometheus1']['privatekey']['results'][i]['privatekey']
if ansible_play_hosts_all[i] in inventory_hostname

我想有这样的效果:) 非常感谢任何帮助。


更新

也许更准确一些:

{% for i in ansible_play_hosts_all|length) %}
{{ hostvars['prometheus1']['privatekey']['results'][i]['privatekey'] }}
{% endfor %}

并在其中添加条件:

{% if ansible_play_hosts_all[i] in inventory_hostname %}
ansible template jinja2
  • 3 个回答
  • 401 Views
Martin Hope
Wipiid
Asked: 2021-02-03 09:51:34 +0800 CST

使用 ansible 模板化 firewalld 区域 - xml 或 vars 问题

  • 0

使用 ansible 模板化 firewalld 区域 - xml 操作问题 我对规则系列有点困惑。

我的CORRECTED vars 文件中有什么内容:

firewalld_zones: 
  - name: public
    short: "Public"
    description: "Public Zone"
    service:
      - { name: ssh }
      - { name: dhcpv6-client }
    port:
      - { protocol: tcp, port: 8000 }
      - { protocol: tcp, port: 8089 }
      - { protocol: udp, port: 52311 }
      - { protocol: udp, port: 514 }
      - { protocol: tcp, port: 8191 }
      - { protocol: tcp, port: 8888 }
    masquerade: true
    forward-port:
      - { to-port: 8000, protocol: tcp, port: 443 }
    rule:
      - family: ipv4
        source:
          - address: "172.18.0.0/16"
          - action: accept
      - family: ipv4
        source:
          - address: "172.17.0.0/16"
          - action: accept

我得到更正的变量和模板:

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>PUBLIC</short>
  <description>Public Zone</description>
  <service name="ssh"/>
  <service name="dhcpv6-client"/>
  <port protocol="tcp" port="8000"/>
  <port protocol="tcp" port="8089"/>
  <port protocol="udp" port="52311"/>
  <port protocol="udp" port="514"/>
  <port protocol="tcp" port="8191"/>
  <port protocol="tcp" port="8888"/>
  <masquerade/>
  <forward-port to-port="8000" protocol="tcp" port="443"/>
  <rule family="ipv4">
    <source address="172.18.0.0/16"/>
    <accept/>
  </rule>
  <rule family="ipv4">
    <source address="172.17.0.0/16"/>
    <accept/>
  </rule>
</zone>

您能否提供一个示例变量来将规则与规则族混合?我尝试了无数次迭代,但没有运气。:(

我的更正模板文件的内容:

<?xml version="1.0" encoding="utf-8"?>
<zone{% if item.target is defined %} target="{{ item.target }}"{% endif %}>
  <short>{{ item.short|default(item.name)|upper }}</short>
{% if item.description is defined %}
  <description>{{ item.description }}</description>
{% endif %}
{% for tag in item %}
{# Settings which can be used several times #}
{% if tag in ['interface','source','service','port','protocol','icmp-block','forward-port','source-port'] %}
{% for subtag in item[tag] %}
  <{{ tag }}{% for name,value in subtag.items() %} {{ name }}="{{ value }}"{% endfor %}/>
{% endfor %}
{# Settings which can be used once #}
{% elif tag in ['icmp-block-inversion','masquerade'] and item[tag] == True %}
  <{{ tag }}/>
{% endif %}
{% endfor %}
{% for rule in item.rule|default([]) %}
  <rule{% if rule.family is defined %} family="{{ rule.family }}"{% endif %}>
{% for tag in rule %}
{% if tag in ['source','destination','service','port','icmp-block','icmp-type','masquerade','forward-port','protocol'] %}
{% for subtag in rule[tag] %}
  {% for name,value in subtag.items() %}
{% if name in ['action'] %}
  <{{ value }}/>
{% else %}
  <{{ tag }} {{ name }}="{{ value }}"/>
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}
  </rule>
{% endfor %}
</zone>
firewalld ansible template firewalld-zone jinja2
  • 2 个回答
  • 155 Views
Martin Hope
Casey
Asked: 2020-10-28 06:41:03 +0800 CST

如何在 Debian 和 FreeBSD 的 ansible 中选择给定 IP 地址的网络接口?

  • 3

我正在寻找一个表达式来获取接口名称,给定分配给该 iface 的 IP 地址,跨 Linux 和 FreeBSD。

这个问题基于这个答案:https ://serverfault.com/a/948288/416946

这个 jinja2 表达式将在 Debian 上返回接口对象(来自 ansible 事实)given_ip

iface_for_ip: >-
  {{ ansible_facts
  | dict2items
  | selectattr('value.ipv4', 'defined')
  | selectattr('value.ipv4.address', 'equalto', given_ip)
  | first  }}

然而,这在 FreeBSD 上不起作用,因为该ipv4结构是一个数组,而不是一个对象。

如果你只运行这个片段:

iface_for_ip: >-
  {{ ansible_facts
  | dict2items
  | selectattr('value.ipv4', 'defined') }}

你会得到这样的输出:

在 Debian 上
  - key: eth0
    value:
      active: true
      device: eth0
      ipv4:
        address: 10.8.20.206
        broadcast: 10.8.20.255
        netmask: 255.255.255.0
        network: 10.8.20.0
      ipv6:
      - address: fe80::84ee:35ff:fed4:a23c
        prefix: '64'
        scope: link
      macaddress: 00:ee:35:00:00:00
      mtu: 1500
      promisc: false
      speed: 10000
      type: ether
在 FreeBSD 上
  - key: epair0b
    value:
      device: epair0b
      flags:
      - UP
      - BROADCAST
      - RUNNING
      - SIMPLEX
      - MULTICAST
      ipv4:
      - address: 10.8.20.207
        broadcast: 10.8.20.255
        netmask: 255.255.255.0
        network: 10.8.20.0
      ipv6: []
      macaddress: 00:ee:23:00:00:00
      media: Ethernet
      media_options:
      - full-duplex
      media_select: 10Gbase-T
      media_type: 10Gbase-T
      metric: '0'
      mtu: '1500'
      options:
      - PERFORMNUD
      status: active
      type: ether

如何使用 jinja2 ansible 表达式来获取仅给出 ip 地址跨平台的接口? json_query在这里可能很有用,但该方法使我无法理解。

freebsd ansible jinja jinja2
  • 2 个回答
  • 1386 Views
Martin Hope
celcoprab
Asked: 2020-09-16 22:23:39 +0800 CST

如何在远程服务器中使用ansible将两个文件合并为一个文件

  • 1

我需要合并两个没有重复条目的文件。有什么办法可以通过ansible模块实现它。例如,我有两个文件 /etc/hosts1 和 /etc/hosts2。我需要一个 /etc/hosts 文件,其中包含 /etc/hosts1 和 /etc/hosts2 中存在的所有条目而没有重复的条目。我怎样才能做到这一点。一个例子将不胜感激

- name: Merge two files
  assemble:
    src: /etc/hosts1
    dest: /etc/hosts2

上面的 assemble 模块失败

python copy ansible ansible-playbook jinja2
  • 1 个回答
  • 7908 Views
Martin Hope
Mike Williams
Asked: 2020-08-22 14:58:50 +0800 CST

Ansible 检查属性列表中是否存在变量

  • 2

我有一个包含网络上主机详细信息的变量(称为“主机列表”-我相信您将其称为字典,但我不确定术语。该变量在 group_vars/all 的文件中定义,所以它是在所有剧本中都可用(不确定这是否重要)。

我有一个剧本,只有在 hostlist 的主机名列表中找不到 ansible_hostname 时我才想运行它。hostlist 中的主机名是变量的属性之一,但我再次不确定“属性”是否是正确的术语......

主机列表定义为:

hostlist:
  - { name: 'host1', ip_addr: '192.168.2.31', hostgrp: 'physical_workstation' }
  - { name: 'host2', ip_addr: '192.168.2.32', hostgrp: 'physical_workstation' }
  - { name: 'host3', ip_addr: '192.168.2.33', hostgrp: 'virtual_machine' }

我用来尝试使其正常工作的游戏是:

- name: Conditional test
  debug:
    msg: "ansible_hostname not found in hostlist."
  when: ansible_hostname not in hostlist.name

我不确定条件中所需的语法,或者我想要的是否可以通过这种方式实现?

ansible yaml jinja2
  • 3 个回答
  • 24189 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve