cmd/headscale: rename the database-bypass flag off gRPC

--bypass-grpc-and-access-database-directly is now
--bypass-server-and-access-database-directly; the gRPC server it named is
gone.
This commit is contained in:
Kristoffer Dalby
2026-06-18 12:26:52 +00:00
parent c3d405ce20
commit 67e0f34527
4 changed files with 21 additions and 11 deletions
+7 -7
View File
@@ -15,13 +15,13 @@ import (
)
const (
bypassFlag = "bypass-grpc-and-access-database-directly" //nolint:gosec // not a credential
bypassFlag = "bypass-server-and-access-database-directly" //nolint:gosec // not a credential
)
var errAborted = errors.New("command aborted by user")
// bypassDatabase loads the server config and opens the database directly,
// bypassing the gRPC server. The caller is responsible for closing the
// bypassing the running server. The caller is responsible for closing the
// returned database handle.
func bypassDatabase() (*db.HSDatabase, error) {
cfg, err := types.LoadServerConfig()
@@ -50,16 +50,16 @@ func openBypassDB(cmd *cobra.Command) (*db.HSDatabase, error) {
func init() {
rootCmd.AddCommand(policyCmd)
getPolicy.Flags().BoolP(bypassFlag, "", false, "Uses the headscale config to directly access the database, bypassing gRPC and does not require the server to be running")
getPolicy.Flags().BoolP(bypassFlag, "", false, "Uses the headscale config to directly access the database, bypassing the API and does not require the server to be running")
policyCmd.AddCommand(getPolicy)
setPolicy.Flags().StringP("file", "f", "", "Path to a policy file in HuJSON format")
setPolicy.Flags().BoolP(bypassFlag, "", false, "Uses the headscale config to directly access the database, bypassing gRPC and does not require the server to be running")
setPolicy.Flags().BoolP(bypassFlag, "", false, "Uses the headscale config to directly access the database, bypassing the API and does not require the server to be running")
mustMarkRequired(setPolicy, "file")
policyCmd.AddCommand(setPolicy)
checkPolicy.Flags().StringP("file", "f", "", "Path to a policy file in HuJSON format")
checkPolicy.Flags().BoolP(bypassFlag, "", false, "Open the database directly (no gRPC, no running server) to resolve user references and to evaluate the policy's tests and sshTests blocks. Required when those checks are needed.")
checkPolicy.Flags().BoolP(bypassFlag, "", false, "Open the database directly (no running server required) to resolve user references and to evaluate the policy's tests and sshTests blocks. Required when those checks are needed.")
mustMarkRequired(checkPolicy, "file")
policyCmd.AddCommand(checkPolicy)
}
@@ -176,8 +176,8 @@ var checkPolicy = &cobra.Command{
Short: "Check the Policy file for errors",
Long: `
Check validates the policy against the server's live users and nodes,
running any "tests" or "sshTests" block. By default the command is a
thin frontend for a gRPC call to a running headscale; pass --` + bypassFlag + ` to
running any "tests" or "sshTests" block. By default the command calls a
running headscale over its API; pass --` + bypassFlag + ` to
open the database directly when headscale is not running.`,
RunE: func(cmd *cobra.Command, args []string) error {
policyPath, _ := cmd.Flags().GetString("file")
+2 -2
View File
@@ -152,9 +152,9 @@ See also <https://tailscale.com/docs/concepts/device-visibility>.
Headscale checks if the policy is valid during startup and refuses to start if it detects an error. The error message
indicates which part of the policy is invalid. Follow these steps to fix your policy:
- Dump the policy to a file: `headscale policy get --bypass-grpc-and-access-database-directly > policy.json`
- Dump the policy to a file: `headscale policy get --bypass-server-and-access-database-directly > policy.json`
- Edit and fixup `policy.json`. Use the command `headscale policy check --file policy.json` to validate the policy.
- Load the modified policy: `headscale policy set --bypass-grpc-and-access-database-directly --file policy.json`
- Load the modified policy: `headscale policy set --bypass-server-and-access-database-directly --file policy.json`
- Start Headscale as usual.
!!! warning "Full server configuration required"
+10
View File
@@ -99,6 +99,16 @@ an empty object.
**Client impact:** scripts parsing the empty `{}` should read the `result`
field (machine-readable output) or rely on the exit code.
### CLI database-bypass flag renamed
**What:** `--bypass-grpc-and-access-database-directly` is now
`--bypass-server-and-access-database-directly`.
**Why:** the gRPC server is gone; the flag bypasses the running server whatever
its transport, so the name no longer mentions gRPC.
**Client impact:** scripts using the old flag name must update it.
### Missing resources return a consistent `404`
**What:** renaming or expiring an unknown node, and expiring or deleting an
+2 -2
View File
@@ -22,7 +22,7 @@ import (
// `check` reads from `--file`, so the server-side mode should not
// change the outcome; running both proves that.
// - fixture: ACL only, ACL with passing tests, ACL with failing tests.
// - bypass: no-bypass talks to the server over gRPC; bypass opens the
// - bypass: no-bypass talks to the server over its API; bypass opens the
// database directly.
//
// Each row spins up its own scenario because policy_mode is fixed at boot
@@ -152,7 +152,7 @@ func TestPolicyCheckCommand(t *testing.T) {
// --force suppresses the "is the server running?"
// confirmation prompt so the command can run
// non-interactively under the test harness.
cmd = append(cmd, "--bypass-grpc-and-access-database-directly", "--force")
cmd = append(cmd, "--bypass-server-and-access-database-directly", "--force")
}
stdout, err := headscale.Execute(cmd)