Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ apiVersion: v2
name: edge-gitops-vms
description: Edge GitOps VMs
type: application
version: 0.4.0
version: 0.5.0
dependencies: [ ]
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# edge-gitops-vms

![Version: 0.4.0](https://img.shields.io/badge/Version-0.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
![Version: 0.5.0](https://img.shields.io/badge/Version-0.5.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)

Edge GitOps VMs

This chart is used to set up Edge GitOps VMs in conjunction with OpenShift Virtualization

### Notable changes

* v0.5.0: Change default VM type to rhel9 and workload type to server; change other defaults to "gitops-vms" from "edge-gitops-vms"
* v0.5.0: Change default waitForMetalNode to false
* v0.5.0: Add optional additional disks per VM; use spec.runStrategy instead of spec.running (default Always); default machineType q35 (KubeVirt generic q35 alias)
* v0.5.0: Fix Windows OS detection (Helm 3/4); skip cloud-init and SSH access credentials for Windows
* v0.4.0: Parameterize ESO API version and default it to v1
* v0.3.5: Several fixes to separate DataSources from VM namespace
* v0.3.4: Correct order of coalesce arguments for main disk storage bus
Expand Down Expand Up @@ -36,7 +40,7 @@ This chart is used to set up Edge GitOps VMs in conjunction with OpenShift Virtu
| rbac.roleBindings[0].subjects.apiGroup | string | `""` | |
| rbac.roleBindings[0].subjects.kind | string | `"ServiceAccount"` | |
| rbac.roleBindings[0].subjects.name | string | `"ansible-edge-gitops-sa"` | |
| rbac.roleBindings[0].subjects.namespace | string | `"edge-gitops-vms"` | |
| rbac.roleBindings[0].subjects.namespace | string | `"gitops-vms"` | |
| rbac.roles[0].apiGroups[0] | string | `"machine.openshift.io"` | |
| rbac.roles[0].createRole | bool | `true` | |
| rbac.roles[0].name | string | `"view-machine-api"` | |
Expand All @@ -51,6 +55,7 @@ This chart is used to set up Edge GitOps VMs in conjunction with OpenShift Virtu
| secretStore.name | string | `"vault-backend"` | |
| serviceAccountName | string | `"ansible-edge-gitops-sa"` | |
| vmDefaults.accessMode | string | `"ReadWriteMany"` | |
| vmDefaults.additionalDiskStorageBus | string | `"virtio"` | |
| vmDefaults.cloudInitSecret | string | `"secret/data/hub/cloud-init"` | |
| vmDefaults.cloudinitsecret | string | `"secret/data/hub/cloud-init"` | |
| vmDefaults.cores | int | `1` | |
Expand All @@ -59,10 +64,10 @@ This chart is used to set up Edge GitOps VMs in conjunction with OpenShift Virtu
| vmDefaults.externalDataSourceAnnotations."cdi.kubevirt.io/storage.bind.immediate.requested" | string | `"true"` | |
| vmDefaults.externalDataSourceNamespace | string | `"openshift-virtualization-os-images"` | |
| vmDefaults.flavor | string | `"medium"` | |
| vmDefaults.machineType | string | `"pc-q35-rhel8.4.0"` | |
| vmDefaults.machineType | string | `"q35"` | |
| vmDefaults.mainDiskStorageBus | string | `"virtio"` | |
| vmDefaults.memory | string | `"4Gi"` | |
| vmDefaults.os | string | `"rhel8"` | |
| vmDefaults.os | string | `"rhel9"` | |
| vmDefaults.ports[0].name | string | `"ssh"` | |
| vmDefaults.ports[0].port | int | `22` | |
| vmDefaults.ports[0].protocol | string | `"TCP"` | |
Expand All @@ -72,19 +77,20 @@ This chart is used to set up Edge GitOps VMs in conjunction with OpenShift Virtu
| vmDefaults.routeEnableTlsBlock | bool | `false` | |
| vmDefaults.routeTlsTermination | string | `"passthrough"` | |
| vmDefaults.routes | object | `{}` | |
| vmDefaults.runStrategy | string | `"Always"` | |
| vmDefaults.serviceType | string | `"NodePort"` | |
| vmDefaults.sockets | int | `1` | |
| vmDefaults.sshpubkeyfield | string | `"publickey"` | |
| vmDefaults.sshsecret | string | `"secret/data/hub/vm-ssh"` | |
| vmDefaults.storage | string | `"30Gi"` | |
| vmDefaults.storageClassName | string | `"ocs-storagecluster-ceph-rbd-virtualization"` | |
| vmDefaults.template | string | `"rhel8-desktop-medium"` | |
| vmDefaults.template | string | `"rhel9-server-medium"` | |
| vmDefaults.threads | int | `1` | |
| vmDefaults.volumeMode | string | `"Block"` | |
| vmDefaults.workload | string | `"desktop"` | |
| vmNamespace | string | `"edge-gitops-vms"` | |
| vmDefaults.workload | string | `"server"` | |
| vmNamespace | string | `"gitops-vms"` | |
| vms | object | `{}` | |
| waitForMetalNode | bool | `true` | |
| waitForMetalNode | bool | `false` | |

----------------------------------------------
Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
4 changes: 4 additions & 0 deletions README.md.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ This chart is used to set up Edge GitOps VMs in conjunction with OpenShift Virtu

### Notable changes

* v0.5.0: Change default VM type to rhel9 and workload type to server; change other defaults to "gitops-vms" from "edge-gitops-vms"
* v0.5.0: Change default waitForMetalNode to false
* v0.5.0: Add optional additional disks per VM; use spec.runStrategy instead of spec.running (default Always); default machineType q35 (KubeVirt generic q35 alias)
* v0.5.0: Fix Windows OS detection (Helm 3/4); skip cloud-init and SSH access credentials for Windows
* v0.4.0: Parameterize ESO API version and default it to v1
* v0.3.5: Several fixes to separate DataSources from VM namespace
* v0.3.4: Correct order of coalesce arguments for main disk storage bus
Expand Down
50 changes: 43 additions & 7 deletions templates/virtual-machines.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{{- $def := .Values.vmDefaults }}
{{- range $vm, $vmr := .Values.vms }}
{{- $windows := contains (coalesce $vmr.os $def.os) "windows" }}
{{- $os := coalesce $vmr.os $def.os }}
{{- $windows := regexMatch "(?i)windows" $os }}
{{- $role := coalesce $vmr.role $def.role }}
{{- if not $.Values.disableExternalSecrets }}
{{- if and (not $windows) (not $.Values.disableExternalSecrets) }}
---
apiVersion: {{ $.Values.secretStore.esoApiVersion }}
kind: ExternalSecret
Expand Down Expand Up @@ -32,7 +33,8 @@ spec:
{{- range $i := until $ctr }}
{{- $idx := printf "%03d" (add $i 1) }}
{{- $identifier := printf "%s-%s-%s" (coalesce $vmr.os $def.os) $role $idx }}
{{- if not $.Values.disableExternalSecrets }}
{{- $additionalDisks := coalesce $vmr.additionalDisks $def.additionalDisks (list) }}
{{- if and (not $windows) (not $.Values.disableExternalSecrets) }}
---
apiVersion: {{ $.Values.secretStore.esoApiVersion }}
kind: ExternalSecret
Expand Down Expand Up @@ -113,7 +115,31 @@ spec:
storage: {{ coalesce $vmr.storage $def.storage }}
storageClassName: {{ coalesce $vmr.storageClassName $def.storageClassName }}
volumeMode: {{ coalesce $vmr.volumeMode $def.volumeMode }}
running: true
{{- range $disk := $additionalDisks }}
- apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
name: {{ $identifier }}-{{ required "additionalDisks[].name is required" $disk.name }}
spec:
{{- if $disk.dataVolume }}
sourceRef:
kind: DataSource
name: {{ $disk.dataVolume }}
namespace: {{ $def.externalDataSourceNamespace }}
{{- else }}
source:
blank: {}
{{- end }}
pvc:
accessModes:
- {{ coalesce $disk.accessMode $vmr.accessMode $def.accessMode }}
resources:
requests:
storage: {{ required (printf "additionalDisks[%s].storage is required" (required "additionalDisks[].name is required" $disk.name)) $disk.storage }}
storageClassName: {{ coalesce $disk.storageClassName $vmr.storageClassName $def.storageClassName }}
volumeMode: {{ coalesce $disk.volumeMode $vmr.volumeMode $def.volumeMode }}
{{- end }}
runStrategy: {{ coalesce $vmr.runStrategy $def.runStrategy "Always" }}
template:
metadata:
annotations:
Expand All @@ -128,7 +154,7 @@ spec:
kubevirt.io/size: {{ coalesce $vmr.flavor $def.flavor }}
vm.kubevirt.io/name: {{ $identifier }}
spec:
{{- if not $.Values.disableExternalSecrets }}
{{- if and (not $windows) (not $.Values.disableExternalSecrets) }}
accessCredentials:
- sshPublicKey:
propagationMethod:
Expand Down Expand Up @@ -158,7 +184,12 @@ spec:
- disk:
bus: {{ coalesce $vmr.mainDiskStorageBus $def.mainDiskStorageBus }}
name: {{ $identifier }}
{{- if not $.Values.disableExternalSecrets }}
{{- range $disk := $additionalDisks }}
- disk:
bus: {{ coalesce $disk.bus $vmr.additionalDiskStorageBus $def.additionalDiskStorageBus $vmr.mainDiskStorageBus $def.mainDiskStorageBus }}
name: {{ $identifier }}-{{ $disk.name }}
{{- end }}
{{- if and (not $windows) (not $.Values.disableExternalSecrets) }}
- disk:
bus: virtio
name: cloudinitdisk
Expand Down Expand Up @@ -186,7 +217,12 @@ spec:
- dataVolume:
name: {{ $identifier }} # name of the disk referenced in this file
name: {{ $identifier }} # name of the disk referenced in this file
{{- if not $.Values.disableExternalSecrets }}
{{- range $disk := $additionalDisks }}
- dataVolume:
name: {{ $identifier }}-{{ $disk.name }}
name: {{ $identifier }}-{{ $disk.name }}
{{- end }}
{{- if and (not $windows) (not $.Values.disableExternalSecrets) }}
- name: cloudinitdisk
cloudInitConfigDrive:
secretRef:
Expand Down
151 changes: 151 additions & 0 deletions tests/virtual-machines_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
---
suite: virtual-machines
templates:
- templates/virtual-machines.yaml
release:
name: test
namespace: gitops-vms
tests:
- it: uses runStrategy instead of running
set:
disableExternalSecrets: true
vms:
testvm:
role: test
count: 1
documentSelector:
path: kind
value: VirtualMachine
asserts:
- notExists:
path: spec.running
- equal:
path: spec.runStrategy
value: Always
- equal:
path: spec.template.spec.domain.machine.type
value: q35

- it: renders additional blank disks
set:
disableExternalSecrets: true
vms:
testvm:
role: test
count: 1
additionalDisks:
- name: data
storage: 50Gi
documentSelector:
path: kind
value: VirtualMachine
asserts:
- equal:
path: spec.dataVolumeTemplates[1].metadata.name
value: rhel9-test-001-data
- equal:
path: spec.dataVolumeTemplates[1].spec.source.blank
value: {}
- equal:
path: spec.dataVolumeTemplates[1].spec.pvc.resources.requests.storage
value: 50Gi
- contains:
path: spec.template.spec.domain.devices.disks
content:
disk:
bus: virtio
name: rhel9-test-001-data

- it: windows defaults additional disks to virtio and omits cloud-init
set:
vms:
winvm:
role: desktop
count: 1
os: windows2k22
additionalDisks:
- name: data
storage: 80Gi
documentSelector:
path: kind
value: VirtualMachine
asserts:
- contains:
path: spec.template.spec.domain.devices.disks
content:
disk:
bus: virtio
name: windows2k22-desktop-001-data
- notContains:
path: spec.template.spec.domain.devices.disks
content:
name: cloudinitdisk
- notContains:
path: spec.template.spec.volumes
content:
name: cloudinitdisk
- notExists:
path: spec.template.spec.accessCredentials
- exists:
path: spec.template.spec.domain.devices.tpm
- matchRegex:
path: metadata.annotations["vm.kubevirt.io/validations"]
pattern: '"min": 4294967296'

- it: windows skips cloud-init and ssh external secrets
set:
vms:
winvm:
role: desktop
count: 1
os: windows2k22
asserts:
- hasDocuments:
count: 2

- it: linux still renders cloud-init when external secrets enabled
set:
vms:
linuxvm:
role: server
count: 1
os: rhel9
documentSelector:
path: kind
value: VirtualMachine
asserts:
- contains:
path: spec.template.spec.domain.devices.disks
content:
disk:
bus: virtio
name: cloudinitdisk
- contains:
path: spec.template.spec.volumes
content:
name: cloudinitdisk
cloudInitConfigDrive:
secretRef:
name: cloudinit-server

- it: windows honors per-disk sata bus override
set:
vms:
winvm:
role: desktop
count: 1
os: windows2k22
additionalDisks:
- name: data
storage: 80Gi
bus: sata
documentSelector:
path: kind
value: VirtualMachine
asserts:
- contains:
path: spec.template.spec.domain.devices.disks
content:
disk:
bus: sata
name: windows2k22-desktop-001-data
25 changes: 18 additions & 7 deletions values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ secretStore:
name: vault-backend
kind: ClusterSecretStore

vmNamespace: edge-gitops-vms
vmNamespace: gitops-vms

waitForMetalNode: true
waitForMetalNode: false
jobTerminationGracePeriod: 3600

vmDefaults:
Expand All @@ -23,19 +23,24 @@ vmDefaults:
storageClassName: "ocs-storagecluster-ceph-rbd-virtualization"
volumeMode: "Block"
count: 1
# Could also be sata
# Override per VM or per additionalDisks[].bus (e.g. sata for generic Windows images).
mainDiskStorageBus: virtio
additionalDiskStorageBus: virtio
# Always | RerunOnFailure | Manual | Halted | Once (mutually exclusive with spec.running)
runStrategy: Always
flavor: medium
workload: desktop
os: rhel8
workload: server
os: rhel9
efi: false
storage: 30Gi
memory: 4Gi
# Generic q35 alias (KubeVirt AMD64 default); libvirt resolves per node. Prefer this over
# pc-q35-rhel9.x.0 unless you must pin a version for live-migration homogeneity.
machineType: q35
cores: 1
sockets: 1
threads: 1
template: rhel8-desktop-medium
template: rhel9-server-medium
sshsecret: secret/data/hub/vm-ssh #checkov:skip=CKV_SECRET_6:External Secret
cloudinitsecret: secret/data/hub/cloud-init
sshpubkeyfield: publickey
Expand Down Expand Up @@ -66,6 +71,12 @@ vmDefaults:

# Define the VMs you want to create with any specific attributes from vmDefaults
# in an overrides file.
# Per-VM additionalDisks (optional; can also be set under vmDefaults):
# additionalDisks:
# - name: data
# storage: 100Gi
# # bus, accessMode, storageClassName, volumeMode optional (inherit vmDefaults)
# # dataVolume: clone from a DataSource name; omit for a blank disk
vms: {}

registryCredentialExternalSecrets: {}
Expand Down Expand Up @@ -120,7 +131,7 @@ rbac:
subjects:
kind: ServiceAccount
name: ansible-edge-gitops-sa
namespace: edge-gitops-vms
namespace: gitops-vms
apiGroup: ""
roleRef:
kind: ClusterRole
Expand Down