Procházet zdrojové kódy

Issue:#207 Add hosts with description to inventory file is getting failed when cobbler is provisioning a new server

Signed-off-by: Shubhangi-dell <shubhangi_srivastava@dell.com>
Shubhangi-dell před 4 roky
rodič
revize
f89192fd3f

+ 11 - 13
appliance/input_config.yml

@@ -1,4 +1,4 @@
-#  Copyright 2020 Dell Inc. or its subsidiaries. All Rights Reserved.
+# 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.
@@ -23,22 +23,20 @@ provision_password: ""
 # The password must not contain -,\, ',"
 awx_password: ""
 
-# Password used for Slurm database.
-# The Length of the password should be atleast 8.
-# The password must not contain -,\, ',"
-mariadb_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 card that needs to be connected to the public internet.
-# The public_nic should be em2, em1 or em3
-# Default value of nic is em2.
+# The nic/ethernet card that will be connected to the public internet.
+# Default value of nic is em2
 public_nic: "em2"
 
-# Kubernetes SDN network.
-# Options: calico/flannel.
-# Default value is calico.
-k8s_cni: "calico"
+# The mapping file consists of the MAC address and its respective IP address and hostname.
+# If user wants to provide a mapping file, set this value to "true"
+# The format of mapping file should be MAC,hostname,IP and must be a CSV file.
+mapping_file_exists: ""
+
+# The dhcp range for assigning the IP address to the baremetal nodes.
+dhcp_start_ip_range: ""
+dhcp_end_ip_range: ""

+ 1 - 1
appliance/roles/common/tasks/password_config.yml

@@ -17,7 +17,7 @@
   command: cat {{ input_config_filename }}
   changed_when: false
   register: config_content
-S
+
 - name: Decrpyt appliance_config.yml
   command: >-
     ansible-vault decrypt {{ input_config_filename }}

+ 6 - 2
appliance/roles/inventory/files/add_host.yml

@@ -35,9 +35,13 @@
   lineinfile:
     path:  "/root/inventory"
     line: "    {{ item }}:\n      _awx_description: {{ host_description }}"
-  when: not check_host.stdout | regex_search(item)
+  when:
+    - not check_host.stdout | regex_search(item)
+    - host_description != "Description Unavailable"
 
 - name: Host added msg
   debug:
     msg: "{{ host_added_msg + item }}"
-  when: not check_host.stdout | regex_search(item)
+  when:
+    - not check_host.stdout | regex_search(item)
+    - host_description != "Description Unavailable"

+ 25 - 11
appliance/roles/inventory/files/create_inventory.yml

@@ -47,45 +47,57 @@
 - name: Set hostname on reachable nodes and gather facts
   hosts: reachable
   gather_facts: False
+  ignore_unreachable: true
   remote_user: "{{ cobbler_username }}"
   vars:
     ansible_password: "{{ cobbler_password }}"
     ansible_become_pass: "{{ cobbler_password }}"
     ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
+    mapping_file_present: ""
   tasks:
     - name: Setup
       setup:
        filter: ansible_*
-    
+
     - name: Check hostname of server
       command: hostname
       register: hostname_check
-      changed_when: false     
+      changed_when: false
+      ignore_errors: true
 
     - name: Check if IP present in mapping file
-      shell: grep "{{ inventory_hostname }}" {{ role_path }}/files/new_mapping_file.csv
+      command: grep "{{ inventory_hostname }}" ../../provision/files/new_mapping_file.csv
       delegate_to: localhost
       register: file_present
-      changed_when: false
+      when: mapping_file == "true"
+      ignore_errors: true
+
+    - name: Set fact if mapping file present
+      set_fact:
+        mapping_file_present: file_present.stdout
+      when: mapping_file == "true"
+      ignore_errors: true
 
     - name: Get the static hostname from mapping file
-      shell:  grep -Po ".* (?="{{ inventory_hostname }}")" {{ role_path }}/files/new_mapping_file.csv| awk -F',' '{print $2}'
+      shell: awk -F',' '$3 == "{{ inventory_hostname }}" { print $2 }' ../../provision/files/new_mapping_file.csv
       delegate_to: localhost
-      when: ('localhost' in hostname_check.stdout) and (file_present.stdout != "")
-      changed_when: false
+      when: ('localhost' in hostname_check.stdout) and (mapping_file_present != "" ) and ( mapping_file == "true" )
       register: host_name
+      ignore_errors: true
 
     - name: Set the hostname from mapping file
       hostname:
         name: "{{ host_name.stdout }}"
       register: result_host_name
-      when: ('localhost' in hostname_check.stdout) and (file_present.stdout != "")
+      when: ('localhost' in hostname_check.stdout) and (mapping_file_present != "" ) and  (mapping_file == "true" )
+      ignore_errors: true
 
     - name: Set the system hostname
       hostname:
         name: "compute{{ inventory_hostname.split('.')[-2] + '-' + inventory_hostname.split('.')[-1] }}"
       register: result_name
