go.{mod,sum},cmd/{k8s-operator,derper,stund}/depaware.txt: bump kube deps ()

Updates kube deps and mkctr, regenerates kube yamls with the updated tooling.

Updates#cleanup

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit is contained in:
Irbe Krumina 2025-01-17 05:37:53 +00:00 committed by GitHub
parent d912a49be6
commit 97a44d6453
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 690 additions and 364 deletions

@ -35,11 +35,11 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
L github.com/mdlayher/netlink/nltest from github.com/google/nftables L github.com/mdlayher/netlink/nltest from github.com/google/nftables
L 💣 github.com/mdlayher/socket from github.com/mdlayher/netlink L 💣 github.com/mdlayher/socket from github.com/mdlayher/netlink
💣 github.com/mitchellh/go-ps from tailscale.com/safesocket 💣 github.com/mitchellh/go-ps from tailscale.com/safesocket
github.com/munnerz/goautoneg from github.com/prometheus/common/expfmt
💣 github.com/prometheus/client_golang/prometheus from tailscale.com/tsweb/promvarz 💣 github.com/prometheus/client_golang/prometheus from tailscale.com/tsweb/promvarz
github.com/prometheus/client_golang/prometheus/internal from github.com/prometheus/client_golang/prometheus github.com/prometheus/client_golang/prometheus/internal from github.com/prometheus/client_golang/prometheus
github.com/prometheus/client_model/go from github.com/prometheus/client_golang/prometheus+ github.com/prometheus/client_model/go from github.com/prometheus/client_golang/prometheus+
github.com/prometheus/common/expfmt from github.com/prometheus/client_golang/prometheus+ github.com/prometheus/common/expfmt from github.com/prometheus/client_golang/prometheus+
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg from github.com/prometheus/common/expfmt
github.com/prometheus/common/model from github.com/prometheus/client_golang/prometheus+ github.com/prometheus/common/model from github.com/prometheus/client_golang/prometheus+
LD github.com/prometheus/procfs from github.com/prometheus/client_golang/prometheus LD github.com/prometheus/procfs from github.com/prometheus/client_golang/prometheus
LD github.com/prometheus/procfs/internal/fs from github.com/prometheus/procfs LD github.com/prometheus/procfs/internal/fs from github.com/prometheus/procfs
@ -264,7 +264,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
html/template from tailscale.com/cmd/derper html/template from tailscale.com/cmd/derper
io from bufio+ io from bufio+
io/fs from crypto/x509+ io/fs from crypto/x509+
io/ioutil from github.com/mitchellh/go-ps+ L io/ioutil from github.com/mitchellh/go-ps+
iter from maps+ iter from maps+
log from expvar+ log from expvar+
log/internal from log log/internal from log

