Просмотр исходного кода

Merge pull request #709 from sakshiarora13/devel

Issue#708: Grafana Installation and Configuration
Sujit Jadhav 3 лет назад
Родитель
Сommit
2910ae2c42
28 измененных файлов с 715 добавлено и 50 удалено
  1. 1 0
      control_plane/control_plane.yml
  2. 5 1
      control_plane/input_params/base_vars.yml
  3. 13 1
      control_plane/input_params/login_vars.yml
  4. 11 2
      control_plane/roles/control_plane_common/tasks/fetch_base_inputs.yml
  5. 23 0
      control_plane/roles/control_plane_common/tasks/password_config.yml
  6. 5 2
      control_plane/roles/control_plane_common/vars/main.yml
  7. 87 0
      control_plane/roles/webui_grafana/tasks/deployment.yml
  8. 39 0
      control_plane/roles/webui_grafana/tasks/main.yml
  9. 35 0
      control_plane/roles/webui_grafana/tasks/plugins.yml
  10. 34 0
      control_plane/roles/webui_grafana/tasks/pre-requisites.yml
  11. 44 0
      control_plane/roles/webui_grafana/tasks/secrets.yml
  12. 52 0
      control_plane/roles/webui_grafana/tasks/volume.yml
  13. 45 0
      control_plane/roles/webui_grafana/vars/main.yml
  14. 2 2
      telemetry/input_params/base_vars.yml
  15. 20 15
      telemetry/input_params/login_vars.yml
  16. 1 1
      telemetry/roles/common/tasks/k8s_secrets.yml
  17. 23 14
      telemetry/roles/common/tasks/pre-requisites.yml
  18. 96 7
      telemetry/roles/common/tasks/validate_login_vars.yml
  19. 15 3
      telemetry/roles/common/vars/main.yml
  20. 55 0
      telemetry/roles/grafana_config/tasks/add_datasource.yml
  21. 20 0
      telemetry/roles/grafana_config/tasks/main.yml
  22. 17 0
      telemetry/roles/grafana_config/vars/main.yml
  23. 16 0
      telemetry/roles/idrac_telemetry/tasks/main.yml
  24. 16 0
      telemetry/roles/idrac_telemetry/vars/main.yml
  25. 32 0
      telemetry/roles/timescaledb/tasks/initialize_db.yml
  26. 5 2
      telemetry/roles/timescaledb/tasks/main.yml
  27. 2 0
      telemetry/roles/timescaledb/vars/main.yml
  28. 1 0
      telemetry/telemetry.yml

+ 1 - 0
control_plane/control_plane.yml

@@ -22,6 +22,7 @@
     - control_plane_device
     - provision_cobbler
     - webui_awx
+    - webui_grafana
     - control_plane_ib
     - control_plane_sm
     - control_plane_customiso

+ 5 - 1
control_plane/input_params/base_vars.yml

@@ -69,6 +69,10 @@ snmp_community_name: "public"
 # Default value: “DellEMC”
 awx_organization: "DellEMC"
 
+### Usage: webui_grafana ###
+# At this location grafana persistent volume will be created.
+mount_location: /mnt/omnia/
+
 ### Usage: provision_cobbler, provision_idrac ###
 
 # This variable is used to set node provisioning method
@@ -171,4 +175,4 @@ ib_network_nic: "ib0"
 # The dhcp range for assigning the IPv4 address
 # Example: 172.17.0.1
 ib_network_dhcp_start_range: "172.25.0.100"
-ib_network_dhcp_end_range: "172.25.0.200"
+ib_network_dhcp_end_range: "172.25.0.200"

+ 13 - 1
control_plane/input_params/login_vars.yml

@@ -48,6 +48,18 @@ idrac_password: ""
 # The password must not contain -,\, ',"
 #awx_password: ""
 
+### Usage: webui_grafana ###
+
+# The username for grafana UI
+# The length of username should be atleast 6
+# The username must not contain -,\, ',"
+grafana_username: ""
+
+# Password used for grafana UI
+# The length of the password should be at least 6
+# The password must not contain -,\, ',"
+grafana_password: ""
+
 ### Usage: network_ethernet ###
 
 # The username for ethernet switch
@@ -89,4 +101,4 @@ directory_manager_password: ""
 
 # The IPA server requires an administrative user, named 'admin'.
 # This user is a regular system account used for IPA server administration
