【问题标题】:Ansible, YAML, and SyntaxAnsible、YAML 和语法
【发布时间】:2015-03-12 23:02:32
【问题描述】:

我正在尝试创建一个 Ansible 配置,该配置将运行一个剧本并利用单个变量文件来创建具有多个项目的单个配置。我正在尝试以下语法,但它失败了。我该如何解决这个问题?

vars/main.yml

---
or1host1:

      - interface: 1/1
        description: or1-servertest
        TRUNK: true
        allowedVlans: 101-103
        NVLAN: true
        nativeVLAN: 101
        ACCESS: false
        accessVlan: none
        PC: true
        pcNUM: 10

      - interface: 1/2
        description: or1-servertest2
        TRUNK: false
        allowedVlans: 101-103
        NVLAN: false
        nativeVLAN: 101
        ACCESS: true
        accessVlan: none
        PC: true
        pcNUM: 10

模板/nxos.j2

{% for interface in or1host1 %}
interface Ethernet{{item.interface}}
description {{item.description}}
{% if item.TRUNK %}
  switchport mode trunk
  switchport trunk allowed vlan {{item.allowedVlans}}
  spanning-tree port type edge trunk
{% if item.NVLAN %}
  switchport trunk native vlan {{item.nativeVLAN}}
{% endif %}
{% endif %}
{% if item.ACCESS %}
  switchport mode access
  switchport access vlan {{item.accessVlan}}
  spanning-tree port type edge
{% endif %}
{% if item.PC %}
  channel-group {{item.pcNUM}} mode active
{% endif %}
  no shut
{% endfor %}

我在运行 playbook 时收到以下错误。

PLAY [Generate Configuration Files] ******************************************* 

GATHERING FACTS *************************************************************** 
ok: [localhost]

