Skip to content

feat(vpc,kubernetes): back VPC subnets with Proxmox VLANs - #4813

Draft
Marian Koreniuk (themoriarti) wants to merge 7 commits into
cozystack:mainfrom
themoriarti:feat/proxmox-vpc-network
Draft

Marian Koreniuk (themoriarti) wants to merge 7 commits into
cozystack:mainfrom
themoriarti:feat/proxmox-vpc-network

Conversation

@themoriarti

@themoriarti Marian Koreniuk (themoriarti) commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

What this PR does

Part of #3481. Design proposal: cozystack/community#93 (on hold).

Status: reference implementation, not for merge in this form. The first step is the smaller design in cozystack/community#104, implemented in #5047: static zones, namespaced IP pools and admission, with no controller and no writes to the OVN database. This PR stays open as a draft so the controller, the egress gateway and the OVN gateway handling can be read next to it. It is rebased on main of 2026-11-06 (cb3fcd335).

This is the networking piece for Proxmox-backed tenant clusters, on top of the provisioning layer that #4087, #4483, #4088 and #4089 put in main. It is opened as a draft so that the proposal can be discussed first; the decision on Proxmox as a supported platform stays in #3481.

A tenant can extend a subnet of its VPC onto Proxmox VE by adding proxmox: {} to the subnet, and put Proxmox VMs on it, the workers of a Proxmox-backed Kubernetes cluster included. The subnet becomes a VLAN-backed logical switch of the tenant's own VPC router: VMs and pods on it are L2 neighbours, the router port is the VMs' gateway, and the VPC's isolation covers the VMs too. The platform picks the VLAN, the bridge and the IP pool, and the tenant cannot set them. Until now a Proxmox-backed cluster needed a raw bridge, VLAN tag and address range from the admin, outside any VPC, and admission had no way to tell a tenant's own VLAN from someone else's.

The owner of every object, lifecycle, failure handling, the security model and operations are in docs/proxmox-networking.md.

  • API proxmox.cozystack.io/v1alpha1: ProxmoxNetworkZone (cluster-scoped, owned by the admin: bridge, Kube-OVN ProviderNetwork, VLAN range, transit network for egress) and ProxmoxNetwork (one VLAN request for one subnet, rendered by the vpc chart).
  • Controller proxmox-network-controller: allocates a Kube-OVN Vlan from the zone's range and names it after the Subnet, so a restart recovers every allocation instead of allocating again; holds the Vlan, the Subnet and the IP pool with finalizers until no VM holds an address; puts each Proxmox-backed router port into an OVN HA_Chassis_Group (see below); annotates each namespace with its ready networks for admission; collects orphaned Vlans; exports cozy_proxmox_* metrics.
  • Package packages/system/proxmox-network (and proxmox-network-crds, installed first): opt-in in the iaas bundle with bundles.enabledPackages: [cozystack.proxmox-network], which also enables the in-cluster IPAM provider. It ships the controller, its RBAC, the trunk ProviderNetwork, the zones, a transit network whose ACL keeps the egress gateways of different VPCs apart, ValidatingAdmissionPolicies, alerts and a read-only role that lets a tenant see its own networks.
  • vpc: subnets[].proxmox (zone, vmRange) and egress (enabled, replicas, internalCidr): a VpcEgressGateway that SNATs traffic leaving the VPC onto the zone's transit network. VM addresses come from one namespaced InClusterIPPool over vmRange, which is excluded from Kube-OVN, so a pod and a VM never get the same address.
  • kubernetes: proxmox.network.{vpc,subnet} instead of proxmox.ipv4Config. kubernetes-nodes: proxmox.network.{vpc,subnet} for net0 and proxmox.additionalNetworks[] for more NICs. The charts read the subnet's ProxmoxNetwork and give capmox the bridge, the VLAN and an ipv4PoolRef, so every worker address comes from the subnet's pool. A raw bridge/vlan next to a subnet is refused.
  • E2E, two Chainsaw suites:
    • hack/e2e-chainsaw/proxmox-network runs in the regular lanes and needs no hypervisor. The e2e nodes have one NIC, so its provider network selects no node and every network stops at NoTrunkNodes, which still shows that the controller reached the OVN NB and found the router port. It covers the package and CRDs, VLAN allocation, exhaustion and release, the Kube-OVN objects and the localnet tag, a network held while an address is in use, and admission of pods and KubeVirt VMs, each refusal next to an admitted control. hack/select-e2e.sh maps the package to the suite, and runs that do not select it disable the package again.
    • hack/e2e-chainsaw/proxmox-network-env needs Proxmox VE with trunk NICs, a zone bridge and a transit router. It ships as chainsaw-test.yaml.disabled, like kubernetes-proxmox, and is run by hand (see its README.md); every environment detail comes from COZY_PXNET_* variables.