-      when: ('localhost' in hostname_check.stdout) and (file_present.stdout == "")
+      when: ('localhost' in hostname_check.stdout) and (mapping_file_present == "")
+      ignore_errors: true
 
     - name: Add new hostname to /etc/hosts
       lineinfile:
@@ -93,7 +105,8 @@
         regexp: '^127\.0\.0\.1[ \t]+localhost'
         line: "127.0.0.1 localhost {{ host_name.stdout }}"
         state: present
-      when: "'localhost' in hostname_check.stdout" and (file_present.stdout != "")
+      when: ('localhost' in hostname_check.stdout) and ( mapping_file_present != "" ) and ( mapping_file == "true" )
+      ignore_errors: true
 
     - name: Add new hostname to /etc/hosts
       lineinfile:
@@ -101,7 +114,8 @@
         regexp: '^127\.0\.0\.1[ \t]+localhost'
         line: "127.0.0.1 localhost 'compute{{ inventory_hostname.split('.')[-2] + '-' + inventory_hostname.split('.')[-1] }}'"
         state: present
-      when: "'localhost' in hostname_check.stdout" and (file_present.stdout == "" )
+      when: ('localhost' in hostname_check.stdout) and (mapping_file_present == "" )
+      ignore_errors: true
 
 - name: Update inventory
   hosts: localhost

+ 4 - 3
appliance/roles/inventory/tasks/main.yml

@@ -49,6 +49,7 @@
     - name: Save input variables from file
       set_fact:
         cobbler_password: "{{ provision_password }}"
+        mapping_file: "{{ mapping_file_exists }}"
       no_log: True
 
     - name: Encrypt input config file
@@ -79,16 +80,16 @@
           command: >-
             ansible-playbook -i {{ role_path }}/files/provisioned_hosts.yml
             {{ role_path }}/files/create_inventory.yml
-            --extra-vars "cobbler_username={{ cobbler_username }} cobbler_password={{ cobbler_password }}"
+            --extra-vars "cobbler_username={{ cobbler_username }} cobbler_password={{ cobbler_password }} mapping_file={{ mapping_file }}"
           no_log: True
           register: register_error
       rescue:
         - name: Fail if host addition was not successful
           fail:
-            msg: "{{ register_error.stdout | regex_replace(cobbler_username) | regex_replace(cobbler_password) }}"
+            msg: "{{ register_error.stderr + register_error.stdout | regex_replace(cobbler_username) | regex_replace(cobbler_password) }}"
 
   when: provisioned_file_result.stat.exists
 
 - name: push inventory to AWX
   command: awx-manage inventory_import --inventory-name {{ omnia_inventory_name }} --source /root/inventory
-  when: provisioned_file_result.stat.exists
+  when: provisioned_file_result.stat.exists

+ 1 - 1
appliance/roles/provision/tasks/provision_password.yml

@@ -34,7 +34,7 @@
   tags: install
 
 - name: Copy cobbler password to cobbler config file
-  shell: printf "%s:%s:%s\n" "{{ username }}" "Cobbler" "{{ encrypt_SSS.stdout }}" > "{{ role_path }}/files/.users.digest"
+  shell: printf "%s:%s:%s\n" "{{ username }}" "Cobbler" "{{ encrypt_password.stdout }}" > "{{ role_path }}/files/.users.digest"
   changed_when: false
   no_log: true
   tags: install

+ 1 - 1
appliance/roles/web_ui/tasks/ui_accessibility.yml

@@ -74,7 +74,7 @@
             return_content: yes
           register: register_error
           until: awx_ui_msg in register_error.content
-          retries: 20
+          retries: 30
           delay: 10
           changed_when: no
           no_log: True

+ 40 - 0
appliance/tools/passwordless_ssh.yml

@@ -0,0 +1,40 @@
+# 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: Fetch provision_password
+  hosts: localhost
+  connection: local
+  gather_facts: no
+  roles:
+    - fetch_password
+
+- name: Prepare the cluster with passwordless ssh from manager to compute
+  hosts: manager
+  gather_facts: false
+  pre_tasks:
+    - name: Set Fact
+      set_fact:
+        ssh_to: "{{ groups['compute'] }}"
+  roles:
+    - cluster_preperation
+
+- name: Prepare the cluster with passwordless ssh from compute to manager
+  hosts: compute
+  gather_facts: false
+  pre_tasks:
+    - name: Set Fact
+      set_fact:
+        ssh_to: "{{ groups['manager'] }}"
+  roles:
+    - cluster_preperation

roles/cluster_preperation/tasks/main.yml → appliance/tools/roles/cluster_preperation/tasks/main.yml


roles/cluster_preperation/tasks/passwordless_ssh.yml → appliance/tools/roles/cluster_preperation/tasks/passwordless_ssh.yml


roles/cluster_preperation/vars/main.yml → appliance/tools/roles/cluster_preperation/vars/main.yml


