Skip to content

feat(kubeovn): add OVN EIP/FIP/SNAT/DNAT, VIP, VPC DNS, Switch LB Rule (Phase 4)#180

Open
jniedergang wants to merge 11 commits intoharvester:masterfrom
jniedergang:upstream-kubeovn-phase4
Open

feat(kubeovn): add OVN EIP/FIP/SNAT/DNAT, VIP, VPC DNS, Switch LB Rule (Phase 4)#180
jniedergang wants to merge 11 commits intoharvester:masterfrom
jniedergang:upstream-kubeovn-phase4

Conversation

@jniedergang
Copy link

@jniedergang jniedergang commented Mar 6, 2026

Summary

Adds 7 new KubeOVN resources and data sources for OVN-level networking:

  • harvester_kubeovn_ovn_eip — OVN Elastic IP from external subnet
  • harvester_kubeovn_ovn_fip — OVN Floating IP (1:1 NAT)
  • harvester_kubeovn_ovn_snat_rule — OVN Source NAT
  • harvester_kubeovn_ovn_dnat_rule — OVN Destination NAT with port mapping
  • harvester_kubeovn_vip — Virtual IP for load balancer/HA
  • harvester_kubeovn_vpc_dns — VPC-scoped DNS resolution
  • harvester_kubeovn_switch_lb_rule — OVN switch-level load balancer rules

Ref: harvester/harvester#10148
Depends on: #176 (Phase 1), #178 (Phase 2), #179 (Phase 3)

Also filters ovn.kubernetes.io/ controller-managed labels in GetLabels() to prevent drift.

Note: This branch builds on #179 (Phase 3). Phase 4 specific commits are the last 2.

Related Issue

harvester/harvester#10148

Test plan

  • Unit tests: 14/14 pass (go test ./pkg/importer/ -run "TestResourceKubeOVN(OvnEip|OvnFip|OvnSnatRule|OvnDnatRule|Vip|VpcDns|SwitchLBRule)")
  • go build ./... — compilation passes
  • gofmt -l . — no formatting issues
  • Functional test on Harvester v1.7.1 (KubeOVN v1.14.10):
    • VIP: create → idempotence (0 changes) → destroy
    • VpcDns: create → idempotence → destroy
    • SwitchLBRule: create → idempotence → destroy
    • OVN EIP/FIP/SNAT/DNAT (requires 2nd physical NIC eno2):
      • Created 10 resources: ProviderNetwork, Vlan, VPC, 2 subnets (external + internal), 2 OVN EIPs, FIP, SNAT, DNAT
      • Idempotence: terraform plan shows 0 changes
      • terraform destroy — clean teardown (external subnet delete may need retry if EIP IPs still releasing)
    • Key findings: OVN EIP type field renamed to eip_type (Terraform SDK conflict); Harvester webhook requires name.namespace.ovn format for subnet provider

@mergify
Copy link

mergify bot commented Mar 6, 2026

This pull request is now in conflict. Could you fix it @jniedergang? 🙏

Terraform Provider Developer added 9 commits March 6, 2026 17:33
Add Terraform resource and data source for managing Harvester addons
(pcidevices-controller, nvidia-driver-toolkit, vm-import-controller,
harvester-seeder). Addons are pre-existing in Harvester and cannot be
created or deleted via the API - Create enables/configures the addon,
Delete disables it.

Schema fields:
- enabled (bool): enable/disable the addon
- values_content (string): Helm values YAML configuration
- repo, chart, version (computed): read-only addon metadata
- state (computed): addon deployment status

Includes unit tests for the importer with coverage for enabled,
disabled, and nil labels/annotations cases.

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
Add Phase 1 core networking support for KubeOVN SDN addon:

- Add kube-ovn v1.13.0 typed client to pkg/client
- harvester_kubeovn_vpc: resource + datasource for OVN virtual private clouds
  with static routes, policy routes, namespace binding
- harvester_kubeovn_subnet: resource + datasource for OVN subnets with
  CIDR, gateway, DHCP, NAT, LB, private/allow controls
- harvester_kubeovn_ip: datasource for reading pod IP assignments
- Unit tests for all three importers
- Terraform examples for all resources and datasources