-ipa_admin_password: ""
+ipa_admin_password: ""

+ 11 - 2
control_plane/roles/control_plane_common/tasks/fetch_base_inputs.yml

@@ -38,7 +38,8 @@
       provision_method | length < 1 or
       default_lease_time | length < 1 or
       provision_os | length < 1 or
-      provision_state | length < 1
+      provision_state | length < 1 or
+      mount_location | length < 1
 
 - name: Validate default lease time
   assert:
@@ -181,6 +182,14 @@
     success_msg: "{{ success_awx_organization }}"
     fail_msg: "{{ fail_awx_organization }}"
 
+- name: Make mount directory for grafana if it doesnt exist
+  file:
+    path: "{{ mount_location }}"
+    state: directory
+    mode: "{{ mount_dir_perm }}"
+    group: root
+    owner: root
+
 - name: Check timezone file
   command: grep -Fx "{{ timezone }}" {{ role_path }}/files/timezone.txt
   failed_when: false
@@ -476,4 +485,4 @@
       - ib_network_nic != host_network_nic
     success_msg: "{{ success_msg_different_nics_ib }}"
     fail_msg: "{{ fail_msg_different_nics_ib }}"
-  when: ib_switch_support
+  when: ib_switch_support

+ 23 - 0
control_plane/roles/control_plane_common/tasks/password_config.yml

@@ -105,6 +105,29 @@
       fail:
         msg: "{{ fail_msg_idrac_credentials }}"
 
+- name: Assert grafana credentials
+  block:
+    - name: Assert grafana_username and grafana_username
+      assert:
+        that:
+          - grafana_username | length >= min_length_grafana
+          - grafana_username | length <= max_length
+          - '"-" not in grafana_username '
+          - '"\\" not in grafana_username '
+          - '"\"" not in grafana_username '
+          - " \"'\" not in grafana_username "
+          - grafana_password | length >= min_length_grafana
+          - grafana_password | length <= max_length
+          - '"-" not in grafana_password '
+          - '"\\" not in grafana_password '
+          - '"\"" not in grafana_password '
+          - " \"'\" not in grafana_password "
+      no_log: true
+  rescue:
+    - name: grafana credentials validation check
+      fail:
+        msg: "{{ fail_msg_grafana_credentials }}"
+
 - name: Assert username and password for ethernet switches
   block:
     - name: Verify ethernet_switch_username and ethernet_switch_password are not empty

+ 5 - 2
control_plane/roles/control_plane_common/vars/main.yml

@@ -13,6 +13,7 @@
 #  limitations under the License.
 ---
 
+
 # vars file for common
 
 # Usage: package_installation.yml
@@ -62,7 +63,6 @@ hostname: github.com
 port_no: 22
 os_supported_centos: "centos"
 os_supported_rocky: "rocky"
-os_supported_leap: "leap"
 os_supported_centos_version: "8.3"
 os_supported_rocky_version: "8.4"
 fail_os_status: "Unsupported OS or OS version. OS should be {{ os_supported_centos }} {{ os_supported_centos_version }} or {{ os_supported_rocky }} {{ os_supported_rocky_version }}"
@@ -79,13 +79,16 @@ vault_filename: input_params/.login_vault_key
 min_length: 8
 max_length: 30
 min_username_length: 4
+min_length_grafana: 6
 file_perm: '0755'
 vault_file_perm: '0644'
+mount_dir_perm: '0775'
 nic_min_length: 3
 login_input_config_failure_msg: "Failed. Please provide all the required parameters in login_vars.yml"
 fail_msg_provision_password: "Failed. Incorrect provision_password format provided in login_vars.yml"
 fail_msg_cobbler_password: "Failed. Incorrect cobbler_password format provided in login_vars.yml file"
 fail_msg_idrac_credentials: "Failed. Incorrect idrac_username or idrac_password format provided in login_vars.yml"
+fail_msg_grafana_credentials: "Failed. Incorrect grafana_username or grafana_password format provided in login_vars.yml"
 fail_msg_ethernet_credentials: "Failed. Incorrect ethernet_switch_username or ethernet_switch_password format provided in login_vars.yml"
 fail_msg_ib_credentials: "Failed. Incorrect ib_username or ib_password format provided in login_vars.yml"
 fail_msg_me4_credentials: "Failed. Incorrect powervault_me4_username or powervault_me4_password format provided in login_vars.yml"
