First commit helm repo tools

Change-Id: Idecbfbd2e7892dcaafdbe8a192e6158997e98b7f
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..cb01311
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,6 @@
+[gerrit]
+host=gerrit.opencord.org
+port=29418
+project=helm-repo-tools.git
+defaultremote=origin
+defaultbranch=master
diff --git a/helmlint.sh b/helmlint.sh
new file mode 100755
index 0000000..aabdca0
--- /dev/null
+++ b/helmlint.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+# helmlint.sh
+# run `helm lint` on all helm charts that are found
+
+set +e -o pipefail
+
+# verify that we have helm installed
+command -v helm >/dev/null 2>&1 || { echo "helm not found, please install it" >&2; exit 1; }
+
+echo "helmlint.sh, using helm version: $(helm version -c --short)"
+
+fail_lint=0
+
+# when not running under Jenkins, use current dir as workspace
+WORKSPACE=${WORKSPACE:-.}
+
+# cleanup repos if `clean` option passed as parameter
+if [ "$1" = "clean" ]
+then
+  echo "Removing dependent charts"
+  find "${WORKSPACE}" -name 'charts' -exec rm -rf {} \;
+fi
+
+while IFS= read -r -d '' chart
+do
+  chartdir=$(dirname "${chart}")
+
+  # only update dependencies for profiles
+  if [[ $chartdir =~ xos-profiles || $chartdir =~ workflows ]] && [ -f "${chartdir}/requirements.yaml" ]
+  then
+    helm dependency update "${chartdir}"
+  fi
+
+  # lint with values.yaml if it exists
+  if [ -f "${chartdir}/values.yaml" ]; then
+    helm lint --strict --values "${chartdir}/values.yaml" "${chartdir}"
+  else
+    helm lint --strict "${chartdir}"
+  fi
+
+  rc=$?
+  if [[ $rc != 0 ]]; then
+    fail_lint=1
+  fi
+done < <(find "${WORKSPACE}" -name Chart.yaml -print0)
+
+if [[ $fail_lint != 0 ]]; then
+  exit 1
+fi
+
+exit 0
diff --git a/helmrepo.sh b/helmrepo.sh
new file mode 100755
index 0000000..3820124
--- /dev/null
+++ b/helmrepo.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+# helmrepo.sh
+# creates a helm repo for publishing on guide website
+
+set -eu -o pipefail
+
+# when not running under Jenkins, use current dir as workspace
+WORKSPACE=${WORKSPACE:-.}
+
+REPO_DIR="${REPO_DIR:-chart_repo}"
+
+GERRIT_BRANCH="${GERRIT_BRANCH:-$(git symbolic-ref --short HEAD)}"
+PUBLISH_URL="${PUBLISH_URL:-https://charts.opencord.org}"
+
+mkdir -p "${REPO_DIR}"
+
+while IFS= read -r -d '' chart
+do
+  chartdir=$(dirname "${chart}")
+
+  echo "Adding ${chartdir}"
+
+  helm package --dependency-update --destination "${REPO_DIR}" "${chartdir}"
+
+done < <(find "${WORKSPACE}" -name Chart.yaml -print0)
+
+echo "Generating repo index"
+
+helm repo index "${REPO_DIR}" --url "${PUBLISH_URL}" --merge index.yaml
+
+echo "Finished, chart repo generated: ${REPO_DIR}"
+
diff --git a/wait_for_jobs.sh b/wait_for_jobs.sh
new file mode 100755
index 0000000..5b48870
--- /dev/null
+++ b/wait_for_jobs.sh
@@ -0,0 +1,86 @@
+#!/usr/bin/env bash
+
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+# wait_for_jobs.sh
+# waits for all kubernetes jobs to complete before exiting
+# inspired by similar scripts in Kolla-Kubernetes and Openstack Helm
+
+set -eu -o pipefail
+fail_wfj=0
+
+# Set these to configure maximum timeout, and interval for checks
+JOBS_TIMEOUT=${JOBS_TIMEOUT:-600}
+CHECK_INTERVAL=${CHECK_INTERVAL:-5}
+KUBECTL_ARGS=${KUBECTL_ARGS:-}
+
+# calculate timeout time
+START_TIME=$(date +%s)
+END_TIME=$((START_TIME + JOBS_TIMEOUT))
+
+echo "wait_for_jobs.sh - Waiting up to ${JOBS_TIMEOUT} seconds for all Kubernetes jobs to complete"
+echo "Number printed is number of currently active jobs"
+
+prev_job_count=0
+
+while true; do
+  NOW=$(date +%s)
+
+  # handle timeout without completion
+  if [ "$NOW" -gt "$END_TIME" ]
+  then
+    echo "Jobs didn't complete before timeout of ${JOBS_TIMEOUT} seconds"
+    fail_wfj=1
+    break
+  fi
+
+  # get list of active jobs, and count of them
+  # jsonpath is picky about string vs comparison quoting, so have to have:
+  # shellcheck disable=SC2026,SC2086
+  active_jobs=$(kubectl get jobs $KUBECTL_ARGS -o=jsonpath='{range .items[?(@.status.active=='1')]}{.metadata.name}{"\n"}{end}')
+
+  # this always is 1 or more, as echo leaves a newline in the output which wc
+  # counts as a line
+  active_job_count=$(echo -n "${active_jobs}" | wc -l)
+
+  # if no jobs active, print runtime and break
+  if [ -z "$active_jobs" ]
+  then
+    runtime=$((NOW - START_TIME))
+    echo ""
+    echo "All jobs completed in $runtime seconds"
+    break
+  fi
+
+  # deal with changes in number of jobs
+  if [ "$active_job_count" -ne "$prev_job_count" ]
+  then
+    echo ""
+    echo "Number of active jobs changed - current jobs:"
+    echo "$active_jobs"
+  fi
+  prev_job_count=$active_job_count
+
+  # print number of remaining jobs every $CHECK_INTERVAL
+  echo -n "$active_job_count "
+  sleep "$CHECK_INTERVAL"
+done
+
+echo ""
+echo "Job Status - Name | Start Time | Completion Time"
+# shellcheck disable=SC2086
+kubectl get jobs $KUBECTL_ARGS -o=jsonpath='{range .items[*]}{.metadata.name}{"\t| "}{.status.startTime}{" | "}{.status.completionTime}{"\n"}{end}'
+
+exit ${fail_wfj}
diff --git a/wait_for_pods.sh b/wait_for_pods.sh
new file mode 100755
index 0000000..6d58010
--- /dev/null
+++ b/wait_for_pods.sh
@@ -0,0 +1,116 @@
+#!/usr/bin/env bash
+
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+# wait_for_pods.sh
+# waits for all kubernetes pods to complete before exiting, optionally only
+# pods in a specific namespace passed as first argument
+# inspired by similar scripts in Kolla-Kubernetes and Openstack Helm
+
+set -e -o pipefail
+fail_wfp=0
+
+# Set these to configure maximum timeout, and interval for checks
+PODS_TIMEOUT=${PODS_TIMEOUT:-600}
+CHECK_INTERVAL=${CHECK_INTERVAL:-5}
+KUBECTL_ARGS=${KUBECTL_ARGS:-}
+
+# use namespace if passed as first arg, or "all" for all namespaces
+if [ ! -z "$1" ]
+then
+  if [[ "$1" == "all" ]]
+  then
+    KUBECTL_ARGS+=" --all-namespaces"
+  else
+    KUBECTL_ARGS+=" --namespace=$1"
+  fi
+fi
+set -u
+
+# calculate timeout time
+START_TIME=$(date +%s)
+END_TIME=$((START_TIME + PODS_TIMEOUT))
+
+echo "wait_for_pods.sh - Waiting up to ${PODS_TIMEOUT} seconds for all Kubernetes pods to be ready"
+echo "Number printed is number of jobs/pods/containers waiting to be ready"
+
+prev_total_unready=0
+
+while true; do
+  NOW=$(date +%s)
+
+  # handle timeout without completion
+  if [ "$NOW" -gt "$END_TIME" ]
+  then
+    echo "Pods/Containers/Jobs not ready before timeout of ${PODS_TIMEOUT} seconds"
+    fail_wfp=1
+    break
+  fi
+
+  # get list of uncompleted items with jsonpath, then count them with wc
+  # ref: https://kubernetes.io/docs/reference/kubectl/jsonpath/
+  # jsonpath is picky about string vs comparison quoting, so may need to
+  # disable SC2026 for these lines. SC2086 allows for multiple args.
+
+  # shellcheck disable=SC2026,SC2086
+  pending_pods=$(kubectl get pods ${KUBECTL_ARGS} -o=jsonpath='{range .items[?(@.status.phase=="Pending")]}{.metadata.name}{"\n"}{end}')
+  # check for empty string before counting lines, echo adds a newline
+  if [ -z "$pending_pods" ]; then
+    pending_pod_count=0
+  else
+    pending_pod_count=$( echo "$pending_pods" | wc -l)
+  fi
+
+  # shellcheck disable=SC2026,SC2086
+  unready_containers=$(kubectl get pods ${KUBECTL_ARGS} -o=jsonpath='{range .items[?(@.status.phase=="Running")]}{range .status.containerStatuses[?(@.ready==false)]}{.name}: {.ready}{"\n"}{end}{end}')
+  if [ -z "$unready_containers" ]; then
+    unready_container_count=0
+  else
+    unready_container_count=$(echo "$unready_containers" | wc -l)
+  fi
+
+  # shellcheck disable=SC2026,SC2086
+  active_jobs=$(kubectl get jobs $KUBECTL_ARGS -o=jsonpath='{range .items[?(@.status.active=='1')]}{.metadata.name}{"\n"}{end}')
+  if [ -z "$active_jobs" ]; then
+    active_job_count=0
+  else
+    active_job_count=$(echo "$active_jobs" | wc -l)
+  fi
+
+  total_unready=$((pending_pod_count + unready_container_count + active_job_count))
+
+  # if everything is ready, print runtime and break
+  if [ "$total_unready" -eq 0 ]
+  then
+    runtime=$((NOW - START_TIME))
+    echo ""
+    echo "All pods ready in $runtime seconds"
+    break
+  fi
+
+  # deal with changes in number of jobs
+  if [ "$total_unready" -ne "$prev_total_unready" ]
+  then
+    echo ""
+    echo "Change in unready pods - Pending Pods: $pending_pod_count, Unready Containers: $unready_container_count, Active Jobs: $active_job_count"
+  fi
+  prev_total_unready=$total_unready
+
+  # print number of unready pods every $CHECK_INTERVAL
+  echo -n "$total_unready "
+  sleep "$CHECK_INTERVAL"
+done
+
+exit ${fail_wfp}
diff --git a/yamllint.conf b/yamllint.conf
new file mode 100644
index 0000000..a0e02ab
--- /dev/null
+++ b/yamllint.conf
@@ -0,0 +1,13 @@
+---
+# yamllint.conf
+
+extends: default
+
+rules:
+  empty-lines:
+    max-end: 1
+  line-length:
+    max: 120
+  braces:
+    min-spaces-inside: 0
+    max-spaces-inside: 1