Configure target hosts for kolla-ansible

deploy-scenario: os-nosdn-nofeature
installer-type: kolla

Change-Id: I68b3f73865b1be401b46447d2f61be037ae3b5a6
diff --git a/playbooks/roles/configure-targethosts/tasks/configure-network-Debian.yml b/playbooks/roles/configure-targethosts/tasks/configure-network-Debian.yml
new file mode 100644
index 0000000..aac29aa
--- /dev/null
+++ b/playbooks/roles/configure-targethosts/tasks/configure-network-Debian.yml
@@ -0,0 +1,115 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+- name: Configure modules
+  lineinfile:
+    dest: /etc/modules
+    state: present
+    create: yes
+    line: "8021q"
+
+- name: Add modules
+  modprobe:
+    name: 8021q
+    state: present
+
+# TODO: we need to look into how to configure with netplan for ubuntu 18
+# Today we perform a reboot after network related confiugration changes
+# to make sure the changes are persistent and prevent various issues.
+
+- name: Ensure interfaces.d folder is empty
+  file:
+    state: "{{ item }}"
+    path: "/etc/network/interfaces.d"
+  with_items:
+    - absent
+    - directory
+
+- name: Ensure /etc/interfaces can source additional files
+  copy:
+    content: |
+      auto lo
+      iface lo inet loopback
+      source /etc/network/interfaces.d/*.cfg
+    dest: "/etc/network/interfaces"
+
+- name: Compute mapping dict from mac address to device name
+  set_fact:
+    device_mac_dict: "{{ (device_mac_dict | default({})) | combine({item.macaddress: item.device}) }}"
+  loop: "{{ ansible_interfaces | map('regex_replace', '-', '_') | map('regex_replace', '^', 'ansible_') | map('extract', hostvars[inventory_hostname]) |  selectattr('macaddress','defined') | list }}"
+
+- name: Compute mapping dict from mac address to interface name (device name with/without VLAN info)
+  set_fact:
+    if_mac_dict: "{{ ( if_mac_dict | default({}) ) | combine({item.mac_address: (item.vlan == 'native') | ternary(device_mac_dict[item.mac_address], device_mac_dict[item.mac_address] + '.' + item.vlan) }) }}"
+  loop: "{{ node.interfaces }}"
+
+- name: Configure networking for host
+  template:
+    src: "{{ ansible_os_family }}.interface.j2"
+    dest: "/etc/network/interfaces.d/{{ item.value }}.cfg"
+  loop: "{{ if_mac_dict | dict2items }}"
+
+- name: Ensure systemd resolved.conf has the correct content
+  lineinfile:
+    path: /etc/systemd/resolved.conf
+    regexp: "^#?DNS=.*$"
+    line: "DNS={{ idf.net_config[engine.public_network | default('public')].dns | join(' ')}}"
+  when: idf.net_config[engine.public_network | default('public')].dns is defined
+
+- name: Proxy configuration for apt
+  block:
+  - name: Check that the /etc/apt/apt.conf exists
+    stat:
+      path: /etc/apt/apt.conf
+    register: stat_result
+
+  - name: Create /etc/apt/apt.conf, if it doesn't exist
+    file:
+      path: /etc/apt/apt.conf
+      state: touch
+    when: stat_result.stat.exists == False
+
+  - name: Add proxy setting to /etc/apt/apt.conf
+    lineinfile:
+      dest: /etc/apt/apt.conf
+      state: present
+      regexp: "^{{ item.name }}"
+      line: "{{ item.name }} {{ item.value }} "
+    with_items:
+      - {name: 'Acquire::http::Proxy', value: '"{{ idf.proxy_settings.http_proxy }}";' }
+      - {name: 'Acquire::https::Proxy', value: '"{{ idf.proxy_settings.https_proxy }}";' }
+  when:
+    idf.proxy_settings is defined
+
+- name: Reboot the machine
+  shell: "sleep 5 && reboot"
+  async: 1
+  poll: 0
+
+- name: Wait for host to come back to life
+  wait_for_connection:
+    connect_timeout: 10
+    sleep: 5
+    delay: 120
+    timeout: 300
+  register: result
+  until: result | succeeded
+  retries: 3
+
+# vim: set ts=2 sw=2 expandtab:
diff --git a/playbooks/roles/configure-targethosts/tasks/configure-network-RedHat.yml b/playbooks/roles/configure-targethosts/tasks/configure-network-RedHat.yml
new file mode 100644
index 0000000..600d5d6
--- /dev/null
+++ b/playbooks/roles/configure-targethosts/tasks/configure-network-RedHat.yml
@@ -0,0 +1,80 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+- name: Configure modules
+  lineinfile:
+    dest: /etc/modules
+    state: present
+    create: yes
+    line: "8021q"
+
+- name: Add modules
+  modprobe:
+    name: 8021q
+    state: present
+
+- name: Compute mapping dict from mac address to device name
+  set_fact:
+    device_mac_dict: "{{ (device_mac_dict | default({})) | combine({item.macaddress: item.device}) }}"
+  with_items:
+    - "{{ ansible_interfaces | map('regex_replace', '-', '_') | map('regex_replace', '^', 'ansible_') | map('extract', hostvars[inventory_hostname]) |  selectattr('macaddress','defined') | list }}"
+
+- name: Compute mapping dict from mac address to interface name (device name with/without VLAN info)
+  set_fact:
+    if_mac_dict: "{{ ( if_mac_dict | default({}) ) | combine({item.mac_address: (item.vlan == 'native') | ternary(device_mac_dict[item.mac_address], device_mac_dict[item.mac_address] + '.' + item.vlan) }) }}"
+  with_items:
+    - "{{ node.interfaces }}"
+
+- name: Configure networking for host
+  template:
+    src: "{{ ansible_os_family }}.interface.j2"
+    dest: "/etc/sysconfig/network-scripts/ifcfg-{{ item.value }}"
+  with_items:
+    - "{{ if_mac_dict | dict2items }}"
+
+- name: Proxy configuration for yum
+  block:
+  - name: Check that the /etc/yum.conf exists
+    stat:
+      path: /etc/yum.conf
+    register: stat_result
+
+  - name: Create /etc/yum.conf, if it doesn't exist
+    file:
+      path: /etc/yum.conf
+      state: touch
+    when: stat_result.stat.exists == False
+
+  - name: Add proxy setting to /etc/yum.conf
+    lineinfile:
+      dest: /etc/yum.conf
+      state: present
+      regexp: "^{{ item.name }}"
+      line: "{{ item.name }}={{ item.value }} "
+    with_items:
+      - {name: 'proxy', value: '"{{ idf.proxy_settings.http_proxy }}"' }
+  when:
+    idf.proxy_settings is defined
+
+- name: Restart network
+  service:
+    name: network
+    state: restarted
+
+# vim: set ts=2 sw=2 expandtab:
diff --git a/playbooks/roles/configure-targethosts/tasks/configure-network.yml b/playbooks/roles/configure-targethosts/tasks/configure-network.yml
new file mode 100644
index 0000000..13393c8
--- /dev/null
+++ b/playbooks/roles/configure-targethosts/tasks/configure-network.yml
@@ -0,0 +1,62 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+- name: Get node name from IDF for host "{{ inventory_hostname }}"
+  set_fact:
+    node_name: "{{ item.key }}"
+  with_dict: "{{ idf.kolla.hostnames }}"
+  when: item.value == inventory_hostname
+
+- name: Set facts for the node "{{ node_name }}"
+  set_fact:
+    node: "{{ nodes | selectattr('name', 'equalto', node_name) | first }}"
+
+- name: Ensure glean rules are removed
+  file:
+    path: "/etc/udev/rules.d/99-glean.rules"
+    state: absent
+
+- name: Add proxy settings to /etc/environment on localhost
+  lineinfile:
+    dest: /etc/environment
+    state: present
+    regexp: "^no_proxy"
+    line: "no_proxy={{ idf.proxy_settings.no_proxy }}"
+  delegate_to: localhost
+  become: true
+  when:
+    idf.proxy_settings is defined
+
+- name: Add proxy settings to /etc/environment on target node
+  lineinfile:
+    dest: /etc/environment
+    state: present
+    regexp: "^{{ item.name }}"
+    line: "{{ item.name }}={{ item.value }}"
+  with_items:
+    - {name: 'http_proxy', value: '{{ idf.proxy_settings.http_proxy }}' }
+    - {name: 'https_proxy', value: '{{ idf.proxy_settings.https_proxy }}' }
+    - {name: 'no_proxy', value: '{{ idf.proxy_settings.no_proxy }}' }
+  when:
+    idf.proxy_settings is defined
+
+- name: Configure networking for {{ ansible_os_family }}
+  include_tasks: "configure-network-{{ ansible_os_family }}.yml"
+
+# vim: set ts=2 sw=2 expandtab:
diff --git a/playbooks/roles/configure-targethosts/tasks/create-swap.yml b/playbooks/roles/configure-targethosts/tasks/create-swap.yml
new file mode 100644
index 0000000..b4a2352
--- /dev/null
+++ b/playbooks/roles/configure-targethosts/tasks/create-swap.yml
@@ -0,0 +1,57 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+# TODO: Sometimes mariadb gets stuck in a restart loop for lack of main memory,
+# using a swap file seems to solve the problem.
+
+- name: Check for swap file
+  stat:
+    path: /swapfile
+  register: swap
+
+- block:
+  - name: Create swap file
+    command: |
+      fallocate -l 2048M /swapfile
+
+  - name: Set swap file permissions
+    file:
+      path: /swapfile
+      state: "file"
+      owner: "root"
+      group: "root"
+      mode: "0600"
+
+  - name: Initialize swap file
+    command: mkswap /swapfile
+
+  - name: Enable swap file
+    command: swapon /swapfile
+
+  - name: Manage swap file in /etc/fstab
+    mount:
+      src: /swapfile
+      name: "none"
+      fstype: "swap"
+      opts: "sw,nofail"
+      dump: "0"
+      passno: "0"
+      state: present
+  when: swap.stat.exists == False
+
+# vim: set ts=2 sw=2 expandtab:
diff --git a/playbooks/roles/configure-targethosts/tasks/install-packages-Debian.yml b/playbooks/roles/configure-targethosts/tasks/install-packages-Debian.yml
new file mode 100644
index 0000000..9abd870
--- /dev/null
+++ b/playbooks/roles/configure-targethosts/tasks/install-packages-Debian.yml
@@ -0,0 +1,34 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+- name: Install packages
+  apt:
+    name: "{{ item }}"
+    state: present
+    update_cache: true
+  with_items:
+    - "apt-transport-https"
+    - "ca-certificates"
+    - "curl"
+    - "gnupg-agent"
+    - "software-properties-common"
+    - "chrony"
+    - "dbus"
+
+# vim: set ts=2 sw=2 expandtab:
diff --git a/playbooks/roles/configure-targethosts/tasks/install-packages-RedHat.yml b/playbooks/roles/configure-targethosts/tasks/install-packages-RedHat.yml
new file mode 100644
index 0000000..5477ad1
--- /dev/null
+++ b/playbooks/roles/configure-targethosts/tasks/install-packages-RedHat.yml
@@ -0,0 +1,31 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+- name: Install packages
+  action: >
+    {{ ansible_pkg_mgr }} name={{ item }} state=present update_cache=yes
+  with_items:
+    - "yum-utils"
+    - "device-mapper-persistent-data"
+    - "lvm2"
+    - "ca-certificates"
+    - "curl"
+    - "chrony"
+    - "dbus"
+
+# vim: set ts=2 sw=2 expandtab:
diff --git a/playbooks/roles/configure-targethosts/tasks/install-packages.yml b/playbooks/roles/configure-targethosts/tasks/install-packages.yml
new file mode 100644
index 0000000..2ea2322
--- /dev/null
+++ b/playbooks/roles/configure-targethosts/tasks/install-packages.yml
@@ -0,0 +1,23 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+- name: Install packages on {{ ansible_os_family }}
+  include_tasks: "install-packages-{{ ansible_os_family }}.yml"
+
+# vim: set ts=2 sw=2 expandtab:
diff --git a/playbooks/roles/configure-targethosts/tasks/main.yml b/playbooks/roles/configure-targethosts/tasks/main.yml
new file mode 100644
index 0000000..b573473
--- /dev/null
+++ b/playbooks/roles/configure-targethosts/tasks/main.yml
@@ -0,0 +1,25 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+- include: configure-network.yml
+- include: install-packages.yml
+- include: sync-time.yml
+- include: create-swap.yml
+
+# vim: set ts=2 sw=2 expandtab:
diff --git a/playbooks/roles/configure-targethosts/tasks/sync-time.yml b/playbooks/roles/configure-targethosts/tasks/sync-time.yml
new file mode 100644
index 0000000..1c96d12
--- /dev/null
+++ b/playbooks/roles/configure-targethosts/tasks/sync-time.yml
@@ -0,0 +1,59 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+- name: Add the OS specific variables
+  include_vars: '{{ ansible_os_family }}.yml'
+
+- name: Remove NTP if installed
+  action: >
+    {{ ansible_pkg_mgr }} name={{ item }} state=absent update_cache=yes
+  with_items:
+    - "ntp"
+
+- name: Install Chrony
+  action: >
+    {{ ansible_pkg_mgr }} name={{ item }} state=present update_cache=yes
+  with_items:
+    - "chrony"
+
+- name: Copy the chrony.conf template file
+  template:
+    src: "chrony.conf.j2"
+    dest: "{{ chrony_config_location }}"
+    owner: "root"
+    group: "root"
+    mode: "0755"
+  become: true
+  when: idf.ntp_servers is defined
+
+- name: Restart chrony
+  service:
+    name: "{{ chrony_service_name }}"
+    state: "restarted"
+  become: true
+
+
+- name: "NTP should be synchronized"
+  shell: timedatectl  | grep 'synchronized'
+  register: synchronized
+  changed_when: false
+  until: "'yes' in synchronized.stdout"
+  retries: 300
+  delay: 2
+
+# vim: set ts=2 sw=2 expandtab: