kubeslice / kubeslice/kubeslice-controller
Bug: validateApplicationNamespaces panics on empty SliceNamespaceSelection entry
- Dominant language
- Go
- Stars
- 73
- Forks
- 48
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 8
Description
### 📜 Description
`validateApplicationNamespaces` in `service/slice_config_webhook_validation.go` panics with an index-out-of-range error when a `SliceNamespaceSelection` entry has both `namespace` and `clusters` empty.
Lines 508–513 guard against only one of the two fields being empty:
- Line 508: rejects `namespace` set + `clusters` empty
- Line 511: rejects `namespace` empty + `clusters` set
But when both are empty (a zero-value `SliceNamespaceSelection{}`), both guards pass. Line 514 calls `CheckDuplicateInArray` on an empty slice, which returns false. Execution then reaches line 517:
```go
// service/slice_config_webhook_validation.go, line 517
if applicationNamespace.Clusters[0] == "*" {
```
This indexes into an empty slice and panics. Since the webhook runs in-process with the controller manager, this crashes the entire controller.
### 👟 Reproduction steps
1. Have an existing Project with a registered cluster:
kubectl get clusters -n kubeslice-my-project
2. Apply a SliceConfig with an empty entry in `applicationNamespaces`:
apiVersion: controller.kubeslice.io/v1alpha1
kind: SliceConfig
metadata:
name: test-slice
namespace: kubeslice-my-project
spec:
sliceSubnet: 10.1.0.0/16
maxClusters: 16
clusters:
- worker-1
namespaceIsolationProfile:
applicationNamespaces:
- {}
3. The validating webhook panics and the controller manager crashes.
### 👍 Expected behavior
The webhook should reject the request with a validation error indicating that both `namespace` and `clusters` are required. The controller should not crash.
### 👎 Actual Behavior
The controller manager panics with:
runtime error: index out of range [0] with length 0
goroutine ... [running]:
github.com/kubeslice/kubeslice-controller/service.validateApplicationNamespaces(...)
service/slice_config_webhook_validation.go:517
The webhook process crashes, taking down all reconciliation cluster-wide until the pod restarts.
### 🐚 Relevant log output
```shell
The panic occurs before any log statement in the function. The only output is the Go runtime
panic trace, visible in the controller manager pod logs:
panic: runtime error: index out of range [0] with length 0
goroutine 123 [running]:
github.com/kubeslice/kubeslice-controller/service.validateApplicationNamespaces(0x...)
/workspace/service/slice_config_webhook_validation.go:517
github.com/kubeslice/kubeslice-controller/service.ValidateSliceConfigCreate(0x...)
/workspace/service/slice_config_webhook_validation.go:38
```
### Version
master branch (latest HEAD as of 2026-05-08). The bug exists in all releases containing the `validateApplicationNamespaces` function. Affected release branches include release-shimla, release-udaipur, and release-varanasi.
### 🖥️ What operating system are you seeing the problem on?
Windows
### ✅ Proposed Solution
Add an explicit rejection for empty entries before the existing guards. Apply at `service/slice_config_webhook_validation.go`, insert before line 508:
Current code (lines 506–517):
for _, applicationNamespace := range sliceConfig.Spec.NamespaceIsolationProfile.ApplicationNamespaces {
/* check duplicate values of clusters */
if len(applicationNamespace.Namespace) > 0 && len(applicationNamespace.Clusters) == 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces").Child("Clusters"), "clusters")
}
if len(applicationNamespace.Namespace) == 0 && len(applicationNamespace.Clusters) > 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces").Child("Namespace"), "Namespace")
}
if duplicate, value := util.CheckDuplicateInArray(applicationNamespace.Clusters); duplicate {
return field.Duplicate(field.NewPath("Spec").Child("NamespaceIsolationProfile.ApplicationNamespaces").Child("Clusters"), strings.Join(value, ", "))
}
if applicationNamespace.Clusters[0] == "*" {
Fixed code (lines 506–520):
for _, applicationNamespace := range sliceConfig.Spec.NamespaceIsolationProfile.ApplicationNamespaces {
/* check duplicate values of clusters */
if len(applicationNamespace.Namespace) == 0 && len(applicationNamespace.Clusters) == 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces"), "namespace and clusters are required")
}
if len(applicationNamespace.Namespace) > 0 && len(applicationNamespace.Clusters) == 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces").Child("Clusters"), "clusters")
}
if len(applicationNamespace.Namespace) == 0 && len(applicationNamespace.Clusters) > 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces").Child("Namespace"), "Namespace")
}
if duplicate, value := util.CheckDuplicateInArray(applicationNamespace.Clusters); duplicate {
return field.Duplicate(field.NewPath("Spec").Child("NamespaceIsolationProfile.ApplicationNamespaces").Child("Clusters"), strings.Join(value, ", "))
}
if applicationNamespace.Clusters[0] == "*" {
The new guard at the top catches the both-empty case before execution can reach line 517. This gives the user a clear validation error instead of crashing the controller.
### 👀 Have you spent some time to check if this issue has been raised before?
- [x] I checked and didn't find any similar issue
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Assessment
This issue has not been assessed yet.