The commits can be reviewed one by one. The first is an independent fix, listed separately in the proposal; it can move to a separate PR if that is preferred:

  • fix(vpc): each end of a VPC peering gets a /30. Kube-OVN parses localConnectIP as a CIDR and fails the whole Vpc reconcile, routes included, on a bare address.

Changes that reach existing installations

  • vpc, every VPC: a static route's nextHopIP must lie inside one of the VPC's subnets, or in 169.254.0.0/16 when peers are declared. A VPC with a next hop elsewhere stops rendering after the upgrade with route to <cidr>: next hop <ip> is outside every subnet of this VPC. A next hop on the shared transit network would otherwise hand a VPC's traffic to another VPC's egress gateway.
  • vpc, every peering: localConnectIP now carries /30 (the fix(vpc) commit).
  • Only with the package enabled: the attachment policies hold in every namespace outside cozy-*, kube-system, the package namespace, the egress gateway namespaces and admission.exemptNamespaces. A pod or a KubeVirt VM may attach only NetworkAttachmentDefinitions and Kube-OVN subnets of its own namespace, and a *.kubernetes.io/logical_switch pin other than the namespace's default switch is refused on CREATE, so a copy of a running pod that keeps Kube-OVN's annotations (kubectl debug --copy-to, a restored backup) is refused as well. admission.vmNetworkNamespace and admission.podNetworkNamespace switch them off.

The controller writes to the OVN northbound database

Kube-OVN drops ARP that arrives from a localnet port for the IP of a distributed router port, so a VM outside the cluster never resolves its gateway. Making the router port a gateway port with an HA_Chassis_Group of the zone's trunk nodes removes that drop. Kube-OVN has no field for it, so the controller manages one group per Proxmox-backed router port, px-<port>, with external_ids owner=proxmox-network and network=<namespace>/<name>. It refuses a group another owner has marked, removes the group before it frees the VLAN, and reports GatewayReady and cozy_proxmox_network_gateway_*. It connects with Kube-OVN's client certificate, read through the API with a Role limited by resourceNames, and writes through the Service that selects the RAFT leader. The groups are keyed by VPC, so every Proxmox-backed port of one VPC is active on the same chassis: with the ports of one VPC on different chassis, the path to the egress gateway crossed Geneve, where Cilium's kube-proxy replacement rewrote traffic to a LoadBalancer IP. --manage-gateway-chassis=false turns it off. This is meant to go away once Kube-OVN sets the group for such subnets itself; that change has not been proposed to Kube-OVN yet.

Known limits

  • Between two VPCs' Proxmox-backed subnets there is no drop inside OVN yet. Isolation holds because each VPC has its own router and VLAN, and the transit router the admin runs outside the cluster forwards only to the LoadBalancer range, DNS, NTP and the Internet. That router alone carries the L3 boundary between VPCs (docs/proxmox-networking.md §8, §10, §12 question 9; an open question of the proposal).
  • VMs run at the zone MTU next to overlay pods at 1400 with no gateway_mtu, so a full-size DF packet from a VM to an overlay pod is dropped silently.
  • A reply from an overlay pod on a node without the trunk reaches the VLAN switch on a chassis with no bridge mapping. It was predicted to fail and passed in the run below, without an explanation yet, so the suite still reports it as an open check.
  • Deleting a VPC may delete its router while the held Subnets stay.
  • Chassis failover and VPC peering with Proxmox-backed subnets have not been exercised on a live cluster.
  • IPv4 only. No inbound path (EIP/DNAT) to a VM and no ClusterIP access from VMs. capmox and the CCM still use one Proxmox API token for every tenant.
  • Neither Chainsaw suite has run on a cluster yet. The fork e2e lane cannot run the CI suite for this PR: Plan build refuses a fork PR that adds an image (hack/fork-new-images.sh, docs/agents/e2e-testing.md section 10), and this PR adds proxmox-network-controller. The environment suite is a port of the shell suite that produced the results below.

