Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5efb8ca
Add extra host variables to variables.yaml
pmtk Apr 22, 2026
00ff01c
Multi cluster keywords
pmtk Apr 22, 2026
2898697
c2cc sanity test
pmtk Apr 22, 2026
dda675d
Init C2CC Route Manager
pmtk Apr 22, 2026
cf6866e
Vendor libovsdb & knftables
pmtk Apr 24, 2026
d5216b0
Routes controller
pmtk Apr 24, 2026
9aad82c
Service Routes Controller
pmtk Apr 24, 2026
e215be9
NBDB
pmtk Apr 24, 2026
72dd158
OVN-K controller
pmtk Apr 24, 2026
98a24cd
nftables controller
pmtk Apr 24, 2026
2324c74
Node annotation controller
pmtk Apr 24, 2026
4638ea6
default NetworkPolicy controller
pmtk Apr 24, 2026
7a0e9c8
Integrate sub-controllers
pmtk Apr 24, 2026
47b9edd
Cleanup on reconcile failure
pmtk Apr 24, 2026
a668f1c
Subscribe to events to retrigger reconciliation
pmtk Apr 24, 2026
97fe31c
Refactor common parts for routes
pmtk Apr 24, 2026
79554f2
routes: remove LinkIndex so kernel can resolve nexthop via main table
pmtk Apr 27, 2026
3d79493
Infra Test Suite
pmtk Apr 27, 2026
c463a56
Connectivity Test Suite
pmtk Apr 27, 2026
467dfcd
Inject network config before installation
pmtk Apr 27, 2026
331506c
Test: wait on greenboot before enabling c2cc
pmtk Apr 27, 2026
cb25307
Don't rollback on failure
pmtk Apr 28, 2026
4172943
Address local CR review
pmtk Apr 28, 2026
913ae39
Add negative tests for reconciliation
pmtk Apr 28, 2026
9000560
Debounce 'nftables-change' log
pmtk Apr 28, 2026
1094edf
CR fixes
pmtk Apr 29, 2026
3188ea9
Filter annotation subscribe to SNAT annotation changes only
pmtk Apr 29, 2026
ec33707
Add context to nftables subscribe for explicit shutdown
pmtk Apr 29, 2026
d3f3321
Drain reconcile channel to coalesce queued events
pmtk Apr 29, 2026
8e59bc6
Apply CodeRabbit suggestions from PR #6599
pmtk Apr 30, 2026
625d5d7
self review
pmtk Apr 30, 2026
305e342
Merge/subtract SNAT annotation CIDRs instead of owning the whole value
pmtk Apr 30, 2026
41e3ab2
Add E2E tests for C2CC cleanup on disable
pmtk Apr 30, 2026
43b3bd9
Check OVSDB per-operation errors in OVN cleanup
pmtk Apr 30, 2026
22dbfdd
Use copy_file_from_vm for IPv6-safe kubeconfig fetch
pmtk Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/openshift/build-machinery-go v0.0.0-20251023084048-5d77c1a5e5af
github.com/openshift/client-go v0.0.0-20260306160707-3935d929fc7d
github.com/openshift/library-go v0.0.0-20260303171201-5d9eb6295ff6
github.com/ovn-kubernetes/libovsdb v0.8.2-0.20260302130604-c07ce22366ac
github.com/pkg/errors v0.9.1 // indirect
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
Expand All @@ -21,10 +22,12 @@ require (
golang.org/x/sys v0.42.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/kube-openapi v0.0.0-20260304202019-5b3e3fdb0acf
sigs.k8s.io/knftables v0.0.20
sigs.k8s.io/yaml v1.6.0
)

