Improve application role testability

Remove different phases for application role as
those are supposed to run after each other anyway
from playbook and pre/post steps can be disabled
by other means.

Enable Helm override file generation customization by
delegating it to separate role.

Separate Helm file transfer to own module.

NOTE: install.yml with all Helm commands (shell/command)
is not idempotent and should be fixed with separate
commit.

Issue-ID: OOM-1655

Change-Id: Ib29773c4d64a0529c71c3f93c2af7265ae94059f
Signed-off-by: Samuli Silvius <s.silvius@partner.samsung.com>
diff --git a/ansible/application.yml b/ansible/application.yml
index bbac7e5..02c654f 100644
--- a/ansible/application.yml
+++ b/ansible/application.yml
@@ -2,22 +2,16 @@
 - name: Setup nfs server
   hosts: nfs-server
   roles:
-    - {role: nfs, when: groups.kubernetes | length > 1 }
+    - role: nfs
+      when: groups.kubernetes | length > 1
 
 - name: Setup nfs mounts
   hosts: kubernetes:!nfs-server
   roles:
-    - {role: nfs, when: groups.kubernetes | length > 1 }
+    - role: nfs
+      when: groups.kubernetes | length > 1
 
 - name: Install Helm application {{ app_name }} into offline Kubernetes cluster
   hosts: infrastructure
   roles:
-    - role: application-install
-      vars:
-        phase: pre-install
-    - role: application-install
-      vars:
-        phase: install
-    - role: application-install
-      vars:
-        phase: post-install
+    - application
diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index 0d22ac5..1dc938f 100755
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -90,9 +90,10 @@
 # Application specific params #
 ###############################
 
-# App Helm charts directory location in installation package.
-# The path is absolute path (even locates relative inside of this sw package
-# installation folder) because it must be visible for ansible docker/chroot
+# App Helm charts directory location in installation package
+# (local path for the ansible process).
+# The path locates relative inside of this sw package
+# installation folder and must be visible for ansible docker/chroot
 # process to find directory and to transfer it into machine (infra node) running
 # Helm repository.
 # Content of the folder must be Helm chart directories of the app with Makefile.
@@ -100,7 +101,7 @@
 # NOTE: This default value should not be changed if not really needed and it
 # must match with the variable "HELM_CHARTS_DIR_IN_PACKAGE" value in package.sh
 # script!
-app_helm_charts_install_directory: "/ansible/application/helm_charts"
+app_helm_charts_install_directory: application/helm_charts
 
 # Specify target dir where helm charts are copied into on infra node.
 # (same as content of "app_helm_charts_install_directory" copied by installer to this dir.)
diff --git a/ansible/group_vars/infrastructure.yml b/ansible/group_vars/infrastructure.yml
index 9fd88f2..450d96f 100755
--- a/ansible/group_vars/infrastructure.yml
+++ b/ansible/group_vars/infrastructure.yml
@@ -32,5 +32,3 @@
 kube_directory: /root/.kube
 kubectl_bin_dir: /usr/local/bin
 helm_bin_dir: /usr/local/bin