How this was tested

On this branch, rebased on main (cb3fcd335). The Proxmox CCM fix that used to be the first commit reached main through #4917 and has left the branch.

  • make unit-tests test-controllers: the Go targets (go-unit-tests, go-module-tests, test-controllers, test-check-readiness, test-backport-audit, rd-presets-check, migrations-target-check), helm-unit-tests and bats-posix-compat-tests pass; go-module-tests with GOTOOLCHAIN=go1.27.1, since the host's own Go is older than the nested modules require. bats-unit-tests did not run: bats-core is not installed on this host.
  • helm-unittest for the touched charts: vpc 32, kubernetes 371, kubernetes-nodes 253, proxmox-network 34, proxmox-network-crds 1, platform 289, all passing.
  • go test -race for ./internal/proxmoxnetworkcontroller/..., ./api/proxmox/..., ./cmd/proxmox-network-controller/... and the api/apps/v1alpha1 module, against a fake OVN NB for the gateway. go vet, gofmt and go build ./... are clean.
  • CRDs, deepcopy and cozyvalues-gen output are in sync. The one diff a local cozyvalues-gen leaves, x-cozystack-name in the kubernetes schema, is the same on main.
  • chainsaw lint test on both suites; bash -n and shellcheck on the suite helper; the guard suites chainsaw-leak-guard_test, chainsaw-op-budgets, bats-runner-coverage, platform-packages_test (with a new test for the opt-in package), run-kubernetes-install-wait_test, select-e2e_test and select-install_test; hack/check-commit-trailers.sh on the range.

End to end, the shell form of the environment suite ran on a two-host Proxmox VE 9 cluster (a VLAN-aware bridge whose tenant VLANs ride inside one outer VLAN between the hosts, MTU 9000) next to a Talos management cluster running Kube-OVN v1.15.10 with Cilium's kube-proxy replacement, capmox v0.7.7 and in-cluster IPAM v1.0.3. Two tenants, each with a VPC of two Proxmox-backed subnets and one overlay subnet, and a Proxmox-backed Kubernetes cluster per tenant whose worker has net0 on one subnet (and, for tenant A, net1 on the other):

Phases Result
preflight, vpc, control, datapath 87/89 ok, 0 failed, 2 open checks
VM reachability from simulated VMs on the hypervisors (not in this PR) 41 cells, 0 failed, 3 open, 2 skipped
capi 34/40 ok, 0 failed, 3 open, 3 skipped
resilience, lifecycle, teardown 30/31 ok, 0 failed, 1 open

The open checks are the known limits above; the skipped ones are cells that topology could not exercise, such as the gateways of two VPCs on different chassis. The resilience phase restarts the controller and kube-ovn-cni and stops capmox during scaling with no change to any allocation; the lifecycle phase deletes a VPC under live VMs (the Vlan, the Subnet and the pool stay held) and then the cluster, after which VLANs, pools, subnets, addresses, OVN groups and the namespace annotation are all gone. main now ships Kube-OVN v1.15.26, so the gateway checks have to be repeated on it.

Screenshots

No UI change.

Downstream repositories

Walking the trigger map against this diff, three repositories are reached: the proposal, the website and the Terraform provider. The website follow-up is a draft PR until this one is decided; the provider pins released API types, so its follow-up is an issue until a tagged release carries these fields.

Release note

feat(vpc,kubernetes): a VPC subnet can be backed by a Proxmox VLAN (`subnets[].proxmox`), and Proxmox-backed Kubernetes clusters and node pools can place their workers on such a subnet (`proxmox.network.vpc`/`subnet`, `proxmox.additionalNetworks`) instead of a raw bridge and address range. VLANs, bridges and IP pools come from the new opt-in `cozystack.proxmox-network` package (`ProxmoxNetworkZone`, `ProxmoxNetwork`). VPC egress for these subnets goes through a VpcEgressGateway (`egress.enabled`). Every VPC now refuses a static route whose next hop lies outside its subnets, and VPC peering link addresses carry their /30.

Assisted-by: LLM

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions github-actions Bot added area/kubernetes Issues or PRs related to the tenant Kubernetes app area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) kind/feature Categorizes issue or PR as related to a new feature size/XXL This PR changes 1000+ lines, ignoring generated files labels Oct 7, 2026
MinVersion: tls.VersionTLS12,
Certificates: []tls.Certificate{cert},
// The chain is verified below, without a host name.
InsecureSkipVerify: true, // #nosec G402
@themoriarti

Copy link
Copy Markdown
Collaborator Author

Status update: following the review in cozystack/community#93, the design is split in two.

This draft stays open for reference only and does not need review.

@themoriarti

Copy link
Copy Markdown
Collaborator Author

The implementation of cozystack/community#104 is open as #5047: the platform-owned bridge, VLANs and IP pools with the admission policies, no controller, no OVN. This draft stays open for reference only and does not need review.

Kube-OVN parses Vpc.spec.vpcPeerings[].localConnectIP as a CIDR
(util.CheckCidrs). A bare address fails that check, and the error
aborts the whole Vpc reconcile, so a peered VPC also stops applying
its static and policy routes. Both ends already take neighbouring
addresses of one /30; writing the prefix makes them parse.

Assisted-by: LLM
Signed-off-by: Marian Koreniuk <[email protected]>
A Proxmox VM can join a VPC subnet only if the subnet's logical switch
reaches the hypervisors on a VLAN. Something has to pick that VLAN,
keep two subnets from sharing it, and keep it until the last VM on the
subnet has given its address back. Helm cannot do any of that: it has
no allocator, and deleting a release would take the Vlan away from
VMs that still use it.

ProxmoxNetworkZone is the admin's side (bridge, Kube-OVN
ProviderNetwork, VLAN range, transit for egress); ProxmoxNetwork is one
request for one subnet. The controller names the Kube-OVN Vlan after
the Subnet, so after a restart it finds every allocation in the
cluster instead of allocating again, and it holds the Vlan, the Subnet
and the IP pool with finalizers until the pool has no address in use.

Kube-OVN drops ARP that arrives from a localnet port for the IP of a
distributed router port, so a VM outside the cluster never resolves
its gateway. Until Kube-OVN can do this itself, the controller puts the
router port of each Proxmox-backed subnet into an HA_Chassis_Group of
the zone's trunk nodes. The group is keyed by VPC, so every such port
of one VPC is active on the same chassis and the path to the VPC's
egress gateway never crosses Geneve, where Cilium's kube-proxy
replacement rewrote LoadBalancer traffic. It writes to the OVN NB
with Kube-OVN's own client certificate, read through the API, and
refuses a group whose external_ids name another owner.

The Kube-OVN and IPAM types are mirrored with only the fields read
here, so this module does not take on their k8s.io dependencies.

Assisted-by: LLM
Signed-off-by: Marian Koreniuk <[email protected]>
capmox takes any bridge and VLAN tag a ProxmoxMachine names, and Multus
resolves an attachment in whatever namespace its name carries. Without
admission a tenant who may create machines, VMs or pods could put a NIC
on another tenant's VLAN or on the transit network every egress
gateway shares. The package therefore ships ValidatingAdmissionPolicies
next to the controller: a Proxmox NIC on a zone bridge must be one of
its own namespace's networks, and a KubeVirt VM or a pod may attach
only networks of its own namespace.

The CRDs are a separate component installed first, so the zones in the
package's values render on the first install rather than on a later
re-render that Flux never performs. The package also carries the trunk
ProviderNetwork, the zones and their transit network with an ACL that
keeps the egress gateways of different VPCs apart, metrics, alerts,
and a read-only role that lets a tenant see its own networks.

It is opt-in in the iaas bundle for the same reason capmox is: nothing
works until the hypervisors and the nodes carry the trunk. It brings
the in-cluster IPAM provider along, because the VM addresses of every
Proxmox-backed subnet live in an InClusterIPPool. The image is in the
root build list, so the build stamps its reference like every other
first-party image.