@@ -229,4 +232,4 @@ dom_name_length: '63'
 dom_name_success_msg: "domain name successfully validated"
 dom_name_fail_msg: "Failed. Incorrect format provided for domain name in security_vars.yml"
 realm_success_msg: "realm_name successfully validated"
-realm_fail_msg: "Failed. Incorrect realm_name format in security_vars.yml"
+realm_fail_msg: "Failed. Incorrect realm_name format in security_vars.yml"

+ 87 - 0
control_plane/roles/webui_grafana/tasks/deployment.yml

@@ -0,0 +1,87 @@
+# Copyright 2022 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: Grafana pod
+  kubernetes.core.k8s:
+    state: present
+    definition:
+      apiVersion: apps/v1
+      kind: Deployment
+      metadata:
+        name: "{{ grafana_k8s }}"
+        namespace: "{{ grafana_namespace }}"
+        labels:
+          app: "{{ grafana_k8s }}"
+      spec:
+        selector:
+          matchLabels:
+            app: "{{ grafana_k8s }}"
+        replicas: 1
+        strategy:
+          type: RollingUpdate
+        template:
+          metadata:
+            labels:
+              app: "{{ grafana_k8s }}"
+          spec:
+            containers:
+              - name: grafana
+                image: "{{ grafana_image }}"
+                imagePullPolicy: "IfNotPresent"
+                env:
+                - name: GF_SERVER_HTTP_PORT
+                  value: "{{ grafana_port }}"
+                - name: GF_PLUGINS_PLUGIN_ADMIN_ENABLED
+                  value: "true"
+                - name: GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS
+                  value: "{{ grafana_plugins_names }}"
+                - name: GF_SECURITY_ADMIN_USER
+                  valueFrom:
+                    secretKeyRef:
+                      name: "{{ grafana_secrets }}"
+                      key: grafana_username
+                - name: GF_SECURITY_ADMIN_PASSWORD
+                  valueFrom:
+                    secretKeyRef:
+                      name: "{{ grafana_secrets }}"
+                      key: grafana_password
+                ports:
+                - containerPort: "{{ grafana_http_port }}"
+                volumeMounts:
+                - mountPath: /var/lib/grafana/
+                  name: grafana-data
+            volumes:
+            - name: grafana-data
+              persistentVolumeClaim:
+                claimName: grafana-volume-claim
+
+- name: Service for grafana
+  kubernetes.core.k8s:
+    state: present
+    definition:
+      apiVersion: v1
+      kind: Service
+      metadata:
+        name: "{{ grafana_k8s }}"
+        namespace: "{{ grafana_namespace }}"
+        labels:
+          app: "{{ grafana_k8s }}"
+      spec:
+        type: ClusterIP
+        ports:
+          - name: http
+            port: "{{ grafana_http_port }}"
+        selector:
+          app: "{{ grafana_k8s }}"

+ 39 - 0
control_plane/roles/webui_grafana/tasks/main.yml

@@ -0,0 +1,39 @@
+# Copyright 2022 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: Pre-requisites for grafana
+  include_tasks: pre-requisites.yml
+
+- name: Create k8s secrets for grafana
+  include_tasks: secrets.yml
+
+- name: Create persistent volume for grafana
+  include_tasks: volume.yml
+
+- name: Create grafana pod
+  include_tasks: deployment.yml
+
+- name: Add grafana-plugins for visualization
+  include_tasks: plugins.yml
+
+- name: Get grafana service IP
+  command: kubectl get svc "{{ grafana_k8s }}" -n "{{ grafana_namespace }}" -o=jsonpath='{.spec.clusterIP}'
+  changed_when: false
+  register: grafana_svc_ip
+
+- name: Get grafana service port
+  command: kubectl get svc "{{ grafana_k8s }}" -n "{{ grafana_namespace }}" -o=jsonpath='{.spec.ports[0].port}'
+  changed_when: false
+  register: grafana_svc_port

+ 35 - 0
control_plane/roles/webui_grafana/tasks/plugins.yml