+ 42 - 0
appliance/tools/roles/fetch_password/tasks/main.yml

@@ -0,0 +1,42 @@
+#  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: Include variables from common role
+  include_vars: "{{ role_path }}/../../../roles/common/vars/main.yml"
+  no_log: True
+
+- name: Check input config file is encrypted
+  command: cat {{ role_path }}/../../../{{ input_config_filename }}
+  changed_when: false
+  register: config_content
+
+- name: Decrpyt appliance_config.yml
+  command: >-
+    ansible-vault decrypt {{ role_path }}/../../../{{ input_config_filename }}
+    --vault-password-file {{ role_path }}/../../../{{ vault_filename }}
+  changed_when: false
+  when: "'$ANSIBLE_VAULT;' in config_content.stdout"
+
+- name: Include variable file appliance_config.yml
+  include_vars: "{{ role_path }}/../../../{{ input_config_filename }}"
+
+- name: Save input variables from file
+  set_fact:
+    cobbler_password: "{{ provision_password }}"
+
+- name: Encrypt input config file
+  command: >-
+    ansible-vault encrypt {{ role_path }}/../../../{{ input_config_filename }}
+    --vault-password-file {{ role_path }}/../../../{{ vault_filename }}
+  changed_when: false

+ 1 - 21
omnia.yml

@@ -123,24 +123,4 @@
 # gather_facts: false
 # roles:
 #   - slurm_exporter
-# tags: slurm
-
-- name: Prepare the cluster with passwordless ssh from manager to compute
-  hosts: manager
-  gather_facts: false
-  pre_tasks:
-    - name: Set Fact
-      set_fact:
-        ssh_to: "{{ groups['compute'] }}"
-  roles:
-    - cluster_preperation
-
-- name: Prepare the cluster with passwordless ssh from compute to manager
-  hosts: compute
-  gather_facts: false
-  pre_tasks:
-    - name: Set Fact
-      set_fact:
-        ssh_to: "{{ groups['manager'] }}"
-  roles:
-    - cluster_preperation
+# tags: slurm

+ 24 - 0
omnia_config.yml

@@ -0,0 +1,24 @@
+# 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 for Slurm database.
+# The Length of the password should be atleast 8.
+# The password must not contain -,\, ',"
+mariadb_password: "password"
+
+# Kubernetes SDN network.
+# It can either be "calico" or "flannel".
+# Default value assigned is "calico".
+k8s_cni: "calico"

+ 54 - 10
roles/cluster_validation/tasks/fetch_password.yml

@@ -12,31 +12,75 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 ---
-- name: Check if input config file is encrypted
-  command: cat {{ role_path }}/../../appliance/{{ input_config_filename }}
+- 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 input_config.yml
+- name: Decrpyt omnia_config.yml
   command: >-
-    ansible-vault decrypt {{ role_path }}/../../appliance/{{ input_config_filename }}
-    --vault-password-file {{ role_path }}/../../appliance/roles/common/files/{{ vault_filename }}
+    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 input_config.yml
-  include_vars: "{{ role_path }}/../../appliance/{{ input_config_filename }}"
+- 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:
-    cobbler_password: "{{ provision_password }}"
     db_password: "{{ mariadb_password }}"
     k8s_cni: "{{ k8s_cni }}"
   no_log: True
 
 - name: Encrypt input config file
   command: >-
-    ansible-vault encrypt {{ role_path }}/../../appliance/{{ input_config_filename }}
-    --vault-password-file {{ role_path }}/../../appliance/roles/common/files/{{ vault_filename }}
+    ansible-vault encrypt {{ role_path }}/../../{{ config_filename }}
+    --vault-password-file {{ role_path }}/../../{{ config_vaultname }}
   when: "'$ANSIBLE_VAULT;' not in config_content.stdout"

+ 1 - 4
roles/cluster_validation/tasks/main.yml

@@ -12,11 +12,8 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 ---
-- name: Include vars file of common role
-  include_vars: "{{ role_path }}/../../appliance/roles/common/vars/main.yml"
-
 - name: Perform validations
   include_tasks: validations.yml
 
-- name: Fetch cobbler password
+- name: Fetch passwords
   include_tasks: fetch_password.yml

+ 10 - 0
roles/cluster_validation/vars/main.yml

@@ -12,7 +12,17 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 ---
+#Usage: fetch_password.yml
+config_filename: "omnia_config.yml"
+config_vaultname: .omnia_vault_key
+min_length: 8
+max_length: 30
+fail_msg_mariadb_password: "maria_db password not given in correct format."
+success_msg_mariadb_password: "mariadb_password validated"
+success_msg_k8s_cni: "Kubernetes CNI Validated"
+fail_msg_k8s_cni: "Kubernetes CNI not correct."
 
+#Usage: validations.yml
 skip_tag_fail_msg: "Can't skip both slurm and kubernetes"
 manager_group_fail_msg: "manager group should contain exactly 1 node"
 manager_group_success_msg: "manager group check passed"