chore: add deprecation notices (#2089)

* fix: revert pv labeling to dircet api reads

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: revert pv labeling to dircet api reads

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: add deprecation warnings

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* chore: implement playground

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* chore: implement playground

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

---------

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
This commit is contained in:
Oliver Bähler
2026-08-19 15:08:47 +02:00
committed by GitHub
parent e714dbcc2a
commit 647b113702
85 changed files with 2452 additions and 517 deletions
+21 -1
View File
@@ -4,6 +4,7 @@
package admission
import (
"errors"
"strings"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
@@ -12,6 +13,7 @@ import (
)
// +kubebuilder:object:generate=true
// +kubebuilder:validation:XValidation:rule="has(self.client.url) != has(self.client.service)",message="client must configure exactly one of url or service"
type DynamicAdmissionConfig struct {
// Name the Admission Webhook
Name meta.RFC1123Name `json:"name,omitempty"`
@@ -21,10 +23,28 @@ type DynamicAdmissionConfig struct {
// Annotations added to the Admission Webhook
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// whats the problem
// Client defines how the Kubernetes API server reaches the admission webhook.
// Exactly one of URL or Service must be configured.
Client *admissionregistrationv1.WebhookClientConfig `json:"client"`
}
// ValidateWebhookClientConfig checks the invariant required by the Kubernetes
// admissionregistration API before a dynamic webhook object is constructed.
func ValidateWebhookClientConfig(client *admissionregistrationv1.WebhookClientConfig) error {
if client == nil {
return errors.New("webhook client config is required")
}
hasURL := client.URL != nil
hasService := client.Service != nil
if hasURL == hasService {
return errors.New("webhook client config must configure exactly one of url or service")
}
return nil
}
func DynamicWebhookURL(baseURL *string, webhookPath string) *string {
cleanPath := normalizePath(webhookPath)
if cleanPath == "" {
+46
View File
@@ -11,6 +11,52 @@ import (
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
)
func TestValidateWebhookClientConfig(t *testing.T) {
t.Parallel()
webhookURL := "https://capsule.example.com"
service := &admissionregistrationv1.ServiceReference{
Name: "capsule-webhook-service",
Namespace: "capsule-system",
}
tests := []struct {
name string
client *admissionregistrationv1.WebhookClientConfig
wantErr bool
}{
{name: "nil", wantErr: true},
{name: "neither", client: &admissionregistrationv1.WebhookClientConfig{}, wantErr: true},
{
name: "url",
client: &admissionregistrationv1.WebhookClientConfig{URL: &webhookURL},
},
{
name: "service",
client: &admissionregistrationv1.WebhookClientConfig{Service: service},
},
{
name: "both",
client: &admissionregistrationv1.WebhookClientConfig{
URL: &webhookURL,
Service: service,
},
wantErr: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
err := admission.ValidateWebhookClientConfig(test.client)
if (err != nil) != test.wantErr {
t.Fatalf("ValidateWebhookClientConfig() error = %v, wantErr %t", err, test.wantErr)
}
})
}
}
func TestDynamicClientWithPath_EmptyPath_NoChange(t *testing.T) {
t.Parallel()
+8
View File
@@ -24,6 +24,10 @@ type WebhookOptions struct {
}
func NewValidatingWebhook(in *ValidatingWebhook, c *admissionregistrationv1.WebhookClientConfig, users rbac.UserListSpec, admins rbac.UserListSpec) (admissionregistrationv1.ValidatingWebhook, error) {
if err := ValidateWebhookClientConfig(c); err != nil {
return admissionregistrationv1.ValidatingWebhook{}, err
}
out := admissionregistrationv1.ValidatingWebhook{
Name: in.Name,
Rules: in.Rules,
@@ -212,6 +216,10 @@ type ValidatingWebhook struct {
}
func NewMutatingWebhook(in *MutatingWebhook, c *admissionregistrationv1.WebhookClientConfig, users rbac.UserListSpec, admins rbac.UserListSpec) (admissionregistrationv1.MutatingWebhook, error) {
if err := ValidateWebhookClientConfig(c); err != nil {
return admissionregistrationv1.MutatingWebhook{}, err
}
out := admissionregistrationv1.MutatingWebhook{
Name: in.Name,
Rules: in.Rules,
@@ -275,6 +275,8 @@ type TenantPodOptionsChangedPredicate struct{ predicate.Funcs }
func (TenantPodOptionsChangedPredicate) Create(event.CreateEvent) bool { return false }
func (TenantPodOptionsChangedPredicate) Delete(event.DeleteEvent) bool { return false }
func (TenantPodOptionsChangedPredicate) Generic(event.GenericEvent) bool { return false }
//nolint:staticcheck
func (TenantPodOptionsChangedPredicate) Update(e event.UpdateEvent) bool {
oldTenant, oldOK := e.ObjectOld.(*capsulev1beta2.Tenant)
newTenant, newOK := e.ObjectNew.(*capsulev1beta2.Tenant)
@@ -287,6 +289,8 @@ type TenantServiceOptionsChangedPredicate struct{ predicate.Funcs }
func (TenantServiceOptionsChangedPredicate) Create(event.CreateEvent) bool { return false }
func (TenantServiceOptionsChangedPredicate) Delete(event.DeleteEvent) bool { return false }
func (TenantServiceOptionsChangedPredicate) Generic(event.GenericEvent) bool { return false }
//nolint:staticcheck
func (TenantServiceOptionsChangedPredicate) Update(e event.UpdateEvent) bool {
oldTenant, oldOK := e.ObjectOld.(*capsulev1beta2.Tenant)
newTenant, newOK := e.ObjectNew.(*capsulev1beta2.Tenant)