Procházet zdrojové kódy

Issue #360: Added cri-o & k8s installation tasks and removed docker installation

Signed-off-by: blesson-james <blesson_james@Dellteam>
Lucas A. Wilson před 3 roky
rodič
revize
5a5773c7f8
28 změnil soubory, kde provedl 1996 přidání a 500 odebrání
  1. 0 64
      control_plane/appliance_config.yml
  2. 135 0
      control_plane/input_params/base_vars.yml
  3. 32 0
      control_plane/input_params/idrac_vars.yml
  4. 69 0
      control_plane/input_params/login_vars.yml
  5. 68 0
      control_plane/input_params/powervault_me4_vars.yml
  6. 0 86
      control_plane/roles/control_plane_common/tasks/docker_installation.yml
  7. 455 0
      control_plane/roles/control_plane_common/tasks/fetch_base_inputs.yml
  8. 5 5
      control_plane/roles/control_plane_common/tasks/main.yml
  9. 135 292
      control_plane/roles/control_plane_common/tasks/password_config.yml
  10. 1 0
      control_plane/roles/control_plane_common/tasks/pre_requisite.yml
  11. 88 0
      control_plane/roles/control_plane_common/tasks/verify_omnia_params.yml
  12. 72 37
      control_plane/roles/control_plane_common/vars/main.yml
  13. 2 0
      control_plane/roles/control_plane_k8s/files/crio.conf
  14. 3 0
      control_plane/roles/control_plane_k8s/files/k8s-crio.conf
  15. 1 0
      control_plane/roles/control_plane_k8s/files/k8s.conf
  16. 18 0
      control_plane/roles/control_plane_k8s/files/k8s_dashboard_admin.yaml
  17. 11 0
      control_plane/roles/control_plane_k8s/files/metal-config.yaml
  18. 223 0
      control_plane/roles/control_plane_k8s/files/metallb.yaml
  19. 56 0
      control_plane/roles/control_plane_k8s/tasks/k8s_firewalld.yml
  20. 41 0
      control_plane/roles/control_plane_k8s/tasks/k8s_helm.yml
  21. 126 0
      control_plane/roles/control_plane_k8s/tasks/k8s_init.yml
  22. 123 0
      control_plane/roles/control_plane_k8s/tasks/k8s_installation.yml
  23. 129 0
      control_plane/roles/control_plane_k8s/tasks/k8s_services.yml
  24. 15 5
      control_plane/roles/control_plane_k8s/tasks/main.yml
  25. 95 0
      control_plane/roles/control_plane_k8s/vars/main.yml
  26. 3 5
      control_plane/roles/control_plane_repo/tasks/main.yml
  27. 78 0
      control_plane/roles/control_plane_repo/tasks/nfs_server_setup.yml
  28. 12 6
      control_plane/roles/control_plane_common/tasks/docker_volume.yml

+ 0 - 64
control_plane/appliance_config.yml

@@ -1,64 +0,0 @@
-# Copyright 2020 Dell Inc. or its subsidiaries. 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.
----
-
-# Password used while deploying OS on bare metal servers and for Cobbler UI.
-# The Length of the password should be at least 8.
-# The password must not contain -,\, ',"
-provision_password: ""
-
-# Password used for the AWX UI.
-# The Length of the password should be at least 8.
-# The password must not contain -,\, ',"
-awx_password: ""
-
-# The nic/ethernet card that needs to be connected to the HPC switch.
-# This nic will be configured by Omnia for the DHCP server.
-# Default value of nic is em1.
-hpc_nic: "em1"
-
-# The nic/ethernet card that will be connected to the public internet.
-# Default value of nic is em2
-public_nic: "em2"
-
-# This is the  path where user has kept the iso image that needs to be provisioned in target nodes.
-# The iso file should be CentOS7-2009-minimal edition.
-# Other iso file not supported.
-iso_file_path: ""
-
-# The mapping file consists of the MAC address and its respective IP address and hostname.
-# The format of mapping file should be MAC,hostname,IP and must be a CSV file.
-# A template for mapping file exists in omnia/examples and is named as mapping_file.csv.
-# This depicts the path where user has kept the mapping file for DHCP configurations.
-mapping_file_path: ""
-
-# The dhcp range for assigning the IPv4 address to the baremetal nodes.
-# Example: 10.1.23.1
-dhcp_gateway: ""
-dhcp_dns1: ""
-dhcp_dns2: ""
-dhcp_start_ip_range: ""
-dhcp_end_ip_range: ""
-
-# This is the timezone that will be set during provisioning of OS
-# Available timezone are provided in list control_plane/control_plane_common/files/timezone.txt
-# Default timezone will be set to "GMT"
-# Some of the other available timezone are EST,CET,MST,CST6CDT,PST8PDT
-timezone: "GMT"
-
-# Path to directory hosting ansible config file (ansible.cfg file)
-# Default value is "/etc/ansible"
-# This directory is on the host running ansible, if ansible is installed using dnf
-# If ansible is installed using pip, this path should be set
-ansible_config_file_path: /etc/ansible

+ 135 - 0
control_plane/input_params/base_vars.yml

@@ -12,3 +12,138 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 ---
+##All variables except mapping_file_path are mandatory##
+
+###default###
+
+# Path to directory hosting ansible config file (ansible.cfg file)
+# Default value is /etc/ansible
+# This directory is on the host running ansible, if ansible is installed using dnf
+# If ansible is installed using pip, this path should be set
+ansible_conf_file_path: /etc/ansible
+
+# This variable is used to enable ethernet switch configuration
+# It accepts boolean values "true" or "false". 
+# By default its value is "false".
+# If ethernet switch support is needed set this to "true"
+ethernet_switch_support: false
+
+# This variable is used to enable infiniband switch configuration
+# It accepts boolean values "true" or "false". 
+# By default its value is "false".
+# If infiniband configuration is needed set this to "true"
+ib_switch_support: false
+
+# This variable is used to enable powervault configuration
+# It accepts boolean values "true" or "false". 
+# By default its value is "false".
+# If powervault configuration is needed set this to "true"
+powervault_support: false
+
+# The nic/ethernet card that will be connected to the public internet.
+# Default value of nic is eno2
+public_nic: "eno2"
+
+# Kubernetes pod network CIDR for appliance k8s network
+# Make sure this value does not overlap with any of the host networks.
+# Default value is "192.168.0.0/16"
+appliance_k8s_pod_net_cidr: "192.168.0.0/16"
+
+### Usage: provision_idrac, network_ib, network_ethernet, powervault_me4 ###
+
+# The trap destination IP address is the IP address of the SNMP Server where the trap will be sent
+# If this variable is left blank, it means SNMP will be disabled
+# Provide a valid SNMP server IP
+snmp_trap_destination: ""
+
+# Provide the snmp community name needed
+# By default this is set to "public"
+snmp_community_name: "public"
+
+### Usage: webui_awx ###
+
+# Organization name that is created in AWX.
+# The default value is “DellEMC”
+awx_organization: "DellEMC"
+
+### Usage: provision_cobbler, provision_idrac ###
+
+# This is the timezone that will be set during provisioning of OS
+# Available timezones are provided in control_plane/common/files/timezone.txt
+# Default timezone will be "GMT"
+# Some of the other available timezones are EST,CET,MST,CST6CDT,PST8PDT
+timezone: "GMT"
+
+# This is the language that will be set during provisioning of the OS
+# Default language supported is "en-US"
+language: "en-US"
+
+# This is the path where the user has to place the iso image that needs to be provisioned in target nodes.
+# The iso file should be CentOS7-2009-minimal edition.
+# Other iso files are not supported.
+# Mandatory value required
+iso_file_path: ""
+
+### Usage: control_plane_device ###
+
+# The nic/ethernet card that needs to be connected to provision 
+# the fabric, idrac and powervault.
+# This nic will be configured by Omnia for the DHCP server.
+# Default value of nic is eno1
+mngmnt_network_nic: "eno1"
+
+# The dhcp range for assigning the IPv4 address
+# Example: 172.17.0.1
+# Mandatory value required
+mngmnt_network_dhcp_start_range: ""
+mngmnt_network_dhcp_end_range: ""
+
+# The mapping file consists of the MAC address and its respective IP address and hostname.
+# The format of mapping file should be MAC,hostname,IP and must be a CSV file.
+# Eg: xx:yy:zz:aa:bb,server,172.17.0.5
+# A template for mapping file exists in omnia/examples and is named as mapping_file.csv.
+# This depicts the path where user has kept the mapping file for DHCP configurations.
+mngmnt_mapping_file_path: ""
+
+### Usage: provision_cobbler ###
+
+# The nic/ethernet card that needs to be connected to provision the OS of bare metal servers
+# This nic will be configured by Omnia for the DHCP server.
+# Default value of nic is eno3
+host_network_nic: "eno3"
+
+# The dhcp range for assigning the IPv4 address
+# Example: 172.17.0.1
+# Mandatory value required
+host_network_dhcp_start_range: ""
+host_network_dhcp_end_range: ""
+
+dhcp_gateway: ""
+dhcp_dns1: ""
+dhcp_dns2: ""
+
+# The mapping file consists of the MAC address and its respective IP address and hostname.
+# The format of mapping file should be MAC,hostname,IP and must be a CSV file.
+# Eg: xx:yy:zz:aa:bb,server,172.17.0.5
+# A template for mapping file exists in omnia/examples and is named as mapping_file.csv.
+# This depicts the path where user has kept the mapping file for DHCP configurations.
+host_mapping_file_path: ""
+
+### Usage: control_plane_ib ###
+
+# The nic/ethernet card that needs to be connected to configure infiniband switch
+# This nic will be configured by Omnia for the DHCP server.
+# Default value of nic is ib0
+ib_network_nic: "ib0"
+
+# The dhcp range for assigning the IPv4 address
+# Example: 172.17.0.1
+ib_network_dhcp_start_range: ""
+ib_network_dhcp_end_range: ""
+
+# The mapping file consists of the MAC address and its respective IP address and hostname.
+# The format of mapping file should be MAC,hostname,IP and must be a CSV file.
+# Eg: xx:yy:zz:aa:bb,server,172.17.0.5
+# A template for mapping file exists in omnia/examples and is named as mapping_file.csv.
+# This depicts the path where user has kept the mapping file for DHCP configurations.
+ib_mapping_file_path: ""

+ 32 - 0
control_plane/input_params/idrac_vars.yml

@@ -12,3 +12,35 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 ---
+
+### Usage: provision_idrac ###
+
+# This indicates the system profile name used for BIOS configuration of the server
+# The values supported are - "Performance", "PerformancePerWatt(DAPC)", "PerformancePerWatt(OS)", "WorkstationPerformance".
+# The default value is "Performance"
+idrac_system_profile: "Performance"
+
+# Boolean value indicating whether OMNIA should perform firmware update or not
+# It takes values "true" or "false" indicating required and not required cases respectively.
+# Default value is "true"
+firmware_update_required: true
+
+#****Security Requirements Configuration****#
+###Enable the security parameters listed below only if you want to configure the security settings in idrac###
+###This feature will be enabled in all the servers (hpc nodes) listed in the idrac inventory###
+###To apply these settings please execute appropriate files in control_plane/tools directory###
+
+### Usage: idrac_secure_boot ###
+
+# Specify whether the secure boot mode to be enabled
+# By default secure boot will be "disabled"
+# If required it can be "enabled"
+uefi_secure_boot: "disabled"
+
+### Usage: idrac_system_lockdown ###
+
+# Specify whether the system lockdown to be enabled
+# By default system lockdown will be "disabled"
+# If required it can be "enabled"
+# Make sure system_lockdown is enabled only after OS provisioning is completed
+system_lockdown: "disabled"

