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] [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: []