diff --git a/charts/info/.gitignore b/charts/info/.gitignore new file mode 100644 index 000000000..ee3892e87 --- /dev/null +++ b/charts/info/.gitignore @@ -0,0 +1 @@ +charts/ diff --git a/charts/info/.helmignore b/charts/info/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/charts/info/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/info/Chart.yaml b/charts/info/Chart.yaml new file mode 100644 index 000000000..9675b9fa1 --- /dev/null +++ b/charts/info/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +name: info +description: A Helm chart to get deployment information +type: application +version: 0.0.1-develop +appVersion: "" +home: https://mosip.io +keywords: + - mosip + - info +maintainers: + - email: info@mosip.io + name: MOSIP diff --git a/charts/info/README.md b/charts/info/README.md new file mode 100644 index 000000000..79e2b6904 --- /dev/null +++ b/charts/info/README.md @@ -0,0 +1,11 @@ +# Info Helm Chart + +This Helm chart deploys an NGINX server along with a script to fetch Namespace, Image, helm chart version and Image ID from k8s cluster. + +## TL;DR + +```console +$ helm repo add mosip https://mosip.github.io +$ helm install my-release mosip/info +``` + diff --git a/charts/info/templates/_helpers.tpl b/charts/info/templates/_helpers.tpl new file mode 100644 index 000000000..1d37bc275 --- /dev/null +++ b/charts/info/templates/_helpers.tpl @@ -0,0 +1,71 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "info.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "info.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "info.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "info.labels" -}} +helm.sh/chart: {{ include "info.chart" . }} +{{ include "info.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "info.selectorLabels" -}} +app.kubernetes.io/name: {{ include "info.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "info.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "info.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Render tpl values. +*/}} +{{- define "common.tplvalues.render" -}} +{{- $value := .value -}} +{{- $context := .context -}} +{{- tpl (toYaml $value) $context -}} +{{- end -}} diff --git a/charts/info/templates/clusterrole.yaml b/charts/info/templates/clusterrole.yaml new file mode 100644 index 000000000..d8a4c9392 --- /dev/null +++ b/charts/info/templates/clusterrole.yaml @@ -0,0 +1,30 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resources: + - namespaces + - pods + verbs: + - get + - list + - apiGroups: + - apps + resources: + - deployments + - statefulsets + verbs: + - get + - list + - apiGroups: + - batch + resources: + - jobs + - cronjobs + verbs: + - get + - list diff --git a/charts/info/templates/clusterrolebinding.yaml b/charts/info/templates/clusterrolebinding.yaml new file mode 100644 index 000000000..d6fde5102 --- /dev/null +++ b/charts/info/templates/clusterrolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }} +subjects: + - kind: ServiceAccount + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Release.Name }} + apiGroup: rbac.authorization.k8s.io diff --git a/charts/info/templates/configmap.yaml b/charts/info/templates/configmap.yaml new file mode 100644 index 000000000..9a2f6f075 --- /dev/null +++ b/charts/info/templates/configmap.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-script-config + namespace: {{ .Release.Namespace }} +data: + fetch-info.sh: | + #!/bin/sh + + EXCLUDED_NAMESPACE='^(istio|cattle|kube|info)' + OUTPUT_DIR=/usr/share/nginx/html/info/info.txt + + # Clear existing info.txt or create if not exists + > $OUTPUT_DIR + + kubectl get namespaces | awk 'NR>1 {print $1}' | grep -vE $EXCLUDED_NAMESPACE | while read namespace; do + echo "Namespace: $namespace" >> $OUTPUT_DIR + echo "----------------" >> $OUTPUT_DIR + + # Get deployments + kubectl get deployments -n $namespace -o json | jq -r '.items[] | "Deployment: \(.metadata.name), Image: \(.spec.template.spec.containers[].image), Helm Chart Version: \(.metadata.labels["helm.sh/chart"])"' >> $OUTPUT_DIR + + # Get statefulsets + kubectl get statefulsets -n $namespace -o json | jq -r '.items[] | "StatefulSet: \(.metadata.name), Image: \(.spec.template.spec.containers[].image), Helm Chart Version: \(.metadata.labels["helm.sh/chart"])"' >> $OUTPUT_DIR + + # Get cronjobs + kubectl get cronjobs -n $namespace -o json | jq -r '.items[] | "CronJob: \(.metadata.name), Image: \(.spec.jobTemplate.spec.template.spec.containers[].image), Helm Chart Version: \(.metadata.labels["helm.sh/chart"])"' >> $OUTPUT_DIR + + # Get jobs + kubectl get jobs -n $namespace -o json | jq -r '.items[] | "Job: \(.metadata.name), Image: \(.spec.template.spec.containers[].image), Helm Chart Version: \(.metadata.labels["helm.sh/chart"])"' >> $OUTPUT_DIR + + kubectl get pods -n $namespace -o json | jq -r '.items[] | .status.containerStatuses[] | select(.imageID | contains("istio") | not) | "ImageID: \(.imageID | sub("docker-pullable://"; ""))"' >> $OUTPUT_DIR + + echo "" >> $OUTPUT_DIR + done + + echo "Script executed at $(date)" >> $OUTPUT_DIR diff --git a/charts/info/templates/deployment.yaml b/charts/info/templates/deployment.yaml new file mode 100644 index 000000000..8b4131902 --- /dev/null +++ b/charts/info/templates/deployment.yaml @@ -0,0 +1,107 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "info.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: info + template: + metadata: + labels: + app: info + spec: + serviceAccountName: {{ .Release.Name }} + containers: + - name: nginx + image: {{ .Values.nginx.image }} + imagePullPolicy: {{ .Values.nginx.imagePullPolicy }} + ports: + - containerPort: 80 + volumeMounts: + - name: result-file + mountPath: /usr/share/nginx/html/info + subPath: info.txt + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + {{- if .Values.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.startupProbe "enabled") "context" $) | nindent 12 }} + {{- else if .Values.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.livenessProbe "enabled") "context" $) | nindent 12 }} + {{- else if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.readinessProbe "enabled") "context" $) | nindent 12 }} + {{- else if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.sidecars "context" $) | nindent 8 }} + {{- end }} + - name: script-runner + image: {{ .Values.scriptRunner.image }} + imagePullPolicy: {{ .Values.nginx.imagePullPolicy }} + command: + - /bin/sh + - -c + - | + apk add --no-cache bash curl bind-tools jq + + curl -LO "https://dl.k8s.io/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" + + chmod +x kubectl + + mv kubectl /usr/local/bin/ + + cp /fetch-info.sh /tmp/fetch-info.sh + + chmod +x /tmp/fetch-info.sh + + /tmp/fetch-info.sh + + echo "0 2 * * * /tmp/fetch-info.sh" > /etc/crontabs/root + + crond -f + volumeMounts: + - name: script-file + mountPath: /fetch-info.sh + subPath: fetch-info.sh + - name: result-file + mountPath: /usr/share/nginx/html/info + subPath: info.txt + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + {{- if .Values.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.startupProbe "enabled") "context" $) | nindent 12 }} + {{- else if .Values.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.livenessProbe "enabled") "context" $) | nindent 12 }} + {{- else if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.readinessProbe "enabled") "context" $) | nindent 12 }} + {{- else if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: script-file + configMap: + name: {{ .Release.Name }}-script-config + - name: result-file + emptyDir: {} diff --git a/charts/info/templates/service.yaml b/charts/info/templates/service.yaml new file mode 100644 index 000000000..8222f6ff8 --- /dev/null +++ b/charts/info/templates/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + app: info + ports: + - protocol: TCP + port: 80 + targetPort: 80 + type: ClusterIP diff --git a/charts/info/templates/serviceaccount.yaml b/charts/info/templates/serviceaccount.yaml new file mode 100644 index 000000000..81c0d7ed4 --- /dev/null +++ b/charts/info/templates/serviceaccount.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} diff --git a/charts/info/templates/virtualservice.yaml b/charts/info/templates/virtualservice.yaml new file mode 100644 index 000000000..db5abae44 --- /dev/null +++ b/charts/info/templates/virtualservice.yaml @@ -0,0 +1,29 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} +spec: + hosts: + - "*" + gateways: + {{- if .Values.istio.gateways }} + {{- range .Values.istio.gateways }} + - {{ . }} + {{- end }} + {{- end }} + http: + - match: + - uri: + prefix: {{ .Values.istio.prefix }} + rewrite: + uri: {{ .Values.istio.rewrite }} + route: + - destination: + host: {{ .Release.Name }} + port: + number: 80 + headers: + request: + set: + x-forwarded-proto: https diff --git a/charts/info/values.yaml b/charts/info/values.yaml new file mode 100644 index 000000000..f76482772 --- /dev/null +++ b/charts/info/values.yaml @@ -0,0 +1,65 @@ +replicaCount: 1 + +nginx: + image: nginx:latest + imagePullPolicy: IfNotPresent + +scriptRunner: + image: alpine:latest + imagePullPolicy: IfNotPresent + + +## Configure extra options for liveness and readiness probes +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes +## +startupProbe: + enabled: true + httpGet: + path: "/" + port: 80 + initialDelaySeconds: 0 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 10 + successThreshold: 1 + +livenessProbe: + enabled: true + httpGet: + path: "/" + port: 80 + initialDelaySeconds: 20 + periodSeconds: 60 + timeoutSeconds: 5 + failureThreshold: 2 + successThreshold: 1 + +readinessProbe: + enabled: true + httpGet: + path: "/" + port: 80 + initialDelaySeconds: 0 + periodSeconds: 60 + timeoutSeconds: 5 + failureThreshold: 2 + successThreshold: 1 + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 500m + memory: 1500Mi + requests: + cpu: 100m + memory: 1500Mi + +istio: + enabled: true + gateways: + - istio-system/internal + prefix: /info + rewrite: /info/info.txt