@ -79,8 +79,8 @@ func TestConnector(t *testing.T) {
subnetRoutes: "10.40.0.0/14", subnetRoutes: "10.40.0.0/14",
app: kubetypes.AppConnector, app: kubetypes.AppConnector,
} }
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// Connector status should get updated with the IP/hostname info when available. // Connector status should get updated with the IP/hostname info when available.
const hostname = "foo.tailnetxyz.ts.net" const hostname = "foo.tailnetxyz.ts.net"
@ -106,7 +106,7 @@ func TestConnector(t *testing.T) {
opts.subnetRoutes = "10.40.0.0/14,10.44.0.0/20" opts.subnetRoutes = "10.40.0.0/14,10.44.0.0/20"
expectReconciled(t, cr, "", "test") expectReconciled(t, cr, "", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// Remove a route. // Remove a route.
mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) { mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) {
@ -114,7 +114,7 @@ func TestConnector(t *testing.T) {
}) })
opts.subnetRoutes = "10.44.0.0/20" opts.subnetRoutes = "10.44.0.0/20"
expectReconciled(t, cr, "", "test") expectReconciled(t, cr, "", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// Remove the subnet router. // Remove the subnet router.
mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) { mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) {
@ -122,7 +122,7 @@ func TestConnector(t *testing.T) {
}) })
opts.subnetRoutes = "" opts.subnetRoutes = ""
expectReconciled(t, cr, "", "test") expectReconciled(t, cr, "", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// Re-add the subnet router. // Re-add the subnet router.
mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) { mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) {
@ -132,7 +132,7 @@ func TestConnector(t *testing.T) {
}) })
opts.subnetRoutes = "10.44.0.0/20" opts.subnetRoutes = "10.44.0.0/20"
expectReconciled(t, cr, "", "test") expectReconciled(t, cr, "", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// Delete the Connector. // Delete the Connector.
if err = fc.Delete(context.Background(), cn); err != nil { if err = fc.Delete(context.Background(), cn); err != nil {
@ -175,8 +175,8 @@ func TestConnector(t *testing.T) {
hostname: "test-connector", hostname: "test-connector",
app: kubetypes.AppConnector, app: kubetypes.AppConnector,
} }
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// Add an exit node. // Add an exit node.
mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) { mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) {
@ -184,7 +184,7 @@ func TestConnector(t *testing.T) {
}) })
opts.isExitNode = true opts.isExitNode = true
expectReconciled(t, cr, "", "test") expectReconciled(t, cr, "", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// Delete the Connector. // Delete the Connector.
if err = fc.Delete(context.Background(), cn); err != nil { if err = fc.Delete(context.Background(), cn); err != nil {
@ -261,8 +261,8 @@ func TestConnectorWithProxyClass(t *testing.T) {
subnetRoutes: "10.40.0.0/14", subnetRoutes: "10.40.0.0/14",
app: kubetypes.AppConnector, app: kubetypes.AppConnector,
} }
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 2. Update Connector to specify a ProxyClass. ProxyClass is not yet // 2. Update Connector to specify a ProxyClass. ProxyClass is not yet
// ready, so its configuration is NOT applied to the Connector // ready, so its configuration is NOT applied to the Connector
@ -271,7 +271,7 @@ func TestConnectorWithProxyClass(t *testing.T) {
conn.Spec.ProxyClass = "custom-metadata" conn.Spec.ProxyClass = "custom-metadata"
}) })
expectReconciled(t, cr, "", "test") expectReconciled(t, cr, "", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 3. ProxyClass is set to Ready by proxy-class reconciler. Connector // 3. ProxyClass is set to Ready by proxy-class reconciler. Connector
// get reconciled and configuration from the ProxyClass is applied to // get reconciled and configuration from the ProxyClass is applied to
@ -286,7 +286,7 @@ func TestConnectorWithProxyClass(t *testing.T) {
}) })
opts.proxyClass = pc.Name opts.proxyClass = pc.Name
expectReconciled(t, cr, "", "test") expectReconciled(t, cr, "", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 4. Connector.spec.proxyClass field is unset, Connector gets // 4. Connector.spec.proxyClass field is unset, Connector gets
// reconciled and configuration from the ProxyClass is removed from the // reconciled and configuration from the ProxyClass is removed from the
@ -296,7 +296,7 @@ func TestConnectorWithProxyClass(t *testing.T) {
}) })
opts.proxyClass = "" opts.proxyClass = ""
expectReconciled(t, cr, "", "test") expectReconciled(t, cr, "", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
} }
func TestConnectorWithAppConnector(t *testing.T) { func TestConnectorWithAppConnector(t *testing.T) {
@ -351,8 +351,8 @@ func TestConnectorWithAppConnector(t *testing.T) {
app: kubetypes.AppConnector, app: kubetypes.AppConnector,
isAppConnector: true, isAppConnector: true,
} }
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// Connector's ready condition should be set to true // Connector's ready condition should be set to true
cn.ObjectMeta.Finalizers = append(cn.ObjectMeta.Finalizers, "tailscale.com/finalizer") cn.ObjectMeta.Finalizers = append(cn.ObjectMeta.Finalizers, "tailscale.com/finalizer")
@ -364,7 +364,7 @@ func TestConnectorWithAppConnector(t *testing.T) {
Reason: reasonConnectorCreated, Reason: reasonConnectorCreated,
Message: reasonConnectorCreated, Message: reasonConnectorCreated,
}} }}
expectEqual(t, fc, cn, nil) expectEqual(t, fc, cn)
// 2. Connector with invalid app connector routes has status set to invalid // 2. Connector with invalid app connector routes has status set to invalid
mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) { mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) {
@ -379,7 +379,7 @@ func TestConnectorWithAppConnector(t *testing.T) {
Reason: reasonConnectorInvalid, Reason: reasonConnectorInvalid,
Message: "Connector is invalid: route 1.2.3.4/5 has non-address bits set; expected 0.0.0.0/5", Message: "Connector is invalid: route 1.2.3.4/5 has non-address bits set; expected 0.0.0.0/5",
}} }}
expectEqual(t, fc, cn, nil) expectEqual(t, fc, cn)
// 3. Connector with valid app connnector routes becomes ready // 3. Connector with valid app connnector routes becomes ready
mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) { mustUpdate[tsapi.Connector](t, fc, "", "test", func(conn *tsapi.Connector) {

@ -94,7 +94,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
github.com/evanphx/json-patch/v5 from sigs.k8s.io/controller-runtime/pkg/client github.com/evanphx/json-patch/v5 from sigs.k8s.io/controller-runtime/pkg/client
github.com/evanphx/json-patch/v5/internal/json from github.com/evanphx/json-patch/v5 github.com/evanphx/json-patch/v5/internal/json from github.com/evanphx/json-patch/v5
💣 github.com/fsnotify/fsnotify from sigs.k8s.io/controller-runtime/pkg/certwatcher 💣 github.com/fsnotify/fsnotify from sigs.k8s.io/controller-runtime/pkg/certwatcher
github.com/fxamacker/cbor/v2 from tailscale.com/tka github.com/fxamacker/cbor/v2 from tailscale.com/tka+
github.com/gaissmai/bart from tailscale.com/net/ipset+ github.com/gaissmai/bart from tailscale.com/net/ipset+
github.com/go-json-experiment/json from tailscale.com/types/opt+ github.com/go-json-experiment/json from tailscale.com/types/opt+
github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json/internal/jsonflags+ github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json/internal/jsonflags+
@ -110,11 +110,11 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
github.com/go-openapi/jsonpointer from github.com/go-openapi/jsonreference github.com/go-openapi/jsonpointer from github.com/go-openapi/jsonreference
github.com/go-openapi/jsonreference from k8s.io/kube-openapi/pkg/internal+ github.com/go-openapi/jsonreference from k8s.io/kube-openapi/pkg/internal+
github.com/go-openapi/jsonreference/internal from github.com/go-openapi/jsonreference github.com/go-openapi/jsonreference/internal from github.com/go-openapi/jsonreference
github.com/go-openapi/swag from github.com/go-openapi/jsonpointer+ 💣 github.com/go-openapi/swag from github.com/go-openapi/jsonpointer+
L 💣 github.com/godbus/dbus/v5 from tailscale.com/net/dns L 💣 github.com/godbus/dbus/v5 from tailscale.com/net/dns
💣 github.com/gogo/protobuf/proto from k8s.io/api/admission/v1+ 💣 github.com/gogo/protobuf/proto from k8s.io/api/admission/v1+
github.com/gogo/protobuf/sortkeys from k8s.io/api/admission/v1+ github.com/gogo/protobuf/sortkeys from k8s.io/api/admission/v1+
github.com/golang/groupcache/lru from k8s.io/client-go/tools/record+ github.com/golang/groupcache/lru from tailscale.com/net/dnscache
github.com/golang/protobuf/proto from k8s.io/client-go/discovery+ github.com/golang/protobuf/proto from k8s.io/client-go/discovery+
github.com/google/btree from gvisor.dev/gvisor/pkg/tcpip/header+ github.com/google/btree from gvisor.dev/gvisor/pkg/tcpip/header+
github.com/google/gnostic-models/compiler from github.com/google/gnostic-models/openapiv2+ github.com/google/gnostic-models/compiler from github.com/google/gnostic-models/openapiv2+
@ -140,7 +140,6 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
github.com/gorilla/securecookie from github.com/gorilla/csrf github.com/gorilla/securecookie from github.com/gorilla/csrf
github.com/hdevalence/ed25519consensus from tailscale.com/clientupdate/distsign+ github.com/hdevalence/ed25519consensus from tailscale.com/clientupdate/distsign+
L 💣 github.com/illarion/gonotify/v2 from tailscale.com/net/dns L 💣 github.com/illarion/gonotify/v2 from tailscale.com/net/dns
github.com/imdario/mergo from k8s.io/client-go/tools/clientcmd
L github.com/insomniacslk/dhcp/dhcpv4 from tailscale.com/net/tstun L github.com/insomniacslk/dhcp/dhcpv4 from tailscale.com/net/tstun
L github.com/insomniacslk/dhcp/iana from github.com/insomniacslk/dhcp/dhcpv4 L github.com/insomniacslk/dhcp/iana from github.com/insomniacslk/dhcp/dhcpv4
L github.com/insomniacslk/dhcp/interfaces from github.com/insomniacslk/dhcp/dhcpv4 L github.com/insomniacslk/dhcp/interfaces from github.com/insomniacslk/dhcp/dhcpv4
@ -171,7 +170,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
💣 github.com/mitchellh/go-ps from tailscale.com/safesocket 💣 github.com/mitchellh/go-ps from tailscale.com/safesocket
github.com/modern-go/concurrent from github.com/json-iterator/go github.com/modern-go/concurrent from github.com/json-iterator/go
💣 github.com/modern-go/reflect2 from github.com/json-iterator/go 💣 github.com/modern-go/reflect2 from github.com/json-iterator/go
github.com/munnerz/goautoneg from k8s.io/kube-openapi/pkg/handler3 github.com/munnerz/goautoneg from k8s.io/kube-openapi/pkg/handler3+
github.com/opencontainers/go-digest from github.com/distribution/reference github.com/opencontainers/go-digest from github.com/distribution/reference
L github.com/pierrec/lz4/v4 from github.com/u-root/uio/uio L github.com/pierrec/lz4/v4 from github.com/u-root/uio/uio
L github.com/pierrec/lz4/v4/internal/lz4block from github.com/pierrec/lz4/v4+ L github.com/pierrec/lz4/v4/internal/lz4block from github.com/pierrec/lz4/v4+
@ -186,7 +185,6 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
github.com/prometheus/client_golang/prometheus/promhttp from sigs.k8s.io/controller-runtime/pkg/metrics/server+ github.com/prometheus/client_golang/prometheus/promhttp from sigs.k8s.io/controller-runtime/pkg/metrics/server+
github.com/prometheus/client_model/go from github.com/prometheus/client_golang/prometheus+ github.com/prometheus/client_model/go from github.com/prometheus/client_golang/prometheus+
github.com/prometheus/common/expfmt from github.com/prometheus/client_golang/prometheus+ github.com/prometheus/common/expfmt from github.com/prometheus/client_golang/prometheus+
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg from github.com/prometheus/common/expfmt
github.com/prometheus/common/model from github.com/prometheus/client_golang/prometheus+ github.com/prometheus/common/model from github.com/prometheus/client_golang/prometheus+
LD github.com/prometheus/procfs from github.com/prometheus/client_golang/prometheus LD github.com/prometheus/procfs from github.com/prometheus/client_golang/prometheus
LD github.com/prometheus/procfs/internal/fs from github.com/prometheus/procfs LD github.com/prometheus/procfs/internal/fs from github.com/prometheus/procfs
@ -250,6 +248,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
google.golang.org/protobuf/internal/descopts from google.golang.org/protobuf/internal/filedesc+ google.golang.org/protobuf/internal/descopts from google.golang.org/protobuf/internal/filedesc+
google.golang.org/protobuf/internal/detrand from google.golang.org/protobuf/internal/descfmt+ google.golang.org/protobuf/internal/detrand from google.golang.org/protobuf/internal/descfmt+
google.golang.org/protobuf/internal/editiondefaults from google.golang.org/protobuf/internal/filedesc+ google.golang.org/protobuf/internal/editiondefaults from google.golang.org/protobuf/internal/filedesc+
google.golang.org/protobuf/internal/editionssupport from google.golang.org/protobuf/reflect/protodesc
google.golang.org/protobuf/internal/encoding/defval from google.golang.org/protobuf/internal/encoding/tag+ google.golang.org/protobuf/internal/encoding/defval from google.golang.org/protobuf/internal/encoding/tag+
google.golang.org/protobuf/internal/encoding/messageset from google.golang.org/protobuf/encoding/prototext+ google.golang.org/protobuf/internal/encoding/messageset from google.golang.org/protobuf/encoding/prototext+
google.golang.org/protobuf/internal/encoding/tag from google.golang.org/protobuf/internal/impl google.golang.org/protobuf/internal/encoding/tag from google.golang.org/protobuf/internal/impl
@ -275,8 +274,8 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
google.golang.org/protobuf/types/gofeaturespb from google.golang.org/protobuf/reflect/protodesc google.golang.org/protobuf/types/gofeaturespb from google.golang.org/protobuf/reflect/protodesc
google.golang.org/protobuf/types/known/anypb from github.com/google/gnostic-models/compiler+ google.golang.org/protobuf/types/known/anypb from github.com/google/gnostic-models/compiler+
google.golang.org/protobuf/types/known/timestamppb from github.com/prometheus/client_golang/prometheus+ google.golang.org/protobuf/types/known/timestamppb from github.com/prometheus/client_golang/prometheus+
gopkg.in/evanphx/json-patch.v4 from k8s.io/client-go/testing
gopkg.in/inf.v0 from k8s.io/apimachinery/pkg/api/resource gopkg.in/inf.v0 from k8s.io/apimachinery/pkg/api/resource
gopkg.in/yaml.v2 from k8s.io/kube-openapi/pkg/util/proto+
gopkg.in/yaml.v3 from github.com/go-openapi/swag+ gopkg.in/yaml.v3 from github.com/go-openapi/swag+
gvisor.dev/gvisor/pkg/atomicbitops from gvisor.dev/gvisor/pkg/buffer+ gvisor.dev/gvisor/pkg/atomicbitops from gvisor.dev/gvisor/pkg/buffer+
gvisor.dev/gvisor/pkg/bits from gvisor.dev/gvisor/pkg/buffer gvisor.dev/gvisor/pkg/bits from gvisor.dev/gvisor/pkg/buffer
@ -345,6 +344,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/api/certificates/v1alpha1 from k8s.io/client-go/applyconfigurations/certificates/v1alpha1+ k8s.io/api/certificates/v1alpha1 from k8s.io/client-go/applyconfigurations/certificates/v1alpha1+
k8s.io/api/certificates/v1beta1 from k8s.io/client-go/applyconfigurations/certificates/v1beta1+ k8s.io/api/certificates/v1beta1 from k8s.io/client-go/applyconfigurations/certificates/v1beta1+
k8s.io/api/coordination/v1 from k8s.io/client-go/applyconfigurations/coordination/v1+ k8s.io/api/coordination/v1 from k8s.io/client-go/applyconfigurations/coordination/v1+
k8s.io/api/coordination/v1alpha2 from k8s.io/client-go/applyconfigurations/coordination/v1alpha2+
k8s.io/api/coordination/v1beta1 from k8s.io/client-go/applyconfigurations/coordination/v1beta1+ k8s.io/api/coordination/v1beta1 from k8s.io/client-go/applyconfigurations/coordination/v1beta1+
k8s.io/api/core/v1 from k8s.io/api/apps/v1+ k8s.io/api/core/v1 from k8s.io/api/apps/v1+
k8s.io/api/discovery/v1 from k8s.io/client-go/applyconfigurations/discovery/v1+ k8s.io/api/discovery/v1 from k8s.io/client-go/applyconfigurations/discovery/v1+
@ -367,7 +367,8 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/api/rbac/v1 from k8s.io/client-go/applyconfigurations/rbac/v1+ k8s.io/api/rbac/v1 from k8s.io/client-go/applyconfigurations/rbac/v1+
k8s.io/api/rbac/v1alpha1 from k8s.io/client-go/applyconfigurations/rbac/v1alpha1+ k8s.io/api/rbac/v1alpha1 from k8s.io/client-go/applyconfigurations/rbac/v1alpha1+
k8s.io/api/rbac/v1beta1 from k8s.io/client-go/applyconfigurations/rbac/v1beta1+ k8s.io/api/rbac/v1beta1 from k8s.io/client-go/applyconfigurations/rbac/v1beta1+
k8s.io/api/resource/v1alpha2 from k8s.io/client-go/applyconfigurations/resource/v1alpha2+ k8s.io/api/resource/v1alpha3 from k8s.io/client-go/applyconfigurations/resource/v1alpha3+
k8s.io/api/resource/v1beta1 from k8s.io/client-go/applyconfigurations/resource/v1beta1+
k8s.io/api/scheduling/v1 from k8s.io/client-go/applyconfigurations/scheduling/v1+ k8s.io/api/scheduling/v1 from k8s.io/client-go/applyconfigurations/scheduling/v1+
k8s.io/api/scheduling/v1alpha1 from k8s.io/client-go/applyconfigurations/scheduling/v1alpha1+ k8s.io/api/scheduling/v1alpha1 from k8s.io/client-go/applyconfigurations/scheduling/v1alpha1+
k8s.io/api/scheduling/v1beta1 from k8s.io/client-go/applyconfigurations/scheduling/v1beta1+ k8s.io/api/scheduling/v1beta1 from k8s.io/client-go/applyconfigurations/scheduling/v1beta1+
@ -380,10 +381,12 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/apimachinery/pkg/api/equality from k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1+ k8s.io/apimachinery/pkg/api/equality from k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1+
k8s.io/apimachinery/pkg/api/errors from k8s.io/apimachinery/pkg/util/managedfields/internal+ k8s.io/apimachinery/pkg/api/errors from k8s.io/apimachinery/pkg/util/managedfields/internal+
k8s.io/apimachinery/pkg/api/meta from k8s.io/apimachinery/pkg/api/validation+ k8s.io/apimachinery/pkg/api/meta from k8s.io/apimachinery/pkg/api/validation+
k8s.io/apimachinery/pkg/api/meta/testrestmapper from k8s.io/client-go/testing
k8s.io/apimachinery/pkg/api/resource from k8s.io/api/autoscaling/v1+ k8s.io/apimachinery/pkg/api/resource from k8s.io/api/autoscaling/v1+
k8s.io/apimachinery/pkg/api/validation from k8s.io/apimachinery/pkg/util/managedfields/internal+ k8s.io/apimachinery/pkg/api/validation from k8s.io/apimachinery/pkg/util/managedfields/internal+
💣 k8s.io/apimachinery/pkg/apis/meta/internalversion from k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme+ 💣 k8s.io/apimachinery/pkg/apis/meta/internalversion from k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme+
k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme from k8s.io/client-go/metadata k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme from k8s.io/client-go/metadata
k8s.io/apimachinery/pkg/apis/meta/internalversion/validation from k8s.io/client-go/util/watchlist
💣 k8s.io/apimachinery/pkg/apis/meta/v1 from k8s.io/api/admission/v1+ 💣 k8s.io/apimachinery/pkg/apis/meta/v1 from k8s.io/api/admission/v1+
k8s.io/apimachinery/pkg/apis/meta/v1/unstructured from k8s.io/apimachinery/pkg/runtime/serializer/versioning+ k8s.io/apimachinery/pkg/apis/meta/v1/unstructured from k8s.io/apimachinery/pkg/runtime/serializer/versioning+
k8s.io/apimachinery/pkg/apis/meta/v1/validation from k8s.io/apimachinery/pkg/api/validation+ k8s.io/apimachinery/pkg/apis/meta/v1/validation from k8s.io/apimachinery/pkg/api/validation+
@ -395,6 +398,9 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/apimachinery/pkg/runtime from k8s.io/api/admission/v1+ k8s.io/apimachinery/pkg/runtime from k8s.io/api/admission/v1+
k8s.io/apimachinery/pkg/runtime/schema from k8s.io/api/admission/v1+ k8s.io/apimachinery/pkg/runtime/schema from k8s.io/api/admission/v1+
k8s.io/apimachinery/pkg/runtime/serializer from k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme+ k8s.io/apimachinery/pkg/runtime/serializer from k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme+
k8s.io/apimachinery/pkg/runtime/serializer/cbor from k8s.io/client-go/dynamic+
k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct from k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1+
k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes from k8s.io/apimachinery/pkg/runtime/serializer/cbor+
k8s.io/apimachinery/pkg/runtime/serializer/json from k8s.io/apimachinery/pkg/runtime/serializer+ k8s.io/apimachinery/pkg/runtime/serializer/json from k8s.io/apimachinery/pkg/runtime/serializer+
k8s.io/apimachinery/pkg/runtime/serializer/protobuf from k8s.io/apimachinery/pkg/runtime/serializer k8s.io/apimachinery/pkg/runtime/serializer/protobuf from k8s.io/apimachinery/pkg/runtime/serializer
k8s.io/apimachinery/pkg/runtime/serializer/recognizer from k8s.io/apimachinery/pkg/runtime/serializer+ k8s.io/apimachinery/pkg/runtime/serializer/recognizer from k8s.io/apimachinery/pkg/runtime/serializer+
@ -446,6 +452,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/client-go/applyconfigurations/certificates/v1alpha1 from k8s.io/client-go/kubernetes/typed/certificates/v1alpha1 k8s.io/client-go/applyconfigurations/certificates/v1alpha1 from k8s.io/client-go/kubernetes/typed/certificates/v1alpha1
k8s.io/client-go/applyconfigurations/certificates/v1beta1 from k8s.io/client-go/kubernetes/typed/certificates/v1beta1 k8s.io/client-go/applyconfigurations/certificates/v1beta1 from k8s.io/client-go/kubernetes/typed/certificates/v1beta1
k8s.io/client-go/applyconfigurations/coordination/v1 from k8s.io/client-go/kubernetes/typed/coordination/v1 k8s.io/client-go/applyconfigurations/coordination/v1 from k8s.io/client-go/kubernetes/typed/coordination/v1
k8s.io/client-go/applyconfigurations/coordination/v1alpha2 from k8s.io/client-go/kubernetes/typed/coordination/v1alpha2
k8s.io/client-go/applyconfigurations/coordination/v1beta1 from k8s.io/client-go/kubernetes/typed/coordination/v1beta1 k8s.io/client-go/applyconfigurations/coordination/v1beta1 from k8s.io/client-go/kubernetes/typed/coordination/v1beta1
k8s.io/client-go/applyconfigurations/core/v1 from k8s.io/client-go/applyconfigurations/apps/v1+ k8s.io/client-go/applyconfigurations/core/v1 from k8s.io/client-go/applyconfigurations/apps/v1+
k8s.io/client-go/applyconfigurations/discovery/v1 from k8s.io/client-go/kubernetes/typed/discovery/v1 k8s.io/client-go/applyconfigurations/discovery/v1 from k8s.io/client-go/kubernetes/typed/discovery/v1
@ -470,7 +477,8 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/client-go/applyconfigurations/rbac/v1 from k8s.io/client-go/kubernetes/typed/rbac/v1 k8s.io/client-go/applyconfigurations/rbac/v1 from k8s.io/client-go/kubernetes/typed/rbac/v1
k8s.io/client-go/applyconfigurations/rbac/v1alpha1 from k8s.io/client-go/kubernetes/typed/rbac/v1alpha1 k8s.io/client-go/applyconfigurations/rbac/v1alpha1 from k8s.io/client-go/kubernetes/typed/rbac/v1alpha1
k8s.io/client-go/applyconfigurations/rbac/v1beta1 from k8s.io/client-go/kubernetes/typed/rbac/v1beta1 k8s.io/client-go/applyconfigurations/rbac/v1beta1 from k8s.io/client-go/kubernetes/typed/rbac/v1beta1
k8s.io/client-go/applyconfigurations/resource/v1alpha2 from k8s.io/client-go/kubernetes/typed/resource/v1alpha2 k8s.io/client-go/applyconfigurations/resource/v1alpha3 from k8s.io/client-go/kubernetes/typed/resource/v1alpha3
k8s.io/client-go/applyconfigurations/resource/v1beta1 from k8s.io/client-go/kubernetes/typed/resource/v1beta1
k8s.io/client-go/applyconfigurations/scheduling/v1 from k8s.io/client-go/kubernetes/typed/scheduling/v1 k8s.io/client-go/applyconfigurations/scheduling/v1 from k8s.io/client-go/kubernetes/typed/scheduling/v1
k8s.io/client-go/applyconfigurations/scheduling/v1alpha1 from k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1 k8s.io/client-go/applyconfigurations/scheduling/v1alpha1 from k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1
k8s.io/client-go/applyconfigurations/scheduling/v1beta1 from k8s.io/client-go/kubernetes/typed/scheduling/v1beta1 k8s.io/client-go/applyconfigurations/scheduling/v1beta1 from k8s.io/client-go/kubernetes/typed/scheduling/v1beta1
@ -480,8 +488,80 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/client-go/applyconfigurations/storagemigration/v1alpha1 from k8s.io/client-go/kubernetes/typed/storagemigration/v1alpha1 k8s.io/client-go/applyconfigurations/storagemigration/v1alpha1 from k8s.io/client-go/kubernetes/typed/storagemigration/v1alpha1
k8s.io/client-go/discovery from k8s.io/client-go/applyconfigurations/meta/v1+ k8s.io/client-go/discovery from k8s.io/client-go/applyconfigurations/meta/v1+
k8s.io/client-go/dynamic from sigs.k8s.io/controller-runtime/pkg/cache/internal+ k8s.io/client-go/dynamic from sigs.k8s.io/controller-runtime/pkg/cache/internal+
k8s.io/client-go/features from k8s.io/client-go/tools/cache k8s.io/client-go/features from k8s.io/client-go/tools/cache+
k8s.io/client-go/kubernetes from k8s.io/client-go/tools/leaderelection/resourcelock k8s.io/client-go/gentype from k8s.io/client-go/kubernetes/typed/admissionregistration/v1+
k8s.io/client-go/informers from k8s.io/client-go/tools/leaderelection
k8s.io/client-go/informers/admissionregistration from k8s.io/client-go/informers
k8s.io/client-go/informers/admissionregistration/v1 from k8s.io/client-go/informers/admissionregistration
k8s.io/client-go/informers/admissionregistration/v1alpha1 from k8s.io/client-go/informers/admissionregistration
k8s.io/client-go/informers/admissionregistration/v1beta1 from k8s.io/client-go/informers/admissionregistration
k8s.io/client-go/informers/apiserverinternal from k8s.io/client-go/informers
k8s.io/client-go/informers/apiserverinternal/v1alpha1 from k8s.io/client-go/informers/apiserverinternal
k8s.io/client-go/informers/apps from k8s.io/client-go/informers
k8s.io/client-go/informers/apps/v1 from k8s.io/client-go/informers/apps
k8s.io/client-go/informers/apps/v1beta1 from k8s.io/client-go/informers/apps
k8s.io/client-go/informers/apps/v1beta2 from k8s.io/client-go/informers/apps
k8s.io/client-go/informers/autoscaling from k8s.io/client-go/informers
k8s.io/client-go/informers/autoscaling/v1 from k8s.io/client-go/informers/autoscaling
k8s.io/client-go/informers/autoscaling/v2 from k8s.io/client-go/informers/autoscaling
k8s.io/client-go/informers/autoscaling/v2beta1 from k8s.io/client-go/informers/autoscaling
k8s.io/client-go/informers/autoscaling/v2beta2 from k8s.io/client-go/informers/autoscaling
k8s.io/client-go/informers/batch from k8s.io/client-go/informers
k8s.io/client-go/informers/batch/v1 from k8s.io/client-go/informers/batch
k8s.io/client-go/informers/batch/v1beta1 from k8s.io/client-go/informers/batch
k8s.io/client-go/informers/certificates from k8s.io/client-go/informers
k8s.io/client-go/informers/certificates/v1 from k8s.io/client-go/informers/certificates
k8s.io/client-go/informers/certificates/v1alpha1 from k8s.io/client-go/informers/certificates
k8s.io/client-go/informers/certificates/v1beta1 from k8s.io/client-go/informers/certificates
k8s.io/client-go/informers/coordination from k8s.io/client-go/informers
k8s.io/client-go/informers/coordination/v1 from k8s.io/client-go/informers/coordination
k8s.io/client-go/informers/coordination/v1alpha2 from k8s.io/client-go/informers/coordination
k8s.io/client-go/informers/coordination/v1beta1 from k8s.io/client-go/informers/coordination
k8s.io/client-go/informers/core from k8s.io/client-go/informers
k8s.io/client-go/informers/core/v1 from k8s.io/client-go/informers/core
k8s.io/client-go/informers/discovery from k8s.io/client-go/informers
k8s.io/client-go/informers/discovery/v1 from k8s.io/client-go/informers/discovery
k8s.io/client-go/informers/discovery/v1beta1 from k8s.io/client-go/informers/discovery
k8s.io/client-go/informers/events from k8s.io/client-go/informers
k8s.io/client-go/informers/events/v1 from k8s.io/client-go/informers/events
k8s.io/client-go/informers/events/v1beta1 from k8s.io/client-go/informers/events
k8s.io/client-go/informers/extensions from k8s.io/client-go/informers
k8s.io/client-go/informers/extensions/v1beta1 from k8s.io/client-go/informers/extensions
k8s.io/client-go/informers/flowcontrol from k8s.io/client-go/informers
k8s.io/client-go/informers/flowcontrol/v1 from k8s.io/client-go/informers/flowcontrol
k8s.io/client-go/informers/flowcontrol/v1beta1 from k8s.io/client-go/informers/flowcontrol
k8s.io/client-go/informers/flowcontrol/v1beta2 from k8s.io/client-go/informers/flowcontrol
k8s.io/client-go/informers/flowcontrol/v1beta3 from k8s.io/client-go/informers/flowcontrol
k8s.io/client-go/informers/internalinterfaces from k8s.io/client-go/informers+
k8s.io/client-go/informers/networking from k8s.io/client-go/informers
k8s.io/client-go/informers/networking/v1 from k8s.io/client-go/informers/networking
k8s.io/client-go/informers/networking/v1alpha1 from k8s.io/client-go/informers/networking
k8s.io/client-go/informers/networking/v1beta1 from k8s.io/client-go/informers/networking
k8s.io/client-go/informers/node from k8s.io/client-go/informers
k8s.io/client-go/informers/node/v1 from k8s.io/client-go/informers/node
k8s.io/client-go/informers/node/v1alpha1 from k8s.io/client-go/informers/node
k8s.io/client-go/informers/node/v1beta1 from k8s.io/client-go/informers/node
k8s.io/client-go/informers/policy from k8s.io/client-go/informers
k8s.io/client-go/informers/policy/v1 from k8s.io/client-go/informers/policy
k8s.io/client-go/informers/policy/v1beta1 from k8s.io/client-go/informers/policy
k8s.io/client-go/informers/rbac from k8s.io/client-go/informers
k8s.io/client-go/informers/rbac/v1 from k8s.io/client-go/informers/rbac
k8s.io/client-go/informers/rbac/v1alpha1 from k8s.io/client-go/informers/rbac
k8s.io/client-go/informers/rbac/v1beta1 from k8s.io/client-go/informers/rbac
k8s.io/client-go/informers/resource from k8s.io/client-go/informers
k8s.io/client-go/informers/resource/v1alpha3 from k8s.io/client-go/informers/resource
k8s.io/client-go/informers/resource/v1beta1 from k8s.io/client-go/informers/resource
k8s.io/client-go/informers/scheduling from k8s.io/client-go/informers
k8s.io/client-go/informers/scheduling/v1 from k8s.io/client-go/informers/scheduling
k8s.io/client-go/informers/scheduling/v1alpha1 from k8s.io/client-go/informers/scheduling
k8s.io/client-go/informers/scheduling/v1beta1 from k8s.io/client-go/informers/scheduling
k8s.io/client-go/informers/storage from k8s.io/client-go/informers
k8s.io/client-go/informers/storage/v1 from k8s.io/client-go/informers/storage
k8s.io/client-go/informers/storage/v1alpha1 from k8s.io/client-go/informers/storage
k8s.io/client-go/informers/storage/v1beta1 from k8s.io/client-go/informers/storage
k8s.io/client-go/informers/storagemigration from k8s.io/client-go/informers
k8s.io/client-go/informers/storagemigration/v1alpha1 from k8s.io/client-go/informers/storagemigration
k8s.io/client-go/kubernetes from k8s.io/client-go/tools/leaderelection/resourcelock+
k8s.io/client-go/kubernetes/scheme from k8s.io/client-go/discovery+ k8s.io/client-go/kubernetes/scheme from k8s.io/client-go/discovery+
k8s.io/client-go/kubernetes/typed/admissionregistration/v1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/admissionregistration/v1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1 from k8s.io/client-go/kubernetes
@ -505,6 +585,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/client-go/kubernetes/typed/certificates/v1alpha1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/certificates/v1alpha1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/certificates/v1beta1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/certificates/v1beta1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/coordination/v1 from k8s.io/client-go/kubernetes+ k8s.io/client-go/kubernetes/typed/coordination/v1 from k8s.io/client-go/kubernetes+
k8s.io/client-go/kubernetes/typed/coordination/v1alpha2 from k8s.io/client-go/kubernetes+
k8s.io/client-go/kubernetes/typed/coordination/v1beta1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/coordination/v1beta1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/core/v1 from k8s.io/client-go/kubernetes+ k8s.io/client-go/kubernetes/typed/core/v1 from k8s.io/client-go/kubernetes+
k8s.io/client-go/kubernetes/typed/discovery/v1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/discovery/v1 from k8s.io/client-go/kubernetes
@ -527,7 +608,8 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/client-go/kubernetes/typed/rbac/v1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/rbac/v1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/rbac/v1alpha1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/rbac/v1alpha1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/rbac/v1beta1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/rbac/v1beta1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/resource/v1alpha2 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/resource/v1alpha3 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/resource/v1beta1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/scheduling/v1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/scheduling/v1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/scheduling/v1beta1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/scheduling/v1beta1 from k8s.io/client-go/kubernetes
@ -535,6 +617,56 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/client-go/kubernetes/typed/storage/v1alpha1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/storage/v1alpha1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/storage/v1beta1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/storage/v1beta1 from k8s.io/client-go/kubernetes
k8s.io/client-go/kubernetes/typed/storagemigration/v1alpha1 from k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/typed/storagemigration/v1alpha1 from k8s.io/client-go/kubernetes
k8s.io/client-go/listers from k8s.io/client-go/listers/admissionregistration/v1+
k8s.io/client-go/listers/admissionregistration/v1 from k8s.io/client-go/informers/admissionregistration/v1
k8s.io/client-go/listers/admissionregistration/v1alpha1 from k8s.io/client-go/informers/admissionregistration/v1alpha1
k8s.io/client-go/listers/admissionregistration/v1beta1 from k8s.io/client-go/informers/admissionregistration/v1beta1
k8s.io/client-go/listers/apiserverinternal/v1alpha1 from k8s.io/client-go/informers/apiserverinternal/v1alpha1
k8s.io/client-go/listers/apps/v1 from k8s.io/client-go/informers/apps/v1
k8s.io/client-go/listers/apps/v1beta1 from k8s.io/client-go/informers/apps/v1beta1
k8s.io/client-go/listers/apps/v1beta2 from k8s.io/client-go/informers/apps/v1beta2
k8s.io/client-go/listers/autoscaling/v1 from k8s.io/client-go/informers/autoscaling/v1
k8s.io/client-go/listers/autoscaling/v2 from k8s.io/client-go/informers/autoscaling/v2
k8s.io/client-go/listers/autoscaling/v2beta1 from k8s.io/client-go/informers/autoscaling/v2beta1
k8s.io/client-go/listers/autoscaling/v2beta2 from k8s.io/client-go/informers/autoscaling/v2beta2
k8s.io/client-go/listers/batch/v1 from k8s.io/client-go/informers/batch/v1
k8s.io/client-go/listers/batch/v1beta1 from k8s.io/client-go/informers/batch/v1beta1
k8s.io/client-go/listers/certificates/v1 from k8s.io/client-go/informers/certificates/v1
k8s.io/client-go/listers/certificates/v1alpha1 from k8s.io/client-go/informers/certificates/v1alpha1
k8s.io/client-go/listers/certificates/v1beta1 from k8s.io/client-go/informers/certificates/v1beta1
k8s.io/client-go/listers/coordination/v1 from k8s.io/client-go/informers/coordination/v1
k8s.io/client-go/listers/coordination/v1alpha2 from k8s.io/client-go/informers/coordination/v1alpha2
k8s.io/client-go/listers/coordination/v1beta1 from k8s.io/client-go/informers/coordination/v1beta1
k8s.io/client-go/listers/core/v1 from k8s.io/client-go/informers/core/v1
k8s.io/client-go/listers/discovery/v1 from k8s.io/client-go/informers/discovery/v1
k8s.io/client-go/listers/discovery/v1beta1 from k8s.io/client-go/informers/discovery/v1beta1
k8s.io/client-go/listers/events/v1 from k8s.io/client-go/informers/events/v1
k8s.io/client-go/listers/events/v1beta1 from k8s.io/client-go/informers/events/v1beta1
k8s.io/client-go/listers/extensions/v1beta1 from k8s.io/client-go/informers/extensions/v1beta1
k8s.io/client-go/listers/flowcontrol/v1 from k8s.io/client-go/informers/flowcontrol/v1
k8s.io/client-go/listers/flowcontrol/v1beta1 from k8s.io/client-go/informers/flowcontrol/v1beta1
k8s.io/client-go/listers/flowcontrol/v1beta2 from k8s.io/client-go/informers/flowcontrol/v1beta2
k8s.io/client-go/listers/flowcontrol/v1beta3 from k8s.io/client-go/informers/flowcontrol/v1beta3
k8s.io/client-go/listers/networking/v1 from k8s.io/client-go/informers/networking/v1
k8s.io/client-go/listers/networking/v1alpha1 from k8s.io/client-go/informers/networking/v1alpha1
k8s.io/client-go/listers/networking/v1beta1 from k8s.io/client-go/informers/networking/v1beta1
k8s.io/client-go/listers/node/v1 from k8s.io/client-go/informers/node/v1
k8s.io/client-go/listers/node/v1alpha1 from k8s.io/client-go/informers/node/v1alpha1
k8s.io/client-go/listers/node/v1beta1 from k8s.io/client-go/informers/node/v1beta1
k8s.io/client-go/listers/policy/v1 from k8s.io/client-go/informers/policy/v1
k8s.io/client-go/listers/policy/v1beta1 from k8s.io/client-go/informers/policy/v1beta1
k8s.io/client-go/listers/rbac/v1 from k8s.io/client-go/informers/rbac/v1
k8s.io/client-go/listers/rbac/v1alpha1 from k8s.io/client-go/informers/rbac/v1alpha1
k8s.io/client-go/listers/rbac/v1beta1 from k8s.io/client-go/informers/rbac/v1beta1
k8s.io/client-go/listers/resource/v1alpha3 from k8s.io/client-go/informers/resource/v1alpha3
k8s.io/client-go/listers/resource/v1beta1 from k8s.io/client-go/informers/resource/v1beta1
k8s.io/client-go/listers/scheduling/v1 from k8s.io/client-go/informers/scheduling/v1
k8s.io/client-go/listers/scheduling/v1alpha1 from k8s.io/client-go/informers/scheduling/v1alpha1
k8s.io/client-go/listers/scheduling/v1beta1 from k8s.io/client-go/informers/scheduling/v1beta1
k8s.io/client-go/listers/storage/v1 from k8s.io/client-go/informers/storage/v1
k8s.io/client-go/listers/storage/v1alpha1 from k8s.io/client-go/informers/storage/v1alpha1
k8s.io/client-go/listers/storage/v1beta1 from k8s.io/client-go/informers/storage/v1beta1
k8s.io/client-go/listers/storagemigration/v1alpha1 from k8s.io/client-go/informers/storagemigration/v1alpha1
k8s.io/client-go/metadata from sigs.k8s.io/controller-runtime/pkg/cache/internal+ k8s.io/client-go/metadata from sigs.k8s.io/controller-runtime/pkg/cache/internal+
k8s.io/client-go/openapi from k8s.io/client-go/discovery k8s.io/client-go/openapi from k8s.io/client-go/discovery
k8s.io/client-go/pkg/apis/clientauthentication from k8s.io/client-go/pkg/apis/clientauthentication/install+ k8s.io/client-go/pkg/apis/clientauthentication from k8s.io/client-go/pkg/apis/clientauthentication/install+
@ -546,6 +678,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/client-go/rest from k8s.io/client-go/discovery+ k8s.io/client-go/rest from k8s.io/client-go/discovery+
k8s.io/client-go/rest/watch from k8s.io/client-go/rest k8s.io/client-go/rest/watch from k8s.io/client-go/rest
k8s.io/client-go/restmapper from sigs.k8s.io/controller-runtime/pkg/client/apiutil k8s.io/client-go/restmapper from sigs.k8s.io/controller-runtime/pkg/client/apiutil
k8s.io/client-go/testing from k8s.io/client-go/gentype
k8s.io/client-go/tools/auth from k8s.io/client-go/tools/clientcmd k8s.io/client-go/tools/auth from k8s.io/client-go/tools/clientcmd
k8s.io/client-go/tools/cache from sigs.k8s.io/controller-runtime/pkg/cache+ k8s.io/client-go/tools/cache from sigs.k8s.io/controller-runtime/pkg/cache+
k8s.io/client-go/tools/cache/synctrack from k8s.io/client-go/tools/cache k8s.io/client-go/tools/cache/synctrack from k8s.io/client-go/tools/cache
@ -562,11 +695,14 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/client-go/tools/record/util from k8s.io/client-go/tools/record k8s.io/client-go/tools/record/util from k8s.io/client-go/tools/record
k8s.io/client-go/tools/reference from k8s.io/client-go/kubernetes/typed/core/v1+ k8s.io/client-go/tools/reference from k8s.io/client-go/kubernetes/typed/core/v1+
k8s.io/client-go/transport from k8s.io/client-go/plugin/pkg/client/auth/exec+ k8s.io/client-go/transport from k8s.io/client-go/plugin/pkg/client/auth/exec+
k8s.io/client-go/util/apply from k8s.io/client-go/dynamic+
k8s.io/client-go/util/cert from k8s.io/client-go/rest+ k8s.io/client-go/util/cert from k8s.io/client-go/rest+
k8s.io/client-go/util/connrotation from k8s.io/client-go/plugin/pkg/client/auth/exec+ k8s.io/client-go/util/connrotation from k8s.io/client-go/plugin/pkg/client/auth/exec+
k8s.io/client-go/util/consistencydetector from k8s.io/client-go/dynamic+
k8s.io/client-go/util/flowcontrol from k8s.io/client-go/kubernetes+ k8s.io/client-go/util/flowcontrol from k8s.io/client-go/kubernetes+
k8s.io/client-go/util/homedir from k8s.io/client-go/tools/clientcmd k8s.io/client-go/util/homedir from k8s.io/client-go/tools/clientcmd
k8s.io/client-go/util/keyutil from k8s.io/client-go/util/cert k8s.io/client-go/util/keyutil from k8s.io/client-go/util/cert
k8s.io/client-go/util/watchlist from k8s.io/client-go/dynamic+
k8s.io/client-go/util/workqueue from k8s.io/client-go/transport+ k8s.io/client-go/util/workqueue from k8s.io/client-go/transport+
k8s.io/klog/v2 from k8s.io/apimachinery/pkg/api/meta+ k8s.io/klog/v2 from k8s.io/apimachinery/pkg/api/meta+
k8s.io/klog/v2/internal/buffer from k8s.io/klog/v2 k8s.io/klog/v2/internal/buffer from k8s.io/klog/v2
@ -587,11 +723,12 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
k8s.io/utils/buffer from k8s.io/client-go/tools/cache k8s.io/utils/buffer from k8s.io/client-go/tools/cache
k8s.io/utils/clock from k8s.io/apimachinery/pkg/util/cache+ k8s.io/utils/clock from k8s.io/apimachinery/pkg/util/cache+
k8s.io/utils/clock/testing from k8s.io/client-go/util/flowcontrol k8s.io/utils/clock/testing from k8s.io/client-go/util/flowcontrol
k8s.io/utils/internal/third_party/forked/golang/golang-lru from k8s.io/utils/lru
k8s.io/utils/internal/third_party/forked/golang/net from k8s.io/utils/net k8s.io/utils/internal/third_party/forked/golang/net from k8s.io/utils/net
k8s.io/utils/lru from k8s.io/client-go/tools/record
k8s.io/utils/net from k8s.io/apimachinery/pkg/util/net+ k8s.io/utils/net from k8s.io/apimachinery/pkg/util/net+
k8s.io/utils/pointer from k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1+ k8s.io/utils/pointer from k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1+
k8s.io/utils/ptr from k8s.io/client-go/tools/cache+ k8s.io/utils/ptr from k8s.io/client-go/tools/cache+
k8s.io/utils/strings/slices from k8s.io/apimachinery/pkg/labels
k8s.io/utils/trace from k8s.io/client-go/tools/cache k8s.io/utils/trace from k8s.io/client-go/tools/cache
sigs.k8s.io/controller-runtime/pkg/builder from tailscale.com/cmd/k8s-operator sigs.k8s.io/controller-runtime/pkg/builder from tailscale.com/cmd/k8s-operator
sigs.k8s.io/controller-runtime/pkg/cache from sigs.k8s.io/controller-runtime/pkg/cluster+ sigs.k8s.io/controller-runtime/pkg/cache from sigs.k8s.io/controller-runtime/pkg/cluster+
@ -624,12 +761,12 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
sigs.k8s.io/controller-runtime/pkg/metrics from sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics+ sigs.k8s.io/controller-runtime/pkg/metrics from sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics+
sigs.k8s.io/controller-runtime/pkg/metrics/server from sigs.k8s.io/controller-runtime/pkg/manager sigs.k8s.io/controller-runtime/pkg/metrics/server from sigs.k8s.io/controller-runtime/pkg/manager
sigs.k8s.io/controller-runtime/pkg/predicate from sigs.k8s.io/controller-runtime/pkg/builder+ sigs.k8s.io/controller-runtime/pkg/predicate from sigs.k8s.io/controller-runtime/pkg/builder+
sigs.k8s.io/controller-runtime/pkg/ratelimiter from sigs.k8s.io/controller-runtime/pkg/controller+
sigs.k8s.io/controller-runtime/pkg/reconcile from sigs.k8s.io/controller-runtime/pkg/builder+ sigs.k8s.io/controller-runtime/pkg/reconcile from sigs.k8s.io/controller-runtime/pkg/builder+
sigs.k8s.io/controller-runtime/pkg/recorder from sigs.k8s.io/controller-runtime/pkg/leaderelection+ sigs.k8s.io/controller-runtime/pkg/recorder from sigs.k8s.io/controller-runtime/pkg/leaderelection+
sigs.k8s.io/controller-runtime/pkg/source from sigs.k8s.io/controller-runtime/pkg/builder+ sigs.k8s.io/controller-runtime/pkg/source from sigs.k8s.io/controller-runtime/pkg/builder+
sigs.k8s.io/controller-runtime/pkg/webhook from sigs.k8s.io/controller-runtime/pkg/manager sigs.k8s.io/controller-runtime/pkg/webhook from sigs.k8s.io/controller-runtime/pkg/manager
sigs.k8s.io/controller-runtime/pkg/webhook/admission from sigs.k8s.io/controller-runtime/pkg/builder+ sigs.k8s.io/controller-runtime/pkg/webhook/admission from sigs.k8s.io/controller-runtime/pkg/builder+
sigs.k8s.io/controller-runtime/pkg/webhook/admission/metrics from sigs.k8s.io/controller-runtime/pkg/webhook/admission
sigs.k8s.io/controller-runtime/pkg/webhook/conversion from sigs.k8s.io/controller-runtime/pkg/builder sigs.k8s.io/controller-runtime/pkg/webhook/conversion from sigs.k8s.io/controller-runtime/pkg/builder
sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics from sigs.k8s.io/controller-runtime/pkg/webhook+ sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics from sigs.k8s.io/controller-runtime/pkg/webhook+
sigs.k8s.io/json from k8s.io/apimachinery/pkg/runtime/serializer/json+ sigs.k8s.io/json from k8s.io/apimachinery/pkg/runtime/serializer/json+
@ -640,7 +777,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
sigs.k8s.io/structured-merge-diff/v4/typed from k8s.io/apimachinery/pkg/util/managedfields+ sigs.k8s.io/structured-merge-diff/v4/typed from k8s.io/apimachinery/pkg/util/managedfields+
sigs.k8s.io/structured-merge-diff/v4/value from k8s.io/apimachinery/pkg/runtime+ sigs.k8s.io/structured-merge-diff/v4/value from k8s.io/apimachinery/pkg/runtime+
sigs.k8s.io/yaml from k8s.io/apimachinery/pkg/runtime/serializer/json+ sigs.k8s.io/yaml from k8s.io/apimachinery/pkg/runtime/serializer/json+
sigs.k8s.io/yaml/goyaml.v2 from sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 from sigs.k8s.io/yaml+
tailscale.com from tailscale.com/version tailscale.com from tailscale.com/version
tailscale.com/appc from tailscale.com/ipn/ipnlocal tailscale.com/appc from tailscale.com/ipn/ipnlocal
💣 tailscale.com/atomicfile from tailscale.com/ipn+ 💣 tailscale.com/atomicfile from tailscale.com/ipn+

@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: connectors.tailscale.com name: connectors.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com

@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: dnsconfigs.tailscale.com name: dnsconfigs.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com

@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: proxyclasses.tailscale.com name: proxyclasses.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com
@ -428,7 +428,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -443,7 +443,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -600,7 +600,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -615,7 +615,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -773,7 +773,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -788,7 +788,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -945,7 +945,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -960,7 +960,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -1174,6 +1174,32 @@ spec:
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
type: integer type: integer
format: int64 format: int64
seLinuxChangePolicy:
description: |-
seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.
It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.
Valid values are "MountOption" and "Recursive".
"Recursive" means relabeling of all files on all Pod volumes by the container runtime.
This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.
"MountOption" mounts all eligible Pod volumes with `-o context` mount option.
This requires all Pods that share the same volume to use the same SELinux label.
It is not possible to share the same volume among privileged and unprivileged Pods.
Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes
whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their
CSIDriver instance. Other volumes are always re-labelled recursively.
"MountOption" value is allowed only when SELinuxMount feature gate is enabled.
If not specified and SELinuxMount feature gate is enabled, "MountOption" is used.
If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes
and "Recursive" for all other volumes.
This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.
All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.
Note that this field cannot be set when spec.os.name is windows.
type: string
seLinuxOptions: seLinuxOptions:
description: |- description: |-
The SELinux context to be applied to all containers. The SELinux context to be applied to all containers.
@ -1222,18 +1248,28 @@ spec:
type: string type: string
supplementalGroups: supplementalGroups:
description: |- description: |-
A list of groups applied to the first process run in each container, in addition A list of groups applied to the first process run in each container, in
to the container's primary GID, the fsGroup (if specified), and group memberships addition to the container's primary GID and fsGroup (if specified). If
defined in the container image for the uid of the container process. If unspecified, the SupplementalGroupsPolicy feature is enabled, the
no additional groups are added to any container. Note that group memberships supplementalGroupsPolicy field determines whether these are in addition
defined in the container image for the uid of the container process are still effective, to or instead of any group memberships defined in the container image.
even if they are not included in this list. If unspecified, no additional groups are added, though group memberships
defined in the container image may still be used, depending on the
supplementalGroupsPolicy field.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
type: array type: array
items: items:
type: integer type: integer
format: int64 format: int64
x-kubernetes-list-type: atomic x-kubernetes-list-type: atomic
supplementalGroupsPolicy:
description: |-
Defines how supplemental groups of the first container processes are calculated.
Valid values are "Merge" and "Strict". If not specified, "Merge" is used.
(Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled
and the container runtime must implement support for this feature.
Note that this field cannot be set when spec.os.name is windows.
type: string
sysctls: sysctls:
description: |- description: |-
Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported
@ -1389,6 +1425,12 @@ spec:
the Pod where this field is used. It makes that resource available the Pod where this field is used. It makes that resource available
inside a container. inside a container.
type: string type: string
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
type: string
x-kubernetes-list-map-keys: x-kubernetes-list-map-keys:
- name - name
x-kubernetes-list-type: map x-kubernetes-list-type: map
@ -1493,7 +1535,7 @@ spec:
procMount: procMount:
description: |- description: |-
procMount denotes the type of proc mount to use for the containers. procMount denotes the type of proc mount to use for the containers.
The default is DefaultProcMount which uses the container runtime defaults for The default value is Default which uses the container runtime defaults for
readonly paths and masked paths. readonly paths and masked paths.
This requires the ProcMountType feature flag to be enabled. This requires the ProcMountType feature flag to be enabled.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
@ -1713,6 +1755,12 @@ spec:
the Pod where this field is used. It makes that resource available the Pod where this field is used. It makes that resource available
inside a container. inside a container.
type: string type: string
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
type: string
x-kubernetes-list-map-keys: x-kubernetes-list-map-keys:
- name - name
x-kubernetes-list-type: map x-kubernetes-list-type: map
@ -1817,7 +1865,7 @@ spec:
procMount: procMount:
description: |- description: |-
procMount denotes the type of proc mount to use for the containers. procMount denotes the type of proc mount to use for the containers.
The default is DefaultProcMount which uses the container runtime defaults for The default value is Default which uses the container runtime defaults for
readonly paths and masked paths. readonly paths and masked paths.
This requires the ProcMountType feature flag to be enabled. This requires the ProcMountType feature flag to be enabled.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.

@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: proxygroups.tailscale.com name: proxygroups.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com

@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: recorders.tailscale.com name: recorders.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com
@ -372,7 +372,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -387,7 +387,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -544,7 +544,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -559,7 +559,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -717,7 +717,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -732,7 +732,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -889,7 +889,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -904,7 +904,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
type: array type: array
items: items:
type: string type: string
@ -1066,6 +1066,12 @@ spec:
the Pod where this field is used. It makes that resource available the Pod where this field is used. It makes that resource available
inside a container. inside a container.
type: string type: string
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
type: string
x-kubernetes-list-map-keys: x-kubernetes-list-map-keys:
- name - name
x-kubernetes-list-type: map x-kubernetes-list-type: map
@ -1165,7 +1171,7 @@ spec:
procMount: procMount:
description: |- description: |-
procMount denotes the type of proc mount to use for the containers. procMount denotes the type of proc mount to use for the containers.
The default is DefaultProcMount which uses the container runtime defaults for The default value is Default which uses the container runtime defaults for
readonly paths and masked paths. readonly paths and masked paths.
This requires the ProcMountType feature flag to be enabled. This requires the ProcMountType feature flag to be enabled.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
@ -1401,6 +1407,32 @@ spec:
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
type: integer type: integer
format: int64 format: int64
seLinuxChangePolicy:
description: |-
seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.
It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.
Valid values are "MountOption" and "Recursive".
"Recursive" means relabeling of all files on all Pod volumes by the container runtime.
This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.
"MountOption" mounts all eligible Pod volumes with `-o context` mount option.
This requires all Pods that share the same volume to use the same SELinux label.
It is not possible to share the same volume among privileged and unprivileged Pods.
Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes
whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their
CSIDriver instance. Other volumes are always re-labelled recursively.
"MountOption" value is allowed only when SELinuxMount feature gate is enabled.
If not specified and SELinuxMount feature gate is enabled, "MountOption" is used.
If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes
and "Recursive" for all other volumes.
This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.
All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.
Note that this field cannot be set when spec.os.name is windows.
type: string
seLinuxOptions: seLinuxOptions:
description: |- description: |-
The SELinux context to be applied to all containers. The SELinux context to be applied to all containers.
@ -1449,18 +1481,28 @@ spec:
type: string type: string
supplementalGroups: supplementalGroups:
description: |- description: |-
A list of groups applied to the first process run in each container, in addition A list of groups applied to the first process run in each container, in
to the container's primary GID, the fsGroup (if specified), and group memberships addition to the container's primary GID and fsGroup (if specified). If
defined in the container image for the uid of the container process. If unspecified, the SupplementalGroupsPolicy feature is enabled, the
no additional groups are added to any container. Note that group memberships supplementalGroupsPolicy field determines whether these are in addition
defined in the container image for the uid of the container process are still effective, to or instead of any group memberships defined in the container image.
even if they are not included in this list. If unspecified, no additional groups are added, though group memberships
defined in the container image may still be used, depending on the
supplementalGroupsPolicy field.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
type: array type: array
items: items:
type: integer type: integer
format: int64 format: int64
x-kubernetes-list-type: atomic x-kubernetes-list-type: atomic
supplementalGroupsPolicy:
description: |-
Defines how supplemental groups of the first container processes are calculated.
Valid values are "Merge" and "Strict". If not specified, "Merge" is used.
(Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled
and the container runtime must implement support for this feature.
Note that this field cannot be set when spec.os.name is windows.
type: string
sysctls: sysctls:
description: |- description: |-
Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported

@ -31,7 +31,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: connectors.tailscale.com name: connectors.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com
@ -294,7 +294,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: dnsconfigs.tailscale.com name: dnsconfigs.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com
@ -476,7 +476,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: proxyclasses.tailscale.com name: proxyclasses.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com
@ -886,7 +886,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -901,7 +901,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -1062,7 +1062,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -1077,7 +1077,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -1231,7 +1231,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -1246,7 +1246,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -1407,7 +1407,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -1422,7 +1422,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -1641,6 +1641,32 @@ spec:
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
format: int64 format: int64
type: integer type: integer
seLinuxChangePolicy:
description: |-
seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.
It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.
Valid values are "MountOption" and "Recursive".
"Recursive" means relabeling of all files on all Pod volumes by the container runtime.
This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.
"MountOption" mounts all eligible Pod volumes with `-o context` mount option.
This requires all Pods that share the same volume to use the same SELinux label.
It is not possible to share the same volume among privileged and unprivileged Pods.
Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes
whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their
CSIDriver instance. Other volumes are always re-labelled recursively.
"MountOption" value is allowed only when SELinuxMount feature gate is enabled.
If not specified and SELinuxMount feature gate is enabled, "MountOption" is used.
If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes
and "Recursive" for all other volumes.
This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.
All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.
Note that this field cannot be set when spec.os.name is windows.
type: string
seLinuxOptions: seLinuxOptions:
description: |- description: |-
The SELinux context to be applied to all containers. The SELinux context to be applied to all containers.
@ -1689,18 +1715,28 @@ spec:
type: object type: object
supplementalGroups: supplementalGroups:
description: |- description: |-
A list of groups applied to the first process run in each container, in addition A list of groups applied to the first process run in each container, in
to the container's primary GID, the fsGroup (if specified), and group memberships addition to the container's primary GID and fsGroup (if specified). If
defined in the container image for the uid of the container process. If unspecified, the SupplementalGroupsPolicy feature is enabled, the
no additional groups are added to any container. Note that group memberships supplementalGroupsPolicy field determines whether these are in addition
defined in the container image for the uid of the container process are still effective, to or instead of any group memberships defined in the container image.
even if they are not included in this list. If unspecified, no additional groups are added, though group memberships
defined in the container image may still be used, depending on the
supplementalGroupsPolicy field.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
items: items:
format: int64 format: int64
type: integer type: integer
type: array type: array
x-kubernetes-list-type: atomic x-kubernetes-list-type: atomic
supplementalGroupsPolicy:
description: |-
Defines how supplemental groups of the first container processes are calculated.
Valid values are "Merge" and "Strict". If not specified, "Merge" is used.
(Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled
and the container runtime must implement support for this feature.
Note that this field cannot be set when spec.os.name is windows.
type: string
sysctls: sysctls:
description: |- description: |-
Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported
@ -1851,6 +1887,12 @@ spec:
the Pod where this field is used. It makes that resource available the Pod where this field is used. It makes that resource available
inside a container. inside a container.
type: string type: string
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
type: string
required: required:
- name - name
type: object type: object
@ -1959,7 +2001,7 @@ spec:
procMount: procMount:
description: |- description: |-
procMount denotes the type of proc mount to use for the containers. procMount denotes the type of proc mount to use for the containers.
The default is DefaultProcMount which uses the container runtime defaults for The default value is Default which uses the container runtime defaults for
readonly paths and masked paths. readonly paths and masked paths.
This requires the ProcMountType feature flag to be enabled. This requires the ProcMountType feature flag to be enabled.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
@ -2175,6 +2217,12 @@ spec:
the Pod where this field is used. It makes that resource available the Pod where this field is used. It makes that resource available
inside a container. inside a container.
type: string type: string
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
type: string
required: required:
- name - name
type: object type: object
@ -2283,7 +2331,7 @@ spec:
procMount: procMount:
description: |- description: |-
procMount denotes the type of proc mount to use for the containers. procMount denotes the type of proc mount to use for the containers.
The default is DefaultProcMount which uses the container runtime defaults for The default value is Default which uses the container runtime defaults for
readonly paths and masked paths. readonly paths and masked paths.
This requires the ProcMountType feature flag to be enabled. This requires the ProcMountType feature flag to be enabled.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
@ -2717,7 +2765,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: proxygroups.tailscale.com name: proxygroups.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com
@ -2927,7 +2975,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.15.1-0.20240618033008-7824932b0cab controller-gen.kubebuilder.io/version: v0.17.0
name: recorders.tailscale.com name: recorders.tailscale.com
spec: spec:
group: tailscale.com group: tailscale.com
@ -3281,7 +3329,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -3296,7 +3344,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -3457,7 +3505,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -3472,7 +3520,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -3626,7 +3674,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -3641,7 +3689,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -3802,7 +3850,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both matchLabelKeys and labelSelector. The same key is forbidden to exist in both matchLabelKeys and labelSelector.
Also, matchLabelKeys cannot be set when labelSelector isn't set. Also, matchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -3817,7 +3865,7 @@ spec:
pod labels will be ignored. The default value is empty. pod labels will be ignored. The default value is empty.
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
Also, mismatchLabelKeys cannot be set when labelSelector isn't set. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
items: items:
type: string type: string
type: array type: array
@ -3979,6 +4027,12 @@ spec:
the Pod where this field is used. It makes that resource available the Pod where this field is used. It makes that resource available
inside a container. inside a container.
type: string type: string
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
type: string
required: required:
- name - name
type: object type: object
@ -4082,7 +4136,7 @@ spec:
procMount: procMount:
description: |- description: |-
procMount denotes the type of proc mount to use for the containers. procMount denotes the type of proc mount to use for the containers.
The default is DefaultProcMount which uses the container runtime defaults for The default value is Default which uses the container runtime defaults for
readonly paths and masked paths. readonly paths and masked paths.
This requires the ProcMountType feature flag to be enabled. This requires the ProcMountType feature flag to be enabled.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
@ -4319,6 +4373,32 @@ spec:
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
format: int64 format: int64
type: integer type: integer
seLinuxChangePolicy:
description: |-
seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.
It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.
Valid values are "MountOption" and "Recursive".
"Recursive" means relabeling of all files on all Pod volumes by the container runtime.
This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.
"MountOption" mounts all eligible Pod volumes with `-o context` mount option.
This requires all Pods that share the same volume to use the same SELinux label.
It is not possible to share the same volume among privileged and unprivileged Pods.
Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes
whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their
CSIDriver instance. Other volumes are always re-labelled recursively.
"MountOption" value is allowed only when SELinuxMount feature gate is enabled.
If not specified and SELinuxMount feature gate is enabled, "MountOption" is used.
If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes
and "Recursive" for all other volumes.
This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.
All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.
Note that this field cannot be set when spec.os.name is windows.
type: string
seLinuxOptions: seLinuxOptions:
description: |- description: |-
The SELinux context to be applied to all containers. The SELinux context to be applied to all containers.
@ -4367,18 +4447,28 @@ spec:
type: object type: object
supplementalGroups: supplementalGroups:
description: |- description: |-
A list of groups applied to the first process run in each container, in addition A list of groups applied to the first process run in each container, in
to the container's primary GID, the fsGroup (if specified), and group memberships addition to the container's primary GID and fsGroup (if specified). If
defined in the container image for the uid of the container process. If unspecified, the SupplementalGroupsPolicy feature is enabled, the
no additional groups are added to any container. Note that group memberships supplementalGroupsPolicy field determines whether these are in addition
defined in the container image for the uid of the container process are still effective, to or instead of any group memberships defined in the container image.
even if they are not included in this list. If unspecified, no additional groups are added, though group memberships
defined in the container image may still be used, depending on the
supplementalGroupsPolicy field.
Note that this field cannot be set when spec.os.name is windows. Note that this field cannot be set when spec.os.name is windows.
items: items:
format: int64 format: int64
type: integer type: integer
type: array type: array
x-kubernetes-list-type: atomic x-kubernetes-list-type: atomic
supplementalGroupsPolicy:
description: |-
Defines how supplemental groups of the first container processes are calculated.
Valid values are "Merge" and "Strict". If not specified, "Merge" is used.
(Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled
and the container runtime must implement support for this feature.
Note that this field cannot be set when spec.os.name is windows.
type: string
sysctls: sysctls:
description: |- description: |-
Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported

@ -112,7 +112,7 @@ func TestTailscaleEgressEndpointSlices(t *testing.T) {
Terminating: pointer.ToBool(false), Terminating: pointer.ToBool(false),
}, },
}) })
expectEqual(t, fc, eps, nil) expectEqual(t, fc, eps)
}) })
t.Run("status_does_not_match_pod_ip", func(t *testing.T) { t.Run("status_does_not_match_pod_ip", func(t *testing.T) {
_, stateS := podAndSecretForProxyGroup("foo") // replica Pod has IP 10.0.0.1 _, stateS := podAndSecretForProxyGroup("foo") // replica Pod has IP 10.0.0.1
@ -122,7 +122,7 @@ func TestTailscaleEgressEndpointSlices(t *testing.T) {
}) })
expectReconciled(t, er, "operator-ns", "foo") expectReconciled(t, er, "operator-ns", "foo")
eps.Endpoints = []discoveryv1.Endpoint{} eps.Endpoints = []discoveryv1.Endpoint{}
expectEqual(t, fc, eps, nil) expectEqual(t, fc, eps)
}) })
} }