+ 69 - 0
control_plane/input_params/login_vars.yml

@@ -12,3 +12,72 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 ---
+
+### Usage: provision_cobbler, provison_idrac ###
+
+# Password used while deploying OS on bare metal servers.
+# The Length of the password should be at least 8.
+# The password must not contain -,\, ',"
+# Mandatory value required
+provision_password: ""
+
+### Usage: provision_cobbler ###
+
+# Password used for cobbler
+# The Length of the password should be at least 8.
+# The password must not contain -,\, ',"
+# Mandatory value required
+cobbler_password: ""
+
+### Usage: webui_awx ###
+
+# Password used for awx UI
+# The Length of the password should be at least 8.
+# The password must not contain -,\, ',"
+#awx_password: ""
+
+### Usage: network_ethernet ###
+
+# The username for ethernet switch
+# The username must not contain -,\, ',"
+ethernet_switch_username: ""
+
+# Password used for ethernet switch
+# The Length of the password should be at least 8.
+# The password must not contain -,\, ',"
+ethernet_switch_password: ""
+
+### Usage: network_ib ###
+
+# The username for infiniband switch
+# The username must not contain -,\, ',"
+ib_username: ""
+
+# Password used for infiniband switch
+# The Length of the password should be at least 8.
+# The password must not contain -,\, ',"
+ib_password: ""
+
+### Usage: provision_idrac ###
+
+# The username for idrac
+# The username must not contain -,\, ',"
+# Mandatory value required
+idrac_username: ""
+
+# Password used for idrac
+# The Length of the password should be at least 8.
+# The password must not contain -,\, ',"
+# Mandatory value required
+idrac_password: ""
+
+### Usage: powervault_me4 ###
+
+# The username for powervault_me4
+# The username must not contain -,\, ',"
+powervault_me4_username: ""
+
+# Password used for powervault_me4
+# The Length of the password should be at least 8.
+# The password must not contain -,\, ',"
+powervault_me4_password: ""

+ 68 - 0
control_plane/input_params/powervault_me4_vars.yml

@@ -12,3 +12,71 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 ---
+
+### Usage: powervault_me4 ###
+
+# User type of powervault_me4
+# The vaules supported are "standard" and "SNMPv3"
+# The default value is "standard"
+powervault_me4_usertype: "standard"
+
+# The user roles for managing and monitoring powervault_me4
+# The values supported are "monitor" and "manage"
+# The default value is "manage"
+# Only "manage" role allows - Addition of disk groups and creation of volumes 
+powervault_me4_roles: "manage"
+
+# This variable indicates the language selection
+# Currently only "English" is supported
+locale: "English"
+
+# Specify the system name to identify the system
+# By default it is set to "Uninitialized Name"
+powervault_me4_system_name: "Unintialized Name"
+
+# Specify the snmp notification level
+# critical: Sends notifications for Critical events only.
+# error: Sends notifications for Error and Critical events.
+# warn: Sends notifications for Warning, Error, and Critical events.
+# resolved: Sends notifications for Resolved, Warning, Error, and Critical events.
+# info: Sends notifications for all events.
+# none: All events are excluded from trap notification and traps are disabled. 
+# However, Critical events and managed-logs events 400–402 are sent regardless of the notification setting.
+# Default value is "none"
+powervault_me4_snmp_notify_level: "none"
+
+# Specify the disk group name
+# If left blank, system automatically assigns the name
+powervault_me4_disk_group_name: ""
+
+# Specify the disk type
+# Values supported are "Virtual" and "Read Cache"
+powervault_me4_disk_type: "Virtual"
+
+# Specify the required RAID Level
+# The different RAID levels and the min and max number of disks supported for each RAID are
+# RAID1: 2
+# RAID5: 3-16
+# RAID6: 4-16
+# RAID10: 4-16
+# ADAPT: 12-128
+# Default value is "RAID1"
+# If Type "Read Cache" is selected, then RAID levels are not required
+powervault_me4_raid_levels: "RAID1"
+
+# Specify the range of disks
+# Select a range of disks within an enclosure by entering a comma-separated list that contains 
+# the enclosure number and disk range in the Enter Range of Disks text box. 
+# Use the format enclosure-number.disk-range,enclosure-number.disk-range. 
+# For example, to select disks 3-12 in enclosure 1 and 5-23 in enclosure 2, enter 1.3-12,2.5-23.
+# For ME4012 - 0.0-0.11,1.0-1.11 are the allowed values
+powervault_me4_disk_range: ""
+
+# Specify the volume name
+# Cannot be left blank
+# the default value is "pv_omnia"
+powervault_me4_volume_name: "pv_omnia"
+
+# Specify the volume size
+# Format: 100GB <SizeGB>
+powervault_me4_volume_size: "100GB"

+ 0 - 86
control_plane/roles/control_plane_common/tasks/docker_installation.yml

@@ -1,86 +0,0 @@
-#  Copyright 2020 Dell Inc. or its subsidiaries. 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.
----
-
-- name: Add docker repo
-  get_url:
-    url: "{{ docker_repo_url }}"
-    dest: "{{ docker_repo_dest }}"
-  tags: install
-
-- name: Enable docker edge and test repo
-  ini_file:
-    dest: "{{ docker_repo_dest }}"
-    section: "{{ item }}"
-    option: enabled
-    value: "{{ success }}"
-  with_items: ['docker-ce-test', 'docker-ce-edge']
-  tags: install
-
-- name: Install docker
-  package:
-    name: "{{ container_repo_install }}"
-    state: present
-  become: yes
-  tags: install
-
-- name: Start services
-  service:
-    name: "{{ container_type }}"
-    state: started
-    enabled: yes
-  become: yes
-  tags: install
-
-- name: Uninstall docker-py using pip
-  pip:
-    name: ['docker-py','docker']
-    state: absent
-  tags: install
-
-- name: Install docker using pip
-  pip:
-    name: docker
-    state: present
-  tags: install
-
-- name: Update pip
-  command: pip3 install --upgrade pip
-  changed_when: false
-
-- name: Installation using python3
-  pip:
-    name: "{{ docker_compose }}"
-    executable: pip3
-  tags: install
-
-- name: Versionlock docker
-  command: "yum versionlock '{{ item }}'"
-  args:
-    warn: false
-  with_items:
-    - "{{ container_repo_install }}"
-  changed_when: true
-  tags: install
-
-- name: Configure docker
-  copy:
-    src: daemon.json
-    dest: "{{ daemon_dest }}"
-  tags: install
-
-- name: Restart docker
-  service:
-    name: docker
-    state: restarted

+ 455 - 0
control_plane/roles/control_plane_common/tasks/fetch_base_inputs.yml