@@ -0,0 +1,35 @@
+# Copyright 2022 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: Git clone grafana plugin repo
+  ansible.builtin.git:
+    repo: "{{ grafana_plugins_github_repo }}"
+    dest: "{{ mount_location + grafana_plugins_folder_name }}"
+    version: main
+
+- name: Wait for grafana pod to come to ready state
+  command: kubectl wait --for=condition=ready --timeout=10m -n "{{ grafana_namespace }}" pod -l app="{{ grafana_k8s }}"
+  changed_when: false
+  
+- name: Unzip plugins at grafana-plugins folder
+  unarchive:
+    src: "{{ mount_location + grafana_plugins_folder_name + item }}"
+    dest: "{{ mount_location + grafana_k8s + '/plugins/'}}"
+  with_items: "{{ plugins_name }}"
+  changed_when: false
+
+- name: Restart grafana deployment to add grafana plugins
+  command: kubectl rollout restart deployment -n "{{ grafana_namespace }}"
+  changed_when: false

+ 34 - 0
control_plane/roles/webui_grafana/tasks/pre-requisites.yml

@@ -0,0 +1,34 @@
+# Copyright 2022 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 kubernetes and grafana ansible-galaxy collection
+  command: ansible-galaxy collection install "{{ item }}"
+  with_items: "{{ collections_name }}"
+  changed_when: false
+
+- name: Create grafana namespace
+  kubernetes.core.k8s:
+    api_version: v1
+    kind: Namespace
+    name: "{{ grafana_namespace }}"
+    state: present
+
+- name: Make grafana persistent directory if it doesnt exist
+  file:
+    path: "{{ mount_location + grafana_k8s }}"
+    state: directory
+    mode: "{{ directory_mode }}"
+    group: root
+    owner: root

+ 44 - 0
control_plane/roles/webui_grafana/tasks/secrets.yml

@@ -0,0 +1,44 @@
+# Copyright 2022 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: Encrypt grafana username
+  shell: |
+    set -o pipefail
+    echo -n "{{ grafana_username }}" | base64
+  register: grafana_user_encrypted
+  changed_when: false
+  no_log: true
+
+- name: Encrypt grafana password
+  shell: |
+    set -o pipefail
+    echo -n "{{ grafana_password }}" | base64
+  register: grafana_password_encrypted
+  changed_when: false
+  no_log: true
+
+- name: Kubernetes secrets
+  kubernetes.core.k8s:
+    state: present
+    definition:
+      apiVersion: v1
+      kind: Secret
+      metadata:
+        name: "{{ grafana_secrets }}"
+        namespace: "{{ grafana_namespace }}"
+      type: Opaque
+      data:
+        grafana_username: "{{ grafana_user_encrypted.stdout }}"
+        grafana_password: "{{ grafana_password_encrypted.stdout }}"

+ 52 - 0
control_plane/roles/webui_grafana/tasks/volume.yml

@@ -0,0 +1,52 @@
+# Copyright 2022 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: Persistent volume for grafana
+  kubernetes.core.k8s:
+    state: present
+    definition:
+      apiVersion: v1
+      kind: PersistentVolume
+      metadata:
+        name: grafana-volume
+        namespace: "{{ grafana_namespace }}"
+        labels:
+          type: manual
+      spec:
+        storageClassName: manual
+        capacity:
+          storage: "{{ grafana_volume_memory }}"
+        accessModes:
+          - ReadWriteOnce
+        hostPath:
+          path: "{{ mount_location + grafana_k8s }}"
+
+
+- name: Persistent volume claim for grafana
+  kubernetes.core.k8s:
+    state: present
+    definition:
+      apiVersion: v1
+      kind: PersistentVolumeClaim
+      metadata:
+        name: grafana-volume-claim
+        namespace: "{{ grafana_namespace }}"
+      spec:
+        storageClassName: manual
+        accessModes:
+          - ReadWriteOnce
+        resources:
+          requests:
+            storage: "{{ grafana_volume_memory }}"

+ 45 - 0
control_plane/roles/webui_grafana/vars/main.yml

@@ -0,0 +1,45 @@
+#  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.
+---
+
+# Usage: pre-requisites.yml
+collections_name:
+  - kubernetes.core
+  - community.grafana
+directory_mode: '0774'
+
+# Usage: secrets.yml
+grafana_secrets: grafana-secrets
+
+# Usage: volume.yml
+grafana_volume_memory: 1Gi
+
+# Usage: deployment.yml
+grafana_k8s: grafana
+grafana_namespace: grafana
+grafana_image: grafana/grafana-enterprise:8.3.2
+
+# Usage: deployment.yml
+grafana_port: "5000"
+grafana_http_port: 5000
+grafana_plugins_names: "hpcviz-idvl-hpcc-sankey,hpcviz-idvl-hpcc-parallel-coordinate,hpcviz-idvl-hpcc-spiral-layout,hpcviz-idvl-hpcc-stream-net"
+
+# Usage: plugins.yml
+plugins_name:
+  - parallel-coordinate.zip
+  - sankey.zip
+  - spiral-layout.zip
+  - stream-net.zip
+grafana_plugins_folder_name: github-grafana-plugins/
+grafana_plugins_github_repo: https://github.com/nsfcac/grafana-plugin.git