@ -67,24 +67,24 @@ func TestEgressServiceReadiness(t *testing.T) {
setClusterNotReady(egressSvc, cl, zl.Sugar()) setClusterNotReady(egressSvc, cl, zl.Sugar())
t.Run("endpointslice_does_not_exist", func(t *testing.T) { t.Run("endpointslice_does_not_exist", func(t *testing.T) {
expectReconciled(t, rec, "dev", "my-app") expectReconciled(t, rec, "dev", "my-app")
expectEqual(t, fc, egressSvc, nil) // not ready expectEqual(t, fc, egressSvc) // not ready
}) })
t.Run("proxy_group_does_not_exist", func(t *testing.T) { t.Run("proxy_group_does_not_exist", func(t *testing.T) {
mustCreate(t, fc, eps) mustCreate(t, fc, eps)
expectReconciled(t, rec, "dev", "my-app") expectReconciled(t, rec, "dev", "my-app")
expectEqual(t, fc, egressSvc, nil) // still not ready expectEqual(t, fc, egressSvc) // still not ready
}) })
t.Run("proxy_group_not_ready", func(t *testing.T) { t.Run("proxy_group_not_ready", func(t *testing.T) {
mustCreate(t, fc, pg) mustCreate(t, fc, pg)
expectReconciled(t, rec, "dev", "my-app") expectReconciled(t, rec, "dev", "my-app")
expectEqual(t, fc, egressSvc, nil) // still not ready expectEqual(t, fc, egressSvc) // still not ready
}) })
t.Run("no_ready_replicas", func(t *testing.T) { t.Run("no_ready_replicas", func(t *testing.T) {
setPGReady(pg, cl, zl.Sugar()) setPGReady(pg, cl, zl.Sugar())
mustUpdateStatus(t, fc, pg.Namespace, pg.Name, func(p *tsapi.ProxyGroup) { mustUpdateStatus(t, fc, pg.Namespace, pg.Name, func(p *tsapi.ProxyGroup) {
p.Status = pg.Status p.Status = pg.Status
}) })
expectEqual(t, fc, pg, nil) expectEqual(t, fc, pg)
for i := range pgReplicas(pg) { for i := range pgReplicas(pg) {
p := pod(pg, i) p := pod(pg, i)
mustCreate(t, fc, p) mustCreate(t, fc, p)
@ -94,7 +94,7 @@ func TestEgressServiceReadiness(t *testing.T) {
} }
expectReconciled(t, rec, "dev", "my-app") expectReconciled(t, rec, "dev", "my-app")
setNotReady(egressSvc, cl, zl.Sugar(), pgReplicas(pg)) setNotReady(egressSvc, cl, zl.Sugar(), pgReplicas(pg))
expectEqual(t, fc, egressSvc, nil) // still not ready expectEqual(t, fc, egressSvc) // still not ready
}) })
t.Run("one_ready_replica", func(t *testing.T) { t.Run("one_ready_replica", func(t *testing.T) {
setEndpointForReplica(pg, 0, eps) setEndpointForReplica(pg, 0, eps)
@ -103,7 +103,7 @@ func TestEgressServiceReadiness(t *testing.T) {
}) })
setReady(egressSvc, cl, zl.Sugar(), pgReplicas(pg), 1) setReady(egressSvc, cl, zl.Sugar(), pgReplicas(pg), 1)
expectReconciled(t, rec, "dev", "my-app") expectReconciled(t, rec, "dev", "my-app")
expectEqual(t, fc, egressSvc, nil) // partially ready expectEqual(t, fc, egressSvc) // partially ready
}) })
t.Run("all_replicas_ready", func(t *testing.T) { t.Run("all_replicas_ready", func(t *testing.T) {
for i := range pgReplicas(pg) { for i := range pgReplicas(pg) {
@ -114,7 +114,7 @@ func TestEgressServiceReadiness(t *testing.T) {
}) })
setReady(egressSvc, cl, zl.Sugar(), pgReplicas(pg), pgReplicas(pg)) setReady(egressSvc, cl, zl.Sugar(), pgReplicas(pg), pgReplicas(pg))
expectReconciled(t, rec, "dev", "my-app") expectReconciled(t, rec, "dev", "my-app")
expectEqual(t, fc, egressSvc, nil) // ready expectEqual(t, fc, egressSvc) // ready
}) })
} }