@@ -0,0 +1,455 @@
+# Copyright 2021 Dell Inc. or its subsidiaries. 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.
+---
+
+- name: Include base variable file base_vars.yml
+  include_vars: "{{ base_vars_filename }}"
+  no_log: true
+
+- name: Validate input parameters of base_vars are not empty
+  fail:
+    msg: "{{ input_base_failure_msg }}"
+  register: input_base_check
+  when:
+    - ansible_conf_file_path | length < 1 or
+      public_nic | length < 1 or
+      appliance_k8s_pod_net_cidr | length < 1 or
+      awx_organization | length < 1 or
+      timezone | length < 1 or
+      language | length < 1 or
+      iso_file_path | length < 1 or
+      mngmnt_network_nic | length < 1 or
+      mngmnt_network_dhcp_start_range | length < 1 or
+      mngmnt_network_dhcp_end_range | length < 1 or
+      host_network_nic | length < 1 or
+      host_network_dhcp_start_range | length < 1 or
+      host_network_dhcp_end_range | length < 1 or
+      dhcp_gateway | length < 1 or
+      dhcp_dns1 | length < 1 or
+      dhcp_dns2 | length < 1
+
+- name: Validate infiniband base_vars are not empty
+  fail:
+    msg: "{{ input_base_failure_msg }} for infiniBand as ib_switch_support is true"
+  register: ib_check
+  when:
+    - ib_network_nic | length < 1 or
+      ib_network_dhcp_start_range | length < 1 or
+      ib_network_dhcp_end_range | length < 1 and ib_switch_support
+
+- name: Set facts to validate snmp support
+  set_fact:
+    snmp_enabled: false   
+    mngmnt_mapping_file: false
+    host_mapping_file: false
+    ib_mapping_file: false
+
+- name: Verify snmp_trap_destination IP address
+  set_fact:
+    snmp_enabled: true
+  when: snmp_trap_destination | length > 1
+
+- name: Assert snmp trap destination address
+  assert:
+    that:
+      - snmp_enabled
+      - snmp_trap_destination | length > 7
+      - snmp_trap_destination | ipv4
+    success_msg: "{{ success_snmp_trap_dest }}"
+    fail_msg: "{{ fail_snmp_trap_dest }}"
+  when: snmp_enabled
+
+- name: Assert snmp community string
+  assert:
+    that:
+      - snmp_enabled
+      - snmp_community_name
+    success_msg: "{{ success_snmp_comm_msg }}"
+    fail_msg: "{{ fail_snmp_comm_msg }}"
+  when: snmp_enabled
+
+- name: Check whether ansible config file exists
+  stat:
+    path: "{{ ansible_conf_file_path }}/ansible.cfg"
+  register: ansible_conf_exists
+
+- name: Create the directory if it does not exist
+  file:
+    path: "{{ ansible_conf_file_path }}"
+    state: directory
+    mode: "{{ file_perm }}"
+  when: not ansible_conf_exists.stat.exists
+  changed_when: false
+
+- name: Create ansible config file if it does not exist
+  copy:
+    dest: '{{ ansible_conf_file_path }}/ansible.cfg'
+    mode: "{{ file_perm }}"
+    content: |
+      [defaults]
+      log_path = /var/log/omnia.log
+  when: not ansible_conf_exists.stat.exists
+
+- name: Assert ethernet_switch_support
+  assert:
+    that:
+      - ethernet_switch_support == true or ethernet_switch_support == false
+    success_msg: "{{ ethernet_switch_support_success_msg }}"
+    fail_msg: "{{ ethernet_switch_support_fail_msg }}"
+
+- name: Assert ib_switch_support
+  assert:
+    that:
+      - ib_switch_support == true or ib_switch_support == false
+    success_msg: "{{ ib_switch_support_success_msg }}"
+    fail_msg: "{{ ib_switch_support_fail_msg }}"
+
+- name: Assert powervault_support
+  assert:
+    that:
+      - powervault_support == true or powervault_support == false
+    success_msg: "{{ powervault_support_success_msg }}"
+    fail_msg: "{{ powervault_support_fail_msg }}"
+
+- name: Fetch the network interfaces in UP state in the system
+  shell: set -o pipefail && ip a | awk '/state UP/{print $2}'
+  register: nic_addr_up
+  changed_when: false
+  
+- name: Assert public nic
+  assert:
+    that:
+      - public_nic in nic_addr_up.stdout
+    success_msg: "{{ success_msg_public_nic }}"
+    fail_msg: "{{ fail_msg_public_nic }}"
+
+- name: Fetch the system public IP
+  set_fact:
+    public_ip: "{{ lookup('vars','ansible_'+public_nic).ipv4.address }}"
+
+- name: Assert kubernetes pod network CIDR
+  assert:
+    that:
+      - appliance_k8s_pod_net_cidr | ipv4
+      - appliance_k8s_pod_net_cidr | length > 9
+      - '"/" in appliance_k8s_pod_net_cidr '
+    success_msg: "{{ success_msg_k8s_pod_network_cidr }}"
+    fail_msg: "{{ fail_msg_k8s_pod_network_cidr }}"
+
+- name: Assert Organization in awx
+  assert:
+    that:
+      - awx_organization | length >= min_username_length
+      - awx_organization | length < max_length
+      - '"-" not in awx_organization '
+      - '"\\" not in awx_organization '
+      - '"\"" not in awx_organization '
+      - " \"'\" not in awx_organization "
+    success_msg: "{{ success_awx_organization }}"
+    fail_msg: "{{ fail_awx_organization }}"
+
+- name: Check timezone file
+  command: grep -Fx "{{ timezone }}" {{ role_path }}/files/timezone.txt
+  ignore_errors: yes
+  register: timezone_out
+  changed_when: false
+
+- name: Assert timezone
+  assert:
+    that: timezone in timezone_out.stdout
+    success_msg: "{{ success_timezone_msg }}"
+    fail_msg: "{{ fail_timezone_msg }}"
+  register: timezone_check
+
+- name: Assert language for provisioning nodes
+  fail:
+    msg: "{{ fail_language }}"
+  when: '"en-US" not in language'
+
+- name: Verify the iso_file_path
+  stat:
+    path: "{{ iso_file_path }}"
+  register: result_path_iso_file
+
+- name : Assert iso_file_path
+  fail:
+    msg: "{{ invalid_iso_file_path }}"
+  when: ( not result_path_iso_file.stat.exists ) and ( ".iso" not in  iso_file_path )
+
+- name: Fail when iso path valid but image not right
+  fail:
+    msg: "{{ invalid_iso_file_path }}"
+  when: ( result_path_iso_file.stat.exists ) and ( ".iso" not in iso_file_path )
+
+####management_net_dhcp_start_end_range
+- name: Assert management network nic
+  assert:
+    that:
+      - mngmnt_network_nic in nic_addr_up.stdout
+    success_msg: "{{ success_msg_mngmnt_network_nic }}"
+    fail_msg: "{{ fail_msg_mngmnt_network_nic }}"
+
+- name: Fetch the management network ip, netmask and subnet
+  set_fact:
+    mngmnt_network_ip: "{{ lookup('vars','ansible_'+mngmnt_network_nic).ipv4.address }}"
+    mngmnt_network_netmask: "{{ lookup('vars','ansible_'+mngmnt_network_nic).ipv4.netmask }}"
+    mngmnt_network_subnet: "{{ lookup('vars','ansible_'+mngmnt_network_nic).ipv4.network }}"
+
+- name: Check the subnet of management network dhcp start range
+  shell: |
+    IFS=. read -r i1 i2 i3 i4 <<< "{{ mngmnt_network_dhcp_start_range }}"
+    IFS=. read -r m1 m2 m3 m4 <<< "{{ mngmnt_network_netmask }}"
+    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
+  args:
+    warn: no
+  register: dhcp_start_mgmnt_result
+  changed_when: false
+
+- name: Set the start dhcp subnet for management network
+  set_fact:
+    dhcp_start_mgmnt: "{{ dhcp_start_mgmnt_result.stdout }}"
+
+- name: Check the subnet of dhcp end range for management network
+  shell: |
+    IFS=. read -r i1 i2 i3 i4 <<< "{{ mngmnt_network_dhcp_end_range }}"
+    IFS=. read -r m1 m2 m3 m4 <<< "{{ mngmnt_network_netmask }}"
+    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
+  register: dhcp_end_mgmnt_result
+  changed_when: false
+
+- name: Set the end dhcp subnet for management network
+  set_fact:
+    dhcp_end_mgmnt: "{{ dhcp_end_mgmnt_result.stdout }}"
+
+- name: Assert management_net_dhcp_start_range
+  assert:
+    that:
+      - mngmnt_network_dhcp_start_range
+      - mngmnt_network_dhcp_start_range | ipv4
+      - mngmnt_network_dhcp_start_range != mngmnt_network_dhcp_end_range
+      - dhcp_start_mgmnt == mngmnt_network_subnet
+      - dhcp_start_mgmnt == dhcp_end_mgmnt
+    success_msg: "{{ success_dhcp_range }} for management network"
+    fail_msg: "{{ fail_dhcp_range }} for management network"
+
+- name: Assert management_net_dhcp_end_range
+  assert:
+    that:
+      - mngmnt_network_dhcp_end_range
+      - mngmnt_network_dhcp_end_range | ipv4
+      - mngmnt_network_dhcp_start_range != mngmnt_network_dhcp_end_range
+      - dhcp_end_mgmnt == mngmnt_network_subnet
+      - dhcp_start_mgmnt == dhcp_end_mgmnt
+    success_msg: "{{ success_dhcp_range }} for management network"
+    fail_msg: "{{ fail_dhcp_range }} for management network"
+
+- name: Set the mapping file value for management network
+  set_fact:
+    mngmnt_mapping_file: true
+  when: mngmnt_mapping_file_path | length > 0
+
+- name: Assert valid mngmnt_mapping_file_path
+  stat:
+    path: "{{ mngmnt_mapping_file_path }}"
+  when: mngmnt_mapping_file
+  register: result_mngmnt_mapping_file
+
+- name : Valid mngmnt_mapping_file_path
+  fail:
+    msg: "{{ invalid_mapping_file_path }} for management network"
+  when: mngmnt_mapping_file and not result_mngmnt_mapping_file.stat.exists
+#########
+
+###Host network####
+- name: Assert host network nic
+  assert:
+    that:
+      - host_network_nic in nic_addr_up.stdout
+    success_msg: "{{ success_msg_host_network_nic }}"
+    fail_msg: "{{ fail_msg_host_network_nic }}"
+
+- name: Fetch the host network ip, netmask and subnet
+  set_fact:
+    hpc_ip: "{{ lookup('vars','ansible_'+host_network_nic).ipv4.address }}"
+    netmask: "{{ lookup('vars','ansible_'+host_network_nic).ipv4.netmask }}"
+    subnet: "{{ lookup('vars','ansible_'+host_network_nic).ipv4.network }}"
+
+- name: Check the subnet of host network dhcp start range
+  shell: |
+    IFS=. read -r i1 i2 i3 i4 <<< "{{ host_network_dhcp_start_range }}"
+    IFS=. read -r m1 m2 m3 m4 <<< "{{ netmask }}"
+    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
+  args:
+    warn: no
+  register: dhcp_start_host_result
+  changed_when: false
+
+- name: Set the start dhcp subnet for host network
+  set_fact:
+    dhcp_start_host: "{{ dhcp_start_host_result.stdout }}"
+
+- name: Check the subnet of dhcp end range for host network
+  shell: |
+    IFS=. read -r i1 i2 i3 i4 <<< "{{ host_network_dhcp_end_range }}"
+    IFS=. read -r m1 m2 m3 m4 <<< "{{ netmask }}"
+    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
+  register: dhcp_end_host_result
+  changed_when: false
+
+- name: Set the end dhcp subnet for host network
+  set_fact:
+    dhcp_end_host: "{{ dhcp_end_host_result.stdout }}"
+
+- name: Assert host_network_dhcp_start_range
+  assert:
+    that:
+      - host_network_dhcp_start_range
+      - host_network_dhcp_start_range | ipv4
+      - host_network_dhcp_start_range != host_network_dhcp_end_range
+      - dhcp_start_host == subnet
+      - dhcp_start_host == dhcp_end_host
+    success_msg: "{{ success_dhcp_range }} for host network"
+    fail_msg: "{{ fail_dhcp_range }} for host network"
+
+- name: Assert host_network_dhcp_end_range
+  assert:
+    that:
+      - host_network_dhcp_end_range
+      - host_network_dhcp_end_range | ipv4
+      - host_network_dhcp_start_range != host_network_dhcp_end_range
+      - dhcp_end_host == subnet
+      - dhcp_start_host == dhcp_end_host
+    success_msg: "{{ success_dhcp_range }} for host network"
+    fail_msg: "{{ fail_dhcp_range }} for host network"
+
+- name: Set the mapping file value for host network
+  set_fact:
+    host_mapping_file: true
+  when: host_mapping_file_path | length > 0
+  
+- name: Assert valid mapping_file_path
+  stat: 
+    path: "{{ host_mapping_file_path }}"
+  when: host_mapping_file
+  register: result_host_mapping_file
+  
+- name: Valid mapping_file_path
+  fail:
+    msg: "{{ invalid_mapping_file_path }} for host_network"
+  when: host_mapping_file and not result_host_mapping_file.stat.exists
+
+- name: Verify different nics
+  assert:
+    that:
+      - public_nic != mngmnt_network_nic
+      - mngmnt_network_nic != host_network_nic
+      - public_nic != host_network_nic
+    success_msg: "{{ success_msg_different_nics }}"
+    fail_msg: "{{ fail_msg_different_nics }}"
+
+########
+- name: Assert infiniband network nic
+  assert:
+    that:
+      - ib_network_nic in nic_addr_up.stdout
+    success_msg: "{{ success_msg_ib_network_nic }}"
+    fail_msg: "{{ fail_msg_ib_network_nic }}"
+  when: ib_switch_support
+
+- name: Fetch the infiniband network ip, netmask and subnet
+  set_fact:
+    ib_ip: "{{ lookup('vars','ansible_'+ib_network_nic).ipv4.address }}"
+    ib_netmask: "{{ lookup('vars','ansible_'+ib_network_nic).ipv4.netmask }}"
+    ib_subnet: "{{ lookup('vars','ansible_'+ib_network_nic).ipv4.network }}"
+  when: ib_switch_support
+
+- name: Check the subnet of infiniband network dhcp start range
+  shell: |
+    IFS=. read -r i1 i2 i3 i4 <<< "{{ ib_network_dhcp_start_range }}"
+    IFS=. read -r m1 m2 m3 m4 <<< "{{ ib_netmask }}"
+    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
+  args:
+    warn: no
+  register: dhcp_start_ib_result
+  when: ib_switch_support
+  changed_when: false
+
+- name: Set the start dhcp subnet for infiniband network
+  set_fact:
+    dhcp_start_ib: "{{ dhcp_start_ib_result.stdout }}"
+  when: ib_switch_support
+
+- name: Check the subnet of dhcp end range for infiniband network
+  shell: |
+    IFS=. read -r i1 i2 i3 i4 <<< "{{ ib_network_dhcp_end_range }}"
+    IFS=. read -r m1 m2 m3 m4 <<< "{{ ib_netmask }}"
+    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
+  register: dhcp_end_ib_result
+  when: ib_switch_support
+  changed_when: false
+
+- name: Set the end dhcp subnet for infiniband network
+  set_fact:
+    dhcp_end_ib: "{{ dhcp_end_ib_result.stdout }}"
+  when: ib_switch_support
+
+- name: Assert infiniband_net_dhcp_start_range
+  assert:
+    that:
+      - ib_network_dhcp_start_range
+      - ib_network_dhcp_start_range | ipv4
+      - ib_network_dhcp_start_range != ib_network_dhcp_end_range
+      - dhcp_start_ib == ib_subnet
+      - dhcp_start_ib == dhcp_end_ib
+    success_msg: "{{ success_dhcp_range }} for infiniband network"
+    fail_msg: "{{ fail_dhcp_range }} for infiniband network"
+  when: ib_switch_support
+
+- name: Assert infiniband_net_dhcp_end_range
+  assert:
+    that:
+      - ib_network_dhcp_end_range
+      - ib_network_dhcp_end_range | ipv4
+      - ib_network_dhcp_start_range != ib_network_dhcp_end_range
+      - dhcp_end_ib == ib_subnet
+      - dhcp_start_ib == dhcp_end_ib
+    success_msg: "{{ success_dhcp_range }} for infiniband network"
+    fail_msg: "{{ fail_dhcp_range }} for infiniband network"
+  when: ib_switch_support
+
+- name: Set the mapping file value for infiniband
+  set_fact:
+    ib_mapping_file: true
+  when: (ib_switch_support) and (ib_mapping_file_path | length > 0)
+
+- name: Assert valid infiniband_mapping_file_path
+  stat:
+    path: "{{ ib_mapping_file_path }}"
+  when: ib_switch_support and ib_mapping_file
+  register: result_ib_mapping_file
+
+- name : Valid infiniband_mapping_file_path
+  fail:
+    msg: "{{ invalid_mapping_file_path }} for infiniBand network configuration"
+  when: ib_mapping_file and (not result_ib_mapping_file.stat.exists)
+
+- name: Verify different nics with infiniband nic
+  assert:
+    that:
+      - public_nic != ib_network_nic
+      - mngmnt_network_nic != ib_network_nic
+      - ib_network_nic != host_network_nic
+    success_msg: "{{ success_msg_different_nics_ib }}"
+    fail_msg: "{{ fail_msg_different_nics_ib }}"
+  when: ib_switch_support