+ 2 - 2
telemetry/input_params/base_vars.yml

@@ -18,12 +18,12 @@
 mount_location: /mnt/omnia/
 
 # This variable is used to enable iDRAC telemetry support and visualizations
-# Accepted values: "true" or "false"
+# Accepted values:  "true" or "false"
 idrac_telemetry_support: true
 
 # This variable is used to enable slurm telemetry support and visualizations
 # Pre-requisite: idrac_telemetry_support should be set to true
-# Accepted values: "true" or "false"
+# Accepted values:  "true" or "false"
 slurm_telemetry_support: true
 
 # Postgres DB with timescale extension is used for storing iDRAC and slurm telemetry metrics

+ 20 - 15
telemetry/input_params/login_vars.yml

@@ -14,26 +14,31 @@
 ---
 
 # Username used for connecting to timescale db
-# The length of the username should be at least 2 characters.
-# Required field
-timescaledb_user: postgres
+# The username must not contain -,\, ',"
+# The Length of the username should be at least 2 characters.
+# Mandatory field
+timescaledb_user: ""
 
 # Password used for connecting to timescale db
-# The length of the password should be at least 2 characters.
-# Required field
-timescaledb_password: postgres
+# The password must not contain -,\, ',"
+# The Length of the password should be at least 2 characters.
+# Mandatory field
+timescaledb_password: ""
 
 # Username used for connecting to mysql db
-# The length of the username should be at least 2 characters.
-# Required field
-mysqldb_user: mysql
+# The username must not contain -,\, ',"
+# The Length of the username should be at least 2 characters.
+# Mandatory field
+mysqldb_user: ""
 
 # Password used for connecting to mysql db
-# The length of the password should be at least 2 characters.
-# Required field
-mysqldb_password: mysql
+# The password must not contain -,\, ',"
+# The Length of the password should be at least 2 characters.
+# Mandatory field
+mysqldb_password: ""
 
 # Password used for connecting to timescale db for root user
-# The length of the password should be at least 2 characters.
-# Required field
-mysqldb_root_password: mysql
+# The password must not contain -,\, ',"
+# The Length of the password should be at least 2 characters.
+# Mandatory field
+mysqldb_root_password: ""

+ 1 - 1
telemetry/roles/common/tasks/k8s_secrets.yml

@@ -13,7 +13,7 @@
 # limitations under the License.
 ---
 
-- name: namespace
+- name: Create namespace
   kubernetes.core.k8s:
     api_version: v1
     kind: Namespace

+ 23 - 14
telemetry/roles/common/tasks/pre-requisites.yml

@@ -13,22 +13,21 @@
 # limitations under the License.
 ---
 
-- name: Check existence of k8s on management station
+- name: Check existence of awx and grafana on management station
   block:
-    - name: Verify that kubernetes is installed
-      command: kubectl cluster-info
-      register: k8s_cluster_info
-      failed_when: "'running' not in k8s_cluster_info.stdout"
+    - name: Check AWX instance
+      command: awx --version
+      changed_when: false
+
+    - name: Check grafana service
+      command: kubectl get svc -n grafana
+      register: grafana_svc_register
+      failed_when: "'grafana' not in grafana_svc_register.stdout"
       changed_when: false
-      no_log: true
   rescue:
-    - name: Kubernetes needs to be installed
+    - name: AWX and grafana needs to be installed
       fail:
-        msg: "{{ k8s_installation_required }}"
-
-- name: Add kubernetes ansible-galaxy collection
-  command: ansible-galaxy collection install kubernetes.core
-  changed_when: false
+        msg: "{{ control_plane_installation_required }}"
 
 - name: Check that the base_vars.yml exists
   stat:
@@ -40,16 +39,26 @@
     msg: "{{ fail_msg_base_vars }}"
   when: not stat_result.stat.exists
 
