Skip to content

Commit 9ee2db5

Browse files
Merge pull request #21 from super-phenix/fix-security
chore(security): ensure nothing can crash the operator
2 parents 6c22281 + b24de44 commit 9ee2db5

5 files changed

Lines changed: 56 additions & 18 deletions

File tree

cmd/main.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"flag"
66
"os"
77
"os/signal"
8+
"regexp"
89

910
"github.com/super-phenix/volume-replicator/internal/k8s"
1011
"github.com/super-phenix/volume-replicator/internal/replicator"
@@ -16,17 +17,25 @@ func main() {
1617
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
1718
defer cancel()
1819

19-
var kubeconfig, namespace string
20+
var kubeconfig, namespace, exclusionRegexStr string
2021
flag.StringVar(&kubeconfig, "kubeconfig", "", "path to kubeconfig file")
2122
flag.StringVar(&namespace, "namespace", os.Getenv("NAMESPACE"), "deployment namespace")
22-
flag.StringVar(&replicator.ExclusionRegex, "exclusion-regex", os.Getenv("EXCLUSION_REGEX"), "regex to exclude PVCs from replication")
23+
flag.StringVar(&exclusionRegexStr, "exclusion-regex", os.Getenv("EXCLUSION_REGEX"), "regex to exclude PVCs from replication")
2324
klog.InitFlags(nil)
2425
flag.Parse()
2526

2627
if namespace == "" {
2728
klog.Fatalf("must provide the namespace in which the controller is running through --namespace")
2829
}
2930

31+
if exclusionRegexStr != "" {
32+
var err error
33+
replicator.ExclusionRegex, err = regexp.Compile(exclusionRegexStr)
34+
if err != nil {
35+
klog.Fatalf("failed to compile exclusion regex: %s", err.Error())
36+
}
37+
}
38+
3039
if err := k8s.Load(kubeconfig); err != nil {
3140
klog.Fatalf("failed to load kubernetes configuration: %s", err.Error())
3241
}

internal/replicator/informers.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,18 @@ func (c *Controller) createPvcInformer(factory informers.SharedInformerFactory)
7272
c.pvcUpdate(newObj.(*corev1.PersistentVolumeClaim))
7373
},
7474
DeleteFunc: func(obj any) {
75-
c.pvcUpdate(obj.(*corev1.PersistentVolumeClaim))
75+
pvc, ok := obj.(*corev1.PersistentVolumeClaim)
76+
if !ok {
77+
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
78+
if !ok {
79+
return
80+
}
81+
pvc, ok = tombstone.Obj.(*corev1.PersistentVolumeClaim)
82+
if !ok {
83+
return
84+
}
85+
}
86+
c.pvcUpdate(pvc)
7687
},
7788
})
7889
}
@@ -87,7 +98,18 @@ func (c *Controller) createVolumeReplicationInformer(factory dynamicinformer.Dyn
8798
c.volumeReplicationUpdate(oldObj.(*unstructured.Unstructured), newObj.(*unstructured.Unstructured))
8899
},
89100
DeleteFunc: func(obj any) {
90-
c.volumeReplicationCreateOrDelete(obj.(*unstructured.Unstructured))
101+
vr, ok := obj.(*unstructured.Unstructured)
102+
if !ok {
103+
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
104+
if !ok {
105+
return
106+
}
107+
vr, ok = tombstone.Obj.(*unstructured.Unstructured)
108+
if !ok {
109+
return
110+
}
111+
}
112+
c.volumeReplicationCreateOrDelete(vr)
91113
},
92114
})
93115
}

internal/replicator/utils.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
"k8s.io/klog/v2"
1616
)
1717

18-
var ExclusionRegex string
18+
var ExclusionRegex *regexp.Regexp
1919

2020
// isVolumeReplicationCorrect verifies if the definition of a VolumeReplication conforms to its originating PVC
2121
func isVolumeReplicationCorrect(pvc *corev1.PersistentVolumeClaim, vr *unstructured.Unstructured) bool {
@@ -197,17 +197,10 @@ func isNamespacePaused(namespace string) bool {
197197
// pvcNameMatchesExclusion returns whether a PVC has a name matching the exclusion regex
198198
func pvcNameMatchesExclusion(pvc *corev1.PersistentVolumeClaim) bool {
199199
// If no regex is provided, return that it doesn't match
200-
// This is to avoid Go matching "" as "everything matches"
201-
if ExclusionRegex == "" {
200+
if ExclusionRegex == nil {
202201
return false
203202
}
204203

205204
// Match the user-provided regex
206-
match, err := regexp.MatchString(ExclusionRegex, pvc.Name)
207-
if err != nil {
208-
klog.Errorf("failed to parse exclusion regex: %s", err.Error())
209-
return false
210-
}
211-
212-
return match
205+
return ExclusionRegex.MatchString(pvc.Name)
213206
}

internal/replicator/utils_test.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package replicator
22

33
import (
44
"fmt"
5+
"regexp"
56
"testing"
67

78
"github.com/stretchr/testify/require"
@@ -940,7 +941,19 @@ func TestPvcNameMatchesExclusion(t *testing.T) {
940941

941942
for _, tt := range tests {
942943
t.Run(tt.name, func(t *testing.T) {
943-
ExclusionRegex = tt.exclusionRegex
944+
if tt.exclusionRegex != "" {
945+
var err error
946+
ExclusionRegex, err = regexp.Compile(tt.exclusionRegex)
947+
if tt.name != "Invalid regex" {
948+
require.NoError(t, err)
949+
} else {
950+
require.Error(t, err)
951+
ExclusionRegex = nil // Simulate what happens when it fails (though main would exit)
952+
}
953+
} else {
954+
ExclusionRegex = nil
955+
}
956+
944957
pvc := &corev1.PersistentVolumeClaim{
945958
ObjectMeta: metav1.ObjectMeta{
946959
Name: tt.pvcName,

internal/replicator/vrc_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package replicator
22

33
import (
44
"fmt"
5+
"regexp"
56
"testing"
67

78
"github.com/stretchr/testify/require"
@@ -211,11 +212,11 @@ func TestGetVolumeReplicationClass(t *testing.T) {
211212

212213
// Set ExclusionRegex specifically for each test case
213214
if tt.name == "Excluded by name regex" {
214-
ExclusionRegex = "exclude-.*"
215+
ExclusionRegex = regexp.MustCompile("exclude-.*")
215216
} else {
216-
ExclusionRegex = ""
217+
ExclusionRegex = nil
217218
}
218-
defer func() { ExclusionRegex = "" }()
219+
defer func() { ExclusionRegex = nil }()
219220

220221
if tt.namespace != nil {
221222
err := NamespaceInformer.Informer().GetIndexer().Add(tt.namespace)

0 commit comments

Comments
 (0)