+ 5 - 5
control_plane/roles/control_plane_common/tasks/main.yml

@@ -26,10 +26,10 @@
   import_tasks: package_installation.yml
 
 - name: Basic Configuration
-  import_tasks: password_config.yml
+  import_tasks: fetch_base_inputs.yml
 
-- name: Docker installation and configuration
-  import_tasks: docker_installation.yml
+- name: Credentials Configuration
+  import_tasks: password_config.yml
 
-- name: Docker volume creation
-  import_tasks: docker_volume.yml
+- name: Omnia inputs validation
+  import_tasks: verify_omnia_params.yml

+ 135 - 292
control_plane/roles/control_plane_common/tasks/password_config.yml

@@ -13,20 +13,20 @@
 # limitations under the License.
 ---
 
-- name: Check input config file is encrypted
-  command: cat {{ input_config_filename }}
+- name: Check login_vars file is encrypted
+  command: cat {{ login_vars_filename }}
   changed_when: false
   register: config_content
 
-- name: Decrpyt appliance_config.yml
+- name: Decrpyt login_vars.yml
   command: >-
-    ansible-vault decrypt {{ input_config_filename }}
+    ansible-vault decrypt {{ login_vars_filename }}
     --vault-password-file {{ vault_filename }}
   changed_when: false
   when: "'$ANSIBLE_VAULT;' in config_content.stdout"
 
-- name: Include variable file appliance_config.yml
-  include_vars: "{{ input_config_filename }}"
+- name: Include variable file login_vars.yml
+  include_vars: "{{ login_vars_filename }}"
   no_log: true
 
 - name: Validate input parameters are not empty
@@ -35,95 +35,25 @@
   register: input_config_check
   when:
     - provision_password | length < 1 or
-      awx_password | length < 1 or
-      hpc_nic | length < 1 or
-      public_nic | length < 1 or
-      iso_file_path | length < 1 or
-      dhcp_start_ip_range | length < 1 or
-      dhcp_end_ip_range | length < 1 or
-      dhcp_gateway | length < 1 or
-      dhcp_dns1 | length < 1 or
-      dhcp_dns2 | length < 1 or
-      timezone | length < 1 or
-      ansible_config_file_path | length < 1
+      cobbler_password | length < 1 or      
+      idrac_username | length < 1 or
+      idrac_password | length < 1      
 
-- name: Save input variables from file
-  set_fact:
-    cobbler_password: "{{ provision_password }}"
-    admin_password: "{{ awx_password }}"
-    nic:  "{{ hpc_nic }}"
-    internet_nic: "{{ public_nic }}"
-    path_for_iso_file: "{{ iso_file_path }}"
-    dhcp_gateway: "{{ dhcp_gateway | ipv4 }}"
-    dhcp_dns1: "{{ dhcp_dns1 | ipv4 }}"
-    dhcp_dns2: "{{ dhcp_dns2 | ipv4 }}"
-    dhcp_start_ip: "{{ dhcp_start_ip_range | ipv4 }}"
-    dhcp_end_ip: "{{ dhcp_end_ip_range | ipv4 }}"
-    mapping_file: false
-    path_for_mapping_file: "{{ mapping_file_path }}"
-    ks_timezone: "{{ timezone }}"
-    ansible_conf_file_path: "{{ ansible_config_file_path ​}}"
+- name: Assert provision_password
+  assert:
+    that:
+      - provision_password | length > min_length | int - 1
+      - provision_password | length < max_length | int + 1
+      - '"-" not in provision_password '
+      - '"\\" not in provision_password '
+      - '"\"" not in provision_password '
+      - " \"'\" not in provision_password "
+    success_msg: "{{ success_msg_provision_password }}"
+    fail_msg: "{{ fail_msg_provision_password }}"
   no_log: true
+  register: provision_password_check
 
-- name: Check whether ansible config file exists
-  stat:
-    path: "{{ ansible_conf_file_path }}/ansible.cfg"
-  register: ansible_conf_exists
-
-- name: Create the directory if it does not exist
-  file:
-    path: "{{ ansible_conf_file_path }}"
-    state: directory
-    mode: "{{ file_perm }}"
-  when: not ansible_conf_exists.stat.exists
-  changed_when: false
-
-- name: Create ansible config file if it does not exist
-  copy:
-    dest: '{{ ansible_conf_file_path }}/ansible.cfg'
-    mode: "{{ file_perm }}"
-    content: |
-      [defaults]
-      log_path = /var/log/omnia.log
-  when: not ansible_conf_exists.stat.exists
-
-- name: Get the system hpc ip
-  shell:  "ifconfig {{ hpc_nic }} | grep 'inet' |cut -d: -f2 |  awk '{ print $2}'"
-  register: ip
-  changed_when: false
-
-- name: Get the system public ip
-  shell:  "ifconfig {{ internet_nic }} | grep 'inet' |cut -d: -f2 |  awk '{ print $2}'"
-  register: internet_ip
-  changed_when: false
-
-- name: Get the system netmask
-  shell:  "ifconfig {{ hpc_nic }} | grep 'inet' |cut -d: -f2 |  awk '{ print $4}'"
-  register: net
-  changed_when: false
-
-- name: HPC nic IP
-  set_fact:
-    hpc_ip: "{{ ip.stdout }}"
-    public_ip: "{{ internet_ip.stdout }}"
-
-- name:  Netmask
-  set_fact:
-    netmask: "{{ net.stdout }}"
-
-- name: shell try
-  shell: |
-    IFS=. read -r i1 i2 i3 i4 <<< "{{ hpc_ip }}"
-    IFS=. read -r m1 m2 m3 m4 <<< "{{ netmask }}"
-    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
-  register: sub_result
-  changed_when: false
-
-- name: Subnet
-  set_fact:
-    subnet: "{{ sub_result.stdout }}"
-
-- name: Assert provision_password
+- name: Assert cobbler_password
   assert:
     that:
       - cobbler_password | length > min_length | int - 1
@@ -132,160 +62,145 @@
       - '"\\" not in cobbler_password '
       - '"\"" not in cobbler_password '
       - " \"'\" not in cobbler_password "
-    success_msg: "{{ success_msg_provision_password }}"
-    fail_msg: "{{ fail_msg_provision_password }}"
+    success_msg: "{{ success_msg_cobbler_password }}"
+    fail_msg: "{{ fail_msg_cobbler_password }}"
   no_log: true
   register: cobbler_password_check
 
-- name: Assert awx_password
+- name: Assert idrac_username
   assert:
     that:
-        - admin_password | length > min_length | int - 1
-        - admin_password | length < max_length | int + 1
-        - '"-" not in admin_password '
-        - '"\\" not in admin_password '
-        - '"\"" not in admin_password '
-        - " \"'\" not in admin_password "
-    success_msg: "{{ success_msg_awx_password }}"
-    fail_msg: "{{ fail_msg_awx_password }}"
+      - idrac_username | length >= min_username_length
+      - idrac_username | length < max_length
+      - '"-" not in idrac_username '
+      - '"\\" not in idrac_username '
+      - '"\"" not in idrac_username '
+      - " \"'\" not in idrac_username "
+    success_msg: "{{ success_idrac_username }}"
+    fail_msg: "{{ fail_idrac_username }}"
   no_log: true
-  register: awx_password_check
 
-- name: Assert hpc_ip
+- name: Assert idrac_password
   assert:
     that:
-      - hpc_ip | length > 7
-    success_msg: "{{ success_hpc_ip }}"
-    fail_msg: "{{ fail_hpc_ip }}"
-  register: hpc_ip_check
+      - idrac_password | length > min_username_length | int - 1
+      - idrac_password | length < max_length | int + 1
+      - '"-" not in idrac_password '
+      - '"\\" not in idrac_password '
+      - '"\"" not in idrac_password '
+      - " \"'\" not in idrac_password "
+    success_msg: "{{ success_msg_idrac_password }}"
+    fail_msg: "{{ fail_msg_idrac_password }}"
+  no_log: true
+  register: idrac_password_check
 
-- name: Assert public_ip
+- name: Verify ethernet_switch_username and ethernet_switch_password are not empty
   assert:
     that:
-      - public_ip | length > 7
-    success_msg: "{{ success_hpc_ip }}"
-    fail_msg: "{{ fail_hpc_ip }}"
-  register: public_ip_check
+      - ethernet_switch_username | length > 0
+      - ethernet_switch_password | length > 0
+    success_msg: "{{ ethernet_params_success_msg }}"
+    fail_msg: "{{ ethernet_params_empty_fail_msg }}"
+  when: ethernet_switch_support
 
-- name: Assert hpc_nic
+- name: Assert ethernet_switch_username
   assert:
     that:
-      - nic | length > nic_min_length | int - 1
-      - nic != internet_nic
-    success_msg: "{{ success_msg_hpc_nic }}"
-    fail_msg: "{{ fail_msg_hpc_nic }}"
-  register: hpc_nic_check
-
-- name: Assert public_nic
+      - ethernet_switch_username | length >= min_username_length
+      - ethernet_switch_username | length < max_length
+      - '"-" not in ethernet_switch_username '
+      - '"\\" not in ethernet_switch_username '
+      - '"\"" not in ethernet_switch_username '
+      - " \"'\" not in ethernet_switch_username "
+    success_msg: "{{ success_ethernet_switch_username }}"
+    fail_msg: "{{ fail_ethernet_switch_username }}"
+  when: ethernet_switch_support
+
+- name: Assert ethernet_switch_password
   assert:
     that:
-      - internet_nic | length > nic_min_length | int - 1
-      - nic != internet_nic
-    success_msg: "{{ success_msg_public_nic }}"
-    fail_msg: "{{ fail_msg_public_nic }}"
-  register: public_nic_check
+      - ethernet_switch_password | length > min_username_length | int - 1
+      - ethernet_switch_password | length < max_length | int + 1
+      - '"-" not in ethernet_switch_password '
+      - '"\\" not in ethernet_switch_password '
+      - '"\"" not in ethernet_switch_password '
+      - " \"'\" not in ethernet_switch_password "
+    success_msg: "{{ success_msg_ethernet_switch_password }}"
+    fail_msg: "{{ fail_msg_ethernet_switch_password }}"
+  when: ethernet_switch_support
+  no_log: true
 
-- name: Assert mapping_file_exists
+- name: Verify ib_username and ib_password are not empty
   assert:
     that:
