From a36214b2f3d73f5e6ba078d718036e19f8b223b8 Mon Sep 17 00:00:00 2001
From: "andrew.greene" <1195-andrew.greene@users.noreply.gitlab.example.com>
Date: Fri, 17 Jun 2022 19:06:29 +0000
Subject: [PATCH] feat: Kubevirt BigBang Integration

---
 CHANGELOG.md                                  |  13 +-
 README.md                                     |  64 ++++++-
 bigbang/Chart.yaml                            |   7 +
 bigbang/README.md                             |  23 +++
 bigbang/templates/_helpers.tpl                | 159 ++++++++++++++++++
 bigbang/templates/kubevirt/gitrepository.yaml |  17 ++
 bigbang/templates/kubevirt/helmrelease.yaml   |  39 +++++
 .../templates/kubevirt/imagepullsecret.yaml   |  16 ++
 bigbang/templates/kubevirt/namespace.yaml     |  10 ++
 bigbang/templates/kubevirt/values.yaml        |   9 +
 bigbang/values.yaml                           |  43 +++++
 chart/Chart.yaml                              |   6 +-
 .../apps_v1_deployment_virt-operator.yaml     |   4 +
 .../kubevirt.io_v1_kubevirt_kubevirt.yaml     |  19 ++-
 chart/values.yaml                             |   8 +
 15 files changed, 426 insertions(+), 11 deletions(-)
 create mode 100644 bigbang/Chart.yaml
 create mode 100644 bigbang/README.md
 create mode 100644 bigbang/templates/_helpers.tpl
 create mode 100644 bigbang/templates/kubevirt/gitrepository.yaml
 create mode 100644 bigbang/templates/kubevirt/helmrelease.yaml
 create mode 100644 bigbang/templates/kubevirt/imagepullsecret.yaml
 create mode 100644 bigbang/templates/kubevirt/namespace.yaml
 create mode 100644 bigbang/templates/kubevirt/values.yaml
 create mode 100644 bigbang/values.yaml

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19af635..11345c6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,11 +2,14 @@
 
 Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
 
-## [0.1.3-alpha-bb.7] - unreleased
+## [0.0.1-bb.0] - 2022-06-17
+### Added
+- Initial Kubevirt v0.53.1
+
+## [0.1.3-alpha]
+### Added
 - Update Kubevirt to v0.53.1
 - Script written with skopeo in order to synchronize images between public locations and repo1
 - Pipeline fixes