@ -96,7 +96,7 @@ func TestTailscaleEgressServices(t *testing.T) {
expectReconciled(t, esr, "default", "test") expectReconciled(t, esr, "default", "test")
// Service should have EgressSvcValid condition set to Unknown. // Service should have EgressSvcValid condition set to Unknown.
svc.Status.Conditions = []metav1.Condition{condition(tsapi.EgressSvcValid, metav1.ConditionUnknown, reasonProxyGroupNotReady, reasonProxyGroupNotReady, clock)} svc.Status.Conditions = []metav1.Condition{condition(tsapi.EgressSvcValid, metav1.ConditionUnknown, reasonProxyGroupNotReady, reasonProxyGroupNotReady, clock)}
expectEqual(t, fc, svc, nil) expectEqual(t, fc, svc)
}) })
t.Run("proxy_group_ready", func(t *testing.T) { t.Run("proxy_group_ready", func(t *testing.T) {
@ -162,7 +162,7 @@ func validateReadyService(t *testing.T, fc client.WithWatch, esr *egressSvcsReco
expectEqual(t, fc, clusterIPSvc(name, svc), removeTargetPortsFromSvc) expectEqual(t, fc, clusterIPSvc(name, svc), removeTargetPortsFromSvc)
clusterSvc := mustGetClusterIPSvc(t, fc, name) clusterSvc := mustGetClusterIPSvc(t, fc, name)
// Verify that an EndpointSlice has been created. // Verify that an EndpointSlice has been created.
expectEqual(t, fc, endpointSlice(name, svc, clusterSvc), nil) expectEqual(t, fc, endpointSlice(name, svc, clusterSvc))
// Verify that ConfigMap contains configuration for the new egress service. // Verify that ConfigMap contains configuration for the new egress service.
mustHaveConfigForSvc(t, fc, svc, clusterSvc, cm) mustHaveConfigForSvc(t, fc, svc, clusterSvc, cm)
r := svcConfiguredReason(svc, true, zl.Sugar()) r := svcConfiguredReason(svc, true, zl.Sugar())
@ -174,7 +174,7 @@ func validateReadyService(t *testing.T, fc client.WithWatch, esr *egressSvcsReco
} }
svc.ObjectMeta.Finalizers = []string{"tailscale.com/finalizer"} svc.ObjectMeta.Finalizers = []string{"tailscale.com/finalizer"}
svc.Spec.ExternalName = fmt.Sprintf("%s.operator-ns.svc.cluster.local", name) svc.Spec.ExternalName = fmt.Sprintf("%s.operator-ns.svc.cluster.local", name)
expectEqual(t, fc, svc, nil) expectEqual(t, fc, svc)
} }

@ -103,9 +103,9 @@ func TestTailscaleIngress(t *testing.T) {
} }
opts.serveConfig = serveConfig opts.serveConfig = serveConfig
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedHeadlessService(shortName, "ingress"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "ingress"))
expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 2. Ingress status gets updated with ingress proxy's MagicDNS name // 2. Ingress status gets updated with ingress proxy's MagicDNS name
// once that becomes available. // once that becomes available.
@ -120,7 +120,7 @@ func TestTailscaleIngress(t *testing.T) {
{Hostname: "foo.tailnetxyz.ts.net", Ports: []networkingv1.IngressPortStatus{{Port: 443, Protocol: "TCP"}}}, {Hostname: "foo.tailnetxyz.ts.net", Ports: []networkingv1.IngressPortStatus{{Port: 443, Protocol: "TCP"}}},
}, },
} }
expectEqual(t, fc, ing, nil) expectEqual(t, fc, ing)
// 3. Resources get created for Ingress that should allow forwarding // 3. Resources get created for Ingress that should allow forwarding
// cluster traffic // cluster traffic
@ -129,7 +129,7 @@ func TestTailscaleIngress(t *testing.T) {
}) })
opts.shouldEnableForwardingClusterTrafficViaIngress = true opts.shouldEnableForwardingClusterTrafficViaIngress = true
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 4. Resources get cleaned up when Ingress class is unset // 4. Resources get cleaned up when Ingress class is unset
mustUpdate(t, fc, "default", "test", func(ing *networkingv1.Ingress) { mustUpdate(t, fc, "default", "test", func(ing *networkingv1.Ingress) {
@ -229,9 +229,9 @@ func TestTailscaleIngressHostname(t *testing.T) {
} }
opts.serveConfig = serveConfig opts.serveConfig = serveConfig
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedHeadlessService(shortName, "ingress"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "ingress"))
expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 2. Ingress proxy with capability version >= 110 does not have an HTTPS endpoint set // 2. Ingress proxy with capability version >= 110 does not have an HTTPS endpoint set
mustUpdate(t, fc, "operator-ns", opts.secretName, func(secret *corev1.Secret) { mustUpdate(t, fc, "operator-ns", opts.secretName, func(secret *corev1.Secret) {
@ -243,7 +243,7 @@ func TestTailscaleIngressHostname(t *testing.T) {
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
ing.Finalizers = append(ing.Finalizers, "tailscale.com/finalizer") ing.Finalizers = append(ing.Finalizers, "tailscale.com/finalizer")
expectEqual(t, fc, ing, nil) expectEqual(t, fc, ing)
// 3. Ingress proxy with capability version >= 110 advertises HTTPS endpoint // 3. Ingress proxy with capability version >= 110 advertises HTTPS endpoint
mustUpdate(t, fc, "operator-ns", opts.secretName, func(secret *corev1.Secret) { mustUpdate(t, fc, "operator-ns", opts.secretName, func(secret *corev1.Secret) {
@ -259,7 +259,7 @@ func TestTailscaleIngressHostname(t *testing.T) {
{Hostname: "foo.tailnetxyz.ts.net", Ports: []networkingv1.IngressPortStatus{{Port: 443, Protocol: "TCP"}}}, {Hostname: "foo.tailnetxyz.ts.net", Ports: []networkingv1.IngressPortStatus{{Port: 443, Protocol: "TCP"}}},
}, },
} }
expectEqual(t, fc, ing, nil) expectEqual(t, fc, ing)
// 4. Ingress proxy with capability version >= 110 does not have an HTTPS endpoint ready // 4. Ingress proxy with capability version >= 110 does not have an HTTPS endpoint ready
mustUpdate(t, fc, "operator-ns", opts.secretName, func(secret *corev1.Secret) { mustUpdate(t, fc, "operator-ns", opts.secretName, func(secret *corev1.Secret) {
@ -271,7 +271,7 @@ func TestTailscaleIngressHostname(t *testing.T) {
}) })
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
ing.Status.LoadBalancer.Ingress = nil ing.Status.LoadBalancer.Ingress = nil
expectEqual(t, fc, ing, nil) expectEqual(t, fc, ing)
// 5. Ingress proxy's state has https_endpoints set, but its capver is not matching Pod UID (downgrade) // 5. Ingress proxy's state has https_endpoints set, but its capver is not matching Pod UID (downgrade)
mustUpdate(t, fc, "operator-ns", opts.secretName, func(secret *corev1.Secret) { mustUpdate(t, fc, "operator-ns", opts.secretName, func(secret *corev1.Secret) {
@ -287,7 +287,7 @@ func TestTailscaleIngressHostname(t *testing.T) {
}, },
} }
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
expectEqual(t, fc, ing, nil) expectEqual(t, fc, ing)
} }
func TestTailscaleIngressWithProxyClass(t *testing.T) { func TestTailscaleIngressWithProxyClass(t *testing.T) {
@ -383,9 +383,9 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) {
} }
opts.serveConfig = serveConfig opts.serveConfig = serveConfig
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedHeadlessService(shortName, "ingress"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "ingress"))
expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 2. Ingress is updated to specify a ProxyClass, ProxyClass is not yet // 2. Ingress is updated to specify a ProxyClass, ProxyClass is not yet
// ready, so proxy resource configuration does not change. // ready, so proxy resource configuration does not change.
@ -393,7 +393,7 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) {
mak.Set(&ing.ObjectMeta.Labels, LabelProxyClass, "custom-metadata") mak.Set(&ing.ObjectMeta.Labels, LabelProxyClass, "custom-metadata")
}) })
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 3. ProxyClass is set to Ready by proxy-class reconciler. Ingress get // 3. ProxyClass is set to Ready by proxy-class reconciler. Ingress get
// reconciled and configuration from the ProxyClass is applied to the // reconciled and configuration from the ProxyClass is applied to the
@ -408,7 +408,7 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) {
}) })
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
opts.proxyClass = pc.Name opts.proxyClass = pc.Name
expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 4. tailscale.com/proxy-class label is removed from the Ingress, the // 4. tailscale.com/proxy-class label is removed from the Ingress, the
// Ingress gets reconciled and the custom ProxyClass configuration is // Ingress gets reconciled and the custom ProxyClass configuration is
@ -418,7 +418,7 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) {
}) })
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
opts.proxyClass = "" opts.proxyClass = ""
expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation, removeResourceReqs)
} }
func TestTailscaleIngressWithServiceMonitor(t *testing.T) { func TestTailscaleIngressWithServiceMonitor(t *testing.T) {
@ -526,20 +526,20 @@ func TestTailscaleIngressWithServiceMonitor(t *testing.T) {
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
expectEqual(t, fc, expectedMetricsService(opts), nil) expectEqual(t, fc, expectedMetricsService(opts))
// 2. Enable ServiceMonitor - should not error when there is no ServiceMonitor CRD in cluster // 2. Enable ServiceMonitor - should not error when there is no ServiceMonitor CRD in cluster
mustUpdate(t, fc, "", "metrics", func(pc *tsapi.ProxyClass) { mustUpdate(t, fc, "", "metrics", func(pc *tsapi.ProxyClass) {
pc.Spec.Metrics.ServiceMonitor = &tsapi.ServiceMonitor{Enable: true, Labels: tsapi.Labels{"foo": "bar"}} pc.Spec.Metrics.ServiceMonitor = &tsapi.ServiceMonitor{Enable: true, Labels: tsapi.Labels{"foo": "bar"}}
}) })
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
expectEqual(t, fc, expectedMetricsService(opts), nil) expectEqual(t, fc, expectedMetricsService(opts))
// 3. Create ServiceMonitor CRD and reconcile- ServiceMonitor should get created // 3. Create ServiceMonitor CRD and reconcile- ServiceMonitor should get created
mustCreate(t, fc, crd) mustCreate(t, fc, crd)
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
opts.serviceMonitorLabels = tsapi.Labels{"foo": "bar"} opts.serviceMonitorLabels = tsapi.Labels{"foo": "bar"}
expectEqual(t, fc, expectedMetricsService(opts), nil) expectEqual(t, fc, expectedMetricsService(opts))
expectEqualUnstructured(t, fc, expectedServiceMonitor(t, opts)) expectEqualUnstructured(t, fc, expectedServiceMonitor(t, opts))
// 4. Update ServiceMonitor CRD and reconcile- ServiceMonitor should get updated // 4. Update ServiceMonitor CRD and reconcile- ServiceMonitor should get updated
@ -549,7 +549,7 @@ func TestTailscaleIngressWithServiceMonitor(t *testing.T) {
expectReconciled(t, ingR, "default", "test") expectReconciled(t, ingR, "default", "test")
opts.serviceMonitorLabels = nil opts.serviceMonitorLabels = nil
opts.resourceVersion = "2" opts.resourceVersion = "2"
expectEqual(t, fc, expectedMetricsService(opts), nil) expectEqual(t, fc, expectedMetricsService(opts))
expectEqualUnstructured(t, fc, expectedServiceMonitor(t, opts)) expectEqualUnstructured(t, fc, expectedServiceMonitor(t, opts))
// 5. Disable metrics - metrics resources should get deleted. // 5. Disable metrics - metrics resources should get deleted.

@ -69,7 +69,7 @@ func TestNameserverReconciler(t *testing.T) {
wantsDeploy.Namespace = "tailscale" wantsDeploy.Namespace = "tailscale"
labels := nameserverResourceLabels("test", "tailscale") labels := nameserverResourceLabels("test", "tailscale")
wantsDeploy.ObjectMeta.Labels = labels wantsDeploy.ObjectMeta.Labels = labels
expectEqual(t, fc, wantsDeploy, nil) expectEqual(t, fc, wantsDeploy)
// Verify that DNSConfig advertizes the nameserver's Service IP address, // Verify that DNSConfig advertizes the nameserver's Service IP address,
// has the ready status condition and tailscale finalizer. // has the ready status condition and tailscale finalizer.
@ -88,7 +88,7 @@ func TestNameserverReconciler(t *testing.T) {
Message: reasonNameserverCreated, Message: reasonNameserverCreated,
LastTransitionTime: metav1.Time{Time: cl.Now().Truncate(time.Second)}, LastTransitionTime: metav1.Time{Time: cl.Now().Truncate(time.Second)},
}) })
expectEqual(t, fc, dnsCfg, nil) expectEqual(t, fc, dnsCfg)
// // Verify that nameserver image gets updated to match DNSConfig spec. // // Verify that nameserver image gets updated to match DNSConfig spec.
mustUpdate(t, fc, "", "test", func(dnsCfg *tsapi.DNSConfig) { mustUpdate(t, fc, "", "test", func(dnsCfg *tsapi.DNSConfig) {
@ -96,7 +96,7 @@ func TestNameserverReconciler(t *testing.T) {
}) })
expectReconciled(t, nr, "", "test") expectReconciled(t, nr, "", "test")
wantsDeploy.Spec.Template.Spec.Containers[0].Image = "test:v0.0.2" wantsDeploy.Spec.Template.Spec.Containers[0].Image = "test:v0.0.2"
expectEqual(t, fc, wantsDeploy, nil) expectEqual(t, fc, wantsDeploy)
// Verify that when another actor sets ConfigMap data, it does not get // Verify that when another actor sets ConfigMap data, it does not get
// overwritten by nameserver reconciler. // overwritten by nameserver reconciler.
@ -114,7 +114,7 @@ func TestNameserverReconciler(t *testing.T) {
TypeMeta: metav1.TypeMeta{Kind: "ConfigMap", APIVersion: "v1"}, TypeMeta: metav1.TypeMeta{Kind: "ConfigMap", APIVersion: "v1"},
Data: map[string]string{"records.json": string(bs)}, Data: map[string]string{"records.json": string(bs)},
} }
expectEqual(t, fc, wantCm, nil) expectEqual(t, fc, wantCm)
// Verify that if dnsconfig.spec.nameserver.image.{repo,tag} are unset, // Verify that if dnsconfig.spec.nameserver.image.{repo,tag} are unset,
// the nameserver image defaults to tailscale/k8s-nameserver:unstable. // the nameserver image defaults to tailscale/k8s-nameserver:unstable.
@ -123,5 +123,5 @@ func TestNameserverReconciler(t *testing.T) {
}) })
expectReconciled(t, nr, "", "test") expectReconciled(t, nr, "", "test")
wantsDeploy.Spec.Template.Spec.Containers[0].Image = "tailscale/k8s-nameserver:unstable" wantsDeploy.Spec.Template.Spec.Containers[0].Image = "tailscale/k8s-nameserver:unstable"
expectEqual(t, fc, wantsDeploy, nil) expectEqual(t, fc, wantsDeploy)
} }