TASK: [nxos | Generate configuration files] *********************************** 
fatal: [localhost] => {'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'str object' has no attribute 'interface'", 'failed': True}
fatal: [localhost] => {'msg': 'One or more items failed.', 'failed': True, 'changed': False, 'results': [{'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'str object' has no attribute 'interface'", 'failed': True}]}

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/gituser/site.retry

localhost                  : ok=1    changed=0    unreachable=1    failed=

0

【问题讨论】:

  • 你遇到了什么样的错误?
  • 我编辑了我的原始问题以考虑到下面提到的一些更改,并包含以下错误。

标签: python networking yaml ansible ansible-playbook


【解决方案1】:

终于弄明白了,看下面的例子。

~/vars/mail.yml

---
nxos:
- {hostname: testhost}
interfaces:
- {ACCESS: 'true', NVLAN: 'true', PC: 'true', TRUNK: 'true', accessVlan: '1', allowedVlans: 500-600,
  desC: serverhost-1005, intF: eth1/1, nativeVLAN: '56', pcNUM: '23'}
- {ACCESS: 'true', NVLAN: 'true', PC: 'true', TRUNK: 'true', accessVlan: '1', allowedVlans: 500-600,
  desC: serverhost-1006, intF: eth1/2, nativeVLAN: '56', pcNUM: '23'}

~/templates/nxos.j2

HOST: {{item.hostname}}

-----------------------------------------------------------
-----------------------------------------------------------

{%for i in interfaces %}
interface Ethernet{{i.intF}}
  description {{i.desC}}
{% if i.TRUNK %}
  switchport mode trunk
  switchport trunk allowed vlan {{i.allowedVlans}}
  spanning-tree port type edge trunk
{% if i.NVLAN %}
  switchport trunk native vlan {{i.nativeVLAN}}
{% endif %}
{% endif %}
{% if i.ACCESS %}
  switchport mode access
  switchport access vlan {{i.accessVlan}}
  spanning-tree port type edge
{% endif %}
{% if i.PC %}
  channel-group {{i.pcNUM}} mode active
{% endif %}
  no shut
!
{% endfor %}

配置

HOST: testhost

-----------------------------------------------------------
-----------------------------------------------------------

interface Etherneteth1/1
  description serverhost-1005
  switchport mode trunk
  switchport trunk allowed vlan 500-600
  spanning-tree port type edge trunk
  switchport trunk native vlan 56
  switchport mode access
  switchport access vlan 1
  spanning-tree port type edge
  channel-group 23 mode active
  no shut
!
interface Etherneteth1/2
  description serverhost-1006
  switchport mode trunk
  switchport trunk allowed vlan 500-600
  spanning-tree port type edge trunk
  switchport trunk native vlan 56
  switchport mode access
  switchport access vlan 1
  spanning-tree port type edge
  channel-group 23 mode active
  no shut
!

【讨论】:

    【解决方案2】:

    这里有几件事。首先,当您不处于 JSON 模式时,您确实必须注意缩进。当您缩进包含 4 个项目的列表项时,所有其他列表项都需要具有相同数量的空格。您的第二项有 6 个空格,如果没有完全松散的元素 interface: 1/2,这将是语法错误,这是这里的主要问题,因为它没有意义,也无法将其解析为一种数据结构。在一个列表中,您可以有任意数量的列表项,但在同一级别上不能有松散的属性。我认为你的意思是把它放在第二个列表项中。两者都更正后,它看起来像这样:

    ---
    or1-host1:
      - { interface: 1/1, 
          description: or1-servertest, 
          TRUNK: true, allowedVlans: 101-103, 
          NVLAN: true, nativeVLAN: 101, 
          ACCESS: false, accessVlan: none, 
          PC: true, pcNUM: 10
        }
    
      - {  interface: 1/2,
           description: or1-servertest2, 
           TRUNK: false, allowedVlans: 101-103, 
           NVLAN: false, nativeVLAN: 101, 
           ACCESS: true, accessVlan: none, 
           PC: true, pcNUM: 10
        }
    

    虽然 JSON 是 YML 的有效子集,但我发现严格使用 YML 语法更具可读性,如下所示:

    --- 
    or1-host1:
      - interface: 1/1
        description: or1-servertest
        TRUNK: true
        allowedVlans: 101-103
        NVLAN: true
        nativeVLAN: 101
        ACCESS: false
        accessVlan: none
        PC: true
        pcNUM: 10
    
      - interface: 1/2 
        description: or1-servertest2
        TRUNK: false
        allowedVlans: 101-103
        NVLAN: false
        nativeVLAN: 101
        ACCESS: true
        accessVlan: none 
        PC: true
        pcNUM: 10
    ...
    

    在您的模板中,尽管您无法像那样访问1/11/2。也许您想遍历模板中的接口?我不确定。

    {% for interface in or1-host1 %}
      ...
    {% endfor %}
    

    我认为您将不得不重命名 or1-host1,因为由于连字符,这看起来不像是一个有效的变量名,or1_host1 可以工作。

    【讨论】:

    • 感谢您的回复,我在上面编辑了我的问题并发布了我遇到的错误。
    • 我认为剩下的问题是您如何访问属性的符号。尝试item["interface"] 而不是item.interface,其他属性也一样。
    • 看起来这可能有效,但是,我需要弄清楚我的 if 语句。使用更改的变量名称运行剧本会给我这个错误:致命:[localhost] => {'msg':“AnsibleUndefinedVariable:一个或多个未定义变量:'TRUNK'未定义”,'失败':True}致命: [localhost] => {'msg': '一个或多个项目失败。', 'failed': True, 'changed': False, 'results': [{'msg': "AnsibleUndefinedVariable: 一个或多个未定义的变量: 'TRUNK' 未定义", '失败': True}]}
    • TRUNK 已定义,在您的情况下您使用tiem["trunk"]?如果TRUNK 是可选元素,您可以使用if "TRUNK" in item 测试其是否存在。
    猜你喜欢
    • 2017-01-14
    • 2019-08-22
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 2022-01-21
    • 1970-01-01
    • 2015-08-04
    相关资源
    最近更新 更多