From abd2b15db59a9e326bd80b0a960a0d0e8724683f Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 30 Mar 2026 13:15:09 +0000 Subject: [PATCH] policy/v2: clean up dead error variables, stale TODO, and test skip reasons Remove unused error variables (ErrGrantViaNotSupported, ErrGrantEmptySources, ErrGrantEmptyDestinations, ErrGrantViaOnlyTag) and the stale TODO for via implementation. Update compat test skip reasons to reflect that user:*@passkey wildcard is a known unsupported feature, not a pending implementation. Updates #2180 --- .../policy/v2/tailscale_grants_compat_test.go | 38 ++++++------------- .../v2/tailscale_ssh_data_compat_test.go | 11 +++--- hscontrol/policy/v2/types.go | 5 --- 3 files changed, 16 insertions(+), 38 deletions(-) diff --git a/hscontrol/policy/v2/tailscale_grants_compat_test.go b/hscontrol/policy/v2/tailscale_grants_compat_test.go index d48c15ec..f983aeff 100644 --- a/hscontrol/policy/v2/tailscale_grants_compat_test.go +++ b/hscontrol/policy/v2/tailscale_grants_compat_test.go @@ -324,52 +324,36 @@ func loadGrantTestFile(t *testing.T, path string) grantTestFile { return tf } -// Skip categories document WHY tests are expected to fail and WHAT needs to be -// implemented to fix them. Tests are grouped by root cause to identify high-impact -// changes. +// Skip categories document WHY tests are expected to differ from Tailscale SaaS. +// Tests are grouped by root cause. // -// Impact summary (highest first): +// USER_PASSKEY_WILDCARD - 2 tests: user:*@passkey wildcard pattern not supported // -// USER_PASSKEY_WILDCARD - 2 tests: user:*@passkey wildcard pattern unresolvable -// -// Total: 2 tests skipped, ~235 tests expected to pass. +// Total: 2 tests skipped, ~246 tests expected to pass. var grantSkipReasons = map[string]string{ - // ======================================================================== // USER_PASSKEY_WILDCARD (2 tests) // - // TODO: Handle user:*@passkey wildcard pattern in grant src/dst. - // // Tailscale SaaS policies can use user:*@passkey as a wildcard matching - // all passkey-authenticated users. headscale's convertPolicyUserEmails - // only converts specific user@passkey addresses (not the wildcard form), - // so the filter compiler logs "user not found: token user:*@passkey" - // and produces no rules. - // - // Fix: Either convert user:*@passkey to a headscale-compatible wildcard, - // or resolve it to all known users during filter compilation. - // ======================================================================== - "GRANT-K20": "USER_PASSKEY_WILDCARD: src=user:*@passkey, dst=tag:server — source can't be resolved, no rules produced", - "GRANT-K21": "USER_PASSKEY_WILDCARD: src=*, dst=user:*@passkey — destination can't be resolved, no rules produced", + // all passkey-authenticated users. headscale does not support passkey + // authentication and has no equivalent for this wildcard pattern. + "GRANT-K20": "USER_PASSKEY_WILDCARD: src=user:*@passkey not supported in headscale", + "GRANT-K21": "USER_PASSKEY_WILDCARD: dst=user:*@passkey not supported in headscale", } -// TestGrantsCompat is a data-driven test that loads all 237 GRANT-*.json +// TestGrantsCompat is a data-driven test that loads all GRANT-*.json // test files captured from Tailscale SaaS and compares headscale's grants // engine output against the real Tailscale behavior. // // Each JSON file contains: // - A full policy (groups, tagOwners, hosts, autoApprovers, grants, optionally acls) -// - For success cases: expected packet_filter_rules per node (8 nodes) +// - For success cases: expected packet_filter_rules per node // - For error cases: expected error message // // The test converts Tailscale user email formats (@passkey, @dalby.cc) to // headscale format (@example.com) and runs the policy through unmarshalPolicy, // validate, compileFilterRulesForNode, and ReduceFilterRules. // -// Skip category impact summary (highest first): -// -// USER_PASSKEY_WILDCARD - 2 tests: user:*@passkey wildcard pattern unresolvable -// -// Total: 2 tests skipped, ~235 tests expected to pass. +// 2 tests are skipped for user:*@passkey wildcard (not supported in headscale). func TestGrantsCompat(t *testing.T) { t.Parallel() diff --git a/hscontrol/policy/v2/tailscale_ssh_data_compat_test.go b/hscontrol/policy/v2/tailscale_ssh_data_compat_test.go index b94460e9..75c9420a 100644 --- a/hscontrol/policy/v2/tailscale_ssh_data_compat_test.go +++ b/hscontrol/policy/v2/tailscale_ssh_data_compat_test.go @@ -204,12 +204,11 @@ func loadSSHTestFile(t *testing.T, path string) sshTestFile { // // 37 of 39 tests are expected to pass. var sshSkipReasons = map[string]string{ - // user:*@domain source alias not yet implemented. - // These tests use "src": ["user:*@passkey"] which requires UserWildcard - // alias type support. Will be added in a follow-up PR that implements - // user:*@domain across all contexts (ACLs, grants, tagOwners, autoApprovers). - "SSH-B5": "user:*@domain source alias not yet implemented", - "SSH-D10": "user:*@domain source alias not yet implemented", + // user:*@passkey wildcard pattern not supported in headscale. + // headscale does not support passkey authentication and has no + // equivalent for this wildcard pattern. + "SSH-B5": "user:*@passkey wildcard not supported in headscale", + "SSH-D10": "user:*@passkey wildcard not supported in headscale", } // TestSSHDataCompat is a data-driven test that loads all SSH-*.json test files diff --git a/hscontrol/policy/v2/types.go b/hscontrol/policy/v2/types.go index 732d18c8..2b3fc4fa 100644 --- a/hscontrol/policy/v2/types.go +++ b/hscontrol/policy/v2/types.go @@ -69,14 +69,10 @@ var ( var ( ErrGrantMissingIPOrApp = errors.New("grants must specify either 'ip' or 'app' field") ErrGrantInvalidViaTag = errors.New("grant 'via' tag is not defined in policy") - ErrGrantViaNotSupported = errors.New("grant 'via' routing is not yet supported in headscale") - ErrGrantEmptySources = errors.New("grant sources cannot be empty") - ErrGrantEmptyDestinations = errors.New("grant destinations cannot be empty") ErrProtocolPortInvalidFormat = errors.New("expected only one colon in Internet protocol and port type") ErrCapNameInvalidForm = errors.New("capability name must have the form {domain}/{path}") ErrCapNameTailscaleDomain = errors.New("capability name must not be in the tailscale.com domain") ErrGrantAutogroupSelfInvalidSource = errors.New("autogroup:self can only be used with users, groups, or supported autogroups") - ErrGrantViaOnlyTag = errors.New("via can only be a tag") ErrGrantAppWithAutogroupInternet = errors.New("cannot use app grants with autogroup:internet") ErrGrantDefaultRouteCIDR = errors.New("to allow all IP addresses, use \"*\" or \"autogroup:internet\"") ) @@ -1899,7 +1895,6 @@ type Grant struct { InternetProtocols []ProtocolPort `json:"ip,omitempty"` App tailcfg.PeerCapMap `json:"app,omitzero"` - // TODO(kradalby): implement via Via []Tag `json:"via,omitzero"` }