-      - "( mapping_file == true ) or ( mapping_file == false )"
-    success_msg: "{{ success_mapping_file }}"
-    fail_msg: "{{ fail_mapping_file }}"
-
-- name: Set the mapping file value
-  set_fact:
-    mapping_file: true
-  when: path_for_mapping_file != ""
-  
-- name: Assert valid mapping_file_path
-  stat: 
-    path: "{{ path_for_mapping_file }}"
-  when: mapping_file == true
-  register: result_path_mapping_file
-  
-- name : Valid mapping_file_path
-  fail:
-    msg: "{{ invalid_mapping_file_path }}"
-  when: ( mapping_file == true ) and ( result_path_mapping_file.stat.exists == false )
-
-- name: Assert valid iso_file_path
-  stat:
-    path: "{{ path_for_iso_file }}"
-  register: result_path_iso_file
-
-- name : Incorrect iso_file_path
-  fail:
-    msg: "{{ invalid_iso_file_path }}"
-  when: ( result_path_iso_file.stat.exists == false ) and ( ".iso" not in  path_for_iso_file )
-
-- name: Fail when iso path valid but image not right
-  fail:
-    msg: "{{ invalid_iso_file_path }}"
-  when: ( result_path_iso_file.stat.exists == true ) and ( ".iso" not in path_for_iso_file )
-
-- name: Check the subnet of dhcp start range
-  shell: |
-    IFS=. read -r i1 i2 i3 i4 <<< "{{ dhcp_start_ip }}"
-    IFS=. read -r m1 m2 m3 m4 <<< "{{ netmask }}"
-    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
-  args:
-    warn: no
-  register: dhcp_start_sub_result
-  changed_when: false
-  when: dhcp_start_ip != "false"
-
-- name: Set the start dhcp subnet
-  set_fact:
-    dhcp_start_sub: "{{ dhcp_start_sub_result.stdout }}"
-  when: dhcp_start_ip != "false"
-
-- name: Check the subnet of dhcp end range
-  shell: |
-    IFS=. read -r i1 i2 i3 i4 <<< "{{ dhcp_end_ip }}"
-    IFS=. read -r m1 m2 m3 m4 <<< "{{ netmask }}"
-    printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
-  register: dhcp_end_sub_result
-  when: dhcp_end_ip != "false"
-  changed_when: false
+      - ib_username | length > 0
+      - ib_password | length > 0
+    success_msg: "{{ ib_params_success_msg }}"
+    fail_msg: "{{ ib_params_empty_fail_msg }}"
+  when: ib_switch_support
 
-- name: Set the end dhcp subnet
-  set_fact:
-    dhcp_end_sub: "{{ dhcp_end_sub_result.stdout }}"
-  when: dhcp_end_ip != "false"
-
-- name: Assert dhcp_start_ip_range
+- name: Assert ib_username
   assert:
     that:
-      - dhcp_start_ip != "false"
-      - dhcp_start_ip != dhcp_end_ip
-      - dhcp_start_sub == subnet
-      - dhcp_start_sub == dhcp_end_sub
-    success_msg: "{{ success_dhcp_range }}"
-    fail_msg: "{{ fail_dhcp_range }}"
-  register: dhcp_start_ip_check
-
-- name: Assert dhcp_end_ip_range
+      - ib_username | length >= min_username_length
+      - ib_username | length < max_length
+      - '"-" not in ib_username '
+      - '"\\" not in ib_username '
+      - '"\"" not in ib_username '
+      - " \"'\" not in ib_username "
+    success_msg: "{{ success_ib_username }}"
+    fail_msg: "{{ fail_ib_username }}"
+  when: ib_switch_support
+
+- name: Assert ib_password
   assert:
     that:
-      - dhcp_end_ip != "false"
-      - dhcp_start_ip != dhcp_end_ip
-      - dhcp_end_sub == subnet
-      - dhcp_start_sub == dhcp_end_sub
-    success_msg: "{{ success_dhcp_range }}"
-    fail_msg: "{{ fail_dhcp_range }}"
-  register: dhcp_end_ip_check
+      - ib_password | length > min_username_length | int - 1
+      - ib_password | length < max_length | int + 1
+      - '"-" not in ib_password '
+      - '"\\" not in ib_password '
+      - '"\"" not in ib_password '
+      - " \"'\" not in ib_password "
+    success_msg: "{{ success_msg_ib_password }}"
+    fail_msg: "{{ fail_msg_ib_password }}"
+  when: ib_switch_support
+  no_log: true
 
-- name: Check timezone file
-  command: grep -Fx "{{ ks_timezone }}" {{ role_path }}/files/timezone.txt
-  ignore_errors: yes
-  register: timezone_out
+- name: Verify powervault_me4_username and powervault_me4_password are not empty
+  assert:
+    that:
+      - powervault_me4_username | length > 0
+      - powervault_me4_password | length > 0
+    success_msg: "{{ pv_params_success_msg }}"
+    fail_msg: "{{ pv_params_empty_fail_msg }}"
+  when: powervault_support
 
-- name: Assert timezone
+- name: Assert powervault_me4_username
   assert:
-    that: ks_timezone in timezone_out.stdout
-    success_msg: "{{ success_timezone }}"
-    fail_msg: "{{ fail_timezone }}"
-  register: timezone_check
+    that:
+      - powervault_me4_username | length >= min_username_length
+      - powervault_me4_username | length < max_length
+      - '"-" not in powervault_me4_username '
+      - '"\\" not in powervault_me4_username '
+      - '"\"" not in powervault_me4_username '
+      - " \"'\" not in powervault_me4_username "
+    success_msg: "{{ success_powervault_me4_username }}"
+    fail_msg: "{{ fail_powervault_me4_username }}"
+  when: powervault_support
+
+- name: Assert powervault_me4_password
+  assert:
+    that:
+      - powervault_me4_password | length > min_username_length | int - 1
+      - powervault_me4_password | length < max_length | int + 1
+      - '"-" not in powervault_me4_password '
+      - '"\\" not in powervault_me4_password '
+      - '"\"" not in powervault_me4_password '
+      - " \"'\" not in powervault_me4_password "
+    success_msg: "{{ success_msg_powervault_me4_password }}"
+    fail_msg: "{{ fail_msg_powervault_me4_password }}"
+  when: powervault_support
+  no_log: true
 
 - name: Create ansible vault key
   set_fact:
@@ -299,83 +214,11 @@
       {{ vault_key }}
     owner: root
     force: yes
+    mode: "{{ vault_file_perm }}"
   when: "'$ANSIBLE_VAULT;' not in config_content.stdout"
 
 - name: Encrypt input config file
   command: >-
-    ansible-vault encrypt {{ input_config_filename }}
+    ansible-vault encrypt {{ login_vars_filename }}
     --vault-password-file {{ vault_filename }}
-  changed_when: false
-
-- name: Check if omnia_vault_key exists
-  stat:
-    path: "{{ role_path }}/../../../{{ config_vaultname }}"
-  register: vault_key_result
-
-- name: Create ansible vault key if it does not exist
-  set_fact:
-    vault_key: "{{ lookup('password', '/dev/null chars=ascii_letters') }}"
-  when: not vault_key_result.stat.exists
-
-- name: Save vault key
-  copy:
-    dest: "{{ role_path }}/../../../{{ config_vaultname }}"
-    content: |
-      {{ vault_key }}
-    owner: root
-    force: yes
-  when: not vault_key_result.stat.exists
-
-- name: Check if omnia config file is encrypted
-  command: cat {{ role_path }}/../../../{{ config_filename }}
-  changed_when: false
-  register: config_content
-  no_log: True
-
-- name: Decrpyt omnia_config.yml
-  command: >-
-    ansible-vault decrypt {{ role_path }}/../../../{{ config_filename }}
-    --vault-password-file {{ role_path }}/../../../{{ config_vaultname }}
-  when: "'$ANSIBLE_VAULT;' in config_content.stdout"
-
-- name: Include variable file omnia_config.yml
-  include_vars: "{{ role_path }}/../../../{{ config_filename }}"
-  no_log: True
-
-- name: Validate input parameters are not empty
-  fail:
-    msg: "{{ input_config_failure_msg }}"
-  register: input_config_check
-  when:
-    - mariadb_password | length < 1 or
-      k8s_cni | length < 1
-
-- name: Assert mariadb_password
-  assert:
-    that:
-        - mariadb_password | length > min_length | int - 1
-        - mariadb_password | length < max_length | int + 1
-        - '"-" not in mariadb_password '
-        - '"\\" not in mariadb_password '
-        - '"\"" not in mariadb_password '
-        - " \"'\" not in mariadb_password "
-    success_msg: "{{ success_msg_mariadb_password }}"
-    fail_msg: "{{ fail_msg_mariadb_password }}"
-
-- name: Assert kubernetes cni
-  assert:
-    that: "('calico' in k8s_cni) or ('flannel' in k8s_cni)"
-    success_msg: "{{ success_msg_k8s_cni }}"
-    fail_msg: "{{ fail_msg_k8s_cni }}"
-
-- name: Save input variables from file
-  set_fact:
-    db_password: "{{ mariadb_password }}"
-    k8s_cni: "{{ k8s_cni }}"
-  no_log: True
-
-- name: Encrypt input config file
-  command: >-
-    ansible-vault encrypt {{ role_path }}/../../../{{ config_filename }}
-    --vault-password-file {{ role_path }}/../../../{{ config_vaultname }}
   changed_when: false

+ 1 - 0
control_plane/roles/control_plane_common/tasks/pre_requisite.yml

@@ -41,6 +41,7 @@
 - name: Fetch SElinux mode
   command: sestatus
   register: sestatus_current
+  changed_when: false
 
 - name: Disable SElinux
   replace:

+ 88 - 0
control_plane/roles/control_plane_common/tasks/verify_omnia_params.yml

@@ -0,0 +1,88 @@
+# Copyright 2021 Dell Inc. or its subsidiaries. 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.
+---
+
+- name: Check if omnia_vault_key exists
+  stat:
+    path: "{{ role_path }}/../../../{{ config_vaultname }}"
+  register: vault_key_result
+
+- name: Create ansible vault key if it does not exist
+  set_fact:
+    vault_key: "{{ lookup('password', '/dev/null chars=ascii_letters') }}"
+  when: not vault_key_result.stat.exists
+
+- name: Save vault key
+  copy:
+    dest: "{{ role_path }}/../../../{{ config_vaultname }}"
+    content: |
+      {{ vault_key }}
+    owner: root
+    force: yes
+    mode: "{{ vault_file_perm }}"
+  when: not vault_key_result.stat.exists
+
+- name: Check if omnia config file is encrypted
+  command: cat {{ role_path }}/../../../{{ config_filename }}
+  changed_when: false
+  register: config_content
+  no_log: True
+
+- name: Decrpyt omnia_config.yml
+  command: >-
+    ansible-vault decrypt {{ role_path }}/../../../{{ config_filename }}
+    --vault-password-file {{ role_path }}/../../../{{ config_vaultname }}
+  when: "'$ANSIBLE_VAULT;' in config_content.stdout"
+
+- name: Include variable file omnia_config.yml
+  include_vars: "{{ role_path }}/../../../{{ config_filename }}"
+  no_log: True
+
+- name: Validate input parameters are not empty
+  fail:
+    msg: "{{ input_omnia_failure_msg }}"
+  register: input_config_check
+  when:
+    - mariadb_password | length < 1 or
+      k8s_cni | length < 1
+
+- name: Assert mariadb_password
+  assert:
+    that:
+        - mariadb_password | length > min_length | int - 1
+        - mariadb_password | length < max_length | int + 1
+        - '"-" not in mariadb_password '
+        - '"\\" not in mariadb_password '
+        - '"\"" not in mariadb_password '
+        - " \"'\" not in mariadb_password "
+    success_msg: "{{ success_msg_mariadb_password }}"
+    fail_msg: "{{ fail_msg_mariadb_password }}"
+
+- name: Assert kubernetes cni
+  assert:
+    that: "('calico' in k8s_cni) or ('flannel' in k8s_cni)"
+    success_msg: "{{ success_msg_k8s_cni }}"
+    fail_msg: "{{ fail_msg_k8s_cni }}"
+
+- name: Save input variables from file
+  set_fact:
+    db_password: "{{ mariadb_password }}"
+    k8s_cni: "{{ k8s_cni }}"
+  no_log: True
+
+- name: Encrypt input config file
+  command: >-
+    ansible-vault encrypt {{ role_path }}/../../../{{ config_filename }}
+    --vault-password-file {{ role_path }}/../../../{{ config_vaultname }}
+  changed_when: false