require (
github.com/cenkalti/backoff/v4 v4.3.0
github.com/coreos/go-systemd/v22 v22.7.0
github.com/evanphx/json-patch v4.12.0+incompatible
github.com/fsnotify/fsnotify v1.9.0
Expand Down Expand Up @@ -68,6 +71,8 @@ require (
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/cenkalti/hub v1.0.2 // indirect
github.com/cenkalti/rpc2 v1.0.5 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/container-storage-interface/spec v1.9.0 // indirect
github.com/containerd/containerd/api v1.9.0 // indirect
Expand All @@ -86,6 +91,7 @@ require (
github.com/felixge/fgprof v0.9.4 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-ldap/ldap/v3 v3.4.11 // indirect
Expand All @@ -106,6 +112,9 @@ require (
github.com/go-openapi/swag/stringutils v0.25.5 // indirect
github.com/go-openapi/swag/typeutils v0.25.5 // indirect
github.com/go-openapi/swag/yamlutils v0.25.5 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.28.0 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
Expand All @@ -121,6 +130,7 @@ require (
github.com/jonboulle/clockwork v0.5.0 // indirect
github.com/karrick/godirwalk v1.17.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/libopenstorage/openstorage v1.0.0 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect
Expand Down
22 changes: 22 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,14 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/cenkalti/hub v1.0.2 h1:Nqv9TNaA9boeO2wQFW8o87BY3zKthtnzXmWGmJqhAV8=
github.com/cenkalti/hub v1.0.2/go.mod h1:8LAFAZcCasb83vfxatMUnZHRoQcffho2ELpHb+kaTJU=
github.com/cenkalti/rpc2 v1.0.5 h1:T6l4SS3ja3eaJfRyZrn7Oco/PSx/pr3YK5cjCgLVLTk=
github.com/cenkalti/rpc2 v1.0.5/go.mod h1:2yfU5b86vOr16+iY1jN3MvT6Kxc9Nf8j5iZWwUf7iaw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
Expand Down Expand Up @@ -107,6 +113,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=
github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
Expand Down Expand Up @@ -160,6 +168,14 @@ github.com/go-openapi/testify/enable/yaml/v2 v2.4.0 h1:7SgOMTvJkM8yWrQlU8Jm18VeD
github.com/go-openapi/testify/enable/yaml/v2 v2.4.0/go.mod h1:14iV8jyyQlinc9StD7w1xVPW3CO3q1Gj04Jy//Kw4VM=
github.com/go-openapi/testify/v2 v2.4.0 h1:8nsPrHVCWkQ4p8h1EsRVymA2XABB4OT40gcvAu+voFM=
github.com/go-openapi/testify/v2 v2.4.0/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
Expand Down Expand Up @@ -244,6 +260,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/libopenstorage/openstorage v1.0.0 h1:GLPam7/0mpdP8ZZtKjbfcXJBTIA/T1O6CBErVEFEyIM=
github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
Expand Down Expand Up @@ -315,6 +333,8 @@ github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251120221002-696928a6a0d7/go.mod
github.com/openshift/route-controller-manager v0.0.0-20260211095309-624742d93f3a h1:jBmugEVHpoRmyNBFb7ZBLeurE5+snu9NXS6bf57iiqA=
github.com/openshift/route-controller-manager v0.0.0-20260211095309-624742d93f3a/go.mod h1:KNxrLlGIh4j2iUAOax5Y9f5rN3vIo8w9QTGKHEQlvFo=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/ovn-kubernetes/libovsdb v0.8.2-0.20260302130604-c07ce22366ac h1:D7Ex9/u5HMz+xvqel1RCCO1AxVG7XRAx9AcP02/nyzk=
github.com/ovn-kubernetes/libovsdb v0.8.2-0.20260302130604-c07ce22366ac/go.mod h1:x2keWyG0K1WmZeZLRh+z4fWwcqp99Yu9/HAiMucj5D0=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
Expand Down Expand Up @@ -530,6 +550,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/knftables v0.0.20 h1:eU2NWpgcJ/wgb4Fy0cX3klK6nDjERvZRdYgkORLU0Tc=
sigs.k8s.io/knftables v0.0.20/go.mod h1:f/5ZLKYEUPUhVjUCg6l80ACdL7CIIyeL0DxfgojGRTk=
sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I=
sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM=
sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78=
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/openshift/microshift/pkg/admin/prerun"
"github.com/openshift/microshift/pkg/config"
"github.com/openshift/microshift/pkg/controllers"
"github.com/openshift/microshift/pkg/controllers/c2cc"
"github.com/openshift/microshift/pkg/gdp"
"github.com/openshift/microshift/pkg/kustomize"
"github.com/openshift/microshift/pkg/loadbalancerservice"
Expand Down Expand Up @@ -237,6 +238,7 @@ func RunMicroshift(cfg *config.Config) error {
util.Must(m.AddService(controllers.NewTelemetryManager(cfg)))
util.Must(m.AddService(controllers.NewHostsWatcherManager(cfg)))
util.Must(m.AddService(gdp.NewGenericDevicePlugin(cfg)))
util.Must(m.AddService(c2cc.NewC2CCRouteManager(cfg)))

// Storing and clearing the env, so other components don't send the READY=1 until MicroShift is fully ready
notifySocket := os.Getenv("NOTIFY_SOCKET")
Expand Down
9 changes: 9 additions & 0 deletions pkg/config/c2cc.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ func (c *C2CC) IsEnabled() bool {
return len(c.RemoteClusters) > 0
}

func (c *C2CC) AllRemoteCIDRs() []string {
var cidrs []string
for _, rc := range c.RemoteClusters {
cidrs = append(cidrs, rc.ClusterNetwork...)
cidrs = append(cidrs, rc.ServiceNetwork...)
}
return cidrs
}

func (rc *RemoteCluster) isEmpty() bool {
return rc.NextHop == "" && len(rc.ClusterNetwork) == 0 && len(rc.ServiceNetwork) == 0 && rc.Domain == ""
}
Expand Down
208 changes: 208 additions & 0 deletions pkg/controllers/c2cc/annotation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package c2cc

import (
"context"
"encoding/json"
"fmt"
"sort"
"time"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)

const (
ovnNodeDontSNATSubnets = "k8s.ovn.org/node-ingress-snat-exclude-subnets"
c2ccSNATTrackingAnnotation = "microshift.io/c2cc-snat-subnets"
)

type annotationManager struct {
kubeClient kubernetes.Interface
nodeName string
desiredCIDRs []string
}

func newAnnotationManager(kubeClient kubernetes.Interface, nodeName string, remoteCIDRs []string) *annotationManager {
sorted := make([]string, len(remoteCIDRs))
copy(sorted, remoteCIDRs)
sort.Strings(sorted)

return &annotationManager{
kubeClient: kubeClient,
nodeName: nodeName,
desiredCIDRs: sorted,
}
}

func parseCIDRAnnotation(value string) []string {
if value == "" {
return nil
}
var cidrs []string
if err := json.Unmarshal([]byte(value), &cidrs); err != nil {
return nil
}
return cidrs
}

func cidrSetContainsAll(superset, subset []string) bool {
set := make(map[string]bool, len(superset))
for _, c := range superset {
set[c] = true
}
for _, c := range subset {
if !set[c] {
return false
}
}
return true
}

func (a *annotationManager) reconcile(ctx context.Context) error {
node, err := a.kubeClient.CoreV1().Nodes().Get(ctx, a.nodeName, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("failed to get node %q: %w", a.nodeName, err)
}

existing := parseCIDRAnnotation(node.Annotations[ovnNodeDontSNATSubnets])
previous := parseCIDRAnnotation(node.Annotations[c2ccSNATTrackingAnnotation])

// Target = (existing - previous) + desired
// This replaces only the CIDRs C2CC previously wrote, preserving anything added by other components.
foreignCIDRs := make(map[string]bool, len(existing))
for _, c := range existing {
foreignCIDRs[c] = true
}
for _, c := range previous {
delete(foreignCIDRs, c)
}

targetSet := make(map[string]bool, len(foreignCIDRs)+len(a.desiredCIDRs))
for c := range foreignCIDRs {
targetSet[c] = true
}
for _, c := range a.desiredCIDRs {
targetSet[c] = true
}

target := make([]string, 0, len(targetSet))
for c := range targetSet {
target = append(target, c)
}
sort.Strings(target)

targetJSON, _ := json.Marshal(target)
desiredJSON, _ := json.Marshal(a.desiredCIDRs)

if node.Annotations[ovnNodeDontSNATSubnets] == string(targetJSON) &&
node.Annotations[c2ccSNATTrackingAnnotation] == string(desiredJSON) {
return nil
}

patch := fmt.Sprintf(`{"metadata":{"annotations":{%q:%q,%q:%q}}}`,
ovnNodeDontSNATSubnets, string(targetJSON),
c2ccSNATTrackingAnnotation, string(desiredJSON))
_, err = a.kubeClient.CoreV1().Nodes().Patch(ctx, a.nodeName,
types.MergePatchType, []byte(patch), metav1.PatchOptions{})
if err != nil {
return fmt.Errorf("failed to patch node annotation: %w", err)
}
klog.V(2).Infof("Updated node annotation %s = %s (tracking: %s)", ovnNodeDontSNATSubnets, string(targetJSON), string(desiredJSON))
return nil
}

func (a *annotationManager) cleanup(ctx context.Context) error {
node, err := a.kubeClient.CoreV1().Nodes().Get(ctx, a.nodeName, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("failed to get node %q for cleanup: %w", a.nodeName, err)
}

tracked := parseCIDRAnnotation(node.Annotations[c2ccSNATTrackingAnnotation])
if len(tracked) == 0 {
return nil
}

existing := parseCIDRAnnotation(node.Annotations[ovnNodeDontSNATSubnets])
trackedSet := make(map[string]bool, len(tracked))
for _, c := range tracked {
trackedSet[c] = true
}

var remaining []string
for _, c := range existing {
if !trackedSet[c] {
remaining = append(remaining, c)
}
}

var snatValue string
if len(remaining) == 0 {
snatValue = "null"
} else {
sort.Strings(remaining)
data, _ := json.Marshal(remaining)
snatValue = fmt.Sprintf("%q", string(data))
}

patch := fmt.Sprintf(`{"metadata":{"annotations":{%s:%s,%q:null}}}`,
fmt.Sprintf("%q", ovnNodeDontSNATSubnets), snatValue,
c2ccSNATTrackingAnnotation)
_, err = a.kubeClient.CoreV1().Nodes().Patch(ctx, a.nodeName,
types.MergePatchType, []byte(patch), metav1.PatchOptions{})
if err != nil {
return fmt.Errorf("failed to cleanup node annotation: %w", err)
}
klog.V(2).Infof("Cleaned up node annotation %s (removed %d C2CC CIDRs, %d remaining)", ovnNodeDontSNATSubnets, len(tracked), len(remaining))
return nil
}

func (a *annotationManager) subscribe(ctx context.Context, reconcileCh chan<- string) {
go func() {
for {
watcher, err := a.kubeClient.CoreV1().Nodes().Watch(ctx, metav1.ListOptions{
FieldSelector: "metadata.name=" + a.nodeName,
})
if err != nil {
klog.Warningf("Could not watch node for annotation changes: %v", err)
select {
case <-ctx.Done():
return
case <-time.After(10 * time.Second):
continue
}
}
for event := range watcher.ResultChan() {
if event.Type != watch.Modified {
continue
}
node, ok := event.Object.(*corev1.Node)
if !ok {
continue
}
current := parseCIDRAnnotation(node.Annotations[ovnNodeDontSNATSubnets])
if cidrSetContainsAll(current, a.desiredCIDRs) {
continue
}
select {
case reconcileCh <- "node-annotation-changed":
default:
}
}
watcher.Stop()
if ctx.Err() != nil {
return
}
klog.V(4).Infof("Node watch closed unexpectedly, reconnecting")
select {
case <-ctx.Done():
return
case <-time.After(1 * time.Second):
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}()
klog.V(2).Infof("Subscribed to node annotation changes for %s", a.nodeName)
}
Loading