-helm_repository_name: local
-helm_repository_url: http://127.0.0.1:8879
diff --git a/ansible/roles/application-install/defaults/main.yml b/ansible/roles/application-install/defaults/main.yml
deleted file mode 100644
index 473fbb8..0000000
--- a/ansible/roles/application-install/defaults/main.yml
+++ /dev/null
@@ -1 +0,0 @@
-phase: install
diff --git a/ansible/roles/application-install/tasks/main.yml b/ansible/roles/application-install/tasks/main.yml
deleted file mode 100644
index ba52279..0000000
--- a/ansible/roles/application-install/tasks/main.yml
+++ /dev/null
@@ -1,22 +0,0 @@
----
-- debug:
-    msg: "phase is {{ phase }}"
-
-- name: Check if install needed
-  block:
-    - name: "Does {{ app_helm_charts_install_directory }} exist and contain Helm Charts"
-      find:
-        paths: "{{ app_helm_charts_install_directory }}"
-        recurse: yes
-      delegate_to: localhost
-      register: charts_files
-    - name: Set install active fact
-      set_fact:
-        install_needed: "{{ true if charts_files.matched | int > 0 else false }}"
-  when: phase == "pre-install"
-
-- include_tasks: "{{ phase }}.yml"
-  when: install_needed
-
-- debug:
-    msg: "Install needed {{ install_needed }}"
diff --git a/ansible/roles/application-override/tasks/main.yml b/ansible/roles/application-override/tasks/main.yml
new file mode 100644
index 0000000..84896fb
--- /dev/null
+++ b/ansible/roles/application-override/tasks/main.yml
@@ -0,0 +1,16 @@
+---
+# Role for generating Helm override.yml file
+- name: Register root certificate
+  slurp:
+    src: "{{ playbook_dir }}/certs/rootCA.crt"
+  register: root_cert
+  delegate_to: localhost
+
+# WA: this is required because deploy plugin dont process params properly
+- name: Create override file with global.cacert
+  copy:
+    dest: "{{ app_helm_override_file }}"
+    content: |
+      global:
+        cacert: |
+          {{ root_cert['content'] | b64decode | indent( width=4, indentfirst=False) }}
diff --git a/ansible/roles/application/defaults/main.yml b/ansible/roles/application/defaults/main.yml
new file mode 100644
index 0000000..dec1760
--- /dev/null
+++ b/ansible/roles/application/defaults/main.yml
@@ -0,0 +1,11 @@
+---
+helm_repository_name: local
+helm_repository_url: http://127.0.0.1:8879
+# Override file generation for Helm application can be customized by any role
+# given by user and found by ansible from roles_path.
+# By default override file is generated by 'application-override' role that is
+# specific for offline installer (for onap) as it's generating server
+# certificate needed to simulate internet by offline installer.
+app_skip_helm_override: false
+app_helm_override_role: application-override
+app_helm_override_file: "{{ app_data_path }}/override.yaml"
diff --git a/ansible/roles/application-install/tasks/custom_role.yml b/ansible/roles/application/tasks/custom_role.yml
similarity index 72%
rename from ansible/roles/application-install/tasks/custom_role.yml
rename to ansible/roles/application/tasks/custom_role.yml
index b6f6f35..f0b9a84 100644
--- a/ansible/roles/application-install/tasks/custom_role.yml
+++ b/ansible/roles/application/tasks/custom_role.yml
@@ -1,6 +1,6 @@
 ---
 # Caller fills application_custom_role variable with actual role name.
-- name: "Execute custom role {{ application_custom_role }} {{ phase }} Helm install."
+- name: "Execute custom role {{ application_custom_role }} for Helm install."
   include_role:
     name: "{{ application_custom_role }}"
   when:
diff --git a/ansible/roles/application-install/tasks/install.yml b/ansible/roles/application/tasks/install.yml
similarity index 74%
rename from ansible/roles/application-install/tasks/install.yml
rename to ansible/roles/application/tasks/install.yml
index 1cccf9a..103ecc8 100644
--- a/ansible/roles/application-install/tasks/install.yml
+++ b/ansible/roles/application/tasks/install.yml
@@ -6,8 +6,8 @@
      --skip-refresh
   changed_when: true # init is always changed type of action
 
-#A correct way to implement this would be using --wait option in helm init invocation.
-#However, it does not work due to https://github.com/helm/helm/issues/4031 (fixed in newer helm release)
+# A correct way to implement this would be using --wait option in helm init invocation.
+# However, it does not work due to https://github.com/helm/helm/issues/4031 (fixed in newer helm release)
 - name: "Wait for helm upgrade to finish"
   command: "{{ helm_bin_dir }}/helm version --tiller-connection-timeout 10"
   register: result
@@ -42,7 +42,7 @@
     - "'Error: no repositories to show' not in helm_repo_list.stderr"
 
 - name: Helm Add Repo
-  command: "{{ helm_bin_dir }}/helm repo add {{ helm_repository_name }} {{ helm_repository_url }}"
+  command: "{{ helm_bin_dir }}/helm repo add {{ helm_repository_name | mandatory }} {{ helm_repository_url | mandatory }}"
   when: "'local' not in helm_repo_list.stdout"
   changed_when: true # when executed its a changed type of action
 
@@ -50,24 +50,14 @@
   make:
     chdir: "{{ app_helm_charts_infra_directory }}"
     target: "{{ item }}"
-  with_items: "{{ app_helm_build_targets }}"
+  loop: "{{ app_helm_build_targets }}"
   environment:
     PATH: "{{ helm_bin_dir }}:{{ ansible_env.PATH }}"
 