+ 72 - 37
control_plane/roles/control_plane_common/vars/main.yml

@@ -50,50 +50,85 @@ ansible_python_version_status: "For CentOS 8.3, python bindings of firewalld, dn
 python_version_support: '3.6.8'
 default_ansible_config_file_path: /etc/ansible/ansible.cfg
 
-# Usage: docker_installation.yml
-docker_repo_url: https://download.docker.com/linux/centos/docker-ce.repo
-docker_repo_dest: /etc/yum.repos.d/docker-ce.repo
-success: '0'
-container_type: docker
-container_repo_install:
-  - docker-ce-cli-20.10.2
-  - docker-ce-20.10.2
-docker_compose: docker-compose
-daemon_dest: /etc/docker/
-
-# Usage: docker_volume.yml
-docker_volume_name: omnia-storage
-
 # Usage: password_config.yml
-input_config_filename: "appliance_config.yml"
-fail_msg_provision_password: "Failed. Incorrect provision_password format provided in appliance_config.yml file"
-success_msg_provision_password: "provision_password validated"
-fail_msg_awx_password: "Failed. Incorrect awx_password format provided in appliance_config.yml file"
-success_msg_awx_password: "awx_password validated"
-fail_msg_hpc_nic: "Failed. Incorrect hpc_nic format provided in appliance_config.yml file"
-success_msg_hpc_nic: "hpc_nic validated"
-fail_msg_public_nic: "Failed. Incorrect public_nic format provided in appliance_config.yml file"
-success_msg_public_nic: "public_nic validated"
-success_mapping_file: "mapping_file_exists validated"
-fail_mapping_file: "Failed. Incorrect mapping_file_exists value in appliance_config.yml. It should be either true or false"
-input_config_failure_msg: "Please provide all the required parameters in appliance_config.yml"
-success_dhcp_range: "Dhcp_range validated"
-fail_dhcp_range: "Failed. Incorrect range assigned for dhcp"
-success_hpc_ip: "IP validated"
-fail_hpc_ip: "Failed. Nic should be configured"
-fail_mapping_file_path: "Failed. Mapping_file_path input is empty in appliance_config.yml. Either set mapping_file_exists to false or provide a path for a valid mapping file."
-invalid_mapping_file_path: "Incorrect mapping_file_path provided in appliance_config.yml"
-invalid_iso_file_path: "Incorrect iso_file_path provided in appliance_config.yml."
+login_vars_filename: "input_params/login_vars.yml"
+vault_filename: input_params/.login_vault_key
 min_length: 8
 max_length: 30
+min_username_length: 4
+file_perm: '0755'
+vault_file_perm: '0600'
 nic_min_length: 3
-vault_filename: .vault_key
+input_config_failure_msg: "Please provide all the required parameters in login_vars.yml"
+fail_msg_provision_password: "Failed. Incorrect provision_password format provided in login_vars.yml"
+success_msg_provision_password: "provision_password validated"
+fail_msg_cobbler_password: "Failed. Incorrect cobbler_password format provided in login_vars.yml file"
+success_msg_cobbler_password: "cobbler_password validated"
+success_idrac_username: "idrac username validated"
+fail_idrac_username: "Failed. Incorrect idrac_username format provided in base_vars.yml"
+success_msg_idrac_password: "idrac password validated"
+fail_msg_idrac_password: "Failed. Incorrect idrac_password format provided in base_vars.yml"
+ethernet_params_success_msg: "Ethernet switch username and password are not blank"
+ethernet_params_empty_fail_msg: "Failed. ethernet switch username or password cannot be empty when ethernet_switch_support is true"
+success_ethernet_switch_username: "Ethernet switch username validated"
+fail_ethernet_switch_username: "Failed. Incorrect ethernet_switch_username format provided in base_vars.yml"
+success_msg_ethernet_switch_password: "Ethernet password validated"
+fail_msg_ethernet_switch_password: "Failed. Incorrect ethernet_switch_password format provided in base_vars.yml"
+ib_params_success_msg: "InfiniBand switch username and password are not blank"
+ib_params_empty_fail_msg: "Failed. InfiniBand username or password cannot be empty when ib_switch_support is true"
+success_ib_username: "ib username validated"
+fail_ib_username: "Failed. Incorrect ib_username format provided in base_vars.yml"
+success_msg_ib_password: "ib password validated"
+fail_msg_ib_password: "Failed. Incorrect ib_password format provided in base_vars.yml"
+pv_params_success_msg: "Powervault switch username and password are not blank"
+pv_params_empty_fail_msg: "Failed. Powervault username or password cannot be empty when powervault_support is true"
+success_powervault_username: "powervault username validated"
+fail_powervault_username: "Failed. Incorrect powervault_username format provided in base_vars.yml"
+success_msg_powervault_password: "powervault password validated"
+fail_msg_powervault_password: "Failed. Incorrect powervault_password format provided in base_vars.yml"
+
+# Usage: verify_omnia_params.yml
 config_filename: "omnia_config.yml"
 config_vaultname: .omnia_vault_key
+input_omnia_failure_msg: "Please provide all the required parameters in omnia_config.yml"
 fail_msg_mariadb_password: "Failed. Incorrect mariadb_password format provided in omnia_config.yml file"
 success_msg_mariadb_password: "mariadb_password validated"
 success_msg_k8s_cni: "Kubernetes CNI Validated"
 fail_msg_k8s_cni: "Failed. Kubernetes CNI is incorrect in omnia_config.yml"
-success_timezone: "timezone validated"
-fail_timezone: "Failed. Incorrect timezone provided. Please check the file timezone.txt in control_plane/roles/control_plane_common/files/ folder"
-file_perm: '0755'
+
+# Usage: fetch_base_inputs.yml
+base_vars_filename: "input_params/base_vars.yml"
+input_base_failure_msg: "Please provide all the required parameters in base_vars.yml"
+success_snmp_trap_dest: "SNMP trap destination IP validated"
+fail_snmp_trap_dest: "Failed. Incorrect SNMP trap destination IP format provided in base_address.yml"
+success_snmp_comm_msg: "SNMP community string validated"
+fail_snmp_comm_msg: "snmp community string cannoy be blank in base_vars.yml"
+success_msg_public_nic: "Public nic successfully validated"
+fail_msg_public_nic: "Failed. Incorrect public nic provided in base_vars.yml"
+success_msg_k8s_pod_network_cidr: "Appliance k8s pod network cidr validated"
+fail_msg_k8s_pod_network_cidr: "Failed. Incorrect appliance k8s pod network cidr provided in base_vars.yml"
+success_awx_organization: "awx organization validated"
+fail_awx_organization: "Failed. Incorrect format in awx organization"
+success_timezone_msg: "timezone validated"
+fail_timezone_msg: "Failed. Incorrect timezone provided. Please check the file timezone.txt in control_plane/roles/control_plane_common/files/ folder"
+fail_language: "Failed. Only en-US(english) language supported"
+invalid_iso_file_path: "Incorrect iso_file_path provided in base_vars.yml."
+ethernet_switch_support_success_msg: "ethernet_switch_support validated"
+ethernet_switch_support_fail_msg: "Failed. ethernet_switch_support only accepts boolean values true or false"
+ib_switch_support_success_msg: "ib_switch_support validated"
+ib_switch_support_fail_msg: "Failed. ib_switch_support only accepts boolean values true or false"
+powervault_support_success_msg: "powervault_support validated"
+powervault_support_fail_msg: "Failed. power_vault_support only accepts boolean values true or false"
+success_msg_mngmnt_network_nic: "Management network nic successfully validated"
+fail_msg_mngmnt_network_nic: "Failed. Incorrect Management network nic provided in base_vars.yml"
+success_msg_host_network_nic: "Host network nic successfully validated"
+fail_msg_host_network_nic: "Failed. Incorrect host network nic provided in base_vars.yml"
+success_msg_ib_network_nic: "Infiniband network nic successfully validated"
+fail_msg_ib_network_nic: "Failed. Incorrect infiniband network nic provided in base_vars.yml"
+success_dhcp_range: "Dhcp_range validated"
+fail_dhcp_range: "Failed. Incorrect range assigned for dhcp"
+invalid_mapping_file_path: "Incorrect mapping_file_path provided in base_vars.yml"
+success_msg_different_nics: "The nics of different containers and public nic are not the same - Validated"
+fail_msg_different_nics: "Failed. Incorrect nic information. public nic, management network nic and host network nic should not be the same"
+success_msg_different_nics_ib: "The nics of different containers and public nic are not the same as infiniband nic- Validated"
+fail_msg_different_nics_ib: "Failed. Infiniband nic cannot be the same as other nics"

+ 2 - 0
control_plane/roles/control_plane_k8s/files/crio.conf

@@ -0,0 +1,2 @@
+overlay
+br_netfilter

+ 3 - 0
control_plane/roles/control_plane_k8s/files/k8s-crio.conf

@@ -0,0 +1,3 @@
+net.bridge.bridge-nf-call-ip6tables = 1
+net.ipv4.ip_forward                 = 1
+net.bridge.bridge-nf-call-iptables  = 1

+ 1 - 0
control_plane/roles/control_plane_k8s/files/k8s.conf

@@ -0,0 +1 @@
+br_netfilter

+ 18 - 0
control_plane/roles/control_plane_k8s/files/k8s_dashboard_admin.yaml

@@ -0,0 +1,18 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: admin-user
+  namespace: kubernetes-dashboard
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: admin-user
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cluster-admin
+subjects:
+- kind: ServiceAccount
+  name: admin-user
+  namespace: kubernetes-dashboard

+ 11 - 0
control_plane/roles/control_plane_k8s/files/metal-config.yaml

@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  namespace: metallb-system
+  name: config
+data:
+  config: |
+    address-pools:
+    - name: default
+      protocol: layer2
+      addresses:

+ 223 - 0
control_plane/roles/control_plane_k8s/files/metallb.yaml

