From f0c4beecce1da41758df4108c469a3e4935f0941 Mon Sep 17 00:00:00 2001 From: Alex Savanovich <40720931+savme@users.noreply.github.com> Date: Fri, 29 May 2026 19:14:10 +0200 Subject: [PATCH 1/2] feat: add kplane deps --- Dockerfile | 2 +- cmd/milo/apiserver/serviceaccounts.go | 8 +- go.mod | 132 ++++++------ go.sum | 278 +++++++++++++------------- 4 files changed, 218 insertions(+), 202 deletions(-) diff --git a/Dockerfile b/Dockerfile index 22f87820..03fbf3e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # and cross-compiles to $TARGETOS/$TARGETARCH. This makes multi-arch builds # (linux/amd64, linux/arm64) fast under buildx without requiring QEMU emulation # for the build itself. -FROM --platform=$BUILDPLATFORM golang:1.25 AS builder +FROM --platform=$BUILDPLATFORM golang:1.26 AS builder # Provided automatically by BuildKit when using buildx with --platform. ARG TARGETOS diff --git a/cmd/milo/apiserver/serviceaccounts.go b/cmd/milo/apiserver/serviceaccounts.go index 09cc9f6d..99dce864 100644 --- a/cmd/milo/apiserver/serviceaccounts.go +++ b/cmd/milo/apiserver/serviceaccounts.go @@ -25,19 +25,19 @@ func genericTokenGetter(factory informers.SharedInformerFactory) serviceaccount. // return clientGetter{secretLister: factory.Core().V1().Secrets().Lister(), serviceAccountLister: factory.Core().V1().ServiceAccounts().Lister()} } -func (c clientGetter) GetServiceAccount(namespace, name string) (*v1.ServiceAccount, error) { +func (c clientGetter) GetServiceAccount(_ context.Context, namespace, name string) (*v1.ServiceAccount, error) { return c.serviceAccountLister.ServiceAccounts(namespace).Get(name) } -func (c clientGetter) GetPod(namespace, name string) (*v1.Pod, error) { +func (c clientGetter) GetPod(_ context.Context, namespace, name string) (*v1.Pod, error) { return nil, apierrors.NewNotFound(v1.Resource("pods"), name) } -func (c clientGetter) GetSecret(namespace, name string) (*v1.Secret, error) { +func (c clientGetter) GetSecret(_ context.Context, namespace, name string) (*v1.Secret, error) { return c.secretLister.Secrets(namespace).Get(name) } -func (c clientGetter) GetNode(name string) (*v1.Node, error) { +func (c clientGetter) GetNode(_ context.Context, name string) (*v1.Node, error) { return nil, apierrors.NewNotFound(v1.Resource("nodes"), name) } diff --git a/go.mod b/go.mod index 8a050358..e5d7591e 100644 --- a/go.mod +++ b/go.mod @@ -1,53 +1,53 @@ module go.miloapis.com/milo -go 1.25.0 +go 1.26.3 require ( github.com/blang/semver/v4 v4.0.0 github.com/go-logr/logr v1.4.3 github.com/google/cel-go v0.26.0 - github.com/spf13/cobra v1.10.0 + github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.9 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 - go.opentelemetry.io/otel v1.36.0 - go.opentelemetry.io/otel/trace v1.36.0 - golang.org/x/sync v0.18.0 - golang.org/x/time v0.12.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 + go.opentelemetry.io/otel v1.41.0 + go.opentelemetry.io/otel/trace v1.41.0 + golang.org/x/sync v0.19.0 + golang.org/x/time v0.14.0 gopkg.in/go-jose/go-jose.v2 v2.6.3 - k8s.io/api v0.35.0 - k8s.io/apiextensions-apiserver v0.35.0 - k8s.io/apimachinery v0.35.0 - k8s.io/apiserver v0.35.0 - k8s.io/client-go v0.35.0 - k8s.io/component-base v0.35.0 + k8s.io/api v0.36.0 + k8s.io/apiextensions-apiserver v0.36.0 + k8s.io/apimachinery v0.36.0 + k8s.io/apiserver v0.36.0 + k8s.io/client-go v0.36.0 + k8s.io/component-base v0.36.0 k8s.io/controller-manager v0.35.0 - k8s.io/klog/v2 v2.130.1 + k8s.io/klog/v2 v2.140.0 k8s.io/kube-aggregator v0.35.0 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a k8s.io/kubernetes v1.35.0 - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 - sigs.k8s.io/controller-runtime v0.23.3 - sigs.k8s.io/multicluster-runtime v0.23.3 + k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 + sigs.k8s.io/controller-runtime v0.24.1 + sigs.k8s.io/multicluster-runtime v0.24.1 sigs.k8s.io/yaml v1.6.0 ) require ( - cel.dev/expr v0.24.0 // indirect - cyphar.com/go-pathrs v0.2.1 // indirect + cel.dev/expr v0.25.1 // indirect + cyphar.com/go-pathrs v0.2.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/coreos/go-oidc v2.3.0+incompatible // indirect + github.com/coreos/go-oidc v2.5.0+incompatible // indirect github.com/coreos/go-semver v0.3.1 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/cyphar/filepath-securejoin v0.6.0 // indirect + github.com/coreos/go-systemd/v22 v22.7.0 // indirect + github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect @@ -59,13 +59,12 @@ require ( github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect - github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect - github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -79,43 +78,43 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/selinux v1.13.0 // indirect + github.com/opencontainers/selinux v1.13.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.etcd.io/etcd/api/v3 v3.6.5 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.5 // indirect - go.etcd.io/etcd/client/v3 v3.6.5 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.36.0 // indirect - go.opentelemetry.io/otel/sdk v1.36.0 // indirect - go.opentelemetry.io/proto/otlp v1.5.0 // indirect + go.etcd.io/etcd/api/v3 v3.6.7 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.7 // indirect + go.etcd.io/etcd/client/v3 v3.6.7 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect + go.opentelemetry.io/otel/metric v1.41.0 // indirect + go.opentelemetry.io/otel/sdk v1.40.0 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect + go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect - golang.org/x/tools v0.38.0 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/term v0.39.0 // indirect + golang.org/x/text v0.33.0 // indirect + golang.org/x/tools v0.41.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect - google.golang.org/grpc v1.72.2 // indirect - google.golang.org/protobuf v1.36.8 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect @@ -137,8 +136,27 @@ require ( k8s.io/metrics v0.35.0 // indirect k8s.io/mount-utils v0.35.0 // indirect k8s.io/pod-security-admission v0.35.0 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect +) + +// pin all k8s.io/* modules to the kplane-dev versions +replace ( + // kplane replace doesn't transit to Milo, so we have to repin here. + github.com/kplane-dev/informer => github.com/kplane-dev/informer v0.0.0-20260404055613-d9279cfd5e9b + github.com/kplane-dev/storage => github.com/kplane-dev/storage v0.0.0-20260404055526-b175d95c9fe7 + k8s.io/api => github.com/kplane-dev/kubernetes/staging/src/k8s.io/api v0.0.0-20260404055358-aac72e7d04ad + k8s.io/apiextensions-apiserver => github.com/kplane-dev/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260404055358-aac72e7d04ad + k8s.io/apimachinery => github.com/kplane-dev/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260404055358-aac72e7d04ad + k8s.io/apiserver => github.com/kplane-dev/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260404055358-aac72e7d04ad + k8s.io/client-go => github.com/kplane-dev/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260404055358-aac72e7d04ad + k8s.io/component-base => github.com/kplane-dev/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260404055358-aac72e7d04ad + k8s.io/controller-manager => github.com/kplane-dev/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260404055358-aac72e7d04ad + k8s.io/endpointslice => github.com/kplane-dev/kubernetes/staging/src/k8s.io/endpointslice v0.0.0-20260404055358-aac72e7d04ad + k8s.io/kms => github.com/kplane-dev/kubernetes/staging/src/k8s.io/kms v0.0.0-20260404055358-aac72e7d04ad + k8s.io/kube-aggregator => github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260404055358-aac72e7d04ad + k8s.io/kube-controller-manager => github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260404055358-aac72e7d04ad + k8s.io/kubernetes => github.com/kplane-dev/kubernetes v0.0.0-20260404055358-aac72e7d04ad ) diff --git a/go.sum b/go.sum index ba4eb680..84cb677b 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= -cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8= -cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +cyphar.com/go-pathrs v0.2.2 h1:y9w7hxbkr3zEL78Fjzeg4HEhs2xNy+fbwHiHGJJY2Xo= +cyphar.com/go-pathrs v0.2.2/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= @@ -18,21 +18,21 @@ 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/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/coreos/go-oidc v2.3.0+incompatible h1:+5vEsrgprdLjjQ9FzIKAzQz1wwPD+83hQRfUIPh7rO0= -github.com/coreos/go-oidc v2.3.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-oidc v2.5.0+incompatible h1:6W0vGJR3Tu0r0PwfmjOrRZSlfxeEln8dsejt3ZWIvwo= +github.com/coreos/go-oidc v2.5.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA= +github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is= -github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= +github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= +github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -41,8 +41,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= @@ -68,11 +68,10 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= @@ -92,14 +91,12 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= -github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= -github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= @@ -112,6 +109,30 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/kplane-dev/kubernetes v0.0.0-20260404055358-aac72e7d04ad h1:249TYMHw60P6D58XGVjf7G2TNp708zRyNa0RbXfQAUQ= +github.com/kplane-dev/kubernetes v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:9uEdeMBkUjkGSL2ioy2pKr0+aLNIvmOan7p8F7ENHbk= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/api v0.0.0-20260404055358-aac72e7d04ad h1:0k/XM+mWOjNWWmc/HkYP5qYcIw72vssnGhS6i7jidBE= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/api v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:KOrdwhDi3QHVXr50HAWBhO2r9uMtWbO46CiIHzRVtU8= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260404055358-aac72e7d04ad h1:XLq9ewx7uGAHa18cYQ1juWA/2dgrp4/bct+38M2XSuQ= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:wZyuUfbqWsRKO42GvZVHZSJ0JttMO7YrXnu/bv/GqPg= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260404055358-aac72e7d04ad h1:hR3yKcG3v2+mjQEMME/9piLycd/Ry7JKtzVGB76satk= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:7mgr/dli8ofwAbcIQXetFVX1fbOYsOYojq3AUbybVmQ= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260404055358-aac72e7d04ad h1:mWkFOi6/+Ttf9RzcReo+0Om1AFJDTrHzxnfIWueiTRQ= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:GNWcUSRqjpm4i1hrLaGA7EQrl60YdahMic4aS+WUQVI= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260404055358-aac72e7d04ad h1:OhrfiUM1g6sHUohSTgiWoTwXfl1fg2He51+X0KneB8c= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:7IM9p4c8CafSxF7ZY0F46WHylFn3o4mLVW5T1VZbaY8= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260404055358-aac72e7d04ad h1:msldiJV5olCNfzoFD7pMKFMa1D0DTMWbASyAS4fxMEs= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:R6vYa1XRfX3PdQEGNkCaL3pt7NvLU2ti7FPzsEsA6GQ= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260404055358-aac72e7d04ad h1:5bXsA+t0Qj8s/qLCB1ZWbjZTBLNYXbW2wLG+XrSiVhI= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:gjjSpBn/ZS8VRB+BMH7Ttd2kk+Hr+IYvm4LwBwQAtaU= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/endpointslice v0.0.0-20260404055358-aac72e7d04ad h1:+GjOBFoY4CtAwNsgRKUoFcL7g7sizw6QROeSnLZZRgM= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/endpointslice v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:fdIUBx+W5Ypy0TBvfW8qonHr4QV3iXw+N+ADcGYf8eI= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/kms v0.0.0-20260404055358-aac72e7d04ad h1:F5GG5dhOffoOm+4jG94RLGaaFdKKO0nPiJCCqTHn8h8= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/kms v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:rhO9JHsWibaRLx12/ViuMQdeZi43hsiXCl8KEEihjaw= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260404055358-aac72e7d04ad h1:0cEi7M+eIESF+kWiEHnL7/kirpbvEn/b2asLQSZHx3o= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:KXJ9MlZYxlzOWKhHqfdxOTDdmfk/+ftdOwN//JGQs0g= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260404055358-aac72e7d04ad h1:BZew8n8DewnquBgR4mEKdgvoq3EVV3/4EMyW37KAd+8= +github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:fvSj40FltpPVU4KLda+I/WhFTwwiGuPpzpy+5UeiOaM= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -136,14 +157,14 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.27.4 h1:fcEcQW/A++6aZAZQNUmNjvA9PSOzefMJBerHJ4t8v8Y= +github.com/onsi/ginkgo/v2 v2.27.4/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= +github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/selinux v1.13.0 h1:Zza88GWezyT7RLql12URvoxsbLfjFx988+LGaWfbL84= -github.com/opencontainers/selinux v1.13.0/go.mod h1:XxWTed+A/s5NNq4GmYScVy+9jzXhGBVEOAyucdRUY8s= +github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE= +github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -155,10 +176,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -168,9 +189,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/cobra v1.10.0 h1:a5/WeUlSDCvV5a45ljW2ZFtV0bTDpkfSAj3uqB6Sc+0= -github.com/spf13/cobra v1.10.0/go.mod h1:9dhySC7dnTtEiqzmqfkLj47BslqLCUPMXjG2lj/NgoE= -github.com/spf13/pflag v1.0.8/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= @@ -197,46 +217,46 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= -go.etcd.io/etcd/api/v3 v3.6.5 h1:pMMc42276sgR1j1raO/Qv3QI9Af/AuyQUW6CBAWuntA= -go.etcd.io/etcd/api/v3 v3.6.5/go.mod h1:ob0/oWA/UQQlT1BmaEkWQzI0sJ1M0Et0mMpaABxguOQ= -go.etcd.io/etcd/client/pkg/v3 v3.6.5 h1:Duz9fAzIZFhYWgRjp/FgNq2gO1jId9Yae/rLn3RrBP8= -go.etcd.io/etcd/client/pkg/v3 v3.6.5/go.mod h1:8Wx3eGRPiy0qOFMZT/hfvdos+DjEaPxdIDiCDUv/FQk= -go.etcd.io/etcd/client/v3 v3.6.5 h1:yRwZNFBx/35VKHTcLDeO7XVLbCBFbPi+XV4OC3QJf2U= -go.etcd.io/etcd/client/v3 v3.6.5/go.mod h1:ZqwG/7TAFZ0BJ0jXRPoJjKQJtbFo/9NIY8uoFFKcCyo= -go.etcd.io/etcd/pkg/v3 v3.6.5 h1:byxWB4AqIKI4SBmquZUG1WGtvMfMaorXFoCcFbVeoxM= -go.etcd.io/etcd/pkg/v3 v3.6.5/go.mod h1:uqrXrzmMIJDEy5j00bCqhVLzR5jEJIwDp5wTlLwPGOU= -go.etcd.io/etcd/server/v3 v3.6.5 h1:4RbUb1Bd4y1WkBHmuF+cZII83JNQMuNXzyjwigQ06y0= -go.etcd.io/etcd/server/v3 v3.6.5/go.mod h1:PLuhyVXz8WWRhzXDsl3A3zv/+aK9e4A9lpQkqawIaH0= +go.etcd.io/etcd/api/v3 v3.6.7 h1:7BNJ2gQmc3DNM+9cRkv7KkGQDayElg8x3X+tFDYS+E0= +go.etcd.io/etcd/api/v3 v3.6.7/go.mod h1:xJ81TLj9hxrYYEDmXTeKURMeY3qEDN24hqe+q7KhbnI= +go.etcd.io/etcd/client/pkg/v3 v3.6.7 h1:vvzgyozz46q+TyeGBuFzVuI53/yd133CHceNb/AhBVs= +go.etcd.io/etcd/client/pkg/v3 v3.6.7/go.mod h1:2IVulJ3FZ/czIGl9T4lMF1uxzrhRahLqe+hSgy+Kh7Q= +go.etcd.io/etcd/client/v3 v3.6.7 h1:9WqA5RpIBtdMxAy1ukXLAdtg2pAxNqW5NUoO2wQrE6U= +go.etcd.io/etcd/client/v3 v3.6.7/go.mod h1:2XfROY56AXnUqGsvl+6k29wrwsSbEh1lAouQB1vHpeE= +go.etcd.io/etcd/pkg/v3 v3.6.7 h1:qIxdSI+LAmKFAjMy42yHQzSNqG/sWES4QjhFSGsMDpY= +go.etcd.io/etcd/pkg/v3 v3.6.7/go.mod h1:nPbpIExp9Q6tR/EVI2aZe0VBlflLys5VGFWSCmqUOyk= +go.etcd.io/etcd/server/v3 v3.6.7 h1:8dEGQ877tj0cQJFEfD2bDoZDA76qbS2OkvCNjwAyrSo= +go.etcd.io/etcd/server/v3 v3.6.7/go.mod h1:LEM328bPA2uVMhN0+Ht/vAsADW127QS1oM7EuHrOTy0= go.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ= go.etcd.io/raft/v3 v3.6.0/go.mod h1:nLvLevg6+xrVtHUmVaTcTz603gQPHfh7kUAwV6YpfGo= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= -go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= -go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 h1:XmiuHzgJt067+a6kwyAzkhXooYVv3/TOw9cM2VfJgUM= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0/go.mod h1:KDgtbWKTQs4bM+VPUr6WlL9m/WXcmkCcBlIzqxPGzmI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= +go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= +go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs= +go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= +go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= +go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= @@ -244,61 +264,63 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0= +golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= -google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M= +google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -313,26 +335,12 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= -k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= -k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4= -k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU= -k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= -k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= -k8s.io/apiserver v0.35.0 h1:CUGo5o+7hW9GcAEF3x3usT3fX4f9r8xmgQeCBDaOgX4= -k8s.io/apiserver v0.35.0/go.mod h1:QUy1U4+PrzbJaM3XGu2tQ7U9A4udRRo5cyxkFX0GEds= -k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= -k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= k8s.io/cloud-provider v0.35.0 h1:syiBCQbKh2gho/S1BkIl006Dc44pV8eAtGZmv5NMe7M= k8s.io/cloud-provider v0.35.0/go.mod h1:7grN+/Nt5Hf7tnSGPT3aErt4K7aQpygyCrGpbrQbzNc= k8s.io/cluster-bootstrap v0.35.0 h1:VXnil8zw+FikqvytJYLB8wcvjxbUCyqMkiC//k426Y0= k8s.io/cluster-bootstrap v0.35.0/go.mod h1:X6sjEjVUFSfFNIzJ6VAIuwwh2QiDtsVX1xZgcGX4gD8= -k8s.io/component-base v0.35.0 h1:+yBrOhzri2S1BVqyVSvcM3PtPyx5GUxCK2tinZz1G94= -k8s.io/component-base v0.35.0/go.mod h1:85SCX4UCa6SCFt6p3IKAPej7jSnF3L8EbfSyMZayJR0= k8s.io/component-helpers v0.35.0 h1:wcXv7HJRksgVjM4VlXJ1CNFBpyDHruRI99RrBtrJceA= k8s.io/component-helpers v0.35.0/go.mod h1:ahX0m/LTYmu7fL3W8zYiIwnQ/5gT28Ex4o2pymF63Co= -k8s.io/controller-manager v0.35.0 h1:KteodmfVIRzfZ3RDaxhnHb72rswBxEngvdL9vuZOA9A= -k8s.io/controller-manager v0.35.0/go.mod h1:1bVuPNUG6/dpWpevsJpXioS0E0SJnZ7I/Wqc9Awyzm4= k8s.io/cri-api v0.35.0 h1:fxLSKyJHqbyCSUsg1rW4DRpmjSEM/elZ1GXzYTSLoDQ= k8s.io/cri-api v0.35.0/go.mod h1:Cnt29u/tYl1Se1cBRL30uSZ/oJ5TaIp4sZm1xDLvcMc= k8s.io/cri-client v0.35.0 h1:U1K4bteO93yioUS38804ybN+kWaon9zrzVtB37I3fCs= @@ -341,20 +349,12 @@ k8s.io/csi-translation-lib v0.35.0 h1:jdVC/9rv3lfHl5/MFQXqIVcEZEOXPbl4IPI8cczPdW k8s.io/csi-translation-lib v0.35.0/go.mod h1:/6R70QdDxBCrMkrLhIBLP4mdtL35hEoJ5a/c2s1k9z8= k8s.io/dynamic-resource-allocation v0.35.0 h1:St6dsCCylLg3HiFPcyHzFF8YQO6yziUDaVRLGdkrNH8= k8s.io/dynamic-resource-allocation v0.35.0/go.mod h1:uaFga3VJtwyfpfZwpuJG7mlurWGQaaiGUa+QZmooz2U= -k8s.io/endpointslice v0.35.0 h1:zLcYAHUhAApGld1kHS4klp6HTRIkn3r4uxitHJiN7PU= -k8s.io/endpointslice v0.35.0/go.mod h1:mHF/Zw1jYWpLWb2MRBrcmZlYvYXQuCcEgK+5TMaQiUE= k8s.io/externaljwt v0.35.0 h1:t2y/WYpxBB9/90DnLAB4cKmi7BdgaVCQZrwwASHjMsU= k8s.io/externaljwt v0.35.0/go.mod h1:BbmVxkdvNrL2ukF4m/AN2D2FBD3vp2df497nfcVl2Nc= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kms v0.35.0 h1:/x87FED2kDSo66csKtcYCEHsxF/DBlNl7LfJ1fVQs1o= -k8s.io/kms v0.35.0/go.mod h1:VT+4ekZAdrZDMgShK37vvlyHUVhwI9t/9tvh0AyCWmQ= -k8s.io/kube-aggregator v0.35.0 h1:FBtbuRFA7Ohe2QKirFZcJf8rgimC8oSaNiCi4pdU5xw= -k8s.io/kube-aggregator v0.35.0/go.mod h1:vKBRpQUfDryb7udwUwF3eCSvv3AJNgHtL4PGl6PqAg8= -k8s.io/kube-controller-manager v0.35.0 h1:NRMhS5mz6E/D2beojOj2/HcCa2thRPVf4vp4QxmFkjo= -k8s.io/kube-controller-manager v0.35.0/go.mod h1:M32fFkRScIW9KSPYUQBVqdjYrja5F2s4v5NrHEUVIJ8= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= +k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= +k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= +k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= k8s.io/kube-proxy v0.35.0 h1:erv2wYmGZ6nyu/FtmaIb+ORD3q2rfZ4Fhn7VXs/8cPQ= k8s.io/kube-proxy v0.35.0/go.mod h1:bd9lpN3uLLOOWc/CFZbkPEi9DTkzQQymbE8FqSU4bWk= k8s.io/kube-scheduler v0.35.0 h1:1uzns+SQl1ols3RXH/oxhOPd4fuicXliqWTBLbqIVRM= @@ -363,27 +363,25 @@ k8s.io/kubectl v0.35.0 h1:cL/wJKHDe8E8+rP3G7avnymcMg6bH6JEcR5w5uo06wc= k8s.io/kubectl v0.35.0/go.mod h1:VR5/TSkYyxZwrRwY5I5dDq6l5KXmiCb+9w8IKplk3Qo= k8s.io/kubelet v0.35.0 h1:8cgJHCBCKLYuuQ7/Pxb/qWbJfX1LXIw7790ce9xHq7c= k8s.io/kubelet v0.35.0/go.mod h1:ciRzAXn7C4z5iB7FhG1L2CGPPXLTVCABDlbXt/Zz8YA= -k8s.io/kubernetes v1.35.0 h1:PUOojD8c8E3csMP5NX+nLLne6SGqZjrYCscptyBfWMY= -k8s.io/kubernetes v1.35.0/go.mod h1:Tzk9Y9W/XUFFFgTUVg+BAowoFe+Pc7koGLuaiLHdcFg= k8s.io/metrics v0.35.0 h1:xVFoqtAGm2dMNJAcB5TFZJPCen0uEqqNt52wW7ABbX8= k8s.io/metrics v0.35.0/go.mod h1:g2Up4dcBygZi2kQSEQVDByFs+VUwepJMzzQLJJLpq4M= k8s.io/mount-utils v0.35.0 h1:UDE8RDeqmQh1u/yRd+GZC2EpDibiyAfmMEsm43lKNQI= k8s.io/mount-utils v0.35.0/go.mod h1:ppC4d+mUpfbAJr/V2E8vvxeCEckNM+S5b0kQBQjd3Pw= k8s.io/pod-security-admission v0.35.0 h1:tT3UHC+Q1mpFRe4IoVTu20ZAx+kqgKBZnewRnsDcyfc= k8s.io/pod-security-admission v0.35.0/go.mod h1:S+57PAqNo6DaUYjmtINiiXlYnEdShrOVMwSc7C4oYPg= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80= -sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= +k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= +k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= +sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= 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/multicluster-runtime v0.23.3 h1:vrzlXRzHTDsjspUAfoW2rCtr0agoI4q20p9x4Fz4png= -sigs.k8s.io/multicluster-runtime v0.23.3/go.mod h1:r/UA4GHgFoXCcR4tcvlZz7SiLx3l1kJKDuBAhILNIHs= +sigs.k8s.io/multicluster-runtime v0.24.1 h1:YlGqqk91ui0/VEXqemPd2+Z4UBmgvS2YwXaj2cItHQI= +sigs.k8s.io/multicluster-runtime v0.24.1/go.mod h1:4+GrvEeaX0hg5MVZT02JNhF2nKZauyGhifjrkbc7yhc= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs= -sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= From 17e2cf40a3f52f0be2fc1d7586945056edfba101 Mon Sep 17 00:00:00 2001 From: Alex Savanovich <40720931+savme@users.noreply.github.com> Date: Mon, 1 Jun 2026 14:54:32 +0200 Subject: [PATCH 2/2] feat: add kplane storage implementation --- Taskfile.yaml | 2 +- cmd/milo/apiserver/config.go | 14 +- cmd/milo/apiserver/server.go | 25 +- go.mod | 34 +- go.sum | 63 ++- .../apiserver/storage/kplane/decorator.go | 81 ++++ .../apiserver/storage/project/decorator.go | 59 --- internal/apiserver/storage/project/mux.go | 436 ------------------ .../apiserver/storage/project/providerwrap.go | 45 -- .../apiserver/storage/project/restoptions.go | 46 -- .../resourcemanager/project_controller.go | 34 +- 11 files changed, 192 insertions(+), 647 deletions(-) create mode 100644 internal/apiserver/storage/kplane/decorator.go delete mode 100644 internal/apiserver/storage/project/decorator.go delete mode 100644 internal/apiserver/storage/project/mux.go delete mode 100644 internal/apiserver/storage/project/providerwrap.go delete mode 100644 internal/apiserver/storage/project/restoptions.go diff --git a/Taskfile.yaml b/Taskfile.yaml index b95f48e4..dad26dcb 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -8,7 +8,7 @@ vars: # renovate: datasource=go depName=fybrik.io/crdoc CRDOC_VERSION: v0.6.4 # renovate: datasource=go depName=github.com/kyverno/chainsaw - CHAINSAW_VERSION: v0.2.13 + CHAINSAW_VERSION: v0.2.15 # Container image configuration MILO_IMAGE_NAME: "ghcr.io/milo-os/milo" MILO_IMAGE_TAG: "dev" diff --git a/cmd/milo/apiserver/config.go b/cmd/milo/apiserver/config.go index 1c99c9b7..f73a6012 100644 --- a/cmd/milo/apiserver/config.go +++ b/cmd/milo/apiserver/config.go @@ -51,6 +51,7 @@ import ( sessionsbackend "go.miloapis.com/milo/internal/apiserver/identity/sessions" useridentitiesbackend "go.miloapis.com/milo/internal/apiserver/identity/useridentities" identitystorage "go.miloapis.com/milo/internal/apiserver/storage/identity" + kplanestorage "go.miloapis.com/milo/internal/apiserver/storage/kplane" admissionquota "go.miloapis.com/milo/internal/quota/admission" discoveryapi "go.miloapis.com/milo/pkg/apis/discovery" identityapi "go.miloapis.com/milo/pkg/apis/identity" @@ -371,9 +372,12 @@ func NewConfig(opts options.CompletedOptions) (*Config, error) { if registry != nil { h = discoveryctx.DiscoveryContextFilter(h, registry) } + // Bridge Milo's request.WithProject(ctx, ...) to kplane's mc.WithCluster(ctx, ...) + // after the project router has parsed the URL but before the rest of the chain runs. + inner := kplanestorage.WithProjectAsCluster(DefaultBuildHandlerChain(h, c, loopbackClientConfig)) return datumfilters.ProjectRouterWithRequestInfo( - DefaultBuildHandlerChain(h, c, loopbackClientConfig), // build stock chain first - c.RequestInfoResolver, // then wrap with router + inner, + c.RequestInfoResolver, ) } @@ -405,8 +409,9 @@ func NewConfig(opts options.CompletedOptions) (*Config, error) { if registry != nil { h = discoveryctx.DiscoveryContextFilter(h, registry) } + inner := kplanestorage.WithProjectAsCluster(DefaultBuildHandlerChain(h, c, loopbackClientConfig)) return datumfilters.ProjectRouterWithRequestInfo( - DefaultBuildHandlerChain(h, c, loopbackClientConfig), + inner, c.RequestInfoResolver, ) } @@ -431,8 +436,9 @@ func NewConfig(opts options.CompletedOptions) (*Config, error) { if registry != nil { h = discoveryctx.DiscoveryContextFilter(h, registry) } + inner := kplanestorage.WithProjectAsCluster(DefaultBuildHandlerChain(h, c, loopbackClientConfig)) return datumfilters.ProjectRouterWithRequestInfo( - DefaultBuildHandlerChain(h, c, loopbackClientConfig), + inner, c.RequestInfoResolver, ) } diff --git a/cmd/milo/apiserver/server.go b/cmd/milo/apiserver/server.go index c8e8f01c..da872b19 100644 --- a/cmd/milo/apiserver/server.go +++ b/cmd/milo/apiserver/server.go @@ -11,7 +11,7 @@ import ( "github.com/spf13/cobra" crd "go.miloapis.com/milo/config/crd" "go.miloapis.com/milo/internal/apiserver/admission/plugin/namespace/lifecycle" - projectstorage "go.miloapis.com/milo/internal/apiserver/storage/project" + kplanestorage "go.miloapis.com/milo/internal/apiserver/storage/kplane" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // ← add / keep this @@ -21,20 +21,20 @@ import ( "k8s.io/apiserver/pkg/admission" genericapifilters "k8s.io/apiserver/pkg/endpoints/filters" genericapiserver "k8s.io/apiserver/pkg/server" + apiservercompat "k8s.io/apiserver/pkg/util/compatibility" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/apiserver/pkg/util/notfoundhandler" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" cliflag "k8s.io/component-base/cli/flag" "k8s.io/component-base/cli/globalflag" + basecompatibility "k8s.io/component-base/compatibility" "k8s.io/component-base/logs" logsapi "k8s.io/component-base/logs/api/v1" _ "k8s.io/component-base/metrics/prometheus/workqueue" "k8s.io/component-base/term" "k8s.io/component-base/version" "k8s.io/component-base/version/verflag" - basecompatibility "k8s.io/component-base/compatibility" - apiservercompat "k8s.io/apiserver/pkg/util/compatibility" "k8s.io/klog/v2" aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver" @@ -299,13 +299,15 @@ func Run(ctx context.Context, opts options.CompletedOptions) error { func CreateServerChain(config CompletedConfig) (*aggregatorapiserver.APIAggregator, error) { notFoundHandler := notfoundhandler.New(config.ControlPlane.Generic.Serializer, genericapifilters.NoMuxAndDiscoveryIncompleteKey) - loopbackConfig := config.ControlPlane.Generic.LoopbackClientConfig - + // Native API providers read the control-plane getter when InstallAPIs calls + // NewRESTStorage, so wrapping it once here covers them; CRD storage uses the + // apiextensions getters wrapped below. config.APIExtensions.GenericConfig.RESTOptionsGetter = - projectstorage.WithProjectAwareDecoratorAndConfig(config.APIExtensions.GenericConfig.RESTOptionsGetter, loopbackConfig) - + kplanestorage.WithKplaneStorage(config.APIExtensions.GenericConfig.RESTOptionsGetter) config.APIExtensions.ExtraConfig.CRDRESTOptionsGetter = - projectstorage.WithProjectAwareDecoratorAndConfig(config.APIExtensions.ExtraConfig.CRDRESTOptionsGetter, loopbackConfig) + kplanestorage.WithKplaneStorage(config.APIExtensions.ExtraConfig.CRDRESTOptionsGetter) + config.ControlPlane.Generic.RESTOptionsGetter = + kplanestorage.WithKplaneStorage(config.ControlPlane.Generic.RESTOptionsGetter) apiExtensionsServer, err := config.APIExtensions.New(genericapiserver.NewEmptyDelegateWithCustomHandler(notFoundHandler)) if err != nil { @@ -353,12 +355,7 @@ func CreateServerChain(config CompletedConfig) (*aggregatorapiserver.APIAggregat return nil, fmt.Errorf("failed to create storage providers: %w", err) } - wrapped := make([]controlplaneapiserver.RESTStorageProvider, 0, len(storageProviders)) - for _, p := range storageProviders { - wrapped = append(wrapped, projectstorage.WrapProvider(p)) - } - - if err := nativeAPIs.InstallAPIs(wrapped...); err != nil { + if err := nativeAPIs.InstallAPIs(storageProviders...); err != nil { return nil, fmt.Errorf("failed to install APIs: %w", err) } diff --git a/go.mod b/go.mod index e5d7591e..f08c0138 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,10 @@ go 1.26.3 require ( github.com/blang/semver/v4 v4.0.0 github.com/go-logr/logr v1.4.3 - github.com/google/cel-go v0.26.0 + github.com/google/cel-go v0.26.1 + github.com/kplane-dev/apiserver v0.0.10 github.com/spf13/cobra v1.10.2 - github.com/spf13/pflag v1.0.9 + github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 go.opentelemetry.io/otel v1.41.0 @@ -19,7 +20,7 @@ require ( k8s.io/apiextensions-apiserver v0.36.0 k8s.io/apimachinery v0.36.0 k8s.io/apiserver v0.36.0 - k8s.io/client-go v0.36.0 + k8s.io/client-go v1.5.2 k8s.io/component-base v0.36.0 k8s.io/controller-manager v0.35.0 k8s.io/klog/v2 v2.140.0 @@ -37,7 +38,7 @@ require ( cyphar.com/go-pathrs v0.2.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -54,9 +55,20 @@ require ( github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/jsonpointer v0.22.0 // indirect + github.com/go-openapi/jsonreference v0.21.1 // indirect + github.com/go-openapi/swag v0.24.1 // indirect + github.com/go-openapi/swag/cmdutils v0.24.0 // indirect + github.com/go-openapi/swag/conv v0.24.0 // indirect + github.com/go-openapi/swag/fileutils v0.24.0 // indirect + github.com/go-openapi/swag/jsonname v0.24.0 // indirect + github.com/go-openapi/swag/jsonutils v0.24.0 // indirect + github.com/go-openapi/swag/loading v0.24.0 // indirect + github.com/go-openapi/swag/mangling v0.24.0 // indirect + github.com/go-openapi/swag/netutils v0.24.0 // indirect + github.com/go-openapi/swag/stringutils v0.24.0 // indirect + github.com/go-openapi/swag/typeutils v0.24.0 // indirect + github.com/go-openapi/swag/yamlutils v0.24.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.7.0 // indirect @@ -68,8 +80,10 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kplane-dev/informer v0.0.0-00010101000000-000000000000 // indirect + github.com/kplane-dev/storage v0.0.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/moby/spdystream v0.5.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/term v0.5.0 // indirect @@ -80,13 +94,13 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/selinux v1.13.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/pquerna/cachecontrol v0.1.0 // indirect + github.com/pquerna/cachecontrol v0.2.0 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/procfs v0.19.2 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect - github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/stoewer/go-strcase v1.3.1 // indirect github.com/x448/float16 v0.8.4 // indirect go.etcd.io/etcd/api/v3 v3.6.7 // indirect go.etcd.io/etcd/client/pkg/v3 v3.6.7 // indirect diff --git a/go.sum b/go.sum index 84cb677b..ca70d53a 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= -github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -60,12 +60,34 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/jsonpointer v0.22.0 h1:TmMhghgNef9YXxTu1tOopo+0BGEytxA+okbry0HjZsM= +github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU= +github.com/go-openapi/jsonreference v0.21.1 h1:bSKrcl8819zKiOgxkbVNRUBIr6Wwj9KYrDbMjRs0cDA= +github.com/go-openapi/jsonreference v0.21.1/go.mod h1:PWs8rO4xxTUqKGu+lEvvCxD5k2X7QYkKAepJyCmSTT8= +github.com/go-openapi/swag v0.24.1 h1:DPdYTZKo6AQCRqzwr/kGkxJzHhpKxZ9i/oX0zag+MF8= +github.com/go-openapi/swag v0.24.1/go.mod h1:sm8I3lCPlspsBBwUm1t5oZeWZS0s7m/A+Psg0ooRU0A= +github.com/go-openapi/swag/cmdutils v0.24.0 h1:KlRCffHwXFI6E5MV9n8o8zBRElpY4uK4yWyAMWETo9I= +github.com/go-openapi/swag/cmdutils v0.24.0/go.mod h1:uxib2FAeQMByyHomTlsP8h1TtPd54Msu2ZDU/H5Vuf8= +github.com/go-openapi/swag/conv v0.24.0 h1:ejB9+7yogkWly6pnruRX45D1/6J+ZxRu92YFivx54ik= +github.com/go-openapi/swag/conv v0.24.0/go.mod h1:jbn140mZd7EW2g8a8Y5bwm8/Wy1slLySQQ0ND6DPc2c= +github.com/go-openapi/swag/fileutils v0.24.0 h1:U9pCpqp4RUytnD689Ek/N1d2N/a//XCeqoH508H5oak= +github.com/go-openapi/swag/fileutils v0.24.0/go.mod h1:3SCrCSBHyP1/N+3oErQ1gP+OX1GV2QYFSnrTbzwli90= +github.com/go-openapi/swag/jsonname v0.24.0 h1:2wKS9bgRV/xB8c62Qg16w4AUiIrqqiniJFtZGi3dg5k= +github.com/go-openapi/swag/jsonname v0.24.0/go.mod h1:GXqrPzGJe611P7LG4QB9JKPtUZ7flE4DOVechNaDd7Q= +github.com/go-openapi/swag/jsonutils v0.24.0 h1:F1vE1q4pg1xtO3HTyJYRmEuJ4jmIp2iZ30bzW5XgZts= +github.com/go-openapi/swag/jsonutils v0.24.0/go.mod h1:vBowZtF5Z4DDApIoxcIVfR8v0l9oq5PpYRUuteVu6f0= +github.com/go-openapi/swag/loading v0.24.0 h1:ln/fWTwJp2Zkj5DdaX4JPiddFC5CHQpvaBKycOlceYc= +github.com/go-openapi/swag/loading v0.24.0/go.mod h1:gShCN4woKZYIxPxbfbyHgjXAhO61m88tmjy0lp/LkJk= +github.com/go-openapi/swag/mangling v0.24.0 h1:PGOQpViCOUroIeak/Uj/sjGAq9LADS3mOyjznmHy2pk= +github.com/go-openapi/swag/mangling v0.24.0/go.mod h1:Jm5Go9LHkycsz0wfoaBDkdc4CkpuSnIEf62brzyCbhc= +github.com/go-openapi/swag/netutils v0.24.0 h1:Bz02HRjYv8046Ycg/w80q3g9QCWeIqTvlyOjQPDjD8w= +github.com/go-openapi/swag/netutils v0.24.0/go.mod h1:WRgiHcYTnx+IqfMCtu0hy9oOaPR0HnPbmArSRN1SkZM= +github.com/go-openapi/swag/stringutils v0.24.0 h1:i4Z/Jawf9EvXOLUbT97O0HbPUja18VdBxeadyAqS1FM= +github.com/go-openapi/swag/stringutils v0.24.0/go.mod h1:5nUXB4xA0kw2df5PRipZDslPJgJut+NjL7D25zPZ/4w= +github.com/go-openapi/swag/typeutils v0.24.0 h1:d3szEGzGDf4L2y1gYOSSLeK6h46F+zibnEas2Jm/wIw= +github.com/go-openapi/swag/typeutils v0.24.0/go.mod h1:q8C3Kmk/vh2VhpCLaoR2MVWOGP8y7Jc8l82qCTd1DYI= +github.com/go-openapi/swag/yamlutils v0.24.0 h1:bhw4894A7Iw6ne+639hsBNRHg9iZg/ISrOVr+sJGp4c= +github.com/go-openapi/swag/yamlutils v0.24.0/go.mod h1:DpKv5aYuaGm/sULePoeiG8uwMpZSfReo1HR3Ik0yaG8= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -76,8 +98,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI= -github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= +github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ= +github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -109,6 +131,10 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/kplane-dev/apiserver v0.0.10 h1:VoS/yl7VpYCv2XvYiPjeRSnzrr66Y8NEoxcHYNEjFo4= +github.com/kplane-dev/apiserver v0.0.10/go.mod h1:C4sG1nUuTiUwrx220yrl2flhEi5580NF5JwlrC7d6no= +github.com/kplane-dev/informer v0.0.0-20260404055613-d9279cfd5e9b h1:Z1+b+fPm/I2STcdIT3Psb3OYng2xYYILMmdgD55KEm8= +github.com/kplane-dev/informer v0.0.0-20260404055613-d9279cfd5e9b/go.mod h1:y+IpeQX/vAaf7h6d+fwTYQ9kqdpwJdjHCc5KuN4JcC4= github.com/kplane-dev/kubernetes v0.0.0-20260404055358-aac72e7d04ad h1:249TYMHw60P6D58XGVjf7G2TNp708zRyNa0RbXfQAUQ= github.com/kplane-dev/kubernetes v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:9uEdeMBkUjkGSL2ioy2pKr0+aLNIvmOan7p8F7ENHbk= github.com/kplane-dev/kubernetes/staging/src/k8s.io/api v0.0.0-20260404055358-aac72e7d04ad h1:0k/XM+mWOjNWWmc/HkYP5qYcIw72vssnGhS6i7jidBE= @@ -133,14 +159,16 @@ github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260 github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:KXJ9MlZYxlzOWKhHqfdxOTDdmfk/+ftdOwN//JGQs0g= github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260404055358-aac72e7d04ad h1:BZew8n8DewnquBgR4mEKdgvoq3EVV3/4EMyW37KAd+8= github.com/kplane-dev/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260404055358-aac72e7d04ad/go.mod h1:fvSj40FltpPVU4KLda+I/WhFTwwiGuPpzpy+5UeiOaM= +github.com/kplane-dev/storage v0.0.0-20260404055526-b175d95c9fe7 h1:mvqa9LueCYKUDY/2Hsrg4E7/UwtFcps5dAua31PgS+0= +github.com/kplane-dev/storage v0.0.0-20260404055526-b175d95c9fe7/go.mod h1:add4/uRzmN2LrWjbWvoEGfIFBD5E1gfG+FJ/V/JN8SI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 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/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= @@ -170,8 +198,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= -github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= +github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k= +github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= @@ -191,10 +219,11 @@ github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= -github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs= +github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= diff --git a/internal/apiserver/storage/kplane/decorator.go b/internal/apiserver/storage/kplane/decorator.go new file mode 100644 index 00000000..a4531b36 --- /dev/null +++ b/internal/apiserver/storage/kplane/decorator.go @@ -0,0 +1,81 @@ +// Package kplane wires Milo's apiserver into kplane-dev's shared-storage +// stack. A single per-resource cacher (built via kplane-dev/storage's +// cluster-identity-aware decorator) provides per-project isolation by +// embedding the project name in the storage key. +// +// All actual storage and key-rewriting logic is delegated to +// kplane-dev/apiserver/pkg/multicluster; this file is a thin adapter that +// constructs the right Options for Milo and translates Milo's existing +// request.ProjectID(ctx) carrier to kplane's mc.WithCluster context. +package kplane + +import ( + "net/http" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + generic "k8s.io/apiserver/pkg/registry/generic" + + mc "github.com/kplane-dev/apiserver/pkg/multicluster" + + "go.miloapis.com/milo/pkg/request" +) + +// ServerName is reported in kplane's storage metrics. +const ServerName = "milo-apiserver" + +// Options returns the multicluster options Milo uses when running on kplane +// storage. EtcdPrefix is left empty so kplane uses its default (/registry), +// matching the upstream apiserver default; the underlying storage decorator +// re-reads the actual etcd prefix from each ConfigForResource at runtime. +func Options() mc.Options { + return mc.Options{ + DefaultCluster: mc.DefaultClusterName, // "root" — used when no project is in context + ServerName: ServerName, + } +} + +// WithKplaneStorage swaps the storage decorator on every RESTOptions returned +// by inner with kplane's cluster-identity decorator, leaving CRD definitions +// alone (those stay cluster-global so discovery is shared across projects). +func WithKplaneStorage(inner generic.RESTOptionsGetter) generic.RESTOptionsGetter { + return kplaneGetter{ + delegate: mc.RESTOptionsDecorator{ + Delegate: inner, + Options: Options(), + }, + } +} + +type kplaneGetter struct { + delegate mc.RESTOptionsDecorator +} + +func (g kplaneGetter) GetRESTOptions(gr schema.GroupResource, example runtime.Object) (generic.RESTOptions, error) { + // CRDs themselves stay global. Falling back to the underlying getter here + // preserves the existing behavior (a single, project-unaware store for + // /apis/apiextensions.k8s.io/v1/customresourcedefinitions). CR *instances* + // flow through the kplane decorator like any other resource. + if gr.Group == "apiextensions.k8s.io" && gr.Resource == "customresourcedefinitions" { + return g.delegate.Delegate.GetRESTOptions(gr, example) + } + return g.delegate.GetRESTOptions(gr, example) +} + +// WithProjectAsCluster bridges Milo's request.ProjectID(ctx) marker into +// kplane's mc.WithCluster(ctx, ...) context so the kplane storage layer can +// extract the cluster ID via its own mc.FromContext / mc.FromContextScope +// helpers. +// +// Install this middleware AFTER pkg/server/filters.ProjectRouterWithRequestInfo +// — which is the call that stashes the project ID via request.WithProject — +// and BEFORE anything that consults storage. +func WithProjectAsCluster(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if proj, ok := request.ProjectID(r.Context()); ok && proj != "" { + r = r.WithContext(mc.WithCluster(r.Context(), proj, false)) + } + next.ServeHTTP(w, r) + }) +} diff --git a/internal/apiserver/storage/project/decorator.go b/internal/apiserver/storage/project/decorator.go deleted file mode 100644 index 9350a675..00000000 --- a/internal/apiserver/storage/project/decorator.go +++ /dev/null @@ -1,59 +0,0 @@ -package projectstorage - -import ( - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/rest" - - generic "k8s.io/apiserver/pkg/registry/generic" - "k8s.io/apiserver/pkg/storage" - storagebackend "k8s.io/apiserver/pkg/storage/storagebackend" - factory "k8s.io/apiserver/pkg/storage/storagebackend/factory" - - "k8s.io/client-go/tools/cache" -) - -// ProjectAwareDecorator builds per-project storage isolation using etcd prefix separation. -// When loopbackConfig is provided, automatically bootstraps milo-system namespace in project control planes. -func ProjectAwareDecorator(gr schema.GroupResource, inner generic.StorageDecorator, loopbackConfig *rest.Config) generic.StorageDecorator { - return func( - cfg *storagebackend.ConfigForResource, - resourcePrefix string, - keyFunc func(obj runtime.Object) (string, error), - newFunc func() runtime.Object, - newListFunc func() runtime.Object, - getAttrs storage.AttrFunc, - triggerFn storage.IndexerFuncs, // <— changed type - indexers *cache.Indexers, // <— from client-go/tools/cache - ) (storage.Interface, factory.DestroyFunc, error) { - - // Build default child (no project in ctx). - defS, defDestroy, err := inner(cfg, resourcePrefix, keyFunc, newFunc, newListFunc, getAttrs, triggerFn, indexers) - if err != nil { - return nil, nil, err - } - - mux := &projectMux{ - inner: inner, - cfg: *cfg, // copy - loopbackConfig: loopbackConfig, - args: decoratorArgs{ - resourceGroup: gr.Group, // "" means core - resourceKind: gr.Resource, // plural - resourcePrefix: resourcePrefix, - - keyFunc: keyFunc, - newFunc: newFunc, - newListFunc: newListFunc, - getAttrs: getAttrs, - triggerFn: triggerFn, - indexers: indexers, - }, - children: map[string]*child{ - "": {s: defS, destroy: defDestroy}, - }, - versioner: defS.Versioner(), - } - return mux, mux.destroyAll, nil - } -} diff --git a/internal/apiserver/storage/project/mux.go b/internal/apiserver/storage/project/mux.go deleted file mode 100644 index 89ae23e5..00000000 --- a/internal/apiserver/storage/project/mux.go +++ /dev/null @@ -1,436 +0,0 @@ -package projectstorage - -import ( - "context" - "fmt" - "path" - "strings" - "sync" - "time" - - "go.miloapis.com/milo/pkg/request" - - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - - generic "k8s.io/apiserver/pkg/registry/generic" - "k8s.io/apiserver/pkg/storage" - storagebackend "k8s.io/apiserver/pkg/storage/storagebackend" - factory "k8s.io/apiserver/pkg/storage/storagebackend/factory" - k8smetrics "k8s.io/component-base/metrics" - k8slegacy "k8s.io/component-base/metrics/legacyregistry" - "k8s.io/klog/v2" - - "k8s.io/client-go/tools/cache" -) - -// -------------------- metrics -------------------- - -var ( - childCreations = k8smetrics.NewCounterVec( - &k8smetrics.CounterOpts{ - Name: "projectstorage_child_creations_total", - Help: "Child storage creations by resource type", - StabilityLevel: k8smetrics.ALPHA, - }, - []string{"resource_group", "resource_kind"}, - ) - - firstReady = k8smetrics.NewHistogramVec( - &k8smetrics.HistogramOpts{ - Name: "projectstorage_first_ready_seconds", - Help: "Time from child creation to first successful op", - Buckets: []float64{0.02, 0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10}, - StabilityLevel: k8smetrics.ALPHA, - }, - []string{"resource_group", "resource_kind"}, - ) - - reinitErrors = k8smetrics.NewCounterVec( - &k8smetrics.CounterOpts{ - Name: "projectstorage_reinitializing_errors_total", - Help: "Ops that hit 'storage is (re)initializing'", - StabilityLevel: k8smetrics.ALPHA, - }, - []string{"resource_group", "resource_kind", "verb"}, - ) -) - -func init() { - k8slegacy.MustRegister(childCreations, firstReady, reinitErrors) -} - -func isReinitErr(err error) bool { - return err != nil && strings.Contains(err.Error(), "storage is (re)initializing") -} - -func incrReinit(group, kind, verb string) { - reinitErrors.WithLabelValues(group, kind, verb).Inc() -} - -func recordFirstReady(c *child, group, kind string) { - c.readyOnce.Do(func() { - firstReady.WithLabelValues(group, kind). - Observe(time.Since(c.created).Seconds()) - }) -} - -// -------------------- child & args -------------------- - -type child struct { - s storage.Interface - destroy factory.DestroyFunc - created time.Time - readyOnce sync.Once -} - -type decoratorArgs struct { - // labels/identity - resourceGroup string // e.g. "", "apps", "iam.miloapis.com" (empty means core) - resourceKind string // resource plural (e.g., "roles", "protectedresources") - - resourcePrefix string - keyFunc func(obj runtime.Object) (string, error) - newFunc func() runtime.Object - newListFunc func() runtime.Object - getAttrs storage.AttrFunc - triggerFn storage.IndexerFuncs - indexers *cache.Indexers -} - -// -------------------- instrumented wrapper -------------------- - -// instrumentedStorage wraps a storage.Interface to emit metrics once per child -type instrumentedStorage struct { - inner storage.Interface - child *child - - // normalized labels - group string // API group ("" => "core" when you query; we keep "" here) - kind string // resource plural -} - -func (i *instrumentedStorage) markSuccess() { - recordFirstReady(i.child, i.group, i.kind) -} -func (i *instrumentedStorage) markReinit(verb string, err error) error { - if isReinitErr(err) { - incrReinit(i.group, i.kind, verb) - } - return err -} - -func (i *instrumentedStorage) Versioner() storage.Versioner { return i.inner.Versioner() } - -func (i *instrumentedStorage) Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error { - if err := i.inner.Create(ctx, key, obj, out, ttl); err != nil { - return i.markReinit("create", err) - } - i.markSuccess() - return nil -} -func (i *instrumentedStorage) Delete(ctx context.Context, key string, out runtime.Object, - precond *storage.Preconditions, validateDeletion storage.ValidateObjectFunc, - cachedExistingObject runtime.Object, opts storage.DeleteOptions) error { - if err := i.inner.Delete(ctx, key, out, precond, validateDeletion, cachedExistingObject, opts); err != nil { - return i.markReinit("delete", err) - } - i.markSuccess() - return nil -} -func (i *instrumentedStorage) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) { - w, err := i.inner.Watch(ctx, key, opts) - if err != nil { - return nil, i.markReinit("watch", err) - } - i.markSuccess() - return w, nil -} -func (i *instrumentedStorage) Get(ctx context.Context, key string, opts storage.GetOptions, objPtr runtime.Object) error { - if err := i.inner.Get(ctx, key, opts, objPtr); err != nil { - return i.markReinit("get", err) - } - i.markSuccess() - return nil -} -func (i *instrumentedStorage) GetList(ctx context.Context, key string, opts storage.ListOptions, listObj runtime.Object) error { - if err := i.inner.GetList(ctx, key, opts, listObj); err != nil { - return i.markReinit("list", err) - } - i.markSuccess() - return nil -} -func (i *instrumentedStorage) GuaranteedUpdate(ctx context.Context, key string, out runtime.Object, - ignoreNotFound bool, precond *storage.Preconditions, tryUpdate storage.UpdateFunc, suggestion runtime.Object) error { - if err := i.inner.GuaranteedUpdate(ctx, key, out, ignoreNotFound, precond, tryUpdate, suggestion); err != nil { - return i.markReinit("update", err) - } - i.markSuccess() - return nil -} -func (i *instrumentedStorage) ReadinessCheck() error { return i.inner.ReadinessCheck() } -func (i *instrumentedStorage) RequestWatchProgress(ctx context.Context) error { - if err := i.inner.RequestWatchProgress(ctx); err != nil { - return i.markReinit("watch_progress", err) - } - return nil -} -func (i *instrumentedStorage) Stats(ctx context.Context) (storage.Stats, error) { - return i.inner.Stats(ctx) -} -func (i *instrumentedStorage) GetCurrentResourceVersion(ctx context.Context) (uint64, error) { - return i.inner.GetCurrentResourceVersion(ctx) -} -func (i *instrumentedStorage) EnableResourceSizeEstimation(fn storage.KeysFunc) error { - return i.inner.EnableResourceSizeEstimation(fn) -} -func (i *instrumentedStorage) CompactRevision() int64 { return i.inner.CompactRevision() } - -// -------------------- mux -------------------- - -// projectMux implements storage.Interface and routes to a per-project child. -type projectMux struct { - mu sync.RWMutex - children map[string]*child - versioner storage.Versioner - - inner generic.StorageDecorator - cfg storagebackend.ConfigForResource - args decoratorArgs - loopbackConfig *rest.Config -} - -func (m *projectMux) Versioner() storage.Versioner { return m.versioner } - -func (m *projectMux) childForProject(project string) (storage.Interface, error) { - m.mu.RLock() - if c, ok := m.children[project]; ok { - m.mu.RUnlock() - return c.s, nil - } - m.mu.RUnlock() - - m.mu.Lock() - defer m.mu.Unlock() - if c, ok := m.children[project]; ok { - return c.s, nil - } - - cfg2 := m.cfg // copy - cfg2.Config.Prefix = "/" + path.Join("projects", project) - - s, destroy, err := m.inner( - &cfg2, - m.args.resourcePrefix, - m.args.keyFunc, - m.args.newFunc, - m.args.newListFunc, - m.args.getAttrs, - m.args.triggerFn, - m.args.indexers, - ) - if err != nil { - return nil, err - } - if m.versioner == nil { - m.versioner = s.Versioner() - } - if m.children == nil { - m.children = make(map[string]*child, 1) - } - - // Wrap the child once with instrumentation. - c := &child{s: s, destroy: destroy, created: time.Now()} - wrapped := &instrumentedStorage{ - inner: s, - child: c, - group: m.args.resourceGroup, - kind: m.args.resourceKind, - } - c.s = wrapped - - m.children[project] = c - childCreations.WithLabelValues(m.args.resourceGroup, m.args.resourceKind).Inc() - - // Bootstrap system namespace synchronously to prevent resource creation failures - if project != "" && m.loopbackConfig != nil { - m.bootstrapMiloSystemNamespace(project) - } - - return c.s, nil -} - -func (m *projectMux) destroyAll() { - m.mu.Lock() - defer m.mu.Unlock() - for k, c := range m.children { - if c.destroy != nil { - c.destroy() - } - delete(m.children, k) - } -} - -// bootstrapMiloSystemNamespace ensures milo-system namespace exists in the project control plane. -// Called synchronously during storage initialization to prevent quota resource creation failures. -func (m *projectMux) bootstrapMiloSystemNamespace(projectName string) { - cfg := rest.CopyConfig(m.loopbackConfig) - cfg.Host = strings.TrimSuffix(cfg.Host, "/") + fmt.Sprintf("/apis/resourcemanager.miloapis.com/v1alpha1/projects/%s/control-plane", projectName) - - clientset, err := kubernetes.NewForConfig(cfg) - if err != nil { - klog.Errorf("Failed to create client for project %s: %v", projectName, err) - return - } - - ctx := context.Background() - - _, err = clientset.CoreV1().Namespaces().Get(ctx, "milo-system", metav1.GetOptions{}) - if err == nil { - return - } - if !apierrors.IsNotFound(err) { - klog.Errorf("Failed to check for milo-system namespace in project %s: %v", projectName, err) - return - } - - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "milo-system", - Labels: map[string]string{ - "miloapis.com/system": "true", - }, - }, - } - - _, err = clientset.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}) - if err != nil && !apierrors.IsAlreadyExists(err) { - klog.Errorf("Failed to create milo-system namespace in project %s: %v", projectName, err) - return - } -} - -func (m *projectMux) pick(ctx context.Context) (storage.Interface, error) { - if proj, ok := request.ProjectID(ctx); ok && proj != "" { - return m.childForProject(proj) - } - return m.childForProject("") -} - -// ---------- storage.Interface forwarding ---------- - -func (m *projectMux) Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error { - s, err := m.pick(ctx) - if err != nil { - return err - } - return s.Create(ctx, key, obj, out, ttl) -} - -func (m *projectMux) Delete(ctx context.Context, key string, out runtime.Object, precond *storage.Preconditions, - validateDeletion storage.ValidateObjectFunc, cachedExistingObject runtime.Object, opts storage.DeleteOptions) error { - s, err := m.pick(ctx) - if err != nil { - return err - } - return s.Delete(ctx, key, out, precond, validateDeletion, cachedExistingObject, opts) -} - -func (m *projectMux) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) { - s, err := m.pick(ctx) - if err != nil { - return nil, err - } - return s.Watch(ctx, key, opts) -} - -func (m *projectMux) Get(ctx context.Context, key string, opts storage.GetOptions, objPtr runtime.Object) error { - s, err := m.pick(ctx) - if err != nil { - return err - } - return s.Get(ctx, key, opts, objPtr) -} - -func (m *projectMux) GetList(ctx context.Context, key string, opts storage.ListOptions, listObj runtime.Object) error { - s, err := m.pick(ctx) - if err != nil { - return err - } - return s.GetList(ctx, key, opts, listObj) -} - -func (m *projectMux) GuaranteedUpdate(ctx context.Context, key string, out runtime.Object, ignoreNotFound bool, - precond *storage.Preconditions, tryUpdate storage.UpdateFunc, suggestion runtime.Object) error { - s, err := m.pick(ctx) - if err != nil { - return err - } - return s.GuaranteedUpdate(ctx, key, out, ignoreNotFound, precond, tryUpdate, suggestion) -} - -// ReadinessCheck proxies to the appropriate child (defaults to the "" project). -func (m *projectMux) ReadinessCheck() error { - m.mu.RLock() - c := m.children[""] - m.mu.RUnlock() - if c == nil { - if _, err := m.childForProject(""); err != nil { - return err - } - m.mu.RLock() - c = m.children[""] - m.mu.RUnlock() - } - return c.s.ReadinessCheck() -} - -func (m *projectMux) RequestWatchProgress(ctx context.Context) error { - s, err := m.pick(ctx) - if err != nil { - return err - } - return s.RequestWatchProgress(ctx) -} - -func (m *projectMux) Stats(ctx context.Context) (storage.Stats, error) { - s, err := m.pick(ctx) - if err != nil { - return storage.Stats{}, err - } - return s.Stats(ctx) -} - -func (m *projectMux) GetCurrentResourceVersion(ctx context.Context) (uint64, error) { - s, err := m.pick(ctx) - if err != nil { - return 0, err - } - return s.GetCurrentResourceVersion(ctx) -} - -func (m *projectMux) EnableResourceSizeEstimation(fn storage.KeysFunc) error { - m.mu.RLock() - defer m.mu.RUnlock() - for _, c := range m.children { - if err := c.s.EnableResourceSizeEstimation(fn); err != nil { - return err - } - } - return nil -} - -func (m *projectMux) CompactRevision() int64 { - m.mu.RLock() - c := m.children[""] - m.mu.RUnlock() - if c == nil { - return 0 - } - return c.s.CompactRevision() -} diff --git a/internal/apiserver/storage/project/providerwrap.go b/internal/apiserver/storage/project/providerwrap.go deleted file mode 100644 index 285816da..00000000 --- a/internal/apiserver/storage/project/providerwrap.go +++ /dev/null @@ -1,45 +0,0 @@ -package projectstorage - -import ( - generic "k8s.io/apiserver/pkg/registry/generic" - apiserver "k8s.io/apiserver/pkg/server" - serverstorage "k8s.io/apiserver/pkg/server/storage" - controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver" -) - -// ---------- common patching logic ------------------------------------- -type baseDecorator struct { - inner controlplaneapiserver.RESTStorageProvider -} - -func (b baseDecorator) GroupName() string { return b.inner.GroupName() } - -func (b baseDecorator) NewRESTStorage( - cfg serverstorage.APIResourceConfigSource, - getter generic.RESTOptionsGetter, -) (apiserver.APIGroupInfo, error) { - - getter = WithProjectAwareDecorator(getter) - - agi, err := b.inner.NewRESTStorage(cfg, getter) - if err != nil { - return agi, err - } - - return agi, nil -} - -// ---------- wrapper *with* PostStartHook ------------------------------- -type withHook struct{ baseDecorator } - -func (w withHook) PostStartHook() (string, apiserver.PostStartHookFunc, error) { - return w.inner.(apiserver.PostStartHookProvider).PostStartHook() -} - -// ---------- factory ---------------------------------------------------- -func WrapProvider(p controlplaneapiserver.RESTStorageProvider) controlplaneapiserver.RESTStorageProvider { - if _, ok := p.(apiserver.PostStartHookProvider); ok { - return withHook{baseDecorator{inner: p}} - } - return baseDecorator{inner: p} -} diff --git a/internal/apiserver/storage/project/restoptions.go b/internal/apiserver/storage/project/restoptions.go deleted file mode 100644 index 17278259..00000000 --- a/internal/apiserver/storage/project/restoptions.go +++ /dev/null @@ -1,46 +0,0 @@ -package projectstorage - -import ( - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/rest" - - generic "k8s.io/apiserver/pkg/registry/generic" - genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" -) - -// Wrap the upstream RESTOptionsGetter to install a per-project decorator. -func WithProjectAwareDecorator(inner generic.RESTOptionsGetter) generic.RESTOptionsGetter { - return roGetter{inner: inner, loopbackConfig: nil} -} - -// WithProjectAwareDecoratorAndConfig wraps the RESTOptionsGetter with project-aware storage -// and provides a loopback config for bootstrapping project namespaces. -func WithProjectAwareDecoratorAndConfig(inner generic.RESTOptionsGetter, loopbackConfig *rest.Config) generic.RESTOptionsGetter { - return roGetter{inner: inner, loopbackConfig: loopbackConfig} -} - -type roGetter struct { - inner generic.RESTOptionsGetter - loopbackConfig *rest.Config -} - -// NOTE: matches your two-arg signature (GroupResource, runtime.Object). -func (g roGetter) GetRESTOptions(gr schema.GroupResource, example runtime.Object) (generic.RESTOptions, error) { - opts, err := g.inner.GetRESTOptions(gr, example) - if err != nil { - return opts, err - } - // 🔒 Leave CRD *definitions* global so discovery is shared cluster-wide - if gr.Group == "apiextensions.k8s.io" && gr.Resource == "customresourcedefinitions" { - return opts, nil - } - - // Ensure we always wrap with our project-aware decorator. - if opts.Decorator == nil { - opts.Decorator = ProjectAwareDecorator(gr, genericregistry.StorageWithCacher(), g.loopbackConfig) - } else { - opts.Decorator = ProjectAwareDecorator(gr, opts.Decorator, g.loopbackConfig) - } - return opts, nil -} diff --git a/internal/controllers/resourcemanager/project_controller.go b/internal/controllers/resourcemanager/project_controller.go index e5c915a9..fff8c972 100644 --- a/internal/controllers/resourcemanager/project_controller.go +++ b/internal/controllers/resourcemanager/project_controller.go @@ -404,21 +404,25 @@ func ensureConnectorClass(ctx context.Context, dc dynamic.Interface, name, contr } func ensureDefaultNamespace(ctx context.Context, cs kubernetes.Interface) error { - // GET is cheap and idempotent - if _, err := cs.CoreV1().Namespaces().Get(ctx, metav1.NamespaceDefault, metav1.GetOptions{}); err == nil { - return nil - } else if !apierrors.IsNotFound(err) { - return fmt.Errorf("get namespace %q: %w", metav1.NamespaceDefault, err) - } - - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: metav1.NamespaceDefault, - Labels: map[string]string{"miloapis.com/project-default": "true"}, - }, - } - if _, err := cs.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("create namespace %q: %w", ns.Name, err) + specs := []struct { + name string + labels map[string]string + }{ + {name: metav1.NamespaceDefault, labels: map[string]string{"miloapis.com/project-default": "true"}}, + {name: "milo-system", labels: map[string]string{"miloapis.com/system": "true"}}, + } + for _, spec := range specs { + if _, err := cs.CoreV1().Namespaces().Get(ctx, spec.name, metav1.GetOptions{}); err == nil { + continue + } else if !apierrors.IsNotFound(err) { + return fmt.Errorf("get namespace %q: %w", spec.name, err) + } + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{Name: spec.name, Labels: spec.labels}, + } + if _, err := cs.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) { + return fmt.Errorf("create namespace %q: %w", ns.Name, err) + } } return nil }