-- name: Register root certificate
-  slurp:
-    src: "{{ playbook_dir }}/certs/rootCA.crt"
-  register: root_cert
-  delegate_to: localhost
-
-# WA: this is required because deploy plugin dont process params properly
-- name: Create override file with global.cacert
-  copy:
-    dest: "{{ app_data_path }}/override.yaml"
-    content: |
-      global:
-        cacert: |
-          {{ root_cert['content'] | b64decode | indent( width=4, indentfirst=False) }}
+- name: Generate Helm application override file with custom role
+  include_role:
+    name: "{{ app_helm_override_role }}"
+  when: not app_skip_helm_override
 
 - name: Check for deploy plugin presence
   stat:
@@ -81,7 +71,7 @@
           {{ app_helm_release_name }}
           {{ helm_repository_name }}/{{ app_helm_chart_name }}
           --namespace {{ app_kubernetes_namespace }}
-          -f {{ app_data_path }}/override.yaml
+          {{ '' if app_skip_helm_override else '-f ' + app_helm_override_file }}
   changed_when: true # when executed its a changed type of action
   register: helm_install
   failed_when: helm_install.stderr
diff --git a/ansible/roles/application/tasks/main.yml b/ansible/roles/application/tasks/main.yml
new file mode 100644
index 0000000..3018e95
--- /dev/null
+++ b/ansible/roles/application/tasks/main.yml
@@ -0,0 +1,24 @@
+---
+- name: Check if application Helm charts exist and install is even needed
+  block:
+    - name: "Does {{ app_helm_charts_install_directory }} directory exist and contain Helm Charts"
+      find:
+        paths: "{{ app_helm_charts_install_directory }}"
+        recurse: true
+      delegate_to: localhost
+      register: charts_files
+    - name: Set install active fact
+      set_fact:
+        install_needed: "{{ true if charts_files.matched | int > 0 else false }}"
+
+- name: Install app with Helm charts
+  block:
+    - include_tasks: transfer-helm-charts.yml
+    - include_tasks: pre-install.yml
+    - include_tasks: install.yml
+    - include_tasks: post-install.yml
+  when: install_needed
+
+- debug:
+    msg: "NOTE, nothing done as application Helm charts does not exist!"
+  when: not install_needed
diff --git a/ansible/roles/application-install/tasks/post-install.yml b/ansible/roles/application/tasks/post-install.yml
similarity index 60%
rename from ansible/roles/application-install/tasks/post-install.yml
rename to ansible/roles/application/tasks/post-install.yml
index 1059423..5464cb4 100644
--- a/ansible/roles/application-install/tasks/post-install.yml
+++ b/ansible/roles/application/tasks/post-install.yml
@@ -2,4 +2,4 @@
 - name: "Execute custome role {{ application_post_install_role }} if defined."
   include_tasks: custom_role.yml
   vars:
-    application_custom_role: "{{ application_post_install_role }}"
+    application_custom_role: "{{ application_post_install_role | default('') }}"
diff --git a/ansible/roles/application/tasks/pre-install.yml b/ansible/roles/application/tasks/pre-install.yml
new file mode 100644
index 0000000..74f1548
--- /dev/null
+++ b/ansible/roles/application/tasks/pre-install.yml
@@ -0,0 +1,5 @@
+---
+- name: "Execute custom role {{ application_pre_install_role }} if defined."
+  include_tasks: custom_role.yml
+  vars:
+    application_custom_role: "{{ application_pre_install_role | default('') }}"
diff --git a/ansible/roles/application-install/tasks/pre-install.yml b/ansible/roles/application/tasks/transfer-helm-charts.yml
similarity index 86%
rename from ansible/roles/application-install/tasks/pre-install.yml
rename to ansible/roles/application/tasks/transfer-helm-charts.yml
index bf6619b..0cd7c02 100644
--- a/ansible/roles/application-install/tasks/pre-install.yml
+++ b/ansible/roles/application/tasks/transfer-helm-charts.yml
@@ -38,14 +38,7 @@
       copy:
         src: "{{ item.path }}"
         dest: "{{ helm_home_dir.stdout }}/plugins"
-        directory_mode: yes
+        directory_mode: true
         mode: 0755
       with_items: "{{ list_of_plugins.files }}"
-  become: true
   when: app_helm_plugins_directory is defined and app_helm_plugins_directory is not none
-
-- name: "Execute custom role {{ application_pre_install_role }} if defined."
-  include_tasks: custom_role.yml
-  vars:
-    application_custom_role: "{{ application_pre_install_role }}"
-