kubeslice / kubeslice/kubeslice-controller
Bug: Webhook validations swallow GetResourceIfExist errors across 7 call sites
- Dominant language
- Go
- Stars
- 73
- Forks
- 48
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 8
Description
### 📜 Description
Seven call sites across three webhook validation files discard the error return from `util.GetResourceIfExist`, using the pattern `exist, _ := util.GetResourceIfExist(...)`. When the API server is temporarily unreachable, `GetResourceIfExist` returns `(false, err)`. The discarded error causes the webhook to misinterpret an API failure as "resource not found" and return a misleading validation error to the user.
**Affected call sites:**
| # | File | Line | What's being looked up | Misleading error returned |
|---|------|------|------------------------|--------------------------|
| 1 | `service/cluster_webhook_validation.go` | 73 | Project namespace | "cluster must be applied on project namespace" |
| 2 | `service/service_export_config_webhook_validation.go` | 65 | Source cluster | "Cluster is not registered" |
| 3 | `service/service_export_config_webhook_validation.go` | 67 | SliceConfig | "There is no valid slice with this name" |
| 4 | `service/service_export_config_webhook_validation.go` | 93 | Endpoint cluster | "Cluster is not registered" |
| 5 | `service/service_export_config_webhook_validation.go` | 95 | Endpoint slice | "There is no valid slice with this name" |
| 6 | `service/service_export_config_webhook_validation.go` | 119 | Project namespace | "ServiceExportConfig must be applied on project namespace" |
| 7 | `service/slice_qos_config_webhook_validation.go` | 60 | Project namespace | "SliceQosConfig must be applied on project namespace" |
Example from `cluster_webhook_validation.go`:
```go
// service/cluster_webhook_validation.go, lines 71-78
func validateAppliedInProjectNamespace(ctx context.Context, c *controllerv1alpha1.Cluster) *field.Error {
namespace := &corev1.Namespace{}
exist, _ := util.GetResourceIfExist(ctx, client.ObjectKey{Name: c.Namespace}, namespace)
// ^ error silently discarded
if !exist || !util.CheckForProjectNamespace(namespace) {
return field.Invalid(field.NewPath("metadata").Child("namespace"), c.Namespace,
"cluster must be applied on project namespace")
}
return nil
}
```
Example from `service_export_config_webhook_validation.go`:
```go
// service/service_export_config_webhook_validation.go, lines 63-73
func validateServiceExportClusterAndSlice(ctx context.Context, serviceExport *controllerv1alpha1.ServiceExportConfig) *field.Error {
cluster := &controllerv1alpha1.Cluster{}
clusterExist, _ := util.GetResourceIfExist(ctx, client.ObjectKey{...}, cluster)
// ^ error discarded
sliceConfig := &controllerv1alpha1.SliceConfig{}
sliceExist, _ := util.GetResourceIfExist(ctx, client.ObjectKey{...}, sliceConfig)
// ^ error discarded
if !sliceExist {
return field.Invalid(..., "There is no valid slice with this name")
}
if !clusterExist {
return field.Invalid(..., "Cluster is not registered")
}
// ...
}
```
Note: this is distinct from issue #360 (SliceConfig validating webhook performing writes). This issue is about swallowed **read** errors across the three *other* webhook validation files.
### 👟 Reproduction steps
1. Have a working kubeslice-controller with clusters, slices, and service exports configured.
2. Induce a transient API server failure affecting GET requests. This can occur naturally during:
- etcd leader failover (typically 1-5 seconds)
- API server rolling restart
- Network partition between the webhook pod and the API server
- API server resource pressure (high QPS causing throttling)
3. During the transient failure, attempt any of these operations:
- Create or update a Cluster → rejected with "cluster must be applied on project namespace"
- Create or update a ServiceExportConfig → rejected with "Cluster is not registered" or "There is no valid slice with this name"
- Create a SliceQoSConfig → rejected with "SliceQosConfig must be applied on project namespace"
4. The error messages are misleading — the resources exist and the namespace is correct, but the API lookup failed transiently.
5. Automated tooling (Helm, ArgoCD, GitOps pipelines) retries the operation, gets the same misleading error, and may escalate as a configuration issue instead of a transient infrastructure issue.
### 👍 Expected behavior
When `GetResourceIfExist` returns an error, the webhook should return a `field.InternalError` that accurately describes the API failure. This allows:
- Users to see the real error ("internal error: failed to look up namespace") instead of a misleading validation error
- Automated tooling to distinguish transient failures from genuine configuration errors
- Operators to troubleshoot the actual root cause
### 👎 Actual Behavior
The error is discarded. The webhook returns a validation error that incorrectly blames the user's input:
- "cluster must be applied on project namespace" (when the namespace IS correct)
- "Cluster is not registered" (when the cluster IS registered)
- "There is no valid slice with this name" (when the slice DOES exist)
This is confusing for operators, wastes debugging time, and causes false alerts in CI/CD pipelines.
### 🐚 Relevant log output
```shell
No error is logged by the webhook validation functions. The actual API error
from GetResourceIfExist is silently discarded.
The user sees only the misleading admission rejection:
Error from server (Invalid): error when creating "cluster.yaml":
Cluster.controller.kubeslice.io "worker-1" is invalid:
metadata.namespace: Invalid value: "kubeslice-my-project":
cluster must be applied on project namespace
This is indistinguishable from a genuinely misconfigured cluster, making the
transient failure extremely difficult to diagnose.
```
### Version
master branch (latest HEAD as of 2026-05-15). The bug exists since the initial implementation of webhook validations in all three files.
### 🖥️ What operating system are you seeing the problem on?
_No response_
### ✅ Proposed Solution
At each of the 7 call sites, check the error and return `field.InternalError` when non-nil.
**Example fix for `cluster_webhook_validation.go` line 73:**
Current code:
```go
exist, _ := util.GetResourceIfExist(ctx, client.ObjectKey{Name: c.Namespace}, namespace)
if !exist || !util.CheckForProjectNamespace(namespace) {
```
Fixed code:
```go
exist, err := util.GetResourceIfExist(ctx, client.ObjectKey{Name: c.Namespace}, namespace)
if err != nil {
return field.InternalError(field.NewPath("metadata").Child("namespace"),
fmt.Errorf("failed to look up namespace %s: %w", c.Namespace, err))
}
if !exist || !util.CheckForProjectNamespace(namespace) {
```
Apply the same pattern to all 7 sites. Each fix is 3-4 lines. Total change: ~25 lines across 3 files.
This is consistent with how the `VpnKeyRotation` webhook validation handles errors (returning `err` directly at lines 26-28 of `vpn_key_rotation_webhook_validation.go`).
### 👀 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.