mirror of https://github.com/tailscale/tailscale/
cmd/tailscale/cli, client/tailscale, ipn/localapi: add tailscale syspolicy {list,reload} commands
In this PR, we add the tailscale syspolicy command with two subcommands: list, which displays policy settings, and reload, which forces a reload of those settings. We also update the LocalAPI and LocalClient to facilitate these additions. Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>pull/13980/head
parent
45354dab9b
commit
3f626c0d77
@ -0,0 +1,110 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"slices"
|
||||||
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"github.com/peterbourgon/ff/v3/ffcli"
|
||||||
|
"tailscale.com/util/syspolicy/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
var syspolicyArgs struct {
|
||||||
|
json bool // JSON output mode
|
||||||
|
}
|
||||||
|
|
||||||
|
var syspolicyCmd = &ffcli.Command{
|
||||||
|
Name: "syspolicy",
|
||||||
|
ShortHelp: "Diagnose the MDM and system policy configuration",
|
||||||
|
LongHelp: "The 'tailscale syspolicy' command provides tools for diagnosing the MDM and system policy configuration.",
|
||||||
|
ShortUsage: "tailscale syspolicy <subcommand>",
|
||||||
|
UsageFunc: usageFuncNoDefaultValues,
|
||||||
|
Subcommands: []*ffcli.Command{
|
||||||
|
{
|
||||||
|
Name: "list",
|
||||||
|
ShortUsage: "tailscale syspolicy list",
|
||||||
|
Exec: runSysPolicyList,
|
||||||
|
ShortHelp: "Prints effective policy settings",
|
||||||
|
LongHelp: "The 'tailscale syspolicy list' subcommand displays the effective policy settings and their sources (e.g., MDM or environment variables).",
|
||||||
|
FlagSet: (func() *flag.FlagSet {
|
||||||
|
fs := newFlagSet("syspolicy list")
|
||||||
|
fs.BoolVar(&syspolicyArgs.json, "json", false, "output in JSON format")
|
||||||
|
return fs
|
||||||
|
})(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "reload",
|
||||||
|
ShortUsage: "tailscale syspolicy reload",
|
||||||
|
Exec: runSysPolicyReload,
|
||||||
|
ShortHelp: "Forces a reload of policy settings, even if no changes are detected, and prints the result",
|
||||||
|
LongHelp: "The 'tailscale syspolicy reload' subcommand forces a reload of policy settings, even if no changes are detected, and prints the result.",
|
||||||
|
FlagSet: (func() *flag.FlagSet {
|
||||||
|
fs := newFlagSet("syspolicy reload")
|
||||||
|
fs.BoolVar(&syspolicyArgs.json, "json", false, "output in JSON format")
|
||||||
|
return fs
|
||||||
|
})(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func runSysPolicyList(ctx context.Context, args []string) error {
|
||||||
|
policy, err := localClient.GetEffectivePolicy(ctx, setting.DefaultScope())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
printPolicySettings(policy)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func runSysPolicyReload(ctx context.Context, args []string) error {
|
||||||
|
policy, err := localClient.ReloadEffectivePolicy(ctx, setting.DefaultScope())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
printPolicySettings(policy)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func printPolicySettings(policy *setting.Snapshot) {
|
||||||
|
if syspolicyArgs.json {
|
||||||
|
json, err := json.MarshalIndent(policy, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
errf("syspolicy marshalling error: %v", err)
|
||||||
|
} else {
|
||||||
|
outln(string(json))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if policy.Len() == 0 {
|
||||||
|
outln("No policy settings")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
||||||
|
fmt.Fprintln(w, "Name\tOrigin\tValue\tError")
|
||||||
|
fmt.Fprintln(w, "----\t------\t-----\t-----")
|
||||||
|
for _, k := range slices.Sorted(policy.Keys()) {
|
||||||
|
setting, _ := policy.GetSetting(k)
|
||||||
|
var origin string
|
||||||
|
if o := setting.Origin(); o != nil {
|
||||||
|
origin = o.String()
|
||||||
|
}
|
||||||
|
if err := setting.Error(); err != nil {
|
||||||
|
fmt.Fprintf(w, "%s\t%s\t\t{%s}\n", k, origin, err)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, "%s\t%s\t%s\t\n", k, origin, setting.Value())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.Flush()
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in New Issue