-- name: Check that the login_vars.yml exists
+- name: Check that telemetry/login_vars.yml exists
   stat:
     path: "{{ login_vars_file }}"
   register: stat_result
 
-- name: Fail if login_vars.yml file doesn't exist
+- name: Fail if telemetry/login_vars.yml file doesn't exist
   fail:
     msg: "{{ fail_msg_login_vars }}"
   when: not stat_result.stat.exists
 
+- name: Check that control_plane/login_vars.yml exists
+  stat:
+    path: "{{ ctrl_plane_login_vars_filename }}"
+  register: stat_result
+
+- name: Fail if control_plane/login_vars.yml file doesn't exist
+  fail:
+    msg: "{{ ctrl_plane_fail_msg_login_vars }}"
+  when: not stat_result.stat.exists
+
 - name: Install openshift using pip3
   pip:
     name: openshift

+ 96 - 7
telemetry/roles/common/tasks/validate_login_vars.yml

@@ -13,7 +13,8 @@
 # limitations under the License.
 ---
 
-- name: Check login_vars.yml file is encrypted
+# Include telemetry/login_vars.yml
+- name: Check login_vars file is encrypted
   command: cat {{ login_vars_file }}
   changed_when: false
   register: config_content
@@ -26,7 +27,7 @@
   changed_when: false
   when: "'$ANSIBLE_VAULT;' in config_content.stdout"
 
-- name: Include variable file login_vars.yml
+- name: Include variable file telemetry/login_vars.yml
   include_vars: "{{ login_vars_file }}"
   no_log: true
 
@@ -34,27 +35,52 @@
   block:
   - name: Assert timescaledb user name
     assert:
-      that: timescaledb_user | length > 1
+      that:
+        - timescaledb_user | length > 1
+        - '"-" not in timescaledb_user '
+        - '"\\" not in timescaledb_user '
+        - '"\"" not in timescaledb_user '
+        - " \"'\" not in timescaledb_user "
     no_log: true
 
   - name: Assert timescaledb user password
     assert:
-      that: timescaledb_password | length > 1
+      that:
+        - timescaledb_password | length > 1
+        - '"-" not in timescaledb_password '
+        - '"\\" not in timescaledb_password '
+        - '"\"" not in timescaledb_password '
+        - " \"'\" not in timescaledb_password "
     no_log: true
 
   - name: Assert mysqldb user name
     assert:
-      that: mysqldb_user | length > 1
+      that:
+        - mysqldb_user | length > 1
+        - '"-" not in mysqldb_user '
+        - '"\\" not in mysqldb_user '
+        - '"\"" not in mysqldb_user '
+        - " \"'\" not in mysqldb_user "
     no_log: true
 
   - name: Assert mysqldb user password
     assert:
-      that: mysqldb_password | length > 1
+      that:
+        - mysqldb_password | length > 1
+        - '"-" not in mysqldb_password '
+        - '"\\" not in mysqldb_password '
+        - '"\"" not in mysqldb_password '
+        - " \"'\" not in mysqldb_password "
     no_log: true
 
   - name: Assert mysqldb root user password
     assert:
-      that: mysqldb_root_password | length > 1
+      that:
+        - mysqldb_root_password | length > 1
+        - '"-" not in mysqldb_root_password '
+        - '"\\" not in mysqldb_root_password '
+        - '"\"" not in mysqldb_root_password '
+        - " \"'\" not in mysqldb_root_password "
     no_log: true
 
   rescue:
@@ -82,3 +108,66 @@
     ansible-vault encrypt {{ login_vars_file }}
     --vault-password-file {{ vault_filename }}
   changed_when: false
