summaryrefslogtreecommitdiffhomepage
AgeCommit message (Collapse)AuthorFilesLines
2025-01-17attempt 1percy/derp-track-queue-depthPercy Wegmann1-19/+60
Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-01-17ipnlocal: allow overriding os.Hostname() via syspolicy (#14676)Andrea Gottardo2-0/+37
Updates tailscale/corp#25936 This defines a new syspolicy 'Hostname' and allows an IT administrator to override the value we normally read from os.Hostname(). This is particularly useful on Android and iOS devices, where the hostname we get from the OS is really just the device model (a platform restriction to prevent fingerprinting). If we don't implement this, all devices on the customer's side will look like `google-pixel-7a-1`, `google-pixel-7a-2`, `google-pixel-7a-3`, etc. and it is not feasible for the customer to use the API or worse the admin console to manually fix these names. Apply code review comment by @nickkhyl Signed-off-by: Andrea Gottardo <andrea@gottardo.me> Co-authored-by: Nick Khyl <1761190+nickkhyl@users.noreply.github.com>
2025-01-17go.{mod,sum},cmd/{k8s-operator,derper,stund}/depaware.txt: bump kube deps ↵Irbe Krumina22-364/+690
(#14601) Updates kube deps and mkctr, regenerates kube yamls with the updated tooling. Updates#cleanup Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2025-01-16net/tstun: add logging to aid developers missing Start callsBrad Fitzpatrick1-1/+15
Since 5297bd2cff8ed03679, tstun.Wrapper has required its Start method to be called for it to function. Failure to do so just results in weird hangs and I've wasted too much time multiple times now debugging. Hopefully this prevents more lost time. Updates tailscale/corp#24454 Change-Id: I87f4539f7be7dc154627f8835a37a8db88c31be0 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-16derp: change packets_dropped metric to also have reason and kind labels (#14651)Mario Minardi2-131/+126
Metrics currently exist for dropped packets by reason, and total received packets by kind (e.g., `disco` or `other`), but relating these two together to gleam information about the drop rate for specific reasons on a per-kind basis is not currently possible. Change `derp_packets_dropped` to use a `metrics.MultiLabelMap` to track both the `reason` and `kind` in the same metric to allow for this desired level of granularity. Drop metrics that this makes unnecessary (namely `packetsDroppedReason` and `packetsDroppedType`). Updates https://github.com/tailscale/corp/issues/25489 Signed-off-by: Mario Minardi <mario@tailscale.com>
2025-01-16net/dns: only populate OSConfig.Hosts when MagicDNS is enabledAaron Klotz2-1/+73
Previously we were doing this unconditionally. Updates #14428 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
2025-01-16cmd/k8s-operator: require namespace config (#14648)Tom Proctor1-0/+9
Most users should not run into this because it's set in the helm chart and the deploy manifest, but if namespace is not set we get confusing authz errors because the kube client tries to fetch some namespaced resources as though they're cluster-scoped and reports permission denied. Try to detect namespace from the default projected volume, and otherwise fatal. Fixes #cleanup Change-Id: I64b34191e440b61204b9ad30bbfa117abbbe09c3 Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
2025-01-15prober: remove DERP pub key copying overheads in qd and non-tun measures ↵Jordan Whited1-6/+10
(#14659) Updates tailscale/corp#25883 Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-01-15prober: remove per-packet DERP pub key copying overheads (#14658)Jordan Whited1-2/+4
Updates tailscale/corp#25883 Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-01-15ipn/ipnserver: fix a deadlock in (*Server).blockWhileIdentityInUseNick Khyl2-1/+58
If the server was in use at the time of the initial check, but disconnected and was removed from the activeReqs map by the time we registered a waiter, the ready channel will never be closed, resulting in a deadlock. To avoid this, we check whether the server is still busy after registering the wait. Fixes #14655 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-15ipn/ipnserver: fix TestConcurrentOSUserSwitchingOnWindowsNick Khyl1-1/+14
I made a last-minute change in #14626 to split a single loop that created 1_000 concurrent connections into an inner and outer loop that create 100 concurrent connections 10 times. This introduced a race because the last user's connection may still be active (from the server's perspective) when a new outer iteration begins. Since every new client gets a unique ClientID, but we reuse usernames and UIDs, the server may let a user in (as the UID matches, which is fine), but the test might then fail due to a ClientID mismatch: server_test.go:232: CurrentUser(Initial): got &{S-1-5-21-1-0-0-1001 User-4 <nil> Client-2 false false}; want &{S-1-5-21-1-0-0-1001 User-4 <nil> Client-114 false false} In this PR, we update (*testIPNServer).blockWhileInUse to check whether the server is currently busy and wait until it frees up. We then call blockWhileInUse at the end of each outer iteration so that the server is always in a known idle state at the beginning of the inner loop. We also check that the current user is not set when the server is idle. Updates tailscale/corp#25804 Updates #14655 (found when working on it) Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-15cmd/tailscaled: add some more depchecker dep testsBrad Fitzpatrick1-2/+4
As we look to add github.com/prometheus/client_golang/prometheus to more parts of the codebase, lock in that we don't use it in tailscaled, primarily for binary size reasons. Updates #12614 Change-Id: I03c100d12a05019a22bdc23ce5c4df63d5a03ec6 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-15types/lazy: fix flaky TestDeferAfterDoNick Khyl2-7/+34
This test verifies, among other things, that init functions cannot be deferred after (*DeferredFuncs).Do has already been called and that all subsequent calls to (*DeferredFuncs).Defer return false. However, the initial implementation of this check was racy: by the time (*DeferredFuncs).Do returned, not all goroutines that successfully deferred an init function may have incremented the atomic variable tracking the number of deferred functions. As a result, the variable's value could differ immediately after (*DeferredFuncs).Do returned and after all goroutines had completed execution (i.e., after wg.Wait()). In this PR, we replace the original racy check with a different one. Although this new check is also racy, it can only produce false negatives. This means that if the test fails, it indicates an actual bug rather than a flaky test. Fixes #14039 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-15ipn/ipnlocal: re-advertise appc routes on startup (#14609)Andrew Lytvynov2-3/+79
There's at least one example of stored routes and advertised routes getting out of sync. I don't know how they got there yet, but this would backfill missing advertised routes on startup from stored routes. Also add logging in LocalBackend.AdvertiseRoute to record when new routes actually get put into prefs. Updates #14606 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-01-15atomicfile: use ReplaceFile on Windows so that attributes and ACLs are preservedAaron Klotz10-7/+261
I moved the actual rename into separate, GOOS-specific files. On non-Windows, we do a simple os.Rename. On Windows, we first try ReplaceFile with a fallback to os.Rename if the target file does not exist. ReplaceFile is the recommended way to rename the file in this use case, as it preserves attributes and ACLs set on the target file. Updates #14428 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
2025-01-15.github: Bump github/codeql-action from 3.27.6 to 3.28.1 (#14618)dependabot[bot]1-3/+3
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.6 to 3.28.1. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/aa578102511db1f4524ed59b8cc2bae4f6e88195...b6a472f63d85b9c78a3ac5e89422239fc15e9b3c) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-15.github: Bump actions/setup-go from 5.1.0 to 5.2.0 (#14391)dependabot[bot]3-3/+3
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.1.0 to 5.2.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed...3041bf56c941b39c61721a86cd11f3bb1338122a) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-15cmd/derper: support explicit configuration of mesh dial hostsPercy Wegmann2-31/+28
The --mesh-with flag now supports the specification of hostname tuples like derp1a.tailscale.com/derp1a-vpc.tailscale.com, which instructs derp to mesh with host 'derp1a.tailscale.com' but dial TCP connections to 'derp1a-vpc.tailscale.com'. For backwards compatibility, --mesh-with still supports individual hostnames. The logic which attempts to auto-discover '[host]-vpc.tailscale.com' dial hosts has been removed. Updates tailscale/corp#25653 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-01-15tailcfg,control/controlclient: treat nil AllowedIPs as Addresses [capver 112]Brad Fitzpatrick3-4/+50
Updates #14635 Change-Id: I21e2bd1ec4eb384eb7a3fc8379f0788a684893f3 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-14net/netmon: trim IPv6 endpoints in already routable subnetsJames Tucker1-1/+16
We have observed some clients with extremely large lists of IPv6 endpoints, in some cases from subnets where the machine also has the zero address for a whole /48 with then arbitrary addresses additionally assigned within that /48. It is in general unnecessary for reachability to report all of these addresses, typically only one will be necessary for reachability. We report two, to cover some other common cases such as some styles of IPv6 private address rotations. Updates tailscale/corp#25850 Signed-off-by: James Tucker <james@tailscale.com>
2025-01-14client/tailscale: fix typo in commentNick Khyl1-1/+1
Updates #cleanup Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14ipn/ipnserver: fix race condition where LocalBackend is reset after a ↵Nick Khyl2-8/+74
different user connects In this commit, we add a failing test to verify that ipn/ipnserver.Server correctly sets and unsets the current user when two different clients send requests concurrently (A sends request, B sends request, A's request completes, B's request completes). The expectation is that the user who wins the race becomes the current user from the LocalBackend's perspective, remaining in this state until they disconnect, after which a different user should be able to connect and use the LocalBackend. We then fix the second of two bugs in (*Server).addActiveHTTPRequest, where a race condition causes the LocalBackend's state to be reset after a new client connects, instead of after the last active request of the previous client completes and the server becomes idle. Fixes tailscale/corp#25804 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14ipn/{ipnlocal,ipnserver}: remove redundant ↵Nick Khyl3-36/+42
(*LocalBackend).ResetForClientDisconnect In this commit, we add a failing test to verify that ipn/ipnserver.Server correctly sets and unsets the current user when two different users connect sequentially (A connects, A disconnects, B connects, B disconnects). We then fix the test by updating (*ipn/ipnserver.Server).addActiveHTTPRequest to avoid calling (*LocalBackend).ResetForClientDisconnect again after a new user has connected and been set as the current user with (*LocalBackend).SetCurrentUser(). Since ipn/ipnserver.Server does not allow simultaneous connections from different Windows users and relies on the LocalBackend's current user, and since we already reset the LocalBackend's state by calling ResetForClientDisconnect when the last active request completes (indicating the server is idle and can accept connections from any Windows user), it is unnecessary to track the last connected user on the ipnserver.Server side or call ResetForClientDisconnect again when the user changes. Additionally, the second call to ResetForClientDisconnect occurs after the new user has been set as the current user, resetting the correct state for the new user instead of the old state of the now-disconnected user, causing issues. Updates tailscale/corp#25804 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14ipn/{ipnauth,ipnlocal,ipnserver}, client/tailscale: make ipnserver.Server ↵Nick Khyl4-3/+389
testable We update client/tailscale.LocalClient to allow specifying an optional Transport (http.RoundTripper) for LocalAPI HTTP requests, and implement one that injects an ipnauth.TestActor via request headers. We also add several functions and types to make testing an ipn/ipnserver.Server possible (or at least easier). We then use these updates to write basic tests for ipnserver.Server, ensuring it works on non-Windows platforms and correctly sets and unsets the LocalBackend's current user when a Windows user connects and disconnects. We intentionally omit tests for switching between different OS users and will add them in follow-up commits. Updates tailscale/corp#25804 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14ipn/ipnserver: use ipnauth.Actor instead of *ipnserver.actor whenever possibleNick Khyl2-12/+20
In preparation for adding test coverage for ipn/ipnserver.Server, we update it to use ipnauth.Actor instead of its concrete implementation where possible. Updates tailscale/corp#25804 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14net/dns: ensure the Windows configurator does not touch the hosts file ↵Aaron Klotz2-14/+102
unless the configuration actually changed We build up maps of both the existing MagicDNS configuration in hosts and the desired MagicDNS configuration, compare the two, and only write out a new one if there are changes. The comparison doesn't need to be perfect, as the occasional false-positive is fine, but this should greatly reduce rewrites of the hosts file. I also changed the hosts updating code to remove the CRLF/LF conversion stuff, and use Fprintf instead of Frintln to let us write those inline. Updates #14428 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
2025-01-14control/controlclient: remove misleading TS_DEBUG_NETMAP, make it ↵Brad Fitzpatrick1-18/+18
TS_DEBUG_MAP=2 (or more) Updates #cleanup Change-Id: Ic1edaed46b7b451ab58bb2303640225223eba9ce Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-14all: add Node.HomeDERP int, phase out "127.3.3.40:$region" hack [capver 111]Brad Fitzpatrick19-97/+171
This deprecates the old "DERP string" packing a DERP region ID into an IP:port of 127.3.3.40:$REGION_ID and just uses an integer, like PeerChange.DERPRegion does. We still support servers sending the old form; they're converted to the new form internally right when they're read off the network. Updates #14636 Change-Id: I9427ec071f02a2c6d75ccb0fcbf0ecff9f19f26f Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-14ipn/ipnlocal: allow Peer API access via either V4MasqAddr or V6MasqAddr when ↵Nick Khyl1-4/+6
both are set This doesn't seem to have any immediate impact, but not allowing access via the IPv6 masquerade address when an IPv4 masquerade address is also set seems like a bug. Updates #cleanup Updates #14570 (found when working on it) Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14cmd/viewer,all: consistently use "read-only" instead of "readonly"Brad Fitzpatrick14-110/+110
Updates #cleanup Change-Id: I8e4e3497d3d0ec5b16a73aedda500fe5cfa37a67 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-14go.mod: bump mdlayher/netlink and u-root/uio to use Go 1.21 NativeEndianBrad Fitzpatrick6-21/+10
This finishes the work started in #14616. Updates #8632 Change-Id: I4dc07d45b1e00c3db32217c03b21b8b1ec19e782 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-14cmd/viewer,types/views,various: avoid allocations in pointer field getters ↵Nick Khyl15-163/+219
whenever possible In this PR, we add a generic views.ValuePointer type that can be used as a view for pointers to basic types and struct types that do not require deep cloning and do not have corresponding view types. Its Get/GetOk methods return stack-allocated shallow copies of the underlying value. We then update the cmd/viewer codegen to produce getters that return either concrete views when available or ValuePointer views when not, for pointer fields in generated view types. This allows us to avoid unnecessary allocations compared to returning pointers to newly allocated shallow copies. Updates #14570 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14cmd/tailscale/cli: add --posture-checking to tailscale upAnton Tolchanov2-0/+19
This will prevent `tailscale up` from resetting the posture checking client pref. Fixes #12154 Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2025-01-13cmd/tailscale/cli: only exit silently if len(args) == 0Michael Stapelberg1-3/+3
This amends commit b7e48058c8d243adf1ff687e3e92d3fb02b035ea. That commit broke all documented ways of starting Tailscale on gokrazy: https://gokrazy.org/packages/tailscale/ — both Option A (tailscale up) and Option B (tailscale up --auth-key) rely on the tailscale CLI working. I verified that the tailscale CLI just prints it help when started without arguments, i.e. it does not stay running and is not restarted. I verified that the tailscale CLI successfully exits when started with tailscale up --auth-key, regardless of whether the node has joined the tailnet yet or not. I verified that the tailscale CLI successfully waits and exits when started with tailscale up, as expected. fixes https://github.com/gokrazy/gokrazy/issues/286 Signed-off-by: Michael Stapelberg <michael@stapelberg.de>
2025-01-13prober: record total bytes transferred in DERP bandwidth probesPercy Wegmann1-8/+14
This will enable Prometheus queries to look at the bandwidth over time windows, for example 'increase(derp_bw_bytes_total)[1h] / increase(derp_bw_transfer_time_seconds_total)[1h]'. Fixes commit a51672cafd8b6c4e87915a55bda1491eb7cbee84. Updates tailscale/corp#25503 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-01-13Revert "Dockerfile: bump base alpine image (#14604)" (#14620)Andrew Lytvynov3-3/+3
This reverts commit 5fdb4f83ad23f0ee7a9dc08ecc2a0ceeabd81fc3. Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-01-13all: use Go 1.21's binary.NativeEndianBrad Fitzpatrick4-11/+10
We still use josharian/native (hi @josharian!) via netlink, but I also sent https://github.com/mdlayher/netlink/pull/220 Updates #8632 Change-Id: I2eedcb7facb36ec894aee7f152c8a1f56d7fc8ba Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-12util/uniq,types/lazy,*: delete code that's now in Go stdBrad Fitzpatrick13-271/+18
sync.OnceValue and slices.Compact were both added in Go 1.21. cmp.Or was added in Go 1.22. Updates #8632 Updates #11058 Change-Id: I89ba4c404f40188e1f8a9566c8aaa049be377754 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-10Dockerfile: bump base alpine image (#14604)Andrew Lytvynov3-3/+3
Bump the versions to pick up some CVE patches. They don't affect us, but customer scanners will complain. Updates #cleanup Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-01-10ipn/ipnlocal: add VIPServices hash to return body of vip-services c2n endpointKevinLiang103-4/+22
This commit updates the return body of c2n endpoint /vip-services to keep hash generation logic on client side. Updates tailscale/corp#24510 Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-01-10prober: support filtering regions by region ID in addition to codePercy Wegmann3-22/+22
Updates tailscale/corp#25758 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-01-10go.mod: bump some depsBrad Fitzpatrick2-34/+30
Most of these are effectively no-ops, but appease security scanners. At least one (x/net for x/net/html) only affect builds from the open source repo, since we already had it updated in our "corp" repo: golang.org/x/net v0.33.1-0.20241230221519-e9d95ba163f7 ... and that's where we do the official releases from. e.g. tailscale.io % go install tailscale.com/cmd/tailscaled tailscale.io % go version -m ~/go/bin/tailscaled | grep x/net dep golang.org/x/net v0.33.1-0.20241230221519-e9d95ba163f7 h1:raAbYgZplPuXQ6s7jPklBFBmmLh6LjnFaJdp3xR2ljY= tailscale.io % cd ../tailscale.com tailscale.com % go install tailscale.com/cmd/tailscaled tailscale.com % go version -m ~/go/bin/tailscaled | grep x/net dep golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= Updates #8043 Updates #14599 Change-Id: I6e238cef62ca22444145a5313554aab8709b33c9 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-10cmd/containerboot: load containerboot serve config that does not contain ↵Irbe Krumina2-11/+290
HTTPS endpoint in tailnets with HTTPS disabled (#14538) cmd/containerboot: load containerboot serve config that does not contain HTTPS endpoint in tailnets with HTTPS disabled Fixes an issue where, if a tailnet has HTTPS disabled, no serve config set via TS_SERVE_CONFIG was loaded, even if it does not contain an HTTPS endpoint. Now for tailnets with HTTPS disabled serve config provided to containerboot is considered invalid (and therefore not loaded) only if there is an HTTPS endpoint defined in the config. Fixes tailscale/tailscale#14495 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2025-01-10cmd/containerboot,cmd/k8s-operator: reload tailscaled config (#14342)Irbe Krumina8-39/+207
cmd/{k8s-operator,containerboot}: reload tailscaled configfile when its contents have changed Instead of restarting the Kubernetes Operator proxies each time tailscaled config has changed, this dynamically reloads the configfile using the new reload endpoint. Older annotation based mechanism will be supported till 1.84 to ensure that proxy versions prior to 1.80 keep working with operator 1.80 and newer. Updates tailscale/tailscale#13032 Updates tailscale/corp#24795 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2025-01-10ipn/conf.go: add VIPServices to tailscaled configfile (#14345)Irbe Krumina1-0/+6
Updates tailscale/corp#24795 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2025-01-09all: illumos/solaris userspace only supportNahum Shalman14-12/+60
Updates #14565 Change-Id: I743148144938794db0a224873ce76c10dbe6fa5f Signed-off-by: Nahum Shalman <nahamu@gmail.com>
2025-01-09types/views: optimize SliceEqualAnyOrderFunc for small slicesAndrew Dunham2-0/+32
If the total number of differences is less than a small amount, just do the dumb quadratic thing and compare every single object instead of allocating a map. Updates tailscale/corp#25479 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I8931b4355a2da4ec0f19739927311cf88711a840
2025-01-09types/views: add SliceEqualAnyOrderFuncAndrew Dunham2-0/+72
Extracted from some code written in the other repo. Updates tailscale/corp#25479 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I6df062fdffa1705524caa44ac3b6f2788cf64595
2025-01-09prober: record total bytes transferred in DERP bandwidth probesPercy Wegmann1-0/+1
This will enable Prometheus queries to look at the bandwidth over time windows, for example 'increase(derp_bw_bytes_total)[1h] / increase(derp_bw_transfer_time_seconds_total)[1h]'. Updates tailscale/corp#25503 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-01-09cmd/k8s-operator,k8s-operator: allow users to set custom labels for the ↵Irbe Krumina15-101/+389
optional ServiceMonitor (#14475) * cmd/k8s-operator,k8s-operator: allow users to set custom labels for the optional ServiceMonitor Updates tailscale/tailscale#14381 Signed-off-by: Irbe Krumina <irbe@tailscale.com>