Implement a job to configure opendistro

Change-Id: If4acf78f0072f467acf28a0ed63dfa323944f7f6
diff --git a/logging/opendistro_setting/Chart.yaml b/logging/opendistro_setting/Chart.yaml
new file mode 100644
index 0000000..f9df0fa
--- /dev/null
+++ b/logging/opendistro_setting/Chart.yaml
@@ -0,0 +1,26 @@
+# Copyright 2021-present Open Networking Foundation
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+
+apiVersion: v2
+name: opendistro-setting
+description: A Helm chart deploying container to config opendistro services
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.1.0
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+appVersion: 0.1.0
diff --git a/logging/opendistro_setting/templates/configmap-script.yml b/logging/opendistro_setting/templates/configmap-script.yml
new file mode 100644
index 0000000..cf9a15c
--- /dev/null
+++ b/logging/opendistro_setting/templates/configmap-script.yml
@@ -0,0 +1,153 @@
+# Copyright 2021-present Open Networking Foundation
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+#
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: "{{ .Release.Name }}-scripts"
+  labels:
+    app: onos
+    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+    release: "{{ .Release.Name }}"
+    heritage: "{{ .Release.Service }}"
+data:
+  update.sh: |
+    #!/bin/bash
+    host=${ES_URL:-localhost:9201}
+    dest_dir=${DEST_DIR}
+    monitor_dir=${MONITOR_DIR}
+    setting_dir=${SETTING_DIR}
+    temp_dir=${OUTPUT_DIR:-/opendistro_temp}
+
+    #return destination id if exist
+    check_destination() { name=$1
+        curl -s -H "content-type: application/json" "$host/_opendistro/_alerting/destinations" | jq -r ".destinations[] | select(.name == \"$name\").id"
+    }
+
+    update_destination() {
+        echo "update"
+        file=$1
+        id=$2
+        #compress the json file to reduce the http size
+        new_file="$temp_dir/$file"
+        jq -c '' < "$file" > "$new_file"
+        curl -s -X PUT -H "content-type: application/json" -d "@$new_file" "$host/_opendistro/_alerting/destinations/$id"
+        rm "$new_file"
+        echo "  "
+    }
+
+    create_destination() {
+        echo "create"
+        file=$1
+        new_file="$temp_dir/$file"
+        jq -c '' < "$file" > "$new_file"
+        curl -s -X POST -H "content-type: application/json" -d "@$new_file" "$host/_opendistro/_alerting/destinations"
+        rm "$new_file"
+        echo "  "
+    }
+
+    #return cluster_id if exist
+    check_monitor() {
+        name=$1
+        curl -s -H "content-type: application/json" \
+            --data "{\"query\":{\"match\":{ \"monitor.name\": \"$name\"}}}" \
+            "$host/_opendistro/_alerting/monitors/_search" | jq -r '.hits.hits[0]._id'
+    }
+
+    create_monitor() {
+        file=$1
+        dest_id=$2
+        new_file="$temp_dir/$file"
+        echo "create monitor"
+        jq -c ".triggers[0].actions[0].destination_id=\"$dest_id\""  "$file" > "$new_file"
+        curl -s -X POST -H "content-type: application/json" -d "@$new_file" "$host/_opendistro/_alerting/monitors/"
+        rm "$new_file"
+        echo " "
+    }
+
+    update_monitor() {
+        file=$1
+        dest_id=$2
+        monitor_id=$3
+        new_file="$temp_dir/$file"
+        echo "update monitor"
+        jq -c ".triggers[0].actions[0].destination_id=\"$dest_id\""  "$file" > "$new_file"
+        curl -s -X PUT -H "content-type: application/json" -d "@$new_file" "$host/_opendistro/_alerting/monitors/$monitor_id"
+        rm "$new_file"
+        echo " "
+    }
+
+    # handle the destination
+    handle_destination() {
+        dir=$dest_dir
+        mkdir -p "$temp_dir/$dir"
+        config_file=$dir/config.json
+        for k in $(jq ' keys | .[]' "$config_file"); do
+            file=$dir/$(jq -r ".[$k].file" "$config_file");
+
+            name=$(jq -r '.name' "$file")
+            id=$(check_destination "$name")
+            if [ -z "$id" ]; then
+                create_destination "$file"
+            else
+                update_destination "$file" "$id"
+            fi
+        done
+    }
+
+    # handle the monitors
+    handle_monitor() {
+        dir=$monitor_dir
+        mkdir -p "$temp_dir/$dir"
+        config_file=$dir/config.json
+        for k in $(jq ' keys | .[]' "$config_file"); do
+            file=$dir/$(jq -r ".[$k].file" "$config_file");
+            dest_name=$(jq -r ".[$k].destination" "$config_file");
+
+            dest_id=$(check_destination "$dest_name")
+            if [ -z "$dest_id" ]; then
+                echo "destination doesn't exist, skip this monitor"
+                continue
+            fi
+
+            name=$(jq -r '.name' "$file")
+            monitor_id=$(check_monitor "$name")
+            if [ "$monitor_id" = "null" ]; then
+                create_monitor "$file" "$dest_id"
+            else
+                update_monitor "$file" "$dest_id" "$monitor_id"
+            fi
+        done
+
+    }
+
+    handle_settings() {
+        dir=$setting_dir
+        mkdir -p "$temp_dir/$dir"
+        config_file=$dir/config.json
+        for k in $(jq ' keys | .[]' "$config_file"); do
+            file=$dir/$(jq -r ".[$k].file" "$config_file");
+            url=$(jq -r ".[$k].url" "$config_file");
+
+            new_file="$temp_dir/$file"
+            jq -c '' < "$file" > "$new_file"
+            curl -s -X POST -H "content-type: application/json" -d "@$new_file" "$host/$url"
+            rm "$new_file"
+            echo "  "
+        done
+    }
+
+    if [ ! -z $setting_dir ]; then
+      echo "handle setting"
+      handle_settings
+    fi
+    if [ ! -z $dest_dir ]; then
+      echo "handle destination"
+      handle_destination
+    fi
+    if [ ! -z $monitor_dir ]; then
+      echo "handle monitor"
+      handle_monitor
+    fi
+
+    exit 0
diff --git a/logging/opendistro_setting/templates/job.yml b/logging/opendistro_setting/templates/job.yml
new file mode 100644
index 0000000..609d6a7
--- /dev/null
+++ b/logging/opendistro_setting/templates/job.yml
@@ -0,0 +1,74 @@
+# Copyright 2020-present Open Networking Foundation
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: "{{ .Release.Name }}"
+spec:
+  backoffLimit: 4
+  activeDeadlineSeconds: 100
+  template:
+    metadata:
+      name: "{{ .Release.Name }}"
+    spec:
+      restartPolicy: OnFailure
+      containers:
+        - name: config
+          image: opennetworking/utils:jq-kubectl-curl
+          imagePullPolicy: IfNotPresent
+          env:
+            - name: ES_URL
+              value: "{{ .Values.elasticsearch.host }}:{{ .Values.elasticsearch.port}}"
+            {{ if .Values.configuration.setting }}
+            - name: SETTING_DIR
+              value: "{{ .Values.configuration.base_dir }}/{{ .Values.configuration.setting }}"
+            {{ end }}
+            {{ if .Values.configuration.monitor }}
+            - name: MONITOR_DIR
+              value: "{{ .Values.configuration.base_dir }}/{{ .Values.configuration.monitor }}"
+            {{ end }}
+            {{ if .Values.configuration.destination }}
+            - name: DEST_DIR
+              value: "{{ .Values.configuration.base_dir }}/{{ .Values.configuration.destination }}"
+            {{ end }}
+          volumeMounts:
+            - name: config-script
+              mountPath: /tmp/update.sh
+              subPath: update.sh
+            {{ if .Values.configuration.setting }}
+            - name: setting-configs
+              mountPath: "{{ .Values.configuration.base_dir }}/{{ .Values.configuration.setting }}"
+            {{ end }}
+            {{ if .Values.configuration.monitor }}
+            - name: monitor-configs
+              mountPath: "{{ .Values.configuration.base_dir }}/{{ .Values.configuration.monitor }}"
+            {{ end }}
+            {{ if .Values.configuration.destination }}
+            - name: destination-configs
+              mountPath: "{{ .Values.configuration.base_dir }}/{{ .Values.configuration.destination }}"
+            {{ end }}
+          command: ["sh", "-c", "/tmp/update.sh"]
+      volumes:
+        - name: "config-script"
+          configMap:
+            name: "{{ .Release.Name }}-scripts"
+            defaultMode: 0755
+        {{ if .Values.configuration.setting }}
+        - name: "setting-configs"
+          configMap:
+            name: "{{ .Values.configuration.setting_configmap }}"
+            defaultMode: 0644
+        {{ end }}
+        {{ if .Values.configuration.monitor }}
+        - name: "monitor-configs"
+          configMap:
+            name: "{{ .Values.configuration.monitor_configmap }}"
+            defaultMode: 0644
+        {{ end }}
+        {{ if .Values.configuration.destination }}
+        - name: "destination-configs"
+          secret:
+            secretName: "{{ .Values.configuration.destination_secret }}"
+            defaultMode: 0644
+        {{ end }}
diff --git a/logging/opendistro_setting/values.yaml b/logging/opendistro_setting/values.yaml
new file mode 100644
index 0000000..347195f
--- /dev/null
+++ b/logging/opendistro_setting/values.yaml
@@ -0,0 +1,20 @@
+# Copyright 2021-present Open Networking Foundation
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+
+
+elasticsearch:
+  host: opendistro-es-client-service.logging
+  port: 9200
+
+
+configuration:
+  base_dir: /tmp/opendistro
+  # Have to prepare the configmap first
+  # setting_configmap: opendistro-kibana-setting
+  # setting: settings/
+  # Have to prepare the configmap first
+  # monitor_configmap: opendistro-kibana-monitor
+  # monitor: monitor/
+  # Have to prepare the secret first
+  # destination_secret: opendistro-kibana-destination
+  # destination: destination/