Assisted-by: LLM
Signed-off-by: Marian Koreniuk <[email protected]>
Proxmox VMs, the workers of a Proxmox-backed Kubernetes cluster among
them, have so far lived on a raw bridge and an address range handed
out by the admin, outside any VPC. With subnets[].proxmox the tenant
puts them on a subnet of its own VPC instead: the subnet becomes a
VLAN-backed logical switch of the VPC's router, the router port is the
VMs' gateway, and VMs and pods on the subnet are L2 neighbours. The
VLAN, bridge and pool come from the platform and the tenant cannot set
them.

VM addresses come from one namespaced InClusterIPPool over vmRange,
and the same range is excluded from Kube-OVN, so pods and VMs never
get the same address. The pool skips the IPAM provider's delete
webhook: that webhook refuses a pool with addresses in use, which left
helm uninstall stuck half way, while the provider's finalizer already
holds the pool until the last address is released.

A VM outside the cluster has no node to masquerade through, so
egress.enabled adds a VpcEgressGateway that SNATs traffic leaving the
VPC onto the zone's transit network; a route narrower than 0.0.0.0/0,
such as one to a peered VPC, keeps its next hop. A static route's next
hop must now lie inside the VPC or on a peering link: one on the
shared transit network would hand the VPC's traffic to another VPC's
egress gateway. A Proxmox-backed subnet cannot be turned back into an
overlay subnet in place, nor dropped while VMs hold addresses on it,
because Kube-OVN would delete the logical switch under them.

Assisted-by: LLM
Signed-off-by: Marian Koreniuk <[email protected]>
A Proxmox-backed cluster had to be given a raw bridge, a VLAN tag and
an address range, values the tenant has to get from the admin and that
admission cannot tell apart from someone else's. proxmox.network.vpc
and .subnet name a Proxmox-backed subnet of the tenant's own VPC
instead. The charts read the subnet's ProxmoxNetwork in the release
namespace and give capmox its bridge, VLAN and InClusterIPPool, so
every worker address comes from the subnet's pool. A pool can add more
NICs the same way with proxmox.additionalNetworks.

A raw bridge or vlan next to a subnet is refused rather than merged:
it would either be ignored or override the platform's allocation, and
overriding it is how a tenant would reach a VLAN that is not its own.

capmox v0.7 refuses a ProxmoxCluster without ipv4Config and builds a
pool from it. For a VPC-backed cluster that pool holds only the
gateway, which the IPAM provider never hands out, so a machine without
a pool reference waits instead of taking an address the subnet's pool
may also hand out.

The lookup lives in cozy-lib so both charts fail with the same message
when the subnet has no ProxmoxNetwork or it is not Ready yet.

Assisted-by: LLM
Signed-off-by: Marian Koreniuk <[email protected]>
Unit and chart tests cannot show how the controller, the vpc chart,
Kube-OVN and admission behave together, and part of it exists only on
a real hypervisor: the inner VLAN tag surviving the uplink, the VPC
router port answering ARP from outside the cluster, a CAPI worker
joining through the egress gateway, and isolation between tenants at
the VM level.

proxmox-network runs in the regular lanes. The e2e cluster has no
Proxmox and no spare NIC, so its provider network selects no node: the
zone stays not Ready and every network stops at NoTrunkNodes, which
still shows that the controller reached the OVN NB and found the
router port. The suite installs the vpc chart from the checkout with
--wait=false, because the application's release would wait on a
network that cannot become Ready there. It checks VLAN allocation,
exhaustion and release, the Vlan, Subnet, pool and OVN localnet tag, a
network held while an address on it is in use, and admission of pods
and KubeVirt VMs by server-side dry run, each refusal next to an
admitted control. The platform install enables the opt-in package;
a run that does not select the suite disables it again through the
selector's complement.

proxmox-network-env needs a Cozystack cluster on Proxmox VE with trunk
NICs, a zone bridge and a transit router, so it ships as
chainsaw-test.yaml.disabled like kubernetes-proxmox and is run by hand.
Its phases live in _lib/run-proxmox-network.sh and take every detail of
the environment from COZY_PXNET_* variables. Every isolation check is
paired with a positive control, so a check cannot pass only because the
path under test is broken altogether, and the design's open questions
are reported without failing the suite.