+
+# Include control_plane/login_vars.yml
+- name: Check login_vars file is encrypted
+  command: cat {{ ctrl_plane_login_vars_filename }}
+  changed_when: false
+  register: config_content
+  no_log: true
+
+- name: Decrpyt login_vars.yml
+  command: >-
+    ansible-vault decrypt {{ ctrl_plane_login_vars_filename }}
+    --vault-password-file {{ ctrl_plane_login_vault_filename }}
+  changed_when: false
+  when: "'$ANSIBLE_VAULT;' in config_content.stdout"
+
+- name: Include variable file control_plane/login_vars.yml
+  include_vars: "{{ ctrl_plane_login_vars_filename }}"
+  no_log: true
+
+- name: Assert grafana credentials
+  block:
+    - name: Assert grafana_username and grafana_username
+      assert:
+        that:
+          - grafana_username | length >= min_length_grafana
+          - grafana_username | length <= max_length
+          - '"-" not in grafana_username '
+          - '"\\" not in grafana_username '
+          - '"\"" not in grafana_username '
+          - " \"'\" not in grafana_username "
+          - grafana_password | length >= min_length_grafana
+          - grafana_password | length <= max_length
+          - '"-" not in grafana_password '
+          - '"\\" not in grafana_password '
+          - '"\"" not in grafana_password '
+          - " \"'\" not in grafana_password "
+      no_log: true
+
+  rescue:
+    - name: Validation issue in control_plane/login_vars.yml
+      fail:
+        msg: "{{ ctrl_plane_login_vars_fail_msg }}"
+
+- name: Create ansible vault key
+  set_fact:
+    vault_key: "{{ lookup('password', '/dev/null chars=ascii_letters') }}"
+  when: "'$ANSIBLE_VAULT;' not in config_content.stdout"
+
+- name: Save vault key
+  copy:
+    dest: "{{ ctrl_plane_login_vault_filename }}"
+    content: |
+      {{ 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 {{ ctrl_plane_login_vars_filename }}
+    --vault-password-file {{ ctrl_plane_login_vault_filename }}
+  changed_when: false

+ 15 - 3
telemetry/roles/common/vars/main.yml

@@ -13,16 +13,19 @@
 # limitations under the License.
 ---
 
-k8s_installation_required: "Kubernetes installation is mandatory for telemetry.yml"
+# Usage: pre-requisites.yml
+control_plane_installation_required: "AWX and grafana installation through control_plane.yml is mandatory for telemetry.yml"
 
 base_vars_file: "{{ role_path }}/../../input_params/base_vars.yml"
 login_vars_file: "{{ role_path }}/../../input_params/login_vars.yml"
-vault_filename: "{{ role_path }}/../../input_params/.login_vault_key"
+ctrl_plane_login_vars_filename: "{{ role_path }}/../../../control_plane/input_params/login_vars.yml"
 
 fail_msg_base_vars: "telemetry/base_vars.yml file doesn't exist."
 fail_msg_login_vars: "telemetry/login_vars.yml file doesn't exist."
+ctrl_plane_fail_msg_login_vars: "control_plane/login_vars.yml file doesn't exist"
 
-folder_perm: 644
+#Usage: validate_base_vars.yml
+folder_perm: '644'
 vault_file_perm: '0644'
 
 idrac_telemetry_support_success_msg: "idrac_telemetry_support validated"
@@ -43,8 +46,17 @@ timescaledb_fail_msg: "Timescale DB name should have minimum length of 2"
 mysqldb_success_msg: "MySQL DB name validated successfully"
 mysqldb_fail_msg: "MySQL DB name should have minimum length of 2"
 
+# Usage: validate_login_vars.yml
+vault_filename: "{{ role_path }}/../../input_params/.login_vault_key"
 login_vars_fail_msg: "Usernames and passwords in input_params/login_vars.yml should have minimum length 2"
 
+ctrl_plane_login_vault_filename: "{{ role_path }}/../../../control_plane/input_params/.login_vault_key"
+min_length_grafana: 6
+max_length: 30
+ctrl_plane_login_vars_fail_msg: "Incorrect grafana_username or grafana_password format provided
+                                  in control_plane/login_vars.yml"
+
+# Usage: k8s_secrets.yml
 namespace: telemetry-and-visualizations
 
 secrets_name: credentials

+ 55 - 0
telemetry/roles/grafana_config/tasks/add_datasource.yml

@@ -0,0 +1,55 @@
+# Copyright 2022 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: Get grafana service IP
+  command: kubectl get svc "{{ grafana_k8s }}" -n "{{ grafana_namespace }}" -o=jsonpath='{.spec.clusterIP}'
+  changed_when: false
+  register: grafana_svc_ip
+
+- name: Get grafana service port
+  command: kubectl get svc "{{ grafana_k8s }}" -n "{{ grafana_namespace }}" -o=jsonpath='{.spec.ports[0].port}'
+  changed_when: false
+  register: grafana_svc_port
+
+- name: Get timescaleDB svc IP
+  command: kubectl get svc -n "{{ namespace }}" -o=jsonpath='{.items[0].spec.clusterIP}'
+  changed_when: false
+  register: timescale_svc_ip
+
+- name: Get timescaleDB svc port
+  command: kubectl get svc -n "{{ namespace }}" -o=jsonpath='{.items[0].spec.ports[0].port}'
+  changed_when: false
+  register: timescale_svc_port
+
+- name: Wait for grafana pod to come to ready state
+  command: kubectl wait --for=condition=ready --timeout=10m -n "{{ grafana_namespace }}" pod -l app="{{ grafana_k8s }}"
+  changed_when: false
+
+- name: Add timescale datasource on grafana
+  community.grafana.grafana_datasource:
+    name: telemetry-postgres
+    grafana_url: "http://{{ grafana_svc_ip.stdout }}:{{ grafana_svc_port.stdout }}"
+    grafana_user: "{{ grafana_username }}"
+    grafana_password: "{{ grafana_password }}"
+    ds_type: "postgres"
+    ds_url: "http://{{ timescale_svc_ip.stdout }}:{{ timescale_svc_port.stdout }}"
+    user: "{{ timescaledb_user }}"
+    sslmode: "disable"
+    additional_json_data:
+      postgresVersion: 12
+      timescaledb: true
+    additional_secure_json_data:
+      password: "{{ timescaledb_password }}"
+  no_log: true

+ 20 - 0
telemetry/roles/grafana_config/tasks/main.yml

@@ -0,0 +1,20 @@
+# Copyright 2022 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 telemetry datasource on grafana
+  include_tasks: add_datasource.yml
+
+#- name: Add dashboards on grafana
+#  include_tasks: add_dashboards.yml

+ 17 - 0
telemetry/roles/grafana_config/vars/main.yml

@@ -0,0 +1,17 @@
+# Copyright 2022 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.
+---
+
+grafana_k8s: grafana
+grafana_namespace: grafana

+ 16 - 0
telemetry/roles/idrac_telemetry/tasks/main.yml

@@ -0,0 +1,16 @@
+# Copyright 2022 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.
+---
+
+#To be updated

+ 16 - 0
telemetry/roles/idrac_telemetry/vars/main.yml

@@ -0,0 +1,16 @@
+# Copyright 2022 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.
+---
+
+#To be updated

+ 32 - 0
telemetry/roles/timescaledb/tasks/initialize_db.yml

@@ -0,0 +1,32 @@
+# Copyright 2022 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 timescale pod to come to ready state
+  command: kubectl wait --for=condition=ready --timeout=10m -n "{{ namespace }}" pod -l app="{{ timescaledb_k8s_name }}"
+  changed_when: false
+
+- name: Get timescaledb pod name
+  command: kubectl get pod -n "{{ namespace }}" -l app="{{ timescaledb_k8s_name }}" -o jsonpath="{.items[0].metadata.name}"
+  register: timescaledb_pod_name
+  changed_when: false
+
+- name: Initialize database
+  command: kubectl exec -it "{{ timescaledb_pod_name.stdout }}" -n "{{ namespace }}" ./cmd/initialize_timescaledb.sh
+  changed_when: false
+  register: status
+  until: status is not failed
+  retries: "{{ retries }}"
+  delay: "{{ delay }}"

+ 5 - 2
telemetry/roles/timescaledb/tasks/main.yml

@@ -13,10 +13,10 @@
 # limitations under the License.
 ---
 
-- name: Create persistent volume for timescale db
+- name: Create persistent volume for timescaledb
   include_tasks: persistent_volume.yml
 
-- name: Create persistent volume claim for timescale db
+- name: Create persistent volume claim for timescaledb
   include_tasks: persistent_volume_claim.yml
 
 - name: Checkout iDRAC telemetry github repo
@@ -30,3 +30,6 @@
 
 - name: Create service for timescale db
   include_tasks: service.yml
+
+- name: Create service for timescale db
+  include_tasks: initialize_db.yml

+ 2 - 0
telemetry/roles/timescaledb/vars/main.yml

@@ -21,3 +21,5 @@ idrac_telemetry_folder_name: iDRAC-Telemetry-Reference-Tools
 statefulset_replicas: 1
 timescaledb_k8s_name: timescaledb
 timescaledb_container_port: 5432
+retries: 10
+delay: 10

+ 1 - 0
telemetry/telemetry.yml

@@ -20,3 +20,4 @@
    roles:
     - common
     - timescaledb
+    - grafana_config