-- issue templates, cleanup
-
-## [0.1.3-alpha-bb.0] - 2022-06-24
-- Initial Chart creation
\ No newline at end of file
+- Initial Chart creation
+- Adding imagePullSecret injection for kubevirt operator and dynamic resources.
diff --git a/README.md b/README.md
index b59808c..0704838 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,67 @@
+# bigbang-kubevirt
+
+![Version: 0.0.1-bb.0](https://img.shields.io/badge/Version-0.0.1--bb.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.53.1](https://img.shields.io/badge/AppVersion-0.53.1-informational?style=flat-square)
+
+BigBang compatible Helm chart for kubevirt
+
+## Learn More
+* [Application Overview](docs/overview.md)
+* [Other Documentation](docs/)
+
+## Pre-Requisites
+
+* Kubernetes Cluster deployed
+* Kubernetes config installed in `~/.kube/config`
+* Helm installed
+
+Install Helm
+
+https://helm.sh/docs/intro/install/
+
+## Deployment
+
+* Clone down the repository
+* cd into directory
+```bash
+helm install bigbang-kubevirt chart/
+```
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| kubevirt.enabled | bool | `true` |  |
+| kubevirt.git.repo | string | `"https://repo1.dso.mil/platform-one/big-bang/apps/third-party/kubevirt"` |  |
+| kubevirt.git.branch | string | `"image_pull_secrets"` |  |
+| kubevirt.git.path | string | `"chart"` |  |
+| kubevirt.flux | object | `{}` |  |
+| monitoring.enabled | bool | `false` |  |
+| logging.enabled | bool | `false` |  |
+| clusterAuditor.enabled | bool | `false` |  |
+| gatekeeper.enabled | bool | `false` |  |
+| eckoperator.enabled | bool | `false` |  |
+| kiali.enabled | bool | `false` |  |
+| jaeger.enabled | bool | `false` |  |
+| fluentbit.enabled | bool | `false` |  |
+| twistlock.enabled | bool | `false` |  |
+| flux.timeout | string | `"10m"` |  |
+| flux.interval | string | `"2m"` |  |
+| flux.test.enable | bool | `false` |  |
+| flux.install.remediation.retries | int | `-1` |  |
+| flux.upgrade.remediation.retries | int | `-1` |  |
+| flux.upgrade.remediation.remediateLastFailure | bool | `true` |  |
+| flux.upgrade.cleanupOnFail | bool | `true` |  |
+| flux.rollback.timeout | string | `"10m"` |  |
+| flux.rollback.cleanupOnFail | bool | `true` |  |
+
+## Contributing
+
+Please see the [contributing guide](./CONTRIBUTING.md) if you are interested in contributing.
 # kubevirt
 
-![Version: 0.1.3-alpha-bb.7](https://img.shields.io/badge/Version-0.1.3--alpha--bb.7-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.53.1](https://img.shields.io/badge/AppVersion-0.53.1-informational?style=flat-square)
+![Version: 0.0.1-bb.0](https://img.shields.io/badge/Version-0.0.1--bb.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.53.1](https://img.shields.io/badge/AppVersion-0.53.1-informational?style=flat-square)
 
-KubeVirt Big Bang package
+KubeVirt helm chart package
 
 ## Learn More
 * [Application Overview](docs/overview.md)
@@ -40,6 +99,7 @@ helm install kubevirt chart/
 | deployment.spec.template.spec.containers.ports.webhooksPort | int | `8444` |  |
 | deployment.spec.template.spec.containers.resources.requests.cpu | string | `"10m"` |  |
 | deployment.spec.template.spec.containers.resources.requests.memory | string | `"150Mi"` |  |
+| imagePullSecrets | list | `[]` |  |
 
 ## Contributing
 
diff --git a/bigbang/Chart.yaml b/bigbang/Chart.yaml
new file mode 100644
index 0000000..003a7d9
--- /dev/null
+++ b/bigbang/Chart.yaml
@@ -0,0 +1,7 @@
+---
+apiVersion: v2
+name: bigbang-kubevirt
+description: BigBang compatible Helm chart for kubevirt
+type: application
+version: 0.0.1-bb.0
+appVersion: "0.53.1"
diff --git a/bigbang/README.md b/bigbang/README.md
new file mode 100644
index 0000000..7897e56
--- /dev/null
+++ b/bigbang/README.md
@@ -0,0 +1,23 @@
+# Big Bang compatible Helm chart
+
+This helm chart deploys the application using the same methods and values as Big Bang.
+
+## Prerequisites
+
+- Kubernetes cluster matching [Big Bang's Prerequisites](https://repo1.dso.mil/platform-one/big-bang/bigbang/-/tree/master/docs/guides/prerequisites)
+- [FluxCD](https://fluxcd.io/) running in the cluster
+- The [Big Bang git repository](https://repo1.dso.mil/platform-one/big-bang/bigbang) cloned into `~/bigbang`
+- [Helm](https://helm.sh/docs/intro/install/)
+
+## Usage
+
+### Installation
+
+1. Install Big Bang
+   `helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang ~/bigbang/chart`
+1. Install this chart
+   `helm upgrade -i -n bigbang --create-namespace -f ~/bigbang/chart/values.yaml -f bigbang/values.yaml bigbang-kubevirt bigbang`
+
+### Removal
+
+`helm delete -n bigbang bigbang-kubevirt`
diff --git a/bigbang/templates/_helpers.tpl b/bigbang/templates/_helpers.tpl
new file mode 100644
index 0000000..d6fc3c5
--- /dev/null
+++ b/bigbang/templates/_helpers.tpl
@@ -0,0 +1,159 @@
+{{- define "imagePullSecret" }}
+  {{- if .Values.registryCredentials -}}
+    {{- $credType := typeOf .Values.registryCredentials -}}
+          {{- /* If we have a list, embed that here directly. This allows for complex configuration from configmap, downward API, etc. */ -}}
+    {{- if eq $credType "[]interface {}" -}}
+    {{- include "multipleCreds" . | b64enc }}
+    {{- else if eq $credType "map[string]interface {}" }}
+      {{- /* If we have a map, treat those as key-value pairs. */ -}}
+      {{- if and .Values.registryCredentials.username .Values.registryCredentials.password }}
+      {{- with .Values.registryCredentials }}
+      {{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }}
+      {{- end }}
+      {{- end }}
+    {{- end -}}
+  {{- end }}
+{{- end }}
+
+{{- define "multipleCreds" -}}
+{
+  "auths": {
+    {{- range $i, $m := .Values.registryCredentials }}
+    {{- /* Only create entry if resulting entry is valid */}}
+    {{- if and $m.registry $m.username $m.password }}
+    {{- if $i }},{{ end }}
+    "{{ $m.registry }}": {
+      "username": "{{ $m.username }}",
+      "password": "{{ $m.password }}",
+      "email": "{{ $m.email | default "" }}",
+      "auth": "{{ printf "%s:%s" $m.username $m.password | b64enc }}"
+    }
+    {{- end }}
+    {{- end }}
+  }
+}
+{{- end }}
+
+{{/*
+Build the appropriate spec.ref.{} given git branch, commit values
+*/}}
+{{- define "validRef" -}}
+{{- if .commit -}}
+{{- if not .branch -}}
+{{- fail "A valid branch is required when a commit is specified!" -}}
+{{- end -}}
+branch: {{ .branch | quote }}
+commit: {{ .commit }}
+{{- else if .semver -}}
+semver: {{ .semver | quote }}
+{{- else if .tag -}}
+tag: {{ .tag }}
+{{- else -}}
+branch: {{ .branch | quote }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Build the appropriate git credentials secret for private git repositories
+*/}}
+{{- define "gitCreds" -}}
+{{- if .Values.git.existingSecret -}}
+secretRef:
+  name: {{ .Values.git.existingSecret }}
+{{- else if coalesce .Values.git.credentials.username .Values.git.credentials.password .Values.git.credentials.caFile .Values.git.credentials.privateKey .Values.git.credentials.publicKey .Values.git.credentials.knownHosts "" -}}
+{{- /* Input validation happens in git-credentials.yaml template */ -}}
+secretRef:
+  name: {{ $.Release.Name }}-git-credentials
+{{- end -}}
+{{- end -}}
+
+{{/*
+Build common set of file extensions to include/exclude
+*/}}
+{{- define "gitIgnore" -}}
+  ignore: |
+    # exclude file extensions
+    /**/*.md
+    /**/*.txt
+    /**/*.sh
+    !/chart/tests/scripts/*.sh
+{{- end -}}
+
+{{/*
+Common labels for all objects
+*/}}
+{{- define "commonLabels" -}}
+app.kubernetes.io/instance: "{{ .Release.Name }}"
+app.kubernetes.io/version: "{{ .Chart.Version }}"
+app.kubernetes.io/part-of: "bigbang"
+app.kubernetes.io/managed-by: "flux"
+{{- end -}}
+
+{{- define "values-secret" -}}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ .root.Release.Name }}-{{ .name }}-values
+  namespace: {{ .root.Release.Namespace }}
+type: generic
+stringData:
+  common: |
+  defaults: {{- toYaml .defaults | nindent 4 }}
+  overlays: |
+    {{- toYaml .package.values | nindent 4 }}
+{{- end -}}
+
+{{/* 
+bigbang.addValueIfSet can be used to nil check parameters before adding them to the values.
+  Expects a list with the following params:
+    * [0] - (string) <yaml_key_to_add>
+    * [1] - (interface{}) <value_to_check>
+  
+  No output is generated if <value> is undefined, however, explicitly set empty values 
+  (i.e. `username=""`) will be passed along. All string fields will be quoted.
+
+  Example command: 
+  - `{{ (list "name" .username) | include "bigbang.addValueIfSet" }}`
+    * When `username: Aniken`
+      -> `name: "Aniken"`
+    * When `username: ""`
+      -> `name: ""`
+    * When username is not defined
+      -> no output 
+*/}}
+{{- define "bigbang.addValueIfSet" -}}
+  {{- $key := (index . 0) }}
+  {{- $value := (index . 1) }}
+  {{- /*If the value is explicitly set (even if it's empty)*/}}
+  {{- if not (kindIs "invalid" $value) }}
+    {{- /*Handle strings*/}}
+    {{- if kindIs "string" $value }}
+      {{- printf "\n%s" $key }}: {{ $value | quote }} 
+    {{- /*Hanldle slices*/}}
+    {{- else if kindIs "slice" $value }}
+      {{- printf "\n%s" $key }}:    
+        {{- range $value }}
+          {{- if kindIs "string" . }}
+            {{- printf "\n  - %s" (. | quote) }}
+          {{- else }} 
+            {{- printf "\n  - %v" . }}
+          {{- end }}
+        {{- end }}
+    {{- /*Handle other types (no quotes)*/}}
+    {{- else }}
+      {{- printf "\n%s" $key }}: {{ $value }} 
+    {{- end }}
+  {{- end }}
+{{- end -}}
+{{/*
+Annotation for Istio version
+*/}}
+{{- define "istioAnnotation" -}}
+{{- if .Values.istio.git.semver -}}
+bigbang.dev/istioVersion: {{ .Values.istio.git.semver | trimSuffix (regexFind "-bb.*" .Values.istio.git.semver) }}
+{{- else if .Values.istio.git.tag -}}
+bigbang.dev/istioVersion: {{ .Values.istio.git.tag | trimSuffix (regexFind "-bb.*" .Values.istio.git.tag) }}
+{{- else if .Values.istio.git.branch -}}
+bigbang.dev/istioVersion: {{ .Values.istio.git.branch }}
+{{- end -}}
+{{- end -}}
diff --git a/bigbang/templates/kubevirt/gitrepository.yaml b/bigbang/templates/kubevirt/gitrepository.yaml
new file mode 100644
index 0000000..ee8e9cf
--- /dev/null
+++ b/bigbang/templates/kubevirt/gitrepository.yaml
@@ -0,0 +1,17 @@
+{{- $pkg := "kubevirt" }}
+{{- if (get .Values $pkg).enabled }}
+apiVersion: source.toolkit.fluxcd.io/v1beta2
+kind: GitRepository
+metadata:
+  name: {{ $pkg }}
+  namespace: {{ .Release.Namespace }}
+  labels:
+    app.kubernetes.io/name: {{ $pkg }}
+    {{- include "commonLabels" . | nindent 4}}
+spec:
+  interval: {{ .Values.flux.interval }}
+  url: {{ (get .Values $pkg).git.repo }}
+  ref:
+    {{- include "validRef" (get .Values $pkg).git | nindent 4 }}
+  {{ include "gitIgnore" . }}
+{{- end }}
diff --git a/bigbang/templates/kubevirt/helmrelease.yaml b/bigbang/templates/kubevirt/helmrelease.yaml
new file mode 100644
index 0000000..6484b09
--- /dev/null
+++ b/bigbang/templates/kubevirt/helmrelease.yaml
@@ -0,0 +1,39 @@
+{{- $pkg := "kubevirt" }}
+{{- $fluxSettings := merge (get .Values $pkg).flux .Values.flux -}}
+{{- if (get .Values $pkg).enabled }}
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+  name: {{ $pkg }}
+  namespace: {{ .Release.Namespace }}
+  labels:
+    app.kubernetes.io/name: {{ $pkg }}
+    {{- include "commonLabels" . | nindent 4}}
+spec:
+  targetNamespace: {{ $pkg }}
+  chart:
+    spec:
+      chart: {{ (get .Values $pkg).git.path }}
+      interval: 5m
+      sourceRef:
+        kind: GitRepository
+        name: {{ $pkg }}
+        namespace: {{ .Release.Namespace }}
+
+  {{- toYaml $fluxSettings | nindent 2 }}
+
+  {{- if (get .Values $pkg).postRenderers }}
+  postRenderers:
+  {{ toYaml (get .Values $pkg).postRenderers | nindent 4 }}
+  {{- end }}
+  valuesFrom:
+    - name: {{ .Release.Name }}-{{ $pkg }}-values
+      kind: Secret
+      valuesKey: "common"
+    - name: {{ .Release.Name }}-{{ $pkg }}-values
+      kind: Secret
+      valuesKey: "defaults"
+    - name: {{ .Release.Name }}-{{ $pkg }}-values
+      kind: Secret
+      valuesKey: "overlays"
+{{- end }}
diff --git a/bigbang/templates/kubevirt/imagepullsecret.yaml b/bigbang/templates/kubevirt/imagepullsecret.yaml
new file mode 100644
index 0000000..a267185
--- /dev/null
+++ b/bigbang/templates/kubevirt/imagepullsecret.yaml
@@ -0,0 +1,16 @@
+{{- $pkg := "kubevirt" }}
+{{- if (get .Values $pkg).enabled }}
+{{- if ( include "imagePullSecret" . ) }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: private-registry
+  namespace: {{ $pkg }}
+  labels:
+    app.kubernetes.io/name: {{ $pkg }}
+    {{- include "commonLabels" . | nindent 4}}
+type: kubernetes.io/dockerconfigjson
+data:
+  .dockerconfigjson: {{ template "imagePullSecret" . }}
+{{- end }}
+{{- end }}
diff --git a/bigbang/templates/kubevirt/namespace.yaml b/bigbang/templates/kubevirt/namespace.yaml
new file mode 100644
index 0000000..d3eceda
--- /dev/null
+++ b/bigbang/templates/kubevirt/namespace.yaml
@@ -0,0 +1,10 @@
+{{- $pkg := "kubevirt" }}
+{{- if (get .Values $pkg).enabled }}
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: {{ $pkg }}
+  labels:
+    app.kubernetes.io/name: {{ $pkg }}
+    {{- include "commonLabels" . | nindent 4}}
+{{- end }}
diff --git a/bigbang/templates/kubevirt/values.yaml b/bigbang/templates/kubevirt/values.yaml
new file mode 100644
index 0000000..7614402
--- /dev/null
+++ b/bigbang/templates/kubevirt/values.yaml
@@ -0,0 +1,9 @@
+{{- $pkg := "kubevirt" }}
+{{- define "bigbang.defaults.kubevirt" -}}
+
+{{- end }}
+
+{{- /* Create secret */ -}}
+{{- if (get .Values $pkg).enabled }}
+{{- include "values-secret" (dict "root" $ "package" (get .Values $pkg) "name" $pkg "defaults" (include (printf "bigbang.defaults.%s" $pkg) .)) }}
+{{- end }}
diff --git a/bigbang/values.yaml b/bigbang/values.yaml
new file mode 100644
index 0000000..0fdaabf
--- /dev/null
+++ b/bigbang/values.yaml
@@ -0,0 +1,43 @@
+kubevirt:
+  enabled: true
+  git:
+    repo: https://repo1.dso.mil/platform-one/big-bang/apps/third-party/kubevirt
+    branch: image_pull_secrets
+    path: chart
+  flux: {}
+
+monitoring:
+  enabled: false
+logging:
+  enabled: false
+clusterAuditor:
+  enabled: false
+gatekeeper:
+  enabled: false
+eckoperator:
+  enabled: false
+kiali:
+  enabled: false
+jaeger:
+  enabled: false
+fluentbit:
+  enabled: false
+twistlock:
+  enabled: false
+
+flux:
+  timeout: 10m
+  interval: 2m
+  test:
+    enable: false
+  install:
+    remediation:
+      retries: -1
+  upgrade:
+    remediation:
+      retries: -1
+      remediateLastFailure: true
+    cleanupOnFail: true
+  rollback:
+    timeout: 10m
+    cleanupOnFail: true
\ No newline at end of file
diff --git a/chart/Chart.yaml b/chart/Chart.yaml
index 0778437..bee40c2 100644
--- a/chart/Chart.yaml
+++ b/chart/Chart.yaml
@@ -1,6 +1,6 @@
 apiVersion: v2
 name: kubevirt
-description: KubeVirt Big Bang package
+description: KubeVirt helm chart package
 type: application
-version: 0.1.3-alpha-bb.7
-appVersion: "0.53.1"
+version: 0.0.1-bb.0
+appVersion: "0.53.1"
\ No newline at end of file
diff --git a/chart/templates/apps_v1_deployment_virt-operator.yaml b/chart/templates/apps_v1_deployment_virt-operator.yaml
index 3621e52..0c606af 100644
--- a/chart/templates/apps_v1_deployment_virt-operator.yaml
+++ b/chart/templates/apps_v1_deployment_virt-operator.yaml
@@ -20,6 +20,10 @@ spec:
         prometheus.kubevirt.io: "true"
       name: virt-operator
     spec:
+      {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
       affinity:
         podAntiAffinity:
           preferredDuringSchedulingIgnoredDuringExecution:
diff --git a/chart/templates/kubevirt.io_v1_kubevirt_kubevirt.yaml b/chart/templates/kubevirt.io_v1_kubevirt_kubevirt.yaml
index 772fd71..250e5ea 100644
--- a/chart/templates/kubevirt.io_v1_kubevirt_kubevirt.yaml
+++ b/chart/templates/kubevirt.io_v1_kubevirt_kubevirt.yaml
@@ -8,9 +8,26 @@ spec:
   configuration:
     developerConfiguration:
       featureGates: []
-  customizeComponents: {}
   imagePullPolicy: IfNotPresent
   imageRegistry: {{ .Values.deployment.spec.template.spec.containers.image.registry }}
   infra:
     replicas: {{ .Values.deployment.spec.replicas }}
   workloadUpdateStrategy: {}
+{{- if .Values.imagePullSecrets }}
+  customizeComponents:
+    patches:
+      - resourceType: Deployment
+        resourceName: virt-api
+        patch: '[{"op":"add","path":"/spec/template/spec/imagePullSecrets","value":{{- .Values.imagePullSecrets | toJson }}}]'
+        type: json
+      - resourceType: Deployment
+        resourceName: virt-controller
+        patch: '[{"op":"add","path":"/spec/template/spec/imagePullSecrets","value":{{- .Values.imagePullSecrets | toJson }}}]'
+        type: json
+      - resourceType: DaemonSet
+        resourceName: virt-handler
+        patch: '[{"op":"add","path":"/spec/template/spec/imagePullSecrets","value":{{- .Values.imagePullSecrets | toJson }}}]'
+        type: json
+{{- else }}
+  customizeComponents: {}
+{{- end }}
diff --git a/chart/values.yaml b/chart/values.yaml
index 57fd924..2c652fa 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -19,3 +19,11 @@ deployment:
             requests:
               cpu: 10m
               memory: 150Mi
+
+# Example of imagePullSecrets settings for private registry access.
+# The secrets themselves are created through the bigbang flux integration.
+#
+#   imagePullSecrets:
+#     - name: private-registry
+#     - name: repo1-read-creds
+imagePullSecrets: []
-- 
GitLab