@@ -0,0 +1,223 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: metallb-system
+  labels:
+    app: metallb
+---
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  namespace: metallb-system
+  name: controller
+  labels:
+    app: metallb
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  namespace: metallb-system
+  name: speaker
+  labels:
+    app: metallb
+
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: metallb-system:controller
+  labels:
+    app: metallb
+rules:
+- apiGroups: [""]
+  resources: ["services"]
+  verbs: ["get", "list", "watch", "update"]
+- apiGroups: [""]
+  resources: ["services/status"]
+  verbs: ["update"]
+- apiGroups: [""]
+  resources: ["events"]
+  verbs: ["create", "patch"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: metallb-system:speaker
+  labels:
+    app: metallb
+rules:
+- apiGroups: [""]
+  resources: ["services", "endpoints", "nodes"]
+  verbs: ["get", "list", "watch"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  namespace: metallb-system
+  name: config-watcher
+  labels:
+    app: metallb
+rules:
+- apiGroups: [""]
+  resources: ["configmaps"]
+  verbs: ["get", "list", "watch"]
+- apiGroups: [""]
+  resources: ["events"]
+  verbs: ["create"]
+---
+
+## Role bindings
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: metallb-system:controller
+  labels:
+    app: metallb
+subjects:
+- kind: ServiceAccount
+  name: controller
+  namespace: metallb-system
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: metallb-system:controller
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: metallb-system:speaker
+  labels:
+    app: metallb
+subjects:
+- kind: ServiceAccount
+  name: speaker
+  namespace: metallb-system
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: metallb-system:speaker
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  namespace: metallb-system
+  name: config-watcher
+  labels:
+    app: metallb
+subjects:
+- kind: ServiceAccount
+  name: controller
+- kind: ServiceAccount
+  name: speaker
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: config-watcher
+---
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  namespace: metallb-system
+  name: speaker
+  labels:
+    app: metallb
+    component: speaker
+spec:
+  selector:
+    matchLabels:
+      app: metallb
+      component: speaker
+  template:
+    metadata:
+      labels:
+        app: metallb
+        component: speaker
+      annotations:
+        prometheus.io/scrape: "true"
+        prometheus.io/port: "metallb_container_port"
+    spec:
+      serviceAccountName: speaker
+      terminationGracePeriodSeconds: 0
+      hostNetwork: true
+      containers:
+      - name: speaker
+        image: metallb/speaker:v0.7.3
+        imagePullPolicy: IfNotPresent
+        args:
+        - --port=metallb_container_port
+        - --config=config
+        env:
+        - name: METALLB_NODE_NAME
+          valueFrom:
+            fieldRef:
+              fieldPath: spec.nodeName
+        ports:
+        - name: monitoring
+          containerPort: metallb_container_port
+        resources:
+          limits:
+            cpu: 100m
+            memory: 100Mi
+
+        securityContext:
+          allowPrivilegeEscalation: false
+          readOnlyRootFilesystem: true
+          capabilities:
+            drop:
+            - all
+            add:
+            - net_raw
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  namespace: metallb-system
+  name: controller
+  labels:
+    app: metallb
+    component: controller
+spec:
+  revisionHistoryLimit: 3
+  selector:
+    matchLabels:
+      app: metallb
+      component: controller
+  template:
+    metadata:
+      labels:
+        app: metallb
+        component: controller
+      annotations:
+        prometheus.io/scrape: "true"
+        prometheus.io/port: "metallb_container_port"
+    spec:
+      serviceAccountName: controller
+      terminationGracePeriodSeconds: 0
+      securityContext:
+        runAsNonRoot: true
+        runAsUser: metallb_run_as_user_port # nobody
+      containers:
+      - name: controller
+        image: metallb/controller:v0.7.3
+        imagePullPolicy: IfNotPresent
+        args:
+        - --port=metallb_container_port
+        - --config=config
+        ports:
+        - name: monitoring
+          containerPort: metallb_container_port
+        resources:
+          limits:
+            cpu: 100m
+            memory: 100Mi
+
+        securityContext:
+          allowPrivilegeEscalation: false
+          capabilities:
+            drop:
+            - all
+          readOnlyRootFilesystem: true
+
+---

+ 56 - 0
control_plane/roles/control_plane_k8s/tasks/k8s_firewalld.yml

@@ -0,0 +1,56 @@
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
+---
+
+- name: Install firewalld
+  package:
+    name: firewalld
+    state: present
+
+- name: Start and enable firewalld
+  service:
+    name: firewalld
+    state: started
+    enabled: yes
+
+- name: Configure firewalld on master nodes
+  firewalld:
+    port: "{{ item }}/tcp"
+    permanent: yes
+    state: enabled
+  with_items: '{{ k8s_master_ports }}'
+
+- name: Open calico UDP ports on the firewall
+  firewalld:
+    port: "{{ item }}/udp"
+    permanent: yes
+    state: enabled
+  with_items: "{{ calico_udp_ports }}"
+
+- name: Open calico TCP ports on the firewall
+  firewalld:
+    port: "{{ item }}/tcp"
+    permanent: yes
+    state: enabled
+  with_items: "{{ calico_tcp_ports }}"
+
+- name: Reload firewalld
+  command: firewall-cmd --reload
+  changed_when: true
+
+- name: Stop and disable firewalld
+  service:
+    name: firewalld
+    state: stopped
+    enabled: no

+ 41 - 0
control_plane/roles/control_plane_k8s/tasks/k8s_helm.yml

@@ -0,0 +1,41 @@
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
+---
+
+- name: Create directory for helm installer file
+  file:
+    path: "{{ helm_installer_file_directory }}"
+    state: directory
+    mode: "{{ helm_installer_file_directory_mode }}"
+
+- name: Get helm installer
+  get_url:
+    url: "{{ helm_installer_url }}"
+    dest: "{{ helm_installer_file_dest }}"
+    mode: "{{ helm_installer_file_mode }}"
+  register: helm_installer_result
+  until: helm_installer_result is not failed
+  retries: 20
+
+- name: Install helm
+  command: "/bin/bash {{ helm_installer_file_dest }}"
+  changed_when: true
+
+- name: Helm - add stable repo
+  command: "helm repo add stable '{{ helm_stable_repo_url }}'"
+  changed_when: true
+
+- name: Helm - update repo
+  command: helm repo update
+  changed_when: true

+ 126 - 0
control_plane/roles/control_plane_k8s/tasks/k8s_init.yml

@@ -0,0 +1,126 @@
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
+---
+
+- name: Disable SWAP (1/2)
+  command: /usr/sbin/swapoff -a
+  changed_when: true
+  tags: init
+
+- name: Disable SWAP in fstab (2/2)
+  replace:
+    path: /etc/fstab
+    regexp: '^([^#].*?\sswap\s+.*)$'
+    replace: '# \1'
+
+- name: Get K8s nodes status
+  command: kubectl get nodes
+  changed_when: false
+  ignore_errors: True
+  register: k8s_nodes
+
+- name: Get K8s pods status
+  command: kubectl get pods --all-namespaces
+  changed_when: false
+  ignore_errors: True
+  register: k8s_pods
+
+- name: Initialize kubeadm
+  block:
+    - name: Initialize kubeadm
+      command: "/bin/kubeadm init --pod-network-cidr='{{ appliance_k8s_pod_net_cidr }}' \
+        --apiserver-advertise-address='{{ ansible_default_ipv4.address }}'"
+      changed_when: true
+      register: init_output
+  rescue:
+    - name: Reset kubeadm
+      command: "kubeadm reset -f"
+      changed_when: true
+
+    - name: Initialize kubeadm
+      command: "/bin/kubeadm init --pod-network-cidr='{{ k8s_pod_network_cidr }}' \
+          --apiserver-advertise-address='{{ ansible_default_ipv4.address }}'"
+      changed_when: true
+      register: init_output
+
+    - name: Get K8s pods status
+      command: kubectl get pods --all-namespaces
+      changed_when: false
+      ignore_errors: True
+      register: k8s_pods
+  when: "'master' not in k8s_nodes.stdout"
+
+- name: Setup directory for Kubernetes environment for root
+  file:
+    path: "{{ k8s_root_directory }}"
+    state: directory
+    mode: "{{ k8s_root_directory_mode }}"
+
+- name: Copy Kubernetes config for root
+  copy:
+    src: "{{ k8s_config_src }}"
+    dest: "{{ k8s_config_dest }}"
+    owner: root
+    group: root
+    mode: "{{ k8s_config_file_mode }}"
+    remote_src: yes
+
+- name: Update the kubernetes config file permissions
+  shell: "chown $(id -u):$(id -g) '{{ k8s_config_dest }}'"
+  args:
+    warn: false
+  changed_when: true
+
+- name: Cluster token
+  shell: >
+    set -o pipefail && \
+      kubeadm token list | cut -d ' ' -f1 | sed -n '2p'
+  changed_when: false
+  register: K8S_TOKEN
+
+- name: CA Hash
+  shell: >
+    set -o pipefail && \
+      openssl x509 -pubkey -in {{ k8s_cert_path }} | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
+  changed_when: false
+  register: K8S_MANAGER_CA_HASH
+
+- name: Add K8S Manager IP, Token, and Hash to dummy host
+  add_host:
+    name:   "K8S_TOKEN_HOLDER"
+    token:  "{{ K8S_TOKEN.stdout }}"
+    hash:   "{{ K8S_MANAGER_CA_HASH.stdout }}"
+    ip:     "{{ ansible_default_ipv4.address }}"
+
+- name: Create yaml repo for setup
+  file:
+    path: "{{ yaml_repo_dir_path }}"
+    state: directory
+    mode: "{{ yaml_repo_dir_mode }}"
+
+- name: Setup Calico SDN network - tigera-operator
+  command: "kubectl create -f {{ tigera_operator_url }}"
+  changed_when: true
+  when: "'tigera-operator' not in k8s_pods.stdout"
+
+- name: Setup Calico SDN network - custom-resources
+  command: "kubectl create -f {{ calico_yml_url }}"
+  changed_when: true
+  ignore_errors: True
+  when: "'calico-system' not in k8s_pods.stdout"
+
+- name: Edge / Workstation Install allows pods to schedule on manager
+  command: kubectl taint nodes --all node-role.kubernetes.io/master-
+  changed_when: true
+  ignore_errors: True

+ 123 - 0
control_plane/roles/control_plane_k8s/tasks/k8s_installation.yml

@@ -0,0 +1,123 @@
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
+---
+
+- name: Permanently Disable swap
+  mount:
+    name: "swap"
+    fstype: swap
+    state: absent
+
+- name: Disable selinux
+  selinux:
+    state: disabled
+
+- name: Copy k8s.conf file
+  copy:
+    src: k8s.conf
+    dest: "{{ k8s_conf_dest }}"
+    owner: root
+    group: root
+    mode: "{{ conf_file_mode }}"
+
+- name: Copy crio.conf file
+  copy:
+    src: crio.conf
+    dest: "{{ crio_conf_dest }}"
+    owner: root
+    group: root
+    mode: "{{ conf_file_mode }}"
+
+- name: Enable the kernel modules overlay and br_netfilter
+  modprobe:
+    name: "{{ item }}"
+    state: present
+  with_items:
+    - overlay
+    - br_netfilter
+
+- name: Update sysctl to handle incorrectly routed traffic when iptables is bypassed
+  copy:
+    src: k8s-crio.conf
+    dest: "{{ k8s_crio_conf_dest }}"
+    owner: root
+    group: root
+    mode: "{{ conf_file_mode }}"
+
+- name: Update sysctl
+  command: /sbin/sysctl --system
+  changed_when: true
+
+- name: Add CRI-O repo (1/2)
+  get_url:
+    url: "{{ crio_repo1_url }}"
+    dest: "{{ crio_repo1_dest }}"
+  register: crio_repo1_result
+  until: crio_repo1_result is not failed
+  retries: 20
+
+- name: Add CRI-O repo (2/2)
+  get_url:
+    url: "{{ crio_repo2_url }}"
+    dest: "{{ crio_repo2_dest }}"
+  register: crio_repo2_result
+  until: crio_repo2_result is not failed
+  retries: 20
+
+- name: Add kubernetes repo
+  yum_repository:
+    name: kubernetes
+    description: kubernetes
+    baseurl: https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
+    enabled: yes
+    gpgcheck: no
+    repo_gpgcheck: no
+    gpgkey:
+      - https://packages.cloud.google.com/yum/doc/yum-key.gpg
+      - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
+
+- name: Install common packages
+  package:
+    name: "{{ common_packages }}"
+    state: present
+
+- name: Install k8s packages
+  package:
+    name: "{{ k8s_packages }}"
+    state: present
+
+- name: Versionlock kubernetes
+  command: "yum versionlock '{{ item }}'"
+  args:
+    warn: false
+  with_items:
+    - "{{ k8s_packages }}"
+  changed_when: true
+
+- name: Start and enable crio
+  service:
+    name: crio
+    state: restarted
+    daemon_reload: yes
+    enabled: yes
+
+- name: Start and enable kubernetes - kubelet
+  service:
+    name: kubelet
+    state: restarted
+    enabled: yes
+
+- name: Wait for 30sec for kubelet to get things ready
+  pause:
+    seconds: 30

+ 129 - 0
control_plane/roles/control_plane_k8s/tasks/k8s_services.yml

@@ -0,0 +1,129 @@
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
+---
+
+- name: Wait for CoreDNS to restart
+  command: kubectl rollout status deployment/coredns -n kube-system
+  changed_when: false
+  ignore_errors: True
+
+- name: Get K8s pods
+  command: kubectl get pods --all-namespaces
+  changed_when: false
+  register: k8s_pods
+
+- name: Deploy MetalLB
+  command: "kubectl apply -f '{{ metallb_yaml_url }}'"
+  changed_when: true
+  when: "'metallb' not in k8s_pods.stdout"
+
+- name: Create MetalLB Setup Config Files
+  copy:
+    src: metal-config.yaml
+    dest: "{{ metallb_config_file_dest }}"
+    owner: root
+    group: root
+    mode: "{{ metallb_config_file_mode }}"
+
+- name: Replace metallb_addresses
+  replace:
+    path: "{{ metallb_config_file_dest }}"
+    regexp: 'addresses:'
+    replace: "{{ metallb_addresses }}"
+
+- name: Remove ^M characters from metal-config file
+  shell: 'sed -e "s/\r//g" {{ metallb_config_file_dest }} > {{ metallb_config_updated_file_dest }}'
+  args:
+    warn: false
+  changed_when: true
+
+- name: Update metal-config file permissions
+  file:
+    path: "{{ metallb_config_updated_file_dest }}"
+    owner: root
+    group: root
+    mode: "{{ metallb_config_file_mode }}"
+
+- name: Remove old metallb-config file
+  file:
+    path: "{{ metallb_config_file_dest }}"
+    state: absent
+
+- name: Create MetalLB Setup Deployment Files
+  copy:
+    src: metallb.yaml
+    dest: "{{ metallb_deployment_file_dest }}"
+    owner: root
+    group: root
+    mode: "{{ metallb_deployment_file_mode }}"
+
+- name: Replace metallb_container_port
+  replace:
+    path: "{{ metallb_deployment_file_dest }}"
+    regexp: 'metallb_container_port'
+    replace: "{{ metallb_container_port }}"
+
+- name: Replace metallb_container_port
+  replace:
+    path: "{{ metallb_deployment_file_dest }}"
+    regexp: 'metallb_run_as_user_port'
+    replace: "{{ metallb_run_as_user_port }}"
+
+- name: Deploy MetalLB
+  command: "kubectl apply -f '{{ metallb_deployment_file_dest }}'"
+  changed_when: true
+  when: "'metallb' not in k8s_pods.stdout"
+
+- name: Create default setup for MetalLB
+  command: "kubectl apply -f '{{ metallb_config_updated_file_dest }}'"
+  changed_when: true
+  when: "'metallb' not in k8s_pods.stdout"
+
+- name: Deploy K8s dashboard
+  command: "kubectl apply -f {{ k8s_dashboard_yaml_url }}"
+  changed_when: true
+  when: "'kubernetes-dashboard' not in k8s_pods.stdout"
+
+- name: Copy k8s_dashboard_admin.yml file
+  copy:
+    src: k8s_dashboard_admin.yaml
+    dest: "{{ k8s_dashboard_admin_file_dest }}"
+    owner: root
+    group: root
+    mode: "{{ k8s_dashboard_admin_file_mode }}"
+
+- name: Create admin user for K8s dashboard
+  command: "kubectl apply -f {{ k8s_dashboard_admin_file_dest }}"
+  changed_when: true
+
+- name: Start NFS Client Provisioner
+  command: "helm install stable/nfs-client-provisioner --set nfs.server='{{ ansible_default_ipv4.address }}' --set nfs.path='{{ nfs_path }}' --generate-name"
+  changed_when: true
+  when: "'nfs-client-provisioner' not in k8s_pods.stdout"
+
+- name: Set NFS-Client Provisioner as DEFAULT StorageClass
+  shell: >
+    kubectl patch storageclasses.storage.k8s.io nfs-client \
+    -p '{ "metadata": { "annotations":{ "storageclass.kubernetes.io/is-default-class":"true" }}}'
+  changed_when: true
+
+- name: Get K8s namespaces
+  command: kubectl get namespaces
+  changed_when: false
+  register: k8s_namespaces
+
+- name: Create namespace network-config
+  command: kubectl create namespace network-config
+  changed_when: true
+  when: "'network-config' not in k8s_namespaces.stdout"

+ 15 - 5
control_plane/roles/control_plane_k8s/tasks/main.yml

@@ -1,4 +1,4 @@
-# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
@@ -13,7 +13,17 @@
 #  limitations under the License.
 ---
 
-# Will be updated later in each PR
-- name: Pass
-  debug:
-    msg: "Pass"
+- name: Install K8s packages
+  import_tasks: k8s_installation.yml
+
+- name: Configure firewalld
+  import_tasks: k8s_firewalld.yml
+
+- name: Install helm
+  import_tasks: k8s_helm.yml
+
+- name: Initialize K8s
+  import_tasks: k8s_init.yml
+
+- name: Deploy K8s dashboard
+  import_tasks: k8s_services.yml

+ 95 - 0
control_plane/roles/control_plane_k8s/vars/main.yml

@@ -0,0 +1,95 @@
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
+---
+
+# vars file for kubernetes
+
+# Usage: k8s_installation.yml
+common_packages:
+  - openssl
+  - bash-completion
+  - cri-o
+  - buildah
+k8s_packages:
+  - kubelet-1.21.0
+  - kubeadm-1.21.0
+  - kubectl-1.21.0
+k8s_conf_dest: /etc/modules-load.d/
+crio_conf_dest: /etc/modules-load.d/
+k8s_crio_conf_dest: /etc/sysctl.d/
+conf_file_mode: 0644
+crio_repo1_url: https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/CentOS_8/devel:kubic:libcontainers:stable.repo
+crio_repo1_dest: /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo
+crio_repo2_url: https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:1.21/CentOS_8/devel:kubic:libcontainers:stable:cri-o:1.21.repo
+crio_repo2_dest: /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:1.21.repo
+
+# Usage: k8s_firewalld.yml
+k8s_master_ports:
+  - 6443
+  - 2379-2380
+  - 10250
+  - 10251
+  - 10252
+calico_udp_ports:
+  - 4789
+calico_tcp_ports:
+  - 5473
+  - 179
+
+# Usage: k8s_helm.yml
+helm_installer_file_directory: /root/bin
+helm_installer_file_directory_mode: 0755
+helm_installer_url: https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
+helm_installer_file_dest: /root/bin/get_helm.sh
+helm_installer_file_mode: 0700
+helm_stable_repo_url: https://charts.helm.sh/stable
+
+# Usage: k8s_init.yml
+k8s_root_directory: /root/.kube
+k8s_root_directory_mode: 0755
+k8s_config_src: /etc/kubernetes/admin.conf
+k8s_config_dest: /root/.kube/config
+k8s_config_file_mode: 0644
+k8s_cert_path: /etc/kubernetes/pki/ca.crt
+yaml_repo_dir_path: /root/k8s
+yaml_repo_dir_mode: 0755
+tigera_operator_url: https://docs.projectcalico.org/manifests/tigera-operator.yaml
+calico_yml_url: https://docs.projectcalico.org/manifests/custom-resources.yaml
+
+# Usage: k8s_services.yml
+metallb_config_file_dest: /root/k8s/metal-config.yaml
+metallb_config_updated_file_dest: /root/k8s/metal-config-updated.yaml
+metallb_config_file_mode: 0655
+metallb_deployment_file_dest: /root/k8s/metallb.yaml
+metallb_deployment_file_mode: 0655
+metallb_yaml_url: https://raw.githubusercontent.com/google/metallb/v0.8.1/manifests/metallb.yaml
+metallb_addresses: |
+  addresses:
+        - 192.168.2.150/32
+        - 192.168.2.151/32
+        - 192.168.2.151/32
+        - 192.168.2.152/32
+        - 192.168.2.153/32
+        - 192.168.2.154/32
+        - 192.168.2.155/32
+        - 192.168.2.156/32
+        - 192.168.2.157/32
+        - 192.168.2.158/32
+        - 192.168.2.159/32
+metallb_container_port: "7472"
+metallb_run_as_user_port: "65534"
+k8s_dashboard_yaml_url: https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
+k8s_dashboard_admin_file_dest: /root/k8s/k8s_dashboard_admin.yaml
+k8s_dashboard_admin_file_mode: 0655
+nfs_path: /var/nfs_awx

+ 3 - 5
control_plane/roles/control_plane_repo/tasks/main.yml

@@ -1,4 +1,4 @@
-# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
@@ -13,7 +13,5 @@
 #  limitations under the License.
 ---
 
-# Will be updated later in each PR
-- name: Pass
-  debug:
-    msg: "Pass"
+- name: NFS Server setup
+  import_tasks: nfs_server_setup.yml

+ 78 - 0
control_plane/roles/control_plane_repo/tasks/nfs_server_setup.yml

@@ -0,0 +1,78 @@
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
+---
+
+- name: Install nfs-utils
+  package:
+    name: nfs-utils
+    state: present
+
+- name: Install firewalld
+  package:
+    name: firewalld
+    state: present
+
+- name: Start and enable firewalld
+  service:
+    name: firewalld
+    state: started
+    enabled: yes
+
+- name: Start and enable rpcbind and nfs-server service
+  service:
+    name: "{{ item }}"
+    state: restarted
+    enabled: yes
+  with_items:
+    - rpcbind
+    - nfs-server
+
+- name: Creating NFS share directory
+  file:
+    path: "{{ item }}"
+    state: directory
+    mode: "{{ nfs_share_dir_mode }}"
+  with_items:
+    - "{{ nfs_share_offline_repo }}"
+    - "{{ nfs_share_awx }}"
+
+- name: Adding NFS share entries in /etc/exports
+  lineinfile:
+    path: "{{ exports_file_path }}"
+    line: "{{ item }} {{ ansible_default_ipv4.address }}(rw,sync,no_root_squash)"
+  with_items:
+    - "{{ nfs_share_offline_repo }}"
+    - "{{ nfs_share_awx }}"
+
+- name: Exporting the shared directories
+  command: exportfs -r
+  changed_when: true
+
+- name: Configuring firewall
+  firewalld:
+    service: "{{ item }}"
+    permanent: true
+    state: enabled
+  with_items:
+    - "{{ nfs_services }}"
+
+- name: Reload firewalld
+  command: firewall-cmd --reload
+  changed_when: true
+
+- name: Stop and disable firewalld
+  service:
+    name: firewalld
+    state: stopped
+    enabled: no

+ 12 - 6
control_plane/roles/control_plane_common/tasks/docker_volume.yml

@@ -1,4 +1,4 @@
-#  Copyright 2020 Dell Inc. or its subsidiaries. All Rights Reserved.
+#  Copyright 2021 Dell Inc. or its subsidiaries. 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.
@@ -13,8 +13,14 @@
 #  limitations under the License.
 ---
 
-- name: Create a docker volume
-  docker_volume:
-    name: "{{ docker_volume_name }}"
-  vars:
-    ansible_python_interpreter: "/usr/bin/python3"
+# vars file for offline_repo
+
+# Usage: nfs_server_setup.yml
+nfs_share_offline_repo: /var/nfs_repo
+nfs_share_awx: /var/nfs_awx
+nfs_share_dir_mode: 0777
+exports_file_path: /etc/exports
+nfs_services:
+  - mountd
+  - rpc-bind
+  - nfs