@ -106,7 +106,7 @@ func TestLoadBalancerClass(t *testing.T) {
}}, }},
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
// Delete the misconfiguration so the proxy starts getting created on the // Delete the misconfiguration so the proxy starts getting created on the
// next reconcile. // next reconcile.
@ -128,9 +128,9 @@ func TestLoadBalancerClass(t *testing.T) {
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
want.Annotations = nil want.Annotations = nil
want.ObjectMeta.Finalizers = []string{"tailscale.com/finalizer"} want.ObjectMeta.Finalizers = []string{"tailscale.com/finalizer"}
@ -143,7 +143,7 @@ func TestLoadBalancerClass(t *testing.T) {
Message: "no Tailscale hostname known yet, waiting for proxy pod to finish auth", Message: "no Tailscale hostname known yet, waiting for proxy pod to finish auth",
}}, }},
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
// Normally the Tailscale proxy pod would come up here and write its info // Normally the Tailscale proxy pod would come up here and write its info
// into the secret. Simulate that, then verify reconcile again and verify // into the secret. Simulate that, then verify reconcile again and verify
@ -169,7 +169,7 @@ func TestLoadBalancerClass(t *testing.T) {
}, },
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
// Turn the service back into a ClusterIP service, which should make the // Turn the service back into a ClusterIP service, which should make the
// operator clean up. // operator clean up.
@ -206,7 +206,7 @@ func TestLoadBalancerClass(t *testing.T) {
Type: corev1.ServiceTypeClusterIP, Type: corev1.ServiceTypeClusterIP,
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
} }
func TestTailnetTargetFQDNAnnotation(t *testing.T) { func TestTailnetTargetFQDNAnnotation(t *testing.T) {
@ -266,9 +266,9 @@ func TestTailnetTargetFQDNAnnotation(t *testing.T) {
app: kubetypes.AppEgressProxy, app: kubetypes.AppEgressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, o), nil) expectEqual(t, fc, expectedSecret(t, fc, o))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
want := &corev1.Service{ want := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "test", Name: "test",
@ -288,10 +288,10 @@ func TestTailnetTargetFQDNAnnotation(t *testing.T) {
Conditions: proxyCreatedCondition(clock), Conditions: proxyCreatedCondition(clock),
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
expectEqual(t, fc, expectedSecret(t, fc, o), nil) expectEqual(t, fc, expectedSecret(t, fc, o))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
// Change the tailscale-target-fqdn annotation which should update the // Change the tailscale-target-fqdn annotation which should update the
// StatefulSet // StatefulSet
@ -378,9 +378,9 @@ func TestTailnetTargetIPAnnotation(t *testing.T) {
app: kubetypes.AppEgressProxy, app: kubetypes.AppEgressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, o), nil) expectEqual(t, fc, expectedSecret(t, fc, o))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
want := &corev1.Service{ want := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "test", Name: "test",
@ -400,10 +400,10 @@ func TestTailnetTargetIPAnnotation(t *testing.T) {
Conditions: proxyCreatedCondition(clock), Conditions: proxyCreatedCondition(clock),
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
expectEqual(t, fc, expectedSecret(t, fc, o), nil) expectEqual(t, fc, expectedSecret(t, fc, o))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
// Change the tailscale-target-ip annotation which should update the // Change the tailscale-target-ip annotation which should update the
// StatefulSet // StatefulSet
@ -501,7 +501,7 @@ func TestTailnetTargetIPAnnotation_IPCouldNotBeParsed(t *testing.T) {
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
} }
func TestTailnetTargetIPAnnotation_InvalidIP(t *testing.T) { func TestTailnetTargetIPAnnotation_InvalidIP(t *testing.T) {
@ -572,7 +572,7 @@ func TestTailnetTargetIPAnnotation_InvalidIP(t *testing.T) {
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
} }
func TestAnnotations(t *testing.T) { func TestAnnotations(t *testing.T) {
@ -629,9 +629,9 @@ func TestAnnotations(t *testing.T) {
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, o), nil) expectEqual(t, fc, expectedSecret(t, fc, o))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
want := &corev1.Service{ want := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "test", Name: "test",
@ -650,7 +650,7 @@ func TestAnnotations(t *testing.T) {
Conditions: proxyCreatedCondition(clock), Conditions: proxyCreatedCondition(clock),
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
// Turn the service back into a ClusterIP service, which should make the // Turn the service back into a ClusterIP service, which should make the
// operator clean up. // operator clean up.
@ -678,7 +678,7 @@ func TestAnnotations(t *testing.T) {
Type: corev1.ServiceTypeClusterIP, Type: corev1.ServiceTypeClusterIP,
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
} }
func TestAnnotationIntoLB(t *testing.T) { func TestAnnotationIntoLB(t *testing.T) {
@ -735,9 +735,9 @@ func TestAnnotationIntoLB(t *testing.T) {
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, o), nil) expectEqual(t, fc, expectedSecret(t, fc, o))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
// Normally the Tailscale proxy pod would come up here and write its info // Normally the Tailscale proxy pod would come up here and write its info
// into the secret. Simulate that, since it would have normally happened at // into the secret. Simulate that, since it would have normally happened at
@ -769,7 +769,7 @@ func TestAnnotationIntoLB(t *testing.T) {
Conditions: proxyCreatedCondition(clock), Conditions: proxyCreatedCondition(clock),
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
// Remove Tailscale's annotation, and at the same time convert the service // Remove Tailscale's annotation, and at the same time convert the service
// into a tailscale LoadBalancer. // into a tailscale LoadBalancer.
@ -780,8 +780,8 @@ func TestAnnotationIntoLB(t *testing.T) {
}) })
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
// None of the proxy machinery should have changed... // None of the proxy machinery should have changed...
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
// ... but the service should have a LoadBalancer status. // ... but the service should have a LoadBalancer status.
want = &corev1.Service{ want = &corev1.Service{
@ -810,7 +810,7 @@ func TestAnnotationIntoLB(t *testing.T) {
Conditions: proxyCreatedCondition(clock), Conditions: proxyCreatedCondition(clock),
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
} }
func TestLBIntoAnnotation(t *testing.T) { func TestLBIntoAnnotation(t *testing.T) {
@ -865,9 +865,9 @@ func TestLBIntoAnnotation(t *testing.T) {
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, o), nil) expectEqual(t, fc, expectedSecret(t, fc, o))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
// Normally the Tailscale proxy pod would come up here and write its info // Normally the Tailscale proxy pod would come up here and write its info
// into the secret. Simulate that, then verify reconcile again and verify // into the secret. Simulate that, then verify reconcile again and verify
@ -907,7 +907,7 @@ func TestLBIntoAnnotation(t *testing.T) {
Conditions: proxyCreatedCondition(clock), Conditions: proxyCreatedCondition(clock),
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
// Turn the service back into a ClusterIP service, but also add the // Turn the service back into a ClusterIP service, but also add the
// tailscale annotation. // tailscale annotation.
@ -926,8 +926,8 @@ func TestLBIntoAnnotation(t *testing.T) {
}) })
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
want = &corev1.Service{ want = &corev1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -947,7 +947,7 @@ func TestLBIntoAnnotation(t *testing.T) {
Conditions: proxyCreatedCondition(clock), Conditions: proxyCreatedCondition(clock),
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
} }
func TestCustomHostname(t *testing.T) { func TestCustomHostname(t *testing.T) {
@ -1005,9 +1005,9 @@ func TestCustomHostname(t *testing.T) {
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, o), nil) expectEqual(t, fc, expectedSecret(t, fc, o))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
want := &corev1.Service{ want := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "test", Name: "test",
@ -1027,7 +1027,7 @@ func TestCustomHostname(t *testing.T) {
Conditions: proxyCreatedCondition(clock), Conditions: proxyCreatedCondition(clock),
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
// Turn the service back into a ClusterIP service, which should make the // Turn the service back into a ClusterIP service, which should make the
// operator clean up. // operator clean up.
@ -1058,7 +1058,7 @@ func TestCustomHostname(t *testing.T) {
Type: corev1.ServiceTypeClusterIP, Type: corev1.ServiceTypeClusterIP,
}, },
} }
expectEqual(t, fc, want, nil) expectEqual(t, fc, want)
} }
func TestCustomPriorityClassName(t *testing.T) { func TestCustomPriorityClassName(t *testing.T) {
@ -1118,7 +1118,7 @@ func TestCustomPriorityClassName(t *testing.T) {
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
} }
func TestProxyClassForService(t *testing.T) { func TestProxyClassForService(t *testing.T) {
@ -1186,9 +1186,9 @@ func TestProxyClassForService(t *testing.T) {
clusterTargetIP: "10.20.30.40", clusterTargetIP: "10.20.30.40",
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 2. The Service gets updated with tailscale.com/proxy-class label // 2. The Service gets updated with tailscale.com/proxy-class label
// pointing at the 'custom-metadata' ProxyClass. The ProxyClass is not // pointing at the 'custom-metadata' ProxyClass. The ProxyClass is not
@ -1197,8 +1197,8 @@ func TestProxyClassForService(t *testing.T) {
mak.Set(&svc.Labels, LabelProxyClass, "custom-metadata") mak.Set(&svc.Labels, LabelProxyClass, "custom-metadata")
}) })
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
// 3. ProxyClass is set to Ready, the Service gets reconciled by the // 3. ProxyClass is set to Ready, the Service gets reconciled by the
// services-reconciler and the customization from the ProxyClass is // services-reconciler and the customization from the ProxyClass is
@ -1213,7 +1213,7 @@ func TestProxyClassForService(t *testing.T) {
}) })
opts.proxyClass = pc.Name opts.proxyClass = pc.Name
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
expectEqual(t, fc, expectedSecret(t, fc, opts), removeAuthKeyIfExistsModifier(t)) expectEqual(t, fc, expectedSecret(t, fc, opts), removeAuthKeyIfExistsModifier(t))
// 4. tailscale.com/proxy-class label is removed from the Service, the // 4. tailscale.com/proxy-class label is removed from the Service, the
@ -1224,7 +1224,7 @@ func TestProxyClassForService(t *testing.T) {
}) })
opts.proxyClass = "" opts.proxyClass = ""
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
} }
func TestDefaultLoadBalancer(t *testing.T) { func TestDefaultLoadBalancer(t *testing.T) {
@ -1270,7 +1270,7 @@ func TestDefaultLoadBalancer(t *testing.T) {
fullName, shortName := findGenName(t, fc, "default", "test", "svc") fullName, shortName := findGenName(t, fc, "default", "test", "svc")
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
o := configOpts{ o := configOpts{
stsName: shortName, stsName: shortName,
secretName: fullName, secretName: fullName,
@ -1280,8 +1280,7 @@ func TestDefaultLoadBalancer(t *testing.T) {
clusterTargetIP: "10.20.30.40", clusterTargetIP: "10.20.30.40",
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
} }
func TestProxyFirewallMode(t *testing.T) { func TestProxyFirewallMode(t *testing.T) {
@ -1337,7 +1336,7 @@ func TestProxyFirewallMode(t *testing.T) {
clusterTargetIP: "10.20.30.40", clusterTargetIP: "10.20.30.40",
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, o), removeHashAnnotation, removeResourceReqs)
} }
func TestTailscaledConfigfileHash(t *testing.T) { func TestTailscaledConfigfileHash(t *testing.T) {
@ -1393,7 +1392,7 @@ func TestTailscaledConfigfileHash(t *testing.T) {
confFileHash: "848bff4b5ba83ac999e6984c8464e597156daba961ae045e7dbaef606d54ab5e", confFileHash: "848bff4b5ba83ac999e6984c8464e597156daba961ae045e7dbaef606d54ab5e",
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSTS(t, fc, o), nil) expectEqual(t, fc, expectedSTS(t, fc, o), removeResourceReqs)
// 2. Hostname gets changed, configfile is updated and a new hash value // 2. Hostname gets changed, configfile is updated and a new hash value
// is produced. // is produced.
@ -1403,7 +1402,7 @@ func TestTailscaledConfigfileHash(t *testing.T) {
o.hostname = "another-test" o.hostname = "another-test"
o.confFileHash = "d4cc13f09f55f4f6775689004f9a466723325b84d2b590692796bfe22aeaa389" o.confFileHash = "d4cc13f09f55f4f6775689004f9a466723325b84d2b590692796bfe22aeaa389"
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
expectEqual(t, fc, expectedSTS(t, fc, o), nil) expectEqual(t, fc, expectedSTS(t, fc, o), removeResourceReqs)
} }
func Test_isMagicDNSName(t *testing.T) { func Test_isMagicDNSName(t *testing.T) {
tests := []struct { tests := []struct {
@ -1681,9 +1680,9 @@ func Test_authKeyRemoval(t *testing.T) {
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 2. Apply update to the Secret that imitates the proxy setting device_id. // 2. Apply update to the Secret that imitates the proxy setting device_id.
s := expectedSecret(t, fc, opts) s := expectedSecret(t, fc, opts)
@ -1695,7 +1694,7 @@ func Test_authKeyRemoval(t *testing.T) {
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
opts.shouldRemoveAuthKey = true opts.shouldRemoveAuthKey = true
opts.secretExtraData = map[string][]byte{"device_id": []byte("dkkdi4CNTRL")} opts.secretExtraData = map[string][]byte{"device_id": []byte("dkkdi4CNTRL")}
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
} }
func Test_externalNameService(t *testing.T) { func Test_externalNameService(t *testing.T) {
@ -1755,9 +1754,9 @@ func Test_externalNameService(t *testing.T) {
app: kubetypes.AppIngressProxy, app: kubetypes.AppIngressProxy,
} }
expectEqual(t, fc, expectedSecret(t, fc, opts), nil) expectEqual(t, fc, expectedSecret(t, fc, opts))
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"), nil) expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
// 2. Change the ExternalName and verify that changes get propagated. // 2. Change the ExternalName and verify that changes get propagated.
mustUpdate(t, sr, "default", "test", func(s *corev1.Service) { mustUpdate(t, sr, "default", "test", func(s *corev1.Service) {
@ -1765,7 +1764,7 @@ func Test_externalNameService(t *testing.T) {
}) })
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
opts.clusterTargetDNS = "bar.com" opts.clusterTargetDNS = "bar.com"
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation) expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
} }
func Test_metricsResourceCreation(t *testing.T) { func Test_metricsResourceCreation(t *testing.T) {
@ -1835,7 +1834,7 @@ func Test_metricsResourceCreation(t *testing.T) {
}) })
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
opts.enableMetrics = true opts.enableMetrics = true
expectEqual(t, fc, expectedMetricsService(opts), nil) expectEqual(t, fc, expectedMetricsService(opts))
// 2. Enable ServiceMonitor - should not error when there is no ServiceMonitor CRD in cluster // 2. Enable ServiceMonitor - should not error when there is no ServiceMonitor CRD in cluster
mustUpdate(t, fc, "", "metrics", func(pc *tsapi.ProxyClass) { mustUpdate(t, fc, "", "metrics", func(pc *tsapi.ProxyClass) {
@ -1855,7 +1854,7 @@ func Test_metricsResourceCreation(t *testing.T) {
expectReconciled(t, sr, "default", "test") expectReconciled(t, sr, "default", "test")
opts.serviceMonitorLabels = tsapi.Labels{"foo": "bar"} opts.serviceMonitorLabels = tsapi.Labels{"foo": "bar"}
opts.resourceVersion = "2" opts.resourceVersion = "2"
expectEqual(t, fc, expectedMetricsService(opts), nil) expectEqual(t, fc, expectedMetricsService(opts))
expectEqualUnstructured(t, fc, expectedServiceMonitor(t, opts)) expectEqualUnstructured(t, fc, expectedServiceMonitor(t, opts))
// 5. Disable metrics- expect metrics Service to be deleted // 5. Disable metrics- expect metrics Service to be deleted

@ -78,7 +78,7 @@ func TestProxyClass(t *testing.T) {
LastTransitionTime: metav1.Time{Time: cl.Now().Truncate(time.Second)}, LastTransitionTime: metav1.Time{Time: cl.Now().Truncate(time.Second)},
}) })
expectEqual(t, fc, pc, nil) expectEqual(t, fc, pc)
// 2. A ProxyClass resource with invalid labels gets its status updated to Invalid with an error message. // 2. A ProxyClass resource with invalid labels gets its status updated to Invalid with an error message.
pc.Spec.StatefulSet.Labels["foo"] = "?!someVal" pc.Spec.StatefulSet.Labels["foo"] = "?!someVal"
@ -88,7 +88,7 @@ func TestProxyClass(t *testing.T) {
expectReconciled(t, pcr, "", "test") expectReconciled(t, pcr, "", "test")
msg := `ProxyClass is not valid: .spec.statefulSet.labels: Invalid value: "?!someVal": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')` msg := `ProxyClass is not valid: .spec.statefulSet.labels: Invalid value: "?!someVal": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')`
tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar()) tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar())
expectEqual(t, fc, pc, nil) expectEqual(t, fc, pc)
expectedEvent := "Warning ProxyClassInvalid ProxyClass is not valid: .spec.statefulSet.labels: Invalid value: \"?!someVal\": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')" expectedEvent := "Warning ProxyClassInvalid ProxyClass is not valid: .spec.statefulSet.labels: Invalid value: \"?!someVal\": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')"
expectEvents(t, fr, []string{expectedEvent}) expectEvents(t, fr, []string{expectedEvent})
@ -102,7 +102,7 @@ func TestProxyClass(t *testing.T) {
expectReconciled(t, pcr, "", "test") expectReconciled(t, pcr, "", "test")
msg = `ProxyClass is not valid: spec.statefulSet.pod.tailscaleContainer.image: Invalid value: "FOO bar": invalid reference format: repository name (library/FOO bar) must be lowercase` msg = `ProxyClass is not valid: spec.statefulSet.pod.tailscaleContainer.image: Invalid value: "FOO bar": invalid reference format: repository name (library/FOO bar) must be lowercase`
tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar()) tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar())
expectEqual(t, fc, pc, nil) expectEqual(t, fc, pc)
expectedEvent = `Warning ProxyClassInvalid ProxyClass is not valid: spec.statefulSet.pod.tailscaleContainer.image: Invalid value: "FOO bar": invalid reference format: repository name (library/FOO bar) must be lowercase` expectedEvent = `Warning ProxyClassInvalid ProxyClass is not valid: spec.statefulSet.pod.tailscaleContainer.image: Invalid value: "FOO bar": invalid reference format: repository name (library/FOO bar) must be lowercase`
expectEvents(t, fr, []string{expectedEvent}) expectEvents(t, fr, []string{expectedEvent})
@ -121,7 +121,7 @@ func TestProxyClass(t *testing.T) {
expectReconciled(t, pcr, "", "test") expectReconciled(t, pcr, "", "test")
msg = `ProxyClass is not valid: spec.statefulSet.pod.tailscaleInitContainer.image: Invalid value: "FOO bar": invalid reference format: repository name (library/FOO bar) must be lowercase` msg = `ProxyClass is not valid: spec.statefulSet.pod.tailscaleInitContainer.image: Invalid value: "FOO bar": invalid reference format: repository name (library/FOO bar) must be lowercase`
tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar()) tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar())
expectEqual(t, fc, pc, nil) expectEqual(t, fc, pc)
expectedEvent = `Warning ProxyClassInvalid ProxyClass is not valid: spec.statefulSet.pod.tailscaleInitContainer.image: Invalid value: "FOO bar": invalid reference format: repository name (library/FOO bar) must be lowercase` expectedEvent = `Warning ProxyClassInvalid ProxyClass is not valid: spec.statefulSet.pod.tailscaleInitContainer.image: Invalid value: "FOO bar": invalid reference format: repository name (library/FOO bar) must be lowercase`
expectEvents(t, fr, []string{expectedEvent}) expectEvents(t, fr, []string{expectedEvent})
@ -145,7 +145,7 @@ func TestProxyClass(t *testing.T) {
expectReconciled(t, pcr, "", "test") expectReconciled(t, pcr, "", "test")
msg = `ProxyClass is not valid: spec.metrics.serviceMonitor: Invalid value: "enable": ProxyClass defines that a ServiceMonitor custom resource should be created, but "servicemonitors.monitoring.coreos.com" CRD was not found` msg = `ProxyClass is not valid: spec.metrics.serviceMonitor: Invalid value: "enable": ProxyClass defines that a ServiceMonitor custom resource should be created, but "servicemonitors.monitoring.coreos.com" CRD was not found`
tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar()) tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar())
expectEqual(t, fc, pc, nil) expectEqual(t, fc, pc)
expectedEvent = "Warning ProxyClassInvalid " + msg expectedEvent = "Warning ProxyClassInvalid " + msg
expectEvents(t, fr, []string{expectedEvent}) expectEvents(t, fr, []string{expectedEvent})
@ -154,7 +154,7 @@ func TestProxyClass(t *testing.T) {
mustCreate(t, fc, crd) mustCreate(t, fc, crd)
expectReconciled(t, pcr, "", "test") expectReconciled(t, pcr, "", "test")
tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionTrue, reasonProxyClassValid, reasonProxyClassValid, 0, cl, zl.Sugar()) tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionTrue, reasonProxyClassValid, reasonProxyClassValid, 0, cl, zl.Sugar())
expectEqual(t, fc, pc, nil) expectEqual(t, fc, pc)
// 7. A ProxyClass with invalid ServiceMonitor labels gets its status updated to Invalid with an error message. // 7. A ProxyClass with invalid ServiceMonitor labels gets its status updated to Invalid with an error message.
pc.Spec.Metrics.ServiceMonitor.Labels = tsapi.Labels{"foo": "bar!"} pc.Spec.Metrics.ServiceMonitor.Labels = tsapi.Labels{"foo": "bar!"}
@ -164,7 +164,7 @@ func TestProxyClass(t *testing.T) {
expectReconciled(t, pcr, "", "test") expectReconciled(t, pcr, "", "test")
msg = `ProxyClass is not valid: .spec.metrics.serviceMonitor.labels: Invalid value: "bar!": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')` msg = `ProxyClass is not valid: .spec.metrics.serviceMonitor.labels: Invalid value: "bar!": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')`
tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar()) tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionFalse, reasonProxyClassInvalid, msg, 0, cl, zl.Sugar())
expectEqual(t, fc, pc, nil) expectEqual(t, fc, pc)
// 8. A ProxyClass with valid ServiceMonitor labels gets its status updated to Valid. // 8. A ProxyClass with valid ServiceMonitor labels gets its status updated to Valid.
pc.Spec.Metrics.ServiceMonitor.Labels = tsapi.Labels{"foo": "bar", "xyz1234": "abc567", "empty": "", "onechar": "a"} pc.Spec.Metrics.ServiceMonitor.Labels = tsapi.Labels{"foo": "bar", "xyz1234": "abc567", "empty": "", "onechar": "a"}
@ -173,7 +173,7 @@ func TestProxyClass(t *testing.T) {
}) })
expectReconciled(t, pcr, "", "test") expectReconciled(t, pcr, "", "test")
tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionTrue, reasonProxyClassValid, reasonProxyClassValid, 0, cl, zl.Sugar()) tsoperator.SetProxyClassCondition(pc, tsapi.ProxyClassReady, metav1.ConditionTrue, reasonProxyClassValid, reasonProxyClassValid, 0, cl, zl.Sugar())
expectEqual(t, fc, pc, nil) expectEqual(t, fc, pc)
} }
func TestValidateProxyClass(t *testing.T) { func TestValidateProxyClass(t *testing.T) {

@ -96,7 +96,7 @@ func TestProxyGroup(t *testing.T) {
expectReconciled(t, reconciler, "", pg.Name) expectReconciled(t, reconciler, "", pg.Name)
tsoperator.SetProxyGroupCondition(pg, tsapi.ProxyGroupReady, metav1.ConditionFalse, reasonProxyGroupCreating, "the ProxyGroup's ProxyClass default-pc is not yet in a ready state, waiting...", 0, cl, zl.Sugar()) tsoperator.SetProxyGroupCondition(pg, tsapi.ProxyGroupReady, metav1.ConditionFalse, reasonProxyGroupCreating, "the ProxyGroup's ProxyClass default-pc is not yet in a ready state, waiting...", 0, cl, zl.Sugar())
expectEqual(t, fc, pg, nil) expectEqual(t, fc, pg)
expectProxyGroupResources(t, fc, pg, false, "") expectProxyGroupResources(t, fc, pg, false, "")
}) })
@ -117,7 +117,7 @@ func TestProxyGroup(t *testing.T) {
expectReconciled(t, reconciler, "", pg.Name) expectReconciled(t, reconciler, "", pg.Name)
tsoperator.SetProxyGroupCondition(pg, tsapi.ProxyGroupReady, metav1.ConditionFalse, reasonProxyGroupCreating, "0/2 ProxyGroup pods running", 0, cl, zl.Sugar()) tsoperator.SetProxyGroupCondition(pg, tsapi.ProxyGroupReady, metav1.ConditionFalse, reasonProxyGroupCreating, "0/2 ProxyGroup pods running", 0, cl, zl.Sugar())
expectEqual(t, fc, pg, nil) expectEqual(t, fc, pg)
expectProxyGroupResources(t, fc, pg, true, "") expectProxyGroupResources(t, fc, pg, true, "")
if expected := 1; reconciler.egressProxyGroups.Len() != expected { if expected := 1; reconciler.egressProxyGroups.Len() != expected {
t.Fatalf("expected %d egress ProxyGroups, got %d", expected, reconciler.egressProxyGroups.Len()) t.Fatalf("expected %d egress ProxyGroups, got %d", expected, reconciler.egressProxyGroups.Len())
@ -153,7 +153,7 @@ func TestProxyGroup(t *testing.T) {
}, },
} }
tsoperator.SetProxyGroupCondition(pg, tsapi.ProxyGroupReady, metav1.ConditionTrue, reasonProxyGroupReady, reasonProxyGroupReady, 0, cl, zl.Sugar()) tsoperator.SetProxyGroupCondition(pg, tsapi.ProxyGroupReady, metav1.ConditionTrue, reasonProxyGroupReady, reasonProxyGroupReady, 0, cl, zl.Sugar())
expectEqual(t, fc, pg, nil) expectEqual(t, fc, pg)
expectProxyGroupResources(t, fc, pg, true, initialCfgHash) expectProxyGroupResources(t, fc, pg, true, initialCfgHash)
}) })
@ -164,7 +164,7 @@ func TestProxyGroup(t *testing.T) {
}) })
expectReconciled(t, reconciler, "", pg.Name) expectReconciled(t, reconciler, "", pg.Name)
tsoperator.SetProxyGroupCondition(pg, tsapi.ProxyGroupReady, metav1.ConditionFalse, reasonProxyGroupCreating, "2/3 ProxyGroup pods running", 0, cl, zl.Sugar()) tsoperator.SetProxyGroupCondition(pg, tsapi.ProxyGroupReady, metav1.ConditionFalse, reasonProxyGroupCreating, "2/3 ProxyGroup pods running", 0, cl, zl.Sugar())
expectEqual(t, fc, pg, nil) expectEqual(t, fc, pg)
expectProxyGroupResources(t, fc, pg, true, initialCfgHash) expectProxyGroupResources(t, fc, pg, true, initialCfgHash)
addNodeIDToStateSecrets(t, fc, pg) addNodeIDToStateSecrets(t, fc, pg)
@ -174,7 +174,7 @@ func TestProxyGroup(t *testing.T) {
Hostname: "hostname-nodeid-2", Hostname: "hostname-nodeid-2",
TailnetIPs: []string{"1.2.3.4", "::1"}, TailnetIPs: []string{"1.2.3.4", "::1"},
}) })
expectEqual(t, fc, pg, nil) expectEqual(t, fc, pg)
expectProxyGroupResources(t, fc, pg, true, initialCfgHash) expectProxyGroupResources(t, fc, pg, true, initialCfgHash)
}) })
@ -187,7 +187,7 @@ func TestProxyGroup(t *testing.T) {
expectReconciled(t, reconciler, "", pg.Name) expectReconciled(t, reconciler, "", pg.Name)
pg.Status.Devices = pg.Status.Devices[:1] // truncate to only the first device. pg.Status.Devices = pg.Status.Devices[:1] // truncate to only the first device.
expectEqual(t, fc, pg, nil) expectEqual(t, fc, pg)
expectProxyGroupResources(t, fc, pg, true, initialCfgHash) expectProxyGroupResources(t, fc, pg, true, initialCfgHash)
}) })
@ -201,7 +201,7 @@ func TestProxyGroup(t *testing.T) {
expectReconciled(t, reconciler, "", pg.Name) expectReconciled(t, reconciler, "", pg.Name)
expectEqual(t, fc, pg, nil) expectEqual(t, fc, pg)
expectProxyGroupResources(t, fc, pg, true, "518a86e9fae64f270f8e0ec2a2ea6ca06c10f725035d3d6caca132cd61e42a74") expectProxyGroupResources(t, fc, pg, true, "518a86e9fae64f270f8e0ec2a2ea6ca06c10f725035d3d6caca132cd61e42a74")
}) })
@ -211,7 +211,7 @@ func TestProxyGroup(t *testing.T) {
p.Spec = pc.Spec p.Spec = pc.Spec
}) })
expectReconciled(t, reconciler, "", pg.Name) expectReconciled(t, reconciler, "", pg.Name)
expectEqual(t, fc, expectedMetricsService(opts), nil) expectEqual(t, fc, expectedMetricsService(opts))
}) })
t.Run("enable_service_monitor_no_crd", func(t *testing.T) { t.Run("enable_service_monitor_no_crd", func(t *testing.T) {
pc.Spec.Metrics.ServiceMonitor = &tsapi.ServiceMonitor{Enable: true} pc.Spec.Metrics.ServiceMonitor = &tsapi.ServiceMonitor{Enable: true}
@ -389,10 +389,10 @@ func expectProxyGroupResources(t *testing.T, fc client.WithWatch, pg *tsapi.Prox
} }
if shouldExist { if shouldExist {
expectEqual(t, fc, role, nil) expectEqual(t, fc, role)
expectEqual(t, fc, roleBinding, nil) expectEqual(t, fc, roleBinding)
expectEqual(t, fc, serviceAccount, nil) expectEqual(t, fc, serviceAccount)
expectEqual(t, fc, statefulSet, nil) expectEqual(t, fc, statefulSet, removeResourceReqs)
} else { } else {
expectMissing[rbacv1.Role](t, fc, role.Namespace, role.Name) expectMissing[rbacv1.Role](t, fc, role.Namespace, role.Name)
expectMissing[rbacv1.RoleBinding](t, fc, roleBinding.Namespace, roleBinding.Name) expectMissing[rbacv1.RoleBinding](t, fc, roleBinding.Namespace, roleBinding.Name)

@ -618,7 +618,7 @@ func mustUpdateStatus[T any, O ptrObject[T]](t *testing.T, client client.Client,
// modify func to ensure that they are removed from the cluster object and the // modify func to ensure that they are removed from the cluster object and the
// object passed as 'want'. If no such modifications are needed, you can pass // object passed as 'want'. If no such modifications are needed, you can pass
// nil in place of the modify function. // nil in place of the modify function.
func expectEqual[T any, O ptrObject[T]](t *testing.T, client client.Client, want O, modifier func(O)) { func expectEqual[T any, O ptrObject[T]](t *testing.T, client client.Client, want O, modifiers ...func(O)) {
t.Helper() t.Helper()
got := O(new(T)) got := O(new(T))
if err := client.Get(context.Background(), types.NamespacedName{ if err := client.Get(context.Background(), types.NamespacedName{
@ -632,7 +632,7 @@ func expectEqual[T any, O ptrObject[T]](t *testing.T, client client.Client, want
// so just remove it from both got and want. // so just remove it from both got and want.
got.SetResourceVersion("") got.SetResourceVersion("")
want.SetResourceVersion("") want.SetResourceVersion("")
if modifier != nil { for _, modifier := range modifiers {
modifier(want) modifier(want)
modifier(got) modifier(got)
} }
@ -799,6 +799,12 @@ func removeHashAnnotation(sts *appsv1.StatefulSet) {
} }
} }
func removeResourceReqs(sts *appsv1.StatefulSet) {
if sts != nil {
sts.Spec.Template.Spec.Resources = nil
}
}
func removeTargetPortsFromSvc(svc *corev1.Service) { func removeTargetPortsFromSvc(svc *corev1.Service) {
newPorts := make([]corev1.ServicePort, 0) newPorts := make([]corev1.ServicePort, 0)
for _, p := range svc.Spec.Ports { for _, p := range svc.Spec.Ports {

@ -57,7 +57,7 @@ func TestRecorder(t *testing.T) {
msg := "Recorder is invalid: must either enable UI or use S3 storage to ensure recordings are accessible" msg := "Recorder is invalid: must either enable UI or use S3 storage to ensure recordings are accessible"
tsoperator.SetRecorderCondition(tsr, tsapi.RecorderReady, metav1.ConditionFalse, reasonRecorderInvalid, msg, 0, cl, zl.Sugar()) tsoperator.SetRecorderCondition(tsr, tsapi.RecorderReady, metav1.ConditionFalse, reasonRecorderInvalid, msg, 0, cl, zl.Sugar())
expectEqual(t, fc, tsr, nil) expectEqual(t, fc, tsr)
if expected := 0; reconciler.recorders.Len() != expected { if expected := 0; reconciler.recorders.Len() != expected {
t.Fatalf("expected %d recorders, got %d", expected, reconciler.recorders.Len()) t.Fatalf("expected %d recorders, got %d", expected, reconciler.recorders.Len())
} }
@ -76,7 +76,7 @@ func TestRecorder(t *testing.T) {
expectReconciled(t, reconciler, "", tsr.Name) expectReconciled(t, reconciler, "", tsr.Name)
tsoperator.SetRecorderCondition(tsr, tsapi.RecorderReady, metav1.ConditionTrue, reasonRecorderCreated, reasonRecorderCreated, 0, cl, zl.Sugar()) tsoperator.SetRecorderCondition(tsr, tsapi.RecorderReady, metav1.ConditionTrue, reasonRecorderCreated, reasonRecorderCreated, 0, cl, zl.Sugar())
expectEqual(t, fc, tsr, nil) expectEqual(t, fc, tsr)
if expected := 1; reconciler.recorders.Len() != expected { if expected := 1; reconciler.recorders.Len() != expected {
t.Fatalf("expected %d recorders, got %d", expected, reconciler.recorders.Len()) t.Fatalf("expected %d recorders, got %d", expected, reconciler.recorders.Len())
} }
@ -112,7 +112,7 @@ func TestRecorder(t *testing.T) {
URL: "https://test-0.example.ts.net", URL: "https://test-0.example.ts.net",
}, },
} }
expectEqual(t, fc, tsr, nil) expectEqual(t, fc, tsr)
}) })
t.Run("delete the Recorder and observe cleanup", func(t *testing.T) { t.Run("delete the Recorder and observe cleanup", func(t *testing.T) {
@ -145,12 +145,12 @@ func expectRecorderResources(t *testing.T, fc client.WithWatch, tsr *tsapi.Recor
statefulSet := tsrStatefulSet(tsr, tsNamespace) statefulSet := tsrStatefulSet(tsr, tsNamespace)
if shouldExist { if shouldExist {
expectEqual(t, fc, auth, nil) expectEqual(t, fc, auth)
expectEqual(t, fc, state, nil) expectEqual(t, fc, state)
expectEqual(t, fc, role, nil) expectEqual(t, fc, role)
expectEqual(t, fc, roleBinding, nil) expectEqual(t, fc, roleBinding)
expectEqual(t, fc, serviceAccount, nil) expectEqual(t, fc, serviceAccount)
expectEqual(t, fc, statefulSet, nil) expectEqual(t, fc, statefulSet, removeResourceReqs)
} else { } else {
expectMissing[corev1.Secret](t, fc, auth.Namespace, auth.Name) expectMissing[corev1.Secret](t, fc, auth.Namespace, auth.Name)
expectMissing[corev1.Secret](t, fc, state.Namespace, state.Name) expectMissing[corev1.Secret](t, fc, state.Namespace, state.Name)

@ -8,11 +8,11 @@ tailscale.com/cmd/stund dependencies: (generated by github.com/tailscale/depawar
github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+ github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+ github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+
github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+ github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+
github.com/munnerz/goautoneg from github.com/prometheus/common/expfmt
💣 github.com/prometheus/client_golang/prometheus from tailscale.com/tsweb/promvarz 💣 github.com/prometheus/client_golang/prometheus from tailscale.com/tsweb/promvarz
github.com/prometheus/client_golang/prometheus/internal from github.com/prometheus/client_golang/prometheus github.com/prometheus/client_golang/prometheus/internal from github.com/prometheus/client_golang/prometheus
github.com/prometheus/client_model/go from github.com/prometheus/client_golang/prometheus+ github.com/prometheus/client_model/go from github.com/prometheus/client_golang/prometheus+
github.com/prometheus/common/expfmt from github.com/prometheus/client_golang/prometheus+ github.com/prometheus/common/expfmt from github.com/prometheus/client_golang/prometheus+
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg from github.com/prometheus/common/expfmt
github.com/prometheus/common/model from github.com/prometheus/client_golang/prometheus+ github.com/prometheus/common/model from github.com/prometheus/client_golang/prometheus+
LD github.com/prometheus/procfs from github.com/prometheus/client_golang/prometheus LD github.com/prometheus/procfs from github.com/prometheus/client_golang/prometheus
LD github.com/prometheus/procfs/internal/fs from github.com/prometheus/procfs LD github.com/prometheus/procfs/internal/fs from github.com/prometheus/procfs
@ -155,7 +155,6 @@ tailscale.com/cmd/stund dependencies: (generated by github.com/tailscale/depawar
html from net/http/pprof+ html from net/http/pprof+
io from bufio+ io from bufio+
io/fs from crypto/x509+ io/fs from crypto/x509+
io/ioutil from google.golang.org/protobuf/internal/impl
iter from maps+ iter from maps+
log from expvar+ log from expvar+
log/internal from log log/internal from log

64
go.mod

@ -32,7 +32,7 @@ require (
github.com/evanw/esbuild v0.19.11 github.com/evanw/esbuild v0.19.11
github.com/fogleman/gg v1.3.0 github.com/fogleman/gg v1.3.0
github.com/frankban/quicktest v1.14.6 github.com/frankban/quicktest v1.14.6
github.com/fxamacker/cbor/v2 v2.6.0 github.com/fxamacker/cbor/v2 v2.7.0
github.com/gaissmai/bart v0.11.1 github.com/gaissmai/bart v0.11.1
github.com/go-json-experiment/json v0.0.0-20250103232110-6a9a0fde9288 github.com/go-json-experiment/json v0.0.0-20250103232110-6a9a0fde9288
github.com/go-logr/zapr v1.3.0 github.com/go-logr/zapr v1.3.0
@ -68,7 +68,7 @@ require (
github.com/pkg/sftp v1.13.6 github.com/pkg/sftp v1.13.6
github.com/prometheus-community/pro-bing v0.4.0 github.com/prometheus-community/pro-bing v0.4.0
github.com/prometheus/client_golang v1.19.1 github.com/prometheus/client_golang v1.19.1
github.com/prometheus/common v0.48.0 github.com/prometheus/common v0.55.0
github.com/prometheus/prometheus v0.49.2-0.20240125131847-c3b8ef1694ff github.com/prometheus/prometheus v0.49.2-0.20240125131847-c3b8ef1694ff
github.com/safchain/ethtool v0.3.0 github.com/safchain/ethtool v0.3.0
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
@ -79,7 +79,7 @@ require (
github.com/tailscale/golang-x-crypto v0.0.0-20240604161659-3fde5e568aa4 github.com/tailscale/golang-x-crypto v0.0.0-20240604161659-3fde5e568aa4
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a
github.com/tailscale/mkctr v0.0.0-20241111153353-1a38f6676f10 github.com/tailscale/mkctr v0.0.0-20250110151924-54977352e4a6
github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7
github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc
github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1 github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1
@ -109,12 +109,12 @@ require (
gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/square/go-jose.v2 v2.6.0
gvisor.dev/gvisor v0.0.0-20240722211153-64c016c92987 gvisor.dev/gvisor v0.0.0-20240722211153-64c016c92987
honnef.co/go/tools v0.5.1 honnef.co/go/tools v0.5.1
k8s.io/api v0.30.3 k8s.io/api v0.32.0
k8s.io/apimachinery v0.30.3 k8s.io/apimachinery v0.32.0
k8s.io/apiserver v0.30.3 k8s.io/apiserver v0.32.0
k8s.io/client-go v0.30.3 k8s.io/client-go v0.32.0
sigs.k8s.io/controller-runtime v0.18.4 sigs.k8s.io/controller-runtime v0.19.4
sigs.k8s.io/controller-tools v0.15.1-0.20240618033008-7824932b0cab sigs.k8s.io/controller-tools v0.17.0
sigs.k8s.io/yaml v1.4.0 sigs.k8s.io/yaml v1.4.0
software.sslmate.com/src/go-pkcs12 v0.4.0 software.sslmate.com/src/go-pkcs12 v0.4.0
) )
@ -143,12 +143,11 @@ require (
github.com/ghostiam/protogetter v0.3.5 // indirect github.com/ghostiam/protogetter v0.3.5 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect
github.com/gobuffalo/flect v1.0.2 // indirect github.com/gobuffalo/flect v1.0.3 // indirect
github.com/goccy/go-yaml v1.12.0 // indirect github.com/goccy/go-yaml v1.12.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golangci/plugin-module-register v0.1.1 // indirect github.com/golangci/plugin-module-register v0.1.1 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect
github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect
github.com/jjti/go-spancheck v0.5.3 // indirect github.com/jjti/go-spancheck v0.5.3 // indirect
github.com/karamaru-alpha/copyloopvar v1.0.8 // indirect github.com/karamaru-alpha/copyloopvar v1.0.8 // indirect
@ -159,12 +158,14 @@ require (
github.com/ykadowak/zerologlint v0.1.5 // indirect github.com/ykadowak/zerologlint v0.1.5 // indirect
go-simpler.org/musttag v0.9.0 // indirect go-simpler.org/musttag v0.9.0 // indirect
go-simpler.org/sloglint v0.5.0 // indirect go-simpler.org/sloglint v0.5.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.32.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
go.opentelemetry.io/otel/metric v1.32.0 // indirect go.opentelemetry.io/otel v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.32.0 // indirect go.opentelemetry.io/otel/metric v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.33.0 // indirect
go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/automaxprocs v1.5.3 // indirect
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
) )
require ( require (
@ -210,25 +211,24 @@ require (
github.com/breml/errchkjson v0.3.6 // indirect github.com/breml/errchkjson v0.3.6 // indirect
github.com/butuzov/ireturn v0.3.0 // indirect github.com/butuzov/ireturn v0.3.0 // indirect
github.com/cavaliergopher/cpio v1.0.1 // indirect github.com/cavaliergopher/cpio v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charithe/durationcheck v0.0.10 // indirect github.com/charithe/durationcheck v0.0.10 // indirect
github.com/chavacava/garif v0.1.0 // indirect github.com/chavacava/garif v0.1.0 // indirect
github.com/cloudflare/circl v1.3.7 // indirect github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect
github.com/daixiang0/gci v0.12.3 // indirect github.com/daixiang0/gci v0.12.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/denis-tingaikin/go-header v0.5.0 // indirect github.com/denis-tingaikin/go-header v0.5.0 // indirect
github.com/docker/cli v27.3.1+incompatible // indirect github.com/docker/cli v27.4.1+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v27.3.1+incompatible // indirect github.com/docker/docker v27.4.1+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect
github.com/emicklei/go-restful/v3 v3.11.2 // indirect github.com/emicklei/go-restful/v3 v3.11.2 // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/ettle/strcase v0.2.0 // indirect github.com/ettle/strcase v0.2.0 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fatih/color v1.17.0 // indirect github.com/fatih/color v1.18.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect github.com/fatih/structtag v1.2.0 // indirect
github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/firefart/nonamedreturns v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 github.com/fsnotify/fsnotify v1.7.0
@ -238,9 +238,9 @@ require (
github.com/go-git/go-billy/v5 v5.6.1 // indirect github.com/go-git/go-billy/v5 v5.6.1 // indirect
github.com/go-git/go-git/v5 v5.13.1 // indirect github.com/go-git/go-git/v5 v5.13.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/swag v0.22.7 // indirect github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect
github.com/go-toolsmith/astcopy v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect
github.com/go-toolsmith/astequal v1.2.0 // indirect github.com/go-toolsmith/astequal v1.2.0 // indirect
@ -328,14 +328,14 @@ require (
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/polyfloyd/go-errorlint v1.4.8 // indirect github.com/polyfloyd/go-errorlint v1.4.8 // indirect
github.com/prometheus/client_model v0.5.0 github.com/prometheus/client_model v0.6.1
github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect
github.com/quasilyte/go-ruleguard v0.4.2 // indirect github.com/quasilyte/go-ruleguard v0.4.2 // indirect
github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
github.com/rivo/uniseg v0.4.4 // indirect github.com/rivo/uniseg v0.4.4 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/ryancurrah/gomodguard v1.3.1 // indirect github.com/ryancurrah/gomodguard v1.3.1 // indirect
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect
@ -387,19 +387,19 @@ require (
golang.org/x/image v0.23.0 // indirect golang.org/x/image v0.23.0 // indirect
golang.org/x/text v0.21.0 // indirect golang.org/x/text v0.21.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
howett.net/plist v1.0.0 // indirect howett.net/plist v1.0.0 // indirect
k8s.io/apiextensions-apiserver v0.30.3 k8s.io/apiextensions-apiserver v0.32.0
k8s.io/klog/v2 v2.130.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
mvdan.cc/gofumpt v0.6.0 // indirect mvdan.cc/gofumpt v0.6.0 // indirect
mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 // indirect mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
) )

169
go.sum

@ -211,13 +211,13 @@ github.com/cavaliergopher/cpio v1.0.1/go.mod h1:pBdaqQjnvXxdS/6CvNDwIANIFSP0xRKI
github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg= github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=
github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4=
github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ=
github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc= github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc=
@ -237,8 +237,8 @@ github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NA
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0=
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
@ -275,12 +275,12 @@ 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/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c= github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c=
github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0= github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0=
github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= github.com/docker/cli v27.4.1+incompatible h1:VzPiUlRJ/xh+otB75gva3r05isHMo5wXDfPRi5/b4hI=
github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v27.4.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= github.com/docker/docker v27.4.1+incompatible h1:ZJvcY7gfwHn1JF48PfbyXg7Jyt9ZCWDW+GGXOIxEwp4=
github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v27.4.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
@ -309,8 +309,8 @@ github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
github.com/evanw/esbuild v0.19.11 h1:mbPO1VJ/df//jjUd+p/nRLYCpizXxXb2w/zZMShxa2k= github.com/evanw/esbuild v0.19.11 h1:mbPO1VJ/df//jjUd+p/nRLYCpizXxXb2w/zZMShxa2k=
github.com/evanw/esbuild v0.19.11/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= github.com/evanw/esbuild v0.19.11/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
@ -323,8 +323,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
github.com/gaissmai/bart v0.11.1 h1:5Uv5XwsaFBRo4E5VBcb9TzY8B7zxFf+U7isDxqOrRfc= github.com/gaissmai/bart v0.11.1 h1:5Uv5XwsaFBRo4E5VBcb9TzY8B7zxFf+U7isDxqOrRfc=
@ -365,12 +365,12 @@ 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-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU=
github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4=
github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
@ -381,7 +381,8 @@ github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= 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/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8=
github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s=
@ -405,8 +406,8 @@ github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsM
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U=
github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4=
github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM=
@ -508,8 +509,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/rpmpack v0.5.0 h1:L16KZ3QvkFGpYhmp23iQip+mx1X39foEsqszjMNBm8A= github.com/google/rpmpack v0.5.0 h1:L16KZ3QvkFGpYhmp23iQip+mx1X39foEsqszjMNBm8A=
github.com/google/rpmpack v0.5.0/go.mod h1:uqVAUVQLq8UY2hCDfmJ/+rtO3aw7qyhc90rCVEabEfI= github.com/google/rpmpack v0.5.0/go.mod h1:uqVAUVQLq8UY2hCDfmJ/+rtO3aw7qyhc90rCVEabEfI=
@ -545,8 +546,8 @@ github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod
github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY=
github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
@ -738,10 +739,10 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= 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/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
@ -790,21 +791,21 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/prometheus/prometheus v0.49.2-0.20240125131847-c3b8ef1694ff h1:X1Tly81aZ22DA1fxBdfvR3iw8+yFoUBUHMEd+AX/ZXI= github.com/prometheus/prometheus v0.49.2-0.20240125131847-c3b8ef1694ff h1:X1Tly81aZ22DA1fxBdfvR3iw8+yFoUBUHMEd+AX/ZXI=
github.com/prometheus/prometheus v0.49.2-0.20240125131847-c3b8ef1694ff/go.mod h1:FvE8dtQ1Ww63IlyKBn1V4s+zMwF9kHkVNkQBR1pM4CU= github.com/prometheus/prometheus v0.49.2-0.20240125131847-c3b8ef1694ff/go.mod h1:FvE8dtQ1Ww63IlyKBn1V4s+zMwF9kHkVNkQBR1pM4CU=
github.com/quasilyte/go-ruleguard v0.4.2 h1:htXcXDK6/rO12kiTHKfHuqR4kr3Y4M0J0rOL6CH/BYs= github.com/quasilyte/go-ruleguard v0.4.2 h1:htXcXDK6/rO12kiTHKfHuqR4kr3Y4M0J0rOL6CH/BYs=
@ -820,8 +821,8 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryancurrah/gomodguard v1.3.1 h1:fH+fUg+ngsQO0ruZXXHnA/2aNllWA1whly4a6UvyzGE= github.com/ryancurrah/gomodguard v1.3.1 h1:fH+fUg+ngsQO0ruZXXHnA/2aNllWA1whly4a6UvyzGE=
github.com/ryancurrah/gomodguard v1.3.1/go.mod h1:DGFHzEhi6iJ0oIDfMuo3TgrS+L9gZvrEfmjjuelnRU0= github.com/ryancurrah/gomodguard v1.3.1/go.mod h1:DGFHzEhi6iJ0oIDfMuo3TgrS+L9gZvrEfmjjuelnRU0=
@ -926,8 +927,8 @@ github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 h1:4chzWmimtJPx
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8= github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8=
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29XwJucQo73FrleVK6t4kYz4NVhp34Yw= github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29XwJucQo73FrleVK6t4kYz4NVhp34Yw=
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8= github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8=
github.com/tailscale/mkctr v0.0.0-20241111153353-1a38f6676f10 h1:ZB47BgnHcEHQJODkDubs5ZiNeJxMhcgzefV3lykRwVQ= github.com/tailscale/mkctr v0.0.0-20250110151924-54977352e4a6 h1:9SuADtKJAGQkIpnpg5znEJ86QaxacN25pHkiEXTDjzg=
github.com/tailscale/mkctr v0.0.0-20241111153353-1a38f6676f10/go.mod h1:iDx/0Rr9VV/KanSUDpJ6I/ROf0sQ7OqljXc/esl0UIA= github.com/tailscale/mkctr v0.0.0-20250110151924-54977352e4a6/go.mod h1:qTslktI+Qh9hXo7ZP8xLkl5V8AxUMfxG0xLtkCFLxnw=
github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 h1:uFsXVBE9Qr4ZoF094vE6iYTLDl0qCiKzYXlL6UeWObU= github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 h1:uFsXVBE9Qr4ZoF094vE6iYTLDl0qCiKzYXlL6UeWObU=
github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0=
github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc h1:24heQPtnFR+yfntqhI3oAu9i27nEojcQ4NuBQOo5ZFA= github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc h1:24heQPtnFR+yfntqhI3oAu9i27nEojcQ4NuBQOo5ZFA=
@ -1017,22 +1018,24 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 h1:DheMAlT6POBP+gh8RUH19EOTnQIor5QE0uSRPtzCpSw= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0/go.mod h1:wZcGmeVO9nzP67aYSLDqXNWK87EZWhi7JWj1v7ZXf94= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 h1:9M3+rhx7kZCIQQhQRYaZCdNu1V73tm4TvXs2ntl98C4= go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0/go.mod h1:noq80iT8rrHP1SfybmPiRGc9dc5M8RPmGvtwo7Oo7tc= go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk=
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M=
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@ -1384,11 +1387,11 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ=
google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac h1:OZkkudMUu9LVQMCoRUbI/1p5VCo9BOrlvkqMvWtqa6s= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw=
google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -1401,8 +1404,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -1415,8 +1418,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -1424,6 +1427,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 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= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
@ -1461,22 +1466,22 @@ honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I=
honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs=
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ= k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE=
k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04= k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0=
k8s.io/apiextensions-apiserver v0.30.3 h1:oChu5li2vsZHx2IvnGP3ah8Nj3KyqG3kRSaKmijhB9U= k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0=
k8s.io/apiextensions-apiserver v0.30.3/go.mod h1:uhXxYDkMAvl6CJw4lrDN4CPbONkF3+XL9cacCT44kV4= k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw=
k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc= k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/apiserver v0.30.3 h1:QZJndA9k2MjFqpnyYv/PH+9PE0SHhx3hBho4X0vE65g= k8s.io/apiserver v0.32.0 h1:VJ89ZvQZ8p1sLeiWdRJpRD6oLozNZD2+qVSLi+ft5Qs=
k8s.io/apiserver v0.30.3/go.mod h1:6Oa88y1CZqnzetd2JdepO0UXzQX4ZnOekx2/PtEjrOg= k8s.io/apiserver v0.32.0/go.mod h1:HFh+dM1/BE/Hm4bS4nTXHVfN6Z6tFIZPi649n83b4Ag=
k8s.io/client-go v0.30.3 h1:bHrJu3xQZNXIi8/MoxYtZBBWQQXwy16zqJwloXXfD3k= k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8=
k8s.io/client-go v0.30.3/go.mod h1:8d4pf8vYu665/kUbsxWAQ/JDBNWqfFeZnvFiVdmx89U= k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo= mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo=
mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA= mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA=
mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 h1:zCr3iRRgdk5eIikZNDphGcM6KGVTx3Yu+/Uu9Es254w= mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 h1:zCr3iRRgdk5eIikZNDphGcM6KGVTx3Yu+/Uu9Es254w=
@ -1484,14 +1489,14 @@ mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14/go.mod h1:ZzZjEpJDOmx8TdVU6u
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= sigs.k8s.io/controller-runtime v0.19.4 h1:SUmheabttt0nx8uJtoII4oIP27BVVvAKFvdvGFwV/Qo=
sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= sigs.k8s.io/controller-runtime v0.19.4/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
sigs.k8s.io/controller-tools v0.15.1-0.20240618033008-7824932b0cab h1:Fq4VD28nejtsijBNTeRRy9Tt3FVwq+o6NB7fIxja8uY= sigs.k8s.io/controller-tools v0.17.0 h1:KaEQZbhrdY6J3zLBHplt+0aKUp8PeIttlhtF2UDo6bI=
sigs.k8s.io/controller-tools v0.15.1-0.20240618033008-7824932b0cab/go.mod h1:egedX5jq2KrZ3A2zaOz3e2DSsh5BhFyyjvNcBRIQel8= sigs.k8s.io/controller-tools v0.17.0/go.mod h1:SKoWY8rwGWDzHtfnhmOwljn6fViG0JF7/xmnxpklgjo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=