From cc9687707ce9e8c18f044f0c5c879b5e26e33188 Mon Sep 17 00:00:00 2001
From: nbykov0 <166552198+nbykov0@users.noreply.github.com>
Date: Tue, 21 Oct 2025 15:02:12 +0300
Subject: [PATCH 1/4] [apps] Add VPC app
Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com>
---
packages/apps/vpc/Chart.yaml | 6 ++
packages/apps/vpc/Makefile | 8 +++
packages/apps/vpc/README.md | 48 +++++++++++++
packages/apps/vpc/logos/vpc.svg | 10 +++
packages/apps/vpc/templates/vpc.yaml | 72 +++++++++++++++++++
packages/apps/vpc/values.schema.json | 20 ++++++
packages/apps/vpc/values.yaml | 15 ++++
.../cozyrds/virtualprivatecloud.yaml | 34 +++++++++
8 files changed, 213 insertions(+)
create mode 100644 packages/apps/vpc/Chart.yaml
create mode 100644 packages/apps/vpc/Makefile
create mode 100644 packages/apps/vpc/README.md
create mode 100644 packages/apps/vpc/logos/vpc.svg
create mode 100644 packages/apps/vpc/templates/vpc.yaml
create mode 100644 packages/apps/vpc/values.schema.json
create mode 100644 packages/apps/vpc/values.yaml
create mode 100644 packages/system/cozystack-resource-definitions/cozyrds/virtualprivatecloud.yaml
diff --git a/packages/apps/vpc/Chart.yaml b/packages/apps/vpc/Chart.yaml
new file mode 100644
index 00000000..d317ed21
--- /dev/null
+++ b/packages/apps/vpc/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: virtualprivatecloud
+description: Isolated networks
+icon: logos/vpc.svg
+type: application
+version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
diff --git a/packages/apps/vpc/Makefile b/packages/apps/vpc/Makefile
new file mode 100644
index 00000000..8807454f
--- /dev/null
+++ b/packages/apps/vpc/Makefile
@@ -0,0 +1,8 @@
+include ../../../scripts/package.mk
+
+generate:
+ cozyvalues-gen -v values.yaml -s values.schema.json
+ ../../../hack/update-crd.sh
+
+update:
+ echo
diff --git a/packages/apps/vpc/README.md b/packages/apps/vpc/README.md
new file mode 100644
index 00000000..ea58b9d1
--- /dev/null
+++ b/packages/apps/vpc/README.md
@@ -0,0 +1,48 @@
+# VPC
+
+VPC offers a subset of dedicated subnets with networking services related to it.
+As the service evolves, it will provide more ways to isolate your workloads.
+
+## Service details
+
+The service utilizes kube-ovn VPC and Subnet resources, which use ovn logical routers and logical switches under the hood.
+Currently every workload will have a connection to a default management network which will also have a default gateway, and the majority of traffic will be going through it.
+VPC subnets are for now an additional dedicated networking spaces.
+
+A VM or a pod may be connected to multiple secondary Subnets at once.
+Each secondary connection will be represented as an additional network interface.
+
+## Deployment notes
+
+VPC name must be unique within a tenant.
+Subnet name and ip address range must be unique within a VPC.
+Subnet ip address space must not overlap with the default management network ip address range, subsets of 172.16.0.0/12 are recommended.
+Currently there are no fail-safe checks, however they are planned for the future.
+
+Different VPCs may have subnets with ovelapping ip address ranges.
+
+## Parameters
+
+### Common parameters
+
+| Name | Description | Type | Value |
+| -------------------- | -------------------------------- | ------------------- | ------- |
+| `subnets` | Subnets of a VPC | `map[string]object` | `{...}` |
+| `subnets[name].cidr` | Subnet CIDR, e.g. 192.168.0.0/24 | `cidr` | `{}` |
+
+
+## Examples
+```yaml
+apiVersion: apps.cozystack.io/v1alpha1
+kind: VirtualPrivateCloud
+metadata:
+ name: vpc00
+spec:
+ subnets:
+ sub00:
+ cidr: 172.16.0.0/24
+ sub01:
+ cidr: 172.16.1.0/24
+ sub02:
+ cidr: 172.16.2.0/24
+```
diff --git a/packages/apps/vpc/logos/vpc.svg b/packages/apps/vpc/logos/vpc.svg
new file mode 100644
index 00000000..555bb12e
--- /dev/null
+++ b/packages/apps/vpc/logos/vpc.svg
@@ -0,0 +1,10 @@
+
diff --git a/packages/apps/vpc/templates/vpc.yaml b/packages/apps/vpc/templates/vpc.yaml
new file mode 100644
index 00000000..eea75518
--- /dev/null
+++ b/packages/apps/vpc/templates/vpc.yaml
@@ -0,0 +1,72 @@
+## Release.Namespace == tenant name
+## Release.Name == vpc name
+
+{{ $vpcId := print "vpc-" (print .Release.Namespace "/" .Release.Name | sha256sum | trunc 6) }}
+
+---
+apiVersion: kubeovn.io/v1
+kind: Vpc
+metadata:
+ name: {{ $vpcId }}
+ labels:
+ cozystack.io/vpcName: {{ .Release.Name }}
+ cozystack.io/tenantName: {{ .Release.Namespace }}
+spec:
+ enableExternal: false
+ namespaces:
+ - {{ .Release.Namespace }}
+
+{{- range $subnetName, $subnetConfig := .Values.subnets }}
+{{- $subnetId := print "subnet-" (print $.Release.Namespace "/" $vpcId "/" $subnetName | sha256sum | trunc 8) }}
+---
+apiVersion: k8s.cni.cncf.io/v1
+kind: NetworkAttachmentDefinition
+metadata:
+ name: {{ $subnetId }}
+ namespace: {{ $.Release.Namespace }}
+ labels:
+ cozystack.io/subnetName: {{ $subnetName }}
+ cozystack.io/vpcId: {{ $vpcId }}
+ cozystack.io/vpcName: {{ $.Release.Name }}
+ cozystack.io/tenantName: {{ $.Release.Namespace }}
+spec:
+ config: '{
+ "cniVersion": "0.3.0",
+ "type": "kube-ovn",
+ "server_socket": "/run/openvswitch/kube-ovn-daemon.sock",
+ "provider": "{{ $subnetId }}.{{ $.Release.Namespace }}.ovn"
+ }'
+---
+apiVersion: kubeovn.io/v1
+kind: Subnet
+metadata:
+ name: {{ $subnetId }}
+ labels:
+ cozystack.io/subnetName: {{ $subnetName }}
+ cozystack.io/vpcId: {{ $vpcId }}
+ cozystack.io/vpcName: {{ $.Release.Name }}
+ cozystack.io/tenantName: {{ $.Release.Namespace }}
+spec:
+ vpc: {{ $vpcId }}
+ cidrBlock: {{ $subnetConfig.cidr }}
+ provider: "{{ $subnetId }}.{{ $.Release.Namespace }}.ovn"
+ protocol: IPv4
+ enableLb: false
+ private: true
+{{- end }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ $vpcId }}-subnets
+ labels:
+ cozystack.io/vpcName: {{ $.Release.Name }}
+ cozystack.io/tenantName: {{ $.Release.Namespace }}
+data:
+ subnets: |
+ {{- range $subnetName, $subnetConfig := .Values.subnets }}
+ - subnetName: {{ $subnetName }}
+ subnetId: {{ print "subnet-" (print $.Release.Namespace "/" $vpcId "/" $subnetName | sha256sum | trunc 8) }}
+ subnetCIDR: {{ $subnetConfig.cidr }}
+ {{- end }}
+
diff --git a/packages/apps/vpc/values.schema.json b/packages/apps/vpc/values.schema.json
new file mode 100644
index 00000000..3e888de4
--- /dev/null
+++ b/packages/apps/vpc/values.schema.json
@@ -0,0 +1,20 @@
+{
+ "title": "Chart Values",
+ "type": "object",
+ "properties": {
+ "subnets": {
+ "description": "Subnets of a VPC",
+ "type": "object",
+ "default": {},
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "cidr": {
+ "description": "IP address range",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/apps/vpc/values.yaml b/packages/apps/vpc/values.yaml
new file mode 100644
index 00000000..e2bd5faa
--- /dev/null
+++ b/packages/apps/vpc/values.yaml
@@ -0,0 +1,15 @@
+##
+## @section Common parameters
+##
+
+## @typedef {struct} Subnet - Subnet of a VPC
+## @field {string} [cidr] - IP address range
+
+## @param {map[string]Subnet} subnets - Subnets of a VPC
+subnets: {}
+## Example:
+## subnets:
+## mysubnet0:
+## cidr: "172.16.0.0/24"
+## mysubnet1:
+## cidr: "172.16.1.0/24"
diff --git a/packages/system/cozystack-resource-definitions/cozyrds/virtualprivatecloud.yaml b/packages/system/cozystack-resource-definitions/cozyrds/virtualprivatecloud.yaml
new file mode 100644
index 00000000..8d05a5b6
--- /dev/null
+++ b/packages/system/cozystack-resource-definitions/cozyrds/virtualprivatecloud.yaml
@@ -0,0 +1,34 @@
+apiVersion: cozystack.io/v1alpha1
+kind: CozystackResourceDefinition
+metadata:
+ name: virtualprivatecloud
+spec:
+ application:
+ kind: VirtualPrivateCloud
+ plural: virtualprivateclouds
+ singular: virtualprivatecloud
+ openAPISchema: |-
+ {"title":"Chart Values","type":"object","properties":{"subnets":{"description":"Subnets of a VPC","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"cidr":{"description":"IP address range","type":"string"}}}}}}
+ release:
+ prefix: "virtualprivatecloud-"
+ labels:
+ cozystack.io/ui: "true"
+ chart:
+ name: virtualprivatecloud
+ sourceRef:
+ kind: HelmRepository
+ name: cozystack-apps
+ namespace: cozy-public
+ dashboard:
+ category: IaaS
+ singular: VPC
+ plural: VPCs
+ description: "Isolated networks"
+ icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8xMDI1XzMpIi8+CjxwYXRoIGQ9Ik0xMDkuNiA4Ni4xSDExNC4zQzExNi44ODUgODYuMSAxMTkgODguMjE1IDExOSA5MC44NDdWMTA0Ljg1M0MxMTkgMTA3LjQ4NSAxMTYuODg1IDEwOS42IDExNC4zIDEwOS42SDk1LjVDOTIuOTE1IDEwOS42IDkwLjggMTA3LjQ4NSA5MC44IDEwNC44NTNWOTAuODQ3QzkwLjggODguMjE1IDkyLjkxNSA4Ni4xIDk1LjUgODYuMUgxMDAuMlY3Ni43SDc2LjdWODYuMUg4MS40QzgzLjk4NSA4Ni4xIDg2LjEgODguMjE1IDg2LjEgOTAuODQ3VjEwNC44NTNDODYuMSAxMDcuNDg1IDgzLjk4NSAxMDkuNiA4MS40IDEwOS42SDYyLjZDNjAuMDE1IDEwOS42IDU3LjkgMTA3LjQ4NSA1Ny45IDEwNC44NTNWOTAuODQ3QzU3LjkgODguMjE1IDYwLjAxNSA4Ni4xIDYyLjYgODYuMUg2Ny4zVjc2LjdINDMuOFY4Ni4xSDQ4LjVDNTEuMDg1IDg2LjEgNTMuMiA4OC4yMTUgNTMuMiA5MC44NDdWMTA0Ljg1M0M1My4yIDEwNy40ODUgNTEuMDg1IDEwOS42IDQ4LjUgMTA5LjZIMjkuN0MyNy4xMTUgMTA5LjYgMjUgMTA3LjQ4NSAyNSAxMDQuODUzVjkwLjg0N0MyNSA4OC4yMTUgMjcuMTE1IDg2LjEgMjkuNyA4Ni4xSDM0LjRWNzYuN0MzNC40IDcxLjUzIDM4LjYzIDY3LjMgNDMuOCA2Ny4zSDY3LjNWNTcuOUg2Mi42QzYwLjAxNSA1Ny45IDU3LjkgNTUuNzg1IDU3LjkgNTMuMTUzVjM5LjE0N0M1Ny45IDM2LjUxNSA2MC4wMTUgMzQuNCA2Mi42IDM0LjRIODEuNEM4My45ODUgMzQuNCA4Ni4xIDM2LjUxNSA4Ni4xIDM5LjE0N1Y1My4xNTNDODYuMSA1NS43ODUgODMuOTg1IDU3LjkgODEuNCA1Ny45SDc2LjdWNjcuM0gxMDAuMkMxMDUuMzcgNjcuMyAxMDkuNiA3MS41MyAxMDkuNiA3Ni43Vjg2LjFaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzEwMjVfMyIgeDE9IjE0Mi41IiB5MT0iMTQzIiB4Mj0iMy45OTk5OSIgeTI9IjkuNDk5OTkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzAwMDgyRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyRTMwNjciLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K
+ keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "subnets"]]
+ secrets:
+ exclude: []
+ include: []
+ services:
+ exclude: []
+ include: []
From 202da193c0ab22999ee09585ae6a925e8ff16c5b Mon Sep 17 00:00:00 2001
From: nbykov0 <166552198+nbykov0@users.noreply.github.com>
Date: Tue, 21 Oct 2025 15:03:16 +0300
Subject: [PATCH 2/4] [apps] virtual-machine: add vpc support
Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com>
---
packages/apps/virtual-machine/README.md | 2 +
.../templates/secret-network-config.yaml | 40 +++++++++++++++++++
.../apps/virtual-machine/templates/vm.yaml | 27 +++++++++++--
.../apps/virtual-machine/values.schema.json | 14 +++++++
packages/apps/virtual-machine/values.yaml | 11 +++++
.../cozyrds/virtual-machine.yaml | 4 +-
6 files changed, 92 insertions(+), 6 deletions(-)
create mode 100644 packages/apps/virtual-machine/templates/secret-network-config.yaml
diff --git a/packages/apps/virtual-machine/README.md b/packages/apps/virtual-machine/README.md
index 1d23e87a..dc6633f2 100644
--- a/packages/apps/virtual-machine/README.md
+++ b/packages/apps/virtual-machine/README.md
@@ -48,6 +48,8 @@ virtctl ssh @
| `systemDisk.image` | The base image for the virtual machine. | `string` | `ubuntu` |
| `systemDisk.storage` | The size of the disk allocated for the virtual machine. | `string` | `5Gi` |
| `systemDisk.storageClass` | StorageClass used to store the data. | `string` | `replicated` |
+| `subnets` | Additional subnets | `[]object` | `[]` |
+| `subnets[i].name` | Subnet name | `string` | `""` |
| `gpus` | List of GPUs to attach. | `[]object` | `[]` |
| `gpus[i].name` | The name of the GPU resource to attach. | `string` | `""` |
| `resources` | Resource configuration for the virtual machine. | `object` | `{}` |
diff --git a/packages/apps/virtual-machine/templates/secret-network-config.yaml b/packages/apps/virtual-machine/templates/secret-network-config.yaml
new file mode 100644
index 00000000..9800ceac
--- /dev/null
+++ b/packages/apps/virtual-machine/templates/secret-network-config.yaml
@@ -0,0 +1,40 @@
+# if subnets are specified and image is either ubunu or alpine
+{{- if and .Values.subnets (or (eq .Values.systemDisk.image "ubuntu") (eq .Values.systemDisk.image "alpine")) }}
+---
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ include "virtual-machine.fullname" $ }}-network-config
+stringData:
+ networkData: |
+ network:
+ version: 1
+ config:
+ {{- if eq .Values.systemDisk.image "ubuntu" }}
+ # main iface
+ - type: physical
+ name: enp1s0
+ subnets:
+ - type: dhcp
+ # additional ifaces attached to subnets
+ {{- range $i, $subnet := .Values.subnets }}
+ - type: physical
+ name: enp{{ add 2 $i }}s0
+ subnets:
+ - type: dhcp
+ {{- end }}
+ {{- else if eq .Values.systemDisk.image "alpine" }}
+ #main iface
+ - type: physical
+ name: eth0
+ subnets:
+ - type: dhcp
+ # additional ifaces attached to subnets
+ {{- range $i, $subnet := .Values.subnets }}
+ - type: physical
+ name: eth{{ add1 $i }}
+ subnets:
+ - type: dhcp
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/packages/apps/virtual-machine/templates/vm.yaml b/packages/apps/virtual-machine/templates/vm.yaml
index 684e48c4..1d7652e8 100644
--- a/packages/apps/virtual-machine/templates/vm.yaml
+++ b/packages/apps/virtual-machine/templates/vm.yaml
@@ -51,9 +51,9 @@ spec:
{{- else if eq .Values.systemDisk.image "ubuntu" }}
url: https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
{{- else if eq .Values.systemDisk.image "fedora" }}
- url: https://download.fedoraproject.org/pub/fedora/linux/releases/40/Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2
+ url: https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2
{{- else if eq .Values.systemDisk.image "alpine" }}
- url: https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/cloud/nocloud_alpine-3.20.2-x86_64-bios-tiny-r0.qcow2
+ url: https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/cloud/nocloud_alpine-3.20.8-x86_64-bios-cloudinit-r0.qcow2
{{- else if eq .Values.systemDisk.image "talos" }}
url: https://github.com/siderolabs/talos/releases/download/v1.7.6/nocloud-amd64.raw.xz
{{- end }}
@@ -93,7 +93,7 @@ spec:
- disk:
bus: scsi
name: systemdisk
- {{- if or .Values.cloudInit .Values.sshKeys }}
+ {{- if or .Values.cloudInit .Values.sshKeys (and .Values.subnets (or (eq .Values.systemDisk.image "ubuntu") (eq .Values.systemDisk.image "alpine"))) }}
- disk:
bus: virtio
name: cloudinitdisk
@@ -102,6 +102,12 @@ spec:
interfaces:
- name: default
bridge: {}
+ {{- if .Values.subnets }}
+ {{- range $i, $subnet := .Values.subnets }}
+ - name: {{ $subnet.name }}
+ bridge: {}
+ {{- end }}
+ {{- end }}
machine:
type: ""
@@ -123,13 +129,26 @@ spec:
- name: systemdisk
dataVolume:
name: {{ include "virtual-machine.fullname" . }}
- {{- if or .Values.cloudInit .Values.sshKeys }}
+ {{- if or .Values.cloudInit .Values.sshKeys (and .Values.subnets (or (eq .Values.systemDisk.image "ubuntu") (eq .Values.systemDisk.image "alpine"))) }}
- name: cloudinitdisk
cloudInitNoCloud:
+ {{- if or .Values.cloudInit .Values.sshKeys }}
secretRef:
name: {{ include "virtual-machine.fullname" . }}-cloud-init
+ {{- end }}
+ {{- if and .Values.subnets (or (eq .Values.systemDisk.image "ubuntu") (eq .Values.systemDisk.image "alpine")) }}
+ networkDataSecretRef:
+ name: {{ include "virtual-machine.fullname" . }}-network-config
+ {{- end }}
{{- end }}
networks:
- name: default
pod: {}
+ {{- if .Values.subnets }}
+ {{- range $i, $subnet := .Values.subnets }}
+ - name: {{ $subnet.name }}
+ multus:
+ networkName: {{ $.Release.Namespace }}/{{ $subnet.name }}
+ {{- end }}
+ {{- end }}
diff --git a/packages/apps/virtual-machine/values.schema.json b/packages/apps/virtual-machine/values.schema.json
index c88568b3..e96d6449 100644
--- a/packages/apps/virtual-machine/values.schema.json
+++ b/packages/apps/virtual-machine/values.schema.json
@@ -167,6 +167,20 @@
"type": "string"
}
},
+ "subnets": {
+ "description": "Additional subnets",
+ "type": "array",
+ "default": [],
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "Subnet name",
+ "type": "string"
+ }
+ }
+ }
+ },
"systemDisk": {
"description": "System disk configuration.",
"type": "object",
diff --git a/packages/apps/virtual-machine/values.yaml b/packages/apps/virtual-machine/values.yaml
index 2f15759e..a4bfbb53 100644
--- a/packages/apps/virtual-machine/values.yaml
+++ b/packages/apps/virtual-machine/values.yaml
@@ -18,6 +18,9 @@
## @field {string} storage - The size of the disk allocated for the virtual machine.
## @field {string} [storageClass] - StorageClass used to store the data.
+## @typedef {struct} Subnet - Additional subnets
+## @field {string} [name] - Subnet name
+
## @typedef {struct} GPU - GPU device configuration.
## @field {string} name - The name of the GPU resource to attach.
@@ -50,6 +53,14 @@ systemDisk:
storage: 5Gi
storageClass: replicated
+## @param {[]Subnet} subnets - Additional subnets
+subnets: []
+## Example:
+## subnets:
+## - name: subnet-84dbec17
+## - name: subnet-aa8896b5
+## - name: subnet-e9b97196
+
## @param {[]GPU} gpus - List of GPUs to attach.
gpus: []
## Example:
diff --git a/packages/system/cozystack-resource-definitions/cozyrds/virtual-machine.yaml b/packages/system/cozystack-resource-definitions/cozyrds/virtual-machine.yaml
index 1a2f2aec..a1e384c4 100644
--- a/packages/system/cozystack-resource-definitions/cozyrds/virtual-machine.yaml
+++ b/packages/system/cozystack-resource-definitions/cozyrds/virtual-machine.yaml
@@ -8,7 +8,7 @@ spec:
plural: virtualmachines
singular: virtualmachine
openAPISchema: |-
- {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Whether the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}},"systemDisk":{"description":"System disk configuration.","type":"object","default":{},"required":["image","storage"],"properties":{"image":{"description":"The base image for the virtual machine.","type":"string","default":"ubuntu","enum":["ubuntu","cirros","alpine","fedora","talos"]},"storage":{"description":"The size of the disk allocated for the virtual machine.","type":"string","default":"5Gi"},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}}}
+ {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Whether the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}},"subnets":{"description":"Additional subnets","type":"array","default":[],"items":{"type":"object","properties":{"name":{"description":"Subnet name","type":"string"}}}},"systemDisk":{"description":"System disk configuration.","type":"object","default":{},"required":["image","storage"],"properties":{"image":{"description":"The base image for the virtual machine.","type":"string","default":"ubuntu","enum":["ubuntu","cirros","alpine","fedora","talos"]},"storage":{"description":"The size of the disk allocated for the virtual machine.","type":"string","default":"5Gi"},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}}}
release:
prefix: virtual-machine-
labels:
@@ -28,7 +28,7 @@ spec:
tags:
- compute
icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQ1NCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDU0KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMDBCM0ZGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi41Mjc1IDUzLjgzNjdDNzIuNDQzMSA1My44MzUxIDcyLjM2MDUgNTMuODEyMiA3Mi4yODczIDUzLjc3MDFMNTYuNDY5OSA0NC43OTM0QzU2LjM5ODMgNDQuNzUxOSA1Ni4zMzg4IDQ0LjY5MjMgNTYuMjk3MyA0NC42MjA3QzU2LjI1NTkgNDQuNTQ5IDU2LjIzMzggNDQuNDY3OCA1Ni4yMzM0IDQ0LjM4NUM1Ni4yMzM0IDQ0LjIxNjkgNTYuMzI1OCA0NC4wNjE3IDU2LjQ2OTkgNDMuOTc4NUw3Mi4xOTEyIDM1LjA2MDlDNzIuMjYzNyAzNS4wMjEgNzIuMzQ1IDM1IDcyLjQyNzcgMzVDNzIuNTEwNSAzNSA3Mi41OTE4IDM1LjAyMSA3Mi42NjQzIDM1LjA2MDlMODguNDg3MiA0NC4wMzk1Qzg4LjU1OTEgNDQuMDgwMSA4OC42MTg4IDQ0LjEzOTIgODguNjYgNDQuMjEwN0M4OC43MDEzIDQ0LjI4MjIgODguNzIyNyA0NC4zNjM1IDg4LjcyMTkgNDQuNDQ2Qzg4LjcyMjUgNDQuNTI4NSA4OC43MDEgNDQuNjA5NyA4OC42NTk4IDQ0LjY4MTJDODguNjE4NSA0NC43NTI2IDg4LjU1ODkgNDQuODExOCA4OC40ODcyIDQ0Ljg1MjVMNzIuNzcxNCA1My43NjgzQzcyLjY5NzIgNTMuODExNCA3Mi42MTMzIDUzLjgzNDkgNzIuNTI3NSA1My44MzY3IiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjciIGQ9Ik03MC4yNTUzIDc1LjY1MTdDNzAuMTcxIDc1LjY1MzUgNzAuMDg3OCA3NS42MzE3IDcwLjAxNTEgNzUuNTg4OEw1NC4yNDU4IDY2LjY0MTdDNTQuMTcxNSA2Ni42MDI0IDU0LjEwOTUgNjYuNTQzNiA1NC4wNjYxIDY2LjQ3MTZDNTQuMDIyOCA2Ni4zOTk3IDU0IDY2LjMxNzMgNTQgNjYuMjMzM1Y0OC4yNzhDNTQgNDguMTA4IDU0LjA5MjQgNDcuOTU0NiA1NC4yNDM5IDQ3Ljg2OTZDNTQuMzE3MiA0Ny44MjcxIDU0LjQwMDQgNDcuODA0NyA1NC40ODUxIDQ3LjgwNDdDNTQuNTY5NyA0Ny44MDQ3IDU0LjY1MjkgNDcuODI3MSA1NC43MjYyIDQ3Ljg2OTZMNzAuNDkzNyA1Ni44MTMxQzcwLjU2NDIgNTYuODU2NSA3MC42MjI1IDU2LjkxNyA3MC42NjMyIDU2Ljk4OTFDNzAuNzAzOSA1Ny4wNjEyIDcwLjcyNTcgNTcuMTQyNCA3MC43MjY1IDU3LjIyNTFWNzUuMTgwNUM3MC43MjU5IDc1LjI2MjggNzAuNzA0MiA3NS4zNDM2IDcwLjY2MzUgNzUuNDE1MUM3MC42MjI3IDc1LjQ4NjYgNzAuNTY0MiA3NS41NDY0IDcwLjQ5MzcgNzUuNTg4OEM3MC40MjA2IDc1LjYyOTEgNzAuMzM4NyA3NS42NTA3IDcwLjI1NTMgNzUuNjUxNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC40IiBkPSJNNzQuNzE5OCA3NS42NTExQzc0LjYzMzMgNzUuNjUxMiA3NC41NDgyIDc1LjYyOTYgNzQuNDcyMiA3NS41ODgzQzc0LjQwMTYgNzUuNTQ2MSA3NC4zNDMyIDc1LjQ4NjIgNzQuMzAyNyA3NS40MTQ3Qzc0LjI2MjMgNzUuMzQzMSA3NC4yNDExIDc1LjI2MjIgNzQuMjQxMiA3NS4xOFY1Ny4zMzczQzc0LjI0MTIgNTcuMTcxIDc0LjMzMzYgNTcuMDE1OCA3NC40NzIyIDU2LjkyOUw5MC4yMzk3IDQ3Ljk4NTVDOTAuMzExOSA0Ny45NDM4IDkwLjM5MzggNDcuOTIxOSA5MC40NzcxIDQ3LjkyMTlDOTAuNTYwNSA0Ny45MjE5IDkwLjY0MjQgNDcuOTQzOCA5MC43MTQ2IDQ3Ljk4NTVDOTAuNzg3NiA0OC4wMjU1IDkwLjg0ODUgNDguMDg0MiA5MC44OTExIDQ4LjE1NTdDOTAuOTMzNyA0OC4yMjcyIDkwLjk1NjMgNDguMzA4OCA5MC45NTY2IDQ4LjM5MlY2Ni4yMzI4QzkwLjk1NyA2Ni4zMTY0IDkwLjkzNDcgNjYuMzk4NSA5MC44OTIxIDY2LjQ3MDRDOTAuODQ5NSA2Ni41NDI0IDkwLjc4ODEgNjYuNjAxNCA5MC43MTQ2IDY2LjY0MTFMNzQuOTUyNiA3NS41ODgzQzc0Ljg4MjUgNzUuNjMwNyA3NC44MDE4IDc1LjY1MjUgNzQuNzE5OCA3NS42NTExIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zNDU0IiB4MT0iMTYxIiB5MT0iMTgwIiB4Mj0iMy41OTI4NGUtMDciIHkyPSI0Ljk5OTk4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTk1NjU2Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNjg3XzM0NTQiPgo8cmVjdCB3aWR0aD0iOTQiIGhlaWdodD0iOTQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNSAyNSkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K
- keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "systemDisk"], ["spec", "systemDisk", "image"], ["spec", "systemDisk", "storage"], ["spec", "systemDisk", "storageClass"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]]
+ keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "systemDisk"], ["spec", "systemDisk", "image"], ["spec", "systemDisk", "storage"], ["spec", "systemDisk", "storageClass"], ["spec", "subnets"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]]
secrets:
exclude: []
include: []
From 19c4674ebb4c894a4324313da5ea615fa1b3d652 Mon Sep 17 00:00:00 2001
From: nbykov0 <166552198+nbykov0@users.noreply.github.com>
Date: Tue, 21 Oct 2025 15:03:42 +0300
Subject: [PATCH 3/4] [apps] vm-instance: add vpc support
Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com>
---
packages/apps/vm-instance/README.md | 2 ++
packages/apps/vm-instance/templates/vm.yaml | 13 +++++++++++++
packages/apps/vm-instance/values.schema.json | 14 ++++++++++++++
packages/apps/vm-instance/values.yaml | 11 +++++++++++
.../cozyrds/vm-instance.yaml | 4 ++--
5 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/packages/apps/vm-instance/README.md b/packages/apps/vm-instance/README.md
index 4d555763..dc63508a 100644
--- a/packages/apps/vm-instance/README.md
+++ b/packages/apps/vm-instance/README.md
@@ -47,6 +47,8 @@ virtctl ssh @
| `disks` | List of disks to attach. | `[]object` | `[]` |
| `disks[i].name` | Disk name. | `string` | `""` |
| `disks[i].bus` | Disk bus type (e.g. "sata"). | `string` | `""` |
+| `subnets` | Additional subnets | `[]object` | `[]` |
+| `subnets[i].name` | Subnet name | `string` | `""` |
| `gpus` | List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM). | `[]object` | `[]` |
| `gpus[i].name` | The name of the GPU resource to attach. | `string` | `""` |
| `resources` | Resource configuration for the virtual machine. | `object` | `{}` |
diff --git a/packages/apps/vm-instance/templates/vm.yaml b/packages/apps/vm-instance/templates/vm.yaml
index c6082a93..e64ec2f6 100644
--- a/packages/apps/vm-instance/templates/vm.yaml
+++ b/packages/apps/vm-instance/templates/vm.yaml
@@ -77,6 +77,12 @@ spec:
interfaces:
- name: default
bridge: {}
+ {{- if .Values.subnets }}
+ {{- range $i, $subnet := .Values.subnets }}
+ - name: {{ $subnet.name }}
+ bridge: {}
+ {{- end }}
+ {{- end }}
machine:
type: ""
{{- with .Values.sshKeys }}
@@ -105,3 +111,10 @@ spec:
networks:
- name: default
pod: {}
+ {{- if .Values.subnets }}
+ {{- range $i, $subnet := .Values.subnets }}
+ - name: {{ $subnet.name }}
+ multus:
+ networkName: {{ $.Release.Namespace }}/{{ $subnet.name }}
+ {{- end }}
+ {{- end }}
diff --git a/packages/apps/vm-instance/values.schema.json b/packages/apps/vm-instance/values.schema.json
index 1a6b88d9..ca6b34e7 100644
--- a/packages/apps/vm-instance/values.schema.json
+++ b/packages/apps/vm-instance/values.schema.json
@@ -187,6 +187,20 @@
"items": {
"type": "string"
}
+ },
+ "subnets": {
+ "description": "Additional subnets",
+ "type": "array",
+ "default": [],
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "Subnet name",
+ "type": "string"
+ }
+ }
+ }
}
}
}
diff --git a/packages/apps/vm-instance/values.yaml b/packages/apps/vm-instance/values.yaml
index 0235f930..9d0a1522 100644
--- a/packages/apps/vm-instance/values.yaml
+++ b/packages/apps/vm-instance/values.yaml
@@ -10,6 +10,9 @@
## @field {string} name - Disk name.
## @field {string} [bus] - Disk bus type (e.g. "sata").
+## @typedef {struct} Subnet - Additional subnets
+## @field {string} [name] - Subnet name
+
## @typedef {struct} GPU - GPU device configuration.
## @field {string} name - The name of the GPU resource to attach.
@@ -45,6 +48,14 @@ disks: []
## - name: example-data
## bus: sata
+## @param {[]Subnet} subnets - Additional subnets
+subnets: []
+## Example:
+## subnets:
+## - name: subnet-84dbec17
+## - name: subnet-aa8896b5
+## - name: subnet-e9b97196
+
## @param {[]GPU} gpus - List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).
gpus: []
## Example:
diff --git a/packages/system/cozystack-resource-definitions/cozyrds/vm-instance.yaml b/packages/system/cozystack-resource-definitions/cozyrds/vm-instance.yaml
index 35b7eb23..58eb5f9a 100644
--- a/packages/system/cozystack-resource-definitions/cozyrds/vm-instance.yaml
+++ b/packages/system/cozystack-resource-definitions/cozyrds/vm-instance.yaml
@@ -8,7 +8,7 @@ spec:
singular: vminstance
plural: vminstances
openAPISchema: |-
- {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"disks":{"description":"List of disks to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"bus":{"description":"Disk bus type (e.g. \"sata\").","type":"string"},"name":{"description":"Disk name.","type":"string"}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Determines if the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}}}}
+ {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"disks":{"description":"List of disks to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"bus":{"description":"Disk bus type (e.g. \"sata\").","type":"string"},"name":{"description":"Disk name.","type":"string"}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Determines if the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}},"subnets":{"description":"Additional subnets","type":"array","default":[],"items":{"type":"object","properties":{"name":{"description":"Subnet name","type":"string"}}}}}}
release:
prefix: vm-instance-
labels:
@@ -28,7 +28,7 @@ spec:
tags:
- compute
icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQ1NCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDU0KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMDBCM0ZGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi41Mjc1IDUzLjgzNjdDNzIuNDQzMSA1My44MzUxIDcyLjM2MDUgNTMuODEyMiA3Mi4yODczIDUzLjc3MDFMNTYuNDY5OSA0NC43OTM0QzU2LjM5ODMgNDQuNzUxOSA1Ni4zMzg4IDQ0LjY5MjMgNTYuMjk3MyA0NC42MjA3QzU2LjI1NTkgNDQuNTQ5IDU2LjIzMzggNDQuNDY3OCA1Ni4yMzM0IDQ0LjM4NUM1Ni4yMzM0IDQ0LjIxNjkgNTYuMzI1OCA0NC4wNjE3IDU2LjQ2OTkgNDMuOTc4NUw3Mi4xOTEyIDM1LjA2MDlDNzIuMjYzNyAzNS4wMjEgNzIuMzQ1IDM1IDcyLjQyNzcgMzVDNzIuNTEwNSAzNSA3Mi41OTE4IDM1LjAyMSA3Mi42NjQzIDM1LjA2MDlMODguNDg3MiA0NC4wMzk1Qzg4LjU1OTEgNDQuMDgwMSA4OC42MTg4IDQ0LjEzOTIgODguNjYgNDQuMjEwN0M4OC43MDEzIDQ0LjI4MjIgODguNzIyNyA0NC4zNjM1IDg4LjcyMTkgNDQuNDQ2Qzg4LjcyMjUgNDQuNTI4NSA4OC43MDEgNDQuNjA5NyA4OC42NTk4IDQ0LjY4MTJDODguNjE4NSA0NC43NTI2IDg4LjU1ODkgNDQuODExOCA4OC40ODcyIDQ0Ljg1MjVMNzIuNzcxNCA1My43NjgzQzcyLjY5NzIgNTMuODExNCA3Mi42MTMzIDUzLjgzNDkgNzIuNTI3NSA1My44MzY3IiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjciIGQ9Ik03MC4yNTUzIDc1LjY1MTdDNzAuMTcxIDc1LjY1MzUgNzAuMDg3OCA3NS42MzE3IDcwLjAxNTEgNzUuNTg4OEw1NC4yNDU4IDY2LjY0MTdDNTQuMTcxNSA2Ni42MDI0IDU0LjEwOTUgNjYuNTQzNiA1NC4wNjYxIDY2LjQ3MTZDNTQuMDIyOCA2Ni4zOTk3IDU0IDY2LjMxNzMgNTQgNjYuMjMzM1Y0OC4yNzhDNTQgNDguMTA4IDU0LjA5MjQgNDcuOTU0NiA1NC4yNDM5IDQ3Ljg2OTZDNTQuMzE3MiA0Ny44MjcxIDU0LjQwMDQgNDcuODA0NyA1NC40ODUxIDQ3LjgwNDdDNTQuNTY5NyA0Ny44MDQ3IDU0LjY1MjkgNDcuODI3MSA1NC43MjYyIDQ3Ljg2OTZMNzAuNDkzNyA1Ni44MTMxQzcwLjU2NDIgNTYuODU2NSA3MC42MjI1IDU2LjkxNyA3MC42NjMyIDU2Ljk4OTFDNzAuNzAzOSA1Ny4wNjEyIDcwLjcyNTcgNTcuMTQyNCA3MC43MjY1IDU3LjIyNTFWNzUuMTgwNUM3MC43MjU5IDc1LjI2MjggNzAuNzA0MiA3NS4zNDM2IDcwLjY2MzUgNzUuNDE1MUM3MC42MjI3IDc1LjQ4NjYgNzAuNTY0MiA3NS41NDY0IDcwLjQ5MzcgNzUuNTg4OEM3MC40MjA2IDc1LjYyOTEgNzAuMzM4NyA3NS42NTA3IDcwLjI1NTMgNzUuNjUxNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC40IiBkPSJNNzQuNzE5OCA3NS42NTExQzc0LjYzMzMgNzUuNjUxMiA3NC41NDgyIDc1LjYyOTYgNzQuNDcyMiA3NS41ODgzQzc0LjQwMTYgNzUuNTQ2MSA3NC4zNDMyIDc1LjQ4NjIgNzQuMzAyNyA3NS40MTQ3Qzc0LjI2MjMgNzUuMzQzMSA3NC4yNDExIDc1LjI2MjIgNzQuMjQxMiA3NS4xOFY1Ny4zMzczQzc0LjI0MTIgNTcuMTcxIDc0LjMzMzYgNTcuMDE1OCA3NC40NzIyIDU2LjkyOUw5MC4yMzk3IDQ3Ljk4NTVDOTAuMzExOSA0Ny45NDM4IDkwLjM5MzggNDcuOTIxOSA5MC40NzcxIDQ3LjkyMTlDOTAuNTYwNSA0Ny45MjE5IDkwLjY0MjQgNDcuOTQzOCA5MC43MTQ2IDQ3Ljk4NTVDOTAuNzg3NiA0OC4wMjU1IDkwLjg0ODUgNDguMDg0MiA5MC44OTExIDQ4LjE1NTdDOTAuOTMzNyA0OC4yMjcyIDkwLjk1NjMgNDguMzA4OCA5MC45NTY2IDQ4LjM5MlY2Ni4yMzI4QzkwLjk1NyA2Ni4zMTY0IDkwLjkzNDcgNjYuMzk4NSA5MC44OTIxIDY2LjQ3MDRDOTAuODQ5NSA2Ni41NDI0IDkwLjc4ODEgNjYuNjAxNCA5MC43MTQ2IDY2LjY0MTFMNzQuOTUyNiA3NS41ODgzQzc0Ljg4MjUgNzUuNjMwNyA3NC44MDE4IDc1LjY1MjUgNzQuNzE5OCA3NS42NTExIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zNDU0IiB4MT0iMTYxIiB5MT0iMTgwIiB4Mj0iMy41OTI4NGUtMDciIHkyPSI0Ljk5OTk4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTk1NjU2Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNjg3XzM0NTQiPgo8cmVjdCB3aWR0aD0iOTQiIGhlaWdodD0iOTQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNSAyNSkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K
- keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "disks"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]]
+ keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "disks"], ["spec", "subnets"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]]
secrets:
exclude: []
include: []
From 023276ebabf7ec61ea355cee16cdfaa73c6adb18 Mon Sep 17 00:00:00 2001
From: nbykov0 <166552198+nbykov0@users.noreply.github.com>
Date: Mon, 27 Oct 2025 17:27:07 +0300
Subject: [PATCH 4/4] [apps] tenant: add vpcs to tenant roles
Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com>
---
packages/apps/tenant/templates/tenant.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/apps/tenant/templates/tenant.yaml b/packages/apps/tenant/templates/tenant.yaml
index d58c37d4..4fb19ef6 100644
--- a/packages/apps/tenant/templates/tenant.yaml
+++ b/packages/apps/tenant/templates/tenant.yaml
@@ -270,6 +270,7 @@ rules:
- vmdisks
- vminstances
- infos
+ - virtualprivateclouds
verbs:
- get
- list