From d89c7ab77ec1327d8d09065406960844d6a32b50 Mon Sep 17 00:00:00 2001 From: "Sergey Bubnov (omg)" Date: Thu, 27 Jun 2019 13:13:45 +0400 Subject: [PATCH] prevent wrong behaviour when more than one dhcp on interfaces firts we check that the VM has already get some IP address and if so we just deploy as usual. If VM have no IP address on any interface we throw all interfaces except first (eth0) to the `empty vlan` that have no DHCP server enabled. VLAD ID defined in environment variable. After network configuration inside VM we restore propper VLAN IDs on all interfaces. This approach should help in situations when DHCP available on more than one interfaces and those interfaces configured as dhcp-clients, thus more than one default gw will be configured with some metrics and all traffic will be routed to the right one or will be not. --- plugins/filters.py | 5 ++++- roles/common/tasks/main.yml | 8 ++++++++ roles/pve/tasks/create_vm.yml | 21 ++++++++++++++++++++- roles/pve/tasks/enable_vlans.yml | 28 ++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 roles/pve/tasks/enable_vlans.yml diff --git a/plugins/filters.py b/plugins/filters.py index cbe1be6..7108767 100644 --- a/plugins/filters.py +++ b/plugins/filters.py @@ -59,10 +59,13 @@ def to_nics_dict(src): "addrs": addrs} return nics -def to_proxmox_net(src): +def to_proxmox_net(src, vlan=None): out = {} ks = ['virtio', 'bridge', 'tag'] for k,v in src.items(): + if k != 'eth0' and vlan: + v['tag'] = vlan + k = k.replace('eth','net') [ v.pop(x, None) for x in set(v.keys()).difference(ks) ] v.pop('ipv4', None) # remove unused key diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 1819b39..6b156da 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -121,6 +121,14 @@ delay: 2 timeout: 300 +- debug: msg="{{hostvars['localhost']['other_nics_to_vlan']}}" + +- name: enable vlans on other interfaces + include_role: + name: pve + tasks_from: enable_vlans.yml + when: hostvars['localhost']['other_nics_to_vlan'] + - name: configure PBR include_tasks: configure_pbr.yml with_dict: "{{node.net}}" diff --git a/roles/pve/tasks/create_vm.yml b/roles/pve/tasks/create_vm.yml index c646968..bed1079 100644 --- a/roles/pve/tasks/create_vm.yml +++ b/roles/pve/tasks/create_vm.yml @@ -1,6 +1,7 @@ --- - set_fact: node_name="{{tmp_node}}" - set_fact: vm_name="{{node_name}}.{{stack.name}}" +- set_fact: other_nics_to_vlan=false - name: "[{{vm_name}}] clone VM" proxmox_kvm: @@ -31,6 +32,24 @@ delay: 1 ignore_errors: yes +- name: "[{{vm_name}}] get VM`s ip addresses" + proxmox_qemu_agent: + api_user: "{{env.pve.username}}" + api_password: "{{env.pve.password}}" + api_host: "{{env.pve.api_url}}" + name: "{{vm_name}}" + command: "network-get-interfaces" + register: res + until: res.results | json_query('[] | [?name!=`lo`]."ip-addresses" | [] | [?"ip-address-type"==`ipv4`] | []."ip-address"') | length > 0 + retries: 3 + delay: 1 + ignore_errors: yes + +- set_fact: other_nics_to_vlan="{{env.pve.empty_vlan}}" + when: res.failed + +- debug: msg="{{hostvars['localhost']['other_nics_to_vlan']}}" + - name: "[{{vm_name}}] configure VM" proxmox_kvm: node: srv @@ -44,7 +63,7 @@ cores: "{{stack.nodes[node_name].cores}}" memory: "{{stack.nodes[node_name].mem}}" # storage: "{{env.pve.storage}}" - net: "{{stack.nodes[node_name].net | to_proxmox_net}}" + net: "{{stack.nodes[node_name].net | to_proxmox_net(other_nics_to_vlan)}}" update: yes state: present # ide: '{ide[2]: "local-lvm:cloudinit"}' diff --git a/roles/pve/tasks/enable_vlans.yml b/roles/pve/tasks/enable_vlans.yml new file mode 100644 index 0000000..d023632 --- /dev/null +++ b/roles/pve/tasks/enable_vlans.yml @@ -0,0 +1,28 @@ +--- +- set_fact: node_name="{{inventory_hostname_short}}" +- set_fact: vm_name="{{node_name}}.{{stack.name}}" + +- name: "[{{vm_name}}] enable all VLANs" + proxmox_kvm: + node: srv + api_user: "{{env.pve.username}}" + api_password: "{{env.pve.password}}" + api_host: "{{env.pve.api_url}}" + name: "{{vm_name}}" + agent: yes + cpu: host + kvm: yes + cores: "{{stack.nodes[node_name].cores}}" + memory: "{{stack.nodes[node_name].mem}}" + net: "{{stack.nodes[node_name].net | to_proxmox_net}}" + update: yes + state: present + ipconfig0: "ip={{stack.nodes[node_name].net.eth0.ipv4[0]}},gw={{stack.nodes[node_name].net.eth0.default}}" + nameserver: "{{stack.nodes[node_name].net.eth0.nameservers | default(omit) | first}}" + searchdomain: "{{stack.nodes[node_name].net.eth0.search | default(omit) | first}}" + register: vm_status + until: vm_status is succeeded + retries: 30 + delay: 1 + ignore_errors: yes + delegate_to: localhost