Assisted-by: LLM
Signed-off-by: Marian Koreniuk <[email protected]>
The feature spans the vpc, kubernetes and kubernetes-nodes charts, a
new controller, Kube-OVN, capmox, the in-cluster IPAM provider and the
hypervisors, and its contract with the admin (trunk, zone, transit)
lives in none of them. The document records the ownership of every
object, the lifecycle and failure handling, the security model,
operations, the questions a live run on Proxmox VE left open, and a
phased plan for Proxmox SDN. It points to the design proposal in
cozystack/community and to cozystack#3481, where Proxmox as a platform is
discussed.

Assisted-by: LLM
Signed-off-by: Marian Koreniuk <[email protected]>
Aleksei Sviridkin (lexfrei) added a commit that referenced this pull request Nov 13, 2026
<!-- Thank you for making a contribution! Here are some tips for you:
- Use Conventional Commits for the PR title: `type(scope): description`
- Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore
- Scopes are not an exhaustive list — pick the most specific scope for
the change and extend the list when a genuinely new area appears.
Examples:
- System components: dashboard, platform, operator, cilium, kube-ovn,
linstor, fluxcd, cluster-api
- Managed apps: postgres, mariadb, redis, kafka, clickhouse,
virtual-machine, kubernetes
- Development and maintenance: api, hack, tests, ci, docs, maintenance
- Breaking changes: append `!` after type/scope (`feat(api)!: ...`) or
add a `BREAKING CHANGE:` footer
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `kind/backport` if it's a bugfix that needs to be
backported to a previous version.
-->

## What this PR does

`packages/apps/vpc/Makefile` is the only app Makefile that calls
`cozyvalues-gen` without `-r README.md`, and it has been that way since
the app was added, so the README's Parameters table was hand-written and
never regenerated. It still documents `subnets` as `map[string]object`
and omits `peers` and `routes`, and the README example uses the map
form, which `values.schema.json` rejects since #2052 made `subnets` a
list. That README is also the source of the website's VPC reference
page, so the published example is the invalid one.

This adds `-r README.md`, regenerates the table with cozyvalues-gen
v1.7.0 (the version CI uses), and rewrites the example as a list. `make
generate` in `packages/apps/vpc` leaves the CRD and Go types unchanged,
and the new example validates against the VPC `openAPISchema`. The draft
#4813 edits this `values.yaml`, so once this lands its `make generate`
will update the README as well.

### Screenshots

<!-- REQUIRED for UI changes: attach screenshots or screen recordings
demonstrating
the visual impact of your changes. PRs with UI changes without
screenshots will not be merged. -->

### Downstream repositories

<!--
Cozystack is upstream for repositories that are NOT kept in sync with it
automatically, and nothing in CI compares the two sides, so a change
here can break them silently.

Which change forces what, and which file to touch, is the trigger map in
docs/agents/contributing.md under "Downstream Repositories". Walk it
before you tick anything.

IF YOU ARE AN AI AGENT OR AN LLM, THIS IS PART OF THE TASK, NOT A FORM
TO FILL IN:

1. Walk the trigger map against the actual diff of this PR, file by
file. Do not decide from the PR title or from your memory of what you
changed.
2. For every repository you tick, open the follow-up PR there and link
it on the same line. A ticked box with no link claims work that does not
exist, which is worse than an empty box. Search that repository for an
open PR or issue covering it first, and link that instead of filing a
duplicate.
3. When the follow-up is out of scope, or needs a decision that is not
yours to make, open an issue in that repository instead, link that, and
say so in the PR body. Do not push a speculative PR into another
repository just to fill a line here.
4. Do not tick "No downstream repository is affected" to make the
checklist go away. If you are unsure, leave every box empty and say so
in the PR body, so a human decides.
-->

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

The website's VPC page is regenerated from this README by the release
bot, so it needs no separate change.

### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same `type(scope):` prefix as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
docs(vpc): document subnets, peers and routes in the VPC README as the list-based parameters the chart accepts.
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Updated the VPC configuration guide to describe subnet entries,
including names, CIDR ranges, and optional allowed source ranges.
* Added guidance for configuring VPC peers with a remote VPC name and
tenant namespace, and routes with a destination range and next-hop IP.
  * Revised the subnet example to use a list of named entries.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/kubernetes Issues or PRs related to the tenant Kubernetes app area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) area/proxmox Issues or PRs related to Proxmox and related components, including CAPMOX and Proxmox CSI. kind/feature Categorizes issue or PR as related to a new feature size/XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants