// SPDX-License-Identifier: MIT package cli import ( "context" "fmt" "io" "github.com/spf13/cobra" "prx/internal/config" "prx/internal/proto" "prx/internal/state" ) func (a *app) newBypassCmd() *cobra.Command { cmd := &cobra.Command{ Use: "bypass", Short: "Manage destinations that must bypass the proxy", } cmd.AddCommand(a.newBypassAddCmd(), a.newBypassRmCmd(), a.newBypassLsCmd()) return cmd } func (a *app) newBypassAddCmd() *cobra.Command { return &cobra.Command{ Use: "add ", Short: "Add a CIDR/IP (routed direct) or domain (engine hint) to the bypass list", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cfg, err := a.loadConfig() if err != nil { return err } arg := args[0] var changed bool if config.IsCIDR(arg) { changed, err = cfg.AddExtraCIDR(arg) } else { changed, err = cfg.AddDomain(arg) } if err != nil { return err } if !changed { fmt.Fprintln(a.out, "already present") return nil } if err := config.Save(a.configPath, cfg); err != nil { return err } fmt.Fprintf(a.out, "added %s to bypass list\n", arg) return a.reapplyIfEnabled(cmd.Context(), cfg) }, } } func (a *app) newBypassRmCmd() *cobra.Command { return &cobra.Command{ Use: "rm ", Short: "Remove an entry from the bypass list", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cfg, err := a.loadConfig() if err != nil { return err } arg := args[0] var changed bool if config.IsCIDR(arg) { changed, err = cfg.RemoveExtraCIDR(arg) } else { changed = cfg.RemoveDomain(arg) } if err != nil { return err } if !changed { fmt.Fprintln(a.out, "not present") return nil } if err := config.Save(a.configPath, cfg); err != nil { return err } fmt.Fprintf(a.out, "removed %s from bypass list\n", arg) return a.reapplyIfEnabled(cmd.Context(), cfg) }, } } func (a *app) newBypassLsCmd() *cobra.Command { return &cobra.Command{ Use: "ls", Short: "List bypass entries", Args: cobra.NoArgs, RunE: func(_ *cobra.Command, _ []string) error { cfg, err := a.loadConfig() if err != nil { return err } writeList(a.out, "always (engine hints):", cfg.Bypass.AlwaysCIDRs, false) writeList(a.out, "extra CIDRs (routed direct):", cfg.Bypass.ExtraCIDRs, true) writeList(a.out, "domains (engine hints):", cfg.Bypass.Domains, true) return nil }, } } // writeList prints a labelled list, showing "(none)" when empty and showEmpty. func writeList(w io.Writer, label string, items []string, showEmpty bool) { fmt.Fprintln(w, label) if len(items) == 0 && showEmpty { fmt.Fprintln(w, " (none)") } for _, item := range items { fmt.Fprintln(w, " "+item) } } // reapplyIfEnabled refreshes the routing rules when prx is currently enabled so // bypass changes take effect immediately. func (a *app) reapplyIfEnabled(ctx context.Context, cfg *config.Config) error { st, err := state.Load(cfg.State.Path) if err != nil { return err } if !st.Enabled { fmt.Fprintln(a.out, "takes effect on the next 'prx on'") return nil } if err := a.dispatch(ctx, cfg, proto.ActionApply, nil); err != nil { return err } fmt.Fprintln(a.out, "routing rules refreshed") return nil }