All resources are cluster-scoped (NonNamespacedSchemaWrap) matching
KubeOVN CRD definitions. Requires kubeovn-operator addon to be enabled.

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
- Rename subnet `provider` field to `network_provider` to avoid
  Terraform reserved field name conflict
- Make VPC static_routes `policy` field Computed (KubeOVN server sets
  default `policyDst`), add `policyDst` to validation
- Add retry loop to VPC delete to handle subnet cleanup race condition
  (KubeOVN webhook rejects VPC deletion while subnets still exist)

Tested on Harvester v1.6.1 with KubeOVN v1.13.13:
- Create VPC + Subnet: OK
- Idempotence (0 changes): OK
- Update in-place: OK
- Destroy (subnet before VPC): OK
- Datasources read: OK

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
Add 5 KubeOVN NAT Gateway resources for external connectivity from VPCs:
- harvester_kubeovn_vpc_nat_gateway: VPC NAT Gateway with delete retry
- harvester_kubeovn_iptables_eip: Elastic IP with ForceNew on nat_gw_dp
- harvester_kubeovn_iptables_snat_rule: Source NAT rule
- harvester_kubeovn_iptables_dnat_rule: Destination NAT rule with protocol
- harvester_kubeovn_iptables_fip_rule: Floating IP rule

Each resource includes: schema, constructor, CRUD, datasource, importer
with unit tests, and TF examples. All cluster-scoped via
NonNamespacedSchemaWrap. Status fields prefixed with status_ to avoid
collisions with spec fields.

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
Run `go generate` to produce tfplugindocs for the 5 new NAT resources
and their data sources.

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
…SecurityGroup, QoSPolicy)

Add 5 new KubeOVN resources with full CRUD, datasources, importers,
unit tests, examples, and generated docs:

- harvester_kubeovn_ippool: IP address pool management with namespace
  scoping and IPv4/IPv6 availability status
- harvester_kubeovn_vlan: VLAN management with provider network binding
  and retry-on-delete for dependent resources
- harvester_kubeovn_provider_network: Physical network interface mapping
  with custom per-node interfaces and node exclusion
- harvester_kubeovn_security_group: Network security rules with ingress/
  egress rule blocks supporting address and security group remote types
- harvester_kubeovn_qos_policy: Quality of Service policies with
  bandwidth limit rules for EIP and NAT Gateway bindings

All resources are cluster-scoped and use the existing KubeOVN v1.13.0
typed client. No dependency changes required.

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
KubeOVN v1.14 webhook rejects Vlan creation without spec.provider.
Update schema from Optional to Required and constructor accordingly.

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
…s (Phase 4)

Add 7 new KubeOVN resources for OVN-level networking:
- harvester_kubeovn_ovn_eip: OVN Elastic IP
- harvester_kubeovn_ovn_fip: OVN Floating IP
- harvester_kubeovn_ovn_snat_rule: OVN SNAT Rule
- harvester_kubeovn_ovn_dnat_rule: OVN DNAT Rule
- harvester_kubeovn_vip: Virtual IP
- harvester_kubeovn_vpc_dns: VPC DNS
- harvester_kubeovn_switch_lb_rule: Switch LB Rule

Each resource includes schema, constructor, CRUD operations, datasource,
importer with unit tests, examples, and generated documentation.

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
KubeOVN controller adds labels with the ovn.kubernetes.io/ prefix
(e.g. ip_reserved, subnet) to VIP resources. These controller-managed
labels caused idempotence drift on subsequent plan/apply cycles.
Filter them in GetLabels alongside existing harvesterhci.io/ filters.

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
@jniedergang jniedergang force-pushed the upstream-kubeovn-phase4 branch from f461b14 to c956a43 Compare March 6, 2026 16:34
Extract assertStringSlice helper to reduce cyclomatic complexity
flagged by CodeFactor.

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
@jniedergang jniedergang changed the title feat(kubeovn): add OVN EIP/FIP/SNAT/DNAT, VIP, VPC DNS, Switch LB Rule resources feat(kubeovn): add OVN EIP/FIP/SNAT/DNAT, VIP, VPC DNS, Switch LB Rule (Phase 4) Mar 6, 2026
…m SDK conflict

Signed-off-by: Terraform Provider Developer <terraform@harvester.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant