Ansible - 带条件和寄存器stdoutput的复杂循环

时间:2017-09-18 12:12:46

标签: ansible provisioning libvirt

我有一个ansible playbook,它根据解析的参数创建libvirt guest。我试图通过额外的参数扩展该剧本,这将允许我将客户操作系统附加到指定的虚拟网络并分配写在文件中的自定义mac地址。

应该像这样调用剧本:

ansible-playbook -e "CPU=2 MEMORY=1024 VM_STORAGE=/tmp/zz VM_NAME=desktop5 VM_NETWORK=bridge,Isolated2" vm.yml

作为最后一步,我必须创建nics并使用以下格式在文件中定义的特定mac地址:

#NAT#52:54:00:aa:aa:01#desktop1
#bridge#52:54:00:aa:bb:01#desktop1
#Isolated1#52:54:00:aa:cc:01#desktop1
#Isolated2#52:54:00:aa:dd:01#desktop1

如何使用ansible playbook功能根据指定的额外参数-e VM_NETWORK附加网络接口,并确定mac地址。

到目前为止,我带来了以下内容:

  - name: Setting up network
  shell: "/bin/grep -e {{ vm_name }} {{ mac_file }} | grep -e {{ item }} | awk -F\"#\" '{print $3}'"
    register: vm_mac
  command: "/usr/bin/virsh attach-interface --domain {{ vm_name }} --type bridge --source 'bridge0' --model virtio --mac {{ vm_mac }} --config"
  when: item == "bridge"
  with_items: 
    - "{{ VM_NETWORK.split(',') }}"

但问题是我在一个任务中无法执行命令和shell操作? 我应该通过调用shell脚本获取mac地址,然后在命令中使用它吗?

目前我有一个bash脚本执行virsh命令以附加或分离接口,但我想知道是否有办法在ansible中动态执行它。

2 个答案:

答案 0 :(得分:0)

你是对的,你只有两个任务。第一个将获得MAC并注册vm_mac变量,而第二个将使用该变量。

对于它的价值,你的shell任务可以大大简化,所以最终可能会看起来像:

- name: Get MAC
  command: >
    awk -F# -vvm_name="{{ vm_name }}" -vvm_network="{{ item }}"
    '$4 == vm_name && $2 == vm_network {print $3}' "{{ mac_file }}"
  register: vm_macs
  with_items: "{{ vm_networks.split(',') }}"

对于每个网络,这将打印出与vm_name关联的MAC地址。 vm_macs变量的内容将包含vm_macs.results密钥中的结果列表,此列表的每个元素都将包含item密钥中的网络名称和stdout中的MAC地址} key:

"vm_macs.results": [
    {
        "item": "bridge", 
        "stdout": "52:54:00:aa:bb:01", 
    },
    {
        "item": "Isolated2", 
        "stdout": "52:54:00:aa:dd:01", 
    }
]

那里还有其他一些东西,但这就是我们关心的。

然后您可以在后续任务中使用它:

- name: attach interface
  command: >
    virsh attach-interface
    --domain {{ vm_name }}
    --type bridge
    --source bridge0
    --model virtio
    --mac {{ item.stdout }}
    --config
  when: item.item == "bridge"
  with_items: "{{ vm_macs.results }}"

答案 1 :(得分:0)

如果在localhost上执行命令并搜索mac_file,则可以使用pipe查找(参见more lookups章节):

- name: Setting up network
  command: >
           /usr/bin/virsh
           attach-interface
           --domain {{ vm_name }}
           --type bridge
           --source 'bridge0'
           --model virtio
           --mac {{ vm_mac }}
           --config
  vars:
    vm_mac: "{{ lookup('pipe', grep_cmd) }}"
    grep_cmd: "/bin/grep -e {{ vm_name }} {{ mac_file }} | grep -e {{ item }} | awk -F\"#\" '{print $3}'"
  when: item == "bridge"
  with_items: "{{ VM_NETWORK.split(',') }}"

注意:我没有测试过这个确切的grep_cmd

这只适用于localhost,因为插件是在本地执行的。