mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-22 11:00:53 +08:00
cmd: Expand cobra support, add short flags (#5379)
* cmd: Expand cobra support * Convert commands to cobra, add short flags * Fix version command typo Co-authored-by: Emily Lange <git@indeednotjames.com> * Apply suggestions from code review Co-authored-by: Matt Holt <mholt@users.noreply.github.com> --------- Co-authored-by: Emily Lange <git@indeednotjames.com> Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
This commit is contained in:
parent
167981d258
commit
9e6919550b
21
cmd/cobra.go
21
cmd/cobra.go
|
@ -109,12 +109,21 @@ func caddyCmdToCobra(caddyCmd Command) *cobra.Command {
|
||||||
Use: caddyCmd.Name,
|
Use: caddyCmd.Name,
|
||||||
Short: caddyCmd.Short,
|
Short: caddyCmd.Short,
|
||||||
Long: caddyCmd.Long,
|
Long: caddyCmd.Long,
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
||||||
fls := cmd.Flags()
|
|
||||||
_, err := caddyCmd.Func(Flags{fls})
|
|
||||||
return err
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
cmd.Flags().AddGoFlagSet(caddyCmd.Flags)
|
if caddyCmd.CobraFunc != nil {
|
||||||
|
caddyCmd.CobraFunc(cmd)
|
||||||
|
} else {
|
||||||
|
cmd.RunE = WrapCommandFuncForCobra(caddyCmd.Func)
|
||||||
|
cmd.Flags().AddGoFlagSet(caddyCmd.Flags)
|
||||||
|
}
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WrapCommandFuncForCobra wraps a Caddy CommandFunc for use
|
||||||
|
// in a cobra command's RunE field.
|
||||||
|
func WrapCommandFuncForCobra(f CommandFunc) func(cmd *cobra.Command, _ []string) error {
|
||||||
|
return func(cmd *cobra.Command, _ []string) error {
|
||||||
|
_, err := f(Flags{cmd.Flags()})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
233
cmd/commands.go
233
cmd/commands.go
|
@ -34,12 +34,6 @@ type Command struct {
|
||||||
// Required.
|
// Required.
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
// Func is a function that executes a subcommand using
|
|
||||||
// the parsed flags. It returns an exit code and any
|
|
||||||
// associated error.
|
|
||||||
// Required.
|
|
||||||
Func CommandFunc
|
|
||||||
|
|
||||||
// Usage is a brief message describing the syntax of
|
// Usage is a brief message describing the syntax of
|
||||||
// the subcommand's flags and args. Use [] to indicate
|
// the subcommand's flags and args. Use [] to indicate
|
||||||
// optional parameters and <> to enclose literal values
|
// optional parameters and <> to enclose literal values
|
||||||
|
@ -60,7 +54,21 @@ type Command struct {
|
||||||
Long string
|
Long string
|
||||||
|
|
||||||
// Flags is the flagset for command.
|
// Flags is the flagset for command.
|
||||||
|
// This is ignored if CobraFunc is set.
|
||||||
Flags *flag.FlagSet
|
Flags *flag.FlagSet
|
||||||
|
|
||||||
|
// Func is a function that executes a subcommand using
|
||||||
|
// the parsed flags. It returns an exit code and any
|
||||||
|
// associated error.
|
||||||
|
// Required if CobraFunc is not set.
|
||||||
|
Func CommandFunc
|
||||||
|
|
||||||
|
// CobraFunc allows further configuration of the command
|
||||||
|
// via cobra's APIs. If this is set, then Func and Flags
|
||||||
|
// are ignored, with the assumption that they are set in
|
||||||
|
// this function. A caddycmd.WrapCommandFuncForCobra helper
|
||||||
|
// exists to simplify porting CommandFunc to Cobra's RunE.
|
||||||
|
CobraFunc func(*cobra.Command)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandFunc is a command's function. It runs the
|
// CommandFunc is a command's function. It runs the
|
||||||
|
@ -79,7 +87,6 @@ var commands = make(map[string]Command)
|
||||||
func init() {
|
func init() {
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "start",
|
Name: "start",
|
||||||
Func: cmdStart,
|
|
||||||
Usage: "[--config <path> [--adapter <name>]] [--envfile <path>] [--watch] [--pidfile <file>]",
|
Usage: "[--config <path> [--adapter <name>]] [--envfile <path>] [--watch] [--pidfile <file>]",
|
||||||
Short: "Starts the Caddy process in the background and then returns",
|
Short: "Starts the Caddy process in the background and then returns",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -93,21 +100,19 @@ On Windows, the spawned child process will remain attached to the terminal, so
|
||||||
closing the window will forcefully stop Caddy; to avoid forgetting this, try
|
closing the window will forcefully stop Caddy; to avoid forgetting this, try
|
||||||
using 'caddy run' instead to keep it in the foreground.
|
using 'caddy run' instead to keep it in the foreground.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("start", flag.ExitOnError)
|
cmd.Flags().StringP("config", "c", "", "Configuration file")
|
||||||
fs.String("config", "", "Configuration file")
|
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter to apply")
|
||||||
fs.String("adapter", "", "Name of config adapter to apply")
|
cmd.Flags().StringP("envfile", "", "", "Environment file to load")
|
||||||
fs.String("envfile", "", "Environment file to load")
|
cmd.Flags().BoolP("watch", "w", false, "Reload changed config file automatically")
|
||||||
fs.Bool("watch", false, "Reload changed config file automatically")
|
cmd.Flags().StringP("pidfile", "", "", "Path of file to which to write process ID")
|
||||||
fs.String("pidfile", "", "Path of file to which to write process ID")
|
cmd.RunE = WrapCommandFuncForCobra(cmdStart)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "run",
|
Name: "run",
|
||||||
Func: cmdRun,
|
Usage: "[--config <path> [--adapter <name>]] [--envfile <path>] [--environ] [--resume] [--watch] [--pidfile <file>]",
|
||||||
Usage: "[--config <path> [--adapter <name>]] [--envfile <path>] [--environ] [--resume] [--watch] [--pidfile <fil>]",
|
|
||||||
Short: `Starts the Caddy process and blocks indefinitely`,
|
Short: `Starts the Caddy process and blocks indefinitely`,
|
||||||
Long: `
|
Long: `
|
||||||
Starts the Caddy process, optionally bootstrapped with an initial config file,
|
Starts the Caddy process, optionally bootstrapped with an initial config file,
|
||||||
|
@ -141,24 +146,22 @@ If --watch is specified, the config file will be loaded automatically after
|
||||||
changes. ⚠️ This can make unintentional config changes easier; only use this
|
changes. ⚠️ This can make unintentional config changes easier; only use this
|
||||||
option in a local development environment.
|
option in a local development environment.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("run", flag.ExitOnError)
|
cmd.Flags().StringP("config", "c", "", "Configuration file")
|
||||||
fs.String("config", "", "Configuration file")
|
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter to apply")
|
||||||
fs.String("adapter", "", "Name of config adapter to apply")
|
cmd.Flags().StringP("envfile", "", "", "Environment file to load")
|
||||||
fs.String("envfile", "", "Environment file to load")
|
cmd.Flags().BoolP("environ", "e", false, "Print environment")
|
||||||
fs.Bool("environ", false, "Print environment")
|
cmd.Flags().BoolP("resume", "r", false, "Use saved config, if any (and prefer over --config file)")
|
||||||
fs.Bool("resume", false, "Use saved config, if any (and prefer over --config file)")
|
cmd.Flags().BoolP("watch", "w", false, "Watch config file for changes and reload it automatically")
|
||||||
fs.Bool("watch", false, "Watch config file for changes and reload it automatically")
|
cmd.Flags().StringP("pidfile", "", "", "Path of file to which to write process ID")
|
||||||
fs.String("pidfile", "", "Path of file to which to write process ID")
|
cmd.Flags().StringP("pingback", "", "", "Echo confirmation bytes to this address on success")
|
||||||
fs.String("pingback", "", "Echo confirmation bytes to this address on success")
|
cmd.RunE = WrapCommandFuncForCobra(cmdRun)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "stop",
|
Name: "stop",
|
||||||
Func: cmdStop,
|
Usage: "[--config <path> [--adapter <name>]] [--address <interface>]",
|
||||||
Usage: "[--address <interface>] [--config <path> [--adapter <name>]]",
|
|
||||||
Short: "Gracefully stops a started Caddy process",
|
Short: "Gracefully stops a started Caddy process",
|
||||||
Long: `
|
Long: `
|
||||||
Stops the background Caddy process as gracefully as possible.
|
Stops the background Caddy process as gracefully as possible.
|
||||||
|
@ -167,18 +170,16 @@ It requires that the admin API is enabled and accessible, since it will
|
||||||
use the API's /stop endpoint. The address of this request can be customized
|
use the API's /stop endpoint. The address of this request can be customized
|
||||||
using the --address flag, or from the given --config, if not the default.
|
using the --address flag, or from the given --config, if not the default.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("stop", flag.ExitOnError)
|
cmd.Flags().StringP("config", "c", "", "Configuration file to use to parse the admin address, if --address is not used")
|
||||||
fs.String("address", "", "The address to use to reach the admin API endpoint, if not the default")
|
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter to apply (when --config is used)")
|
||||||
fs.String("config", "", "Configuration file to use to parse the admin address, if --address is not used")
|
cmd.Flags().StringP("address", "", "", "The address to use to reach the admin API endpoint, if not the default")
|
||||||
fs.String("adapter", "", "Name of config adapter to apply (when --config is used)")
|
cmd.RunE = WrapCommandFuncForCobra(cmdStop)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "reload",
|
Name: "reload",
|
||||||
Func: cmdReload,
|
|
||||||
Usage: "--config <path> [--adapter <name>] [--address <interface>]",
|
Usage: "--config <path> [--adapter <name>] [--address <interface>]",
|
||||||
Short: "Changes the config of the running Caddy instance",
|
Short: "Changes the config of the running Caddy instance",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -190,19 +191,17 @@ Since the admin endpoint is configurable, the endpoint configuration is loaded
|
||||||
from the --address flag if specified; otherwise it is loaded from the given
|
from the --address flag if specified; otherwise it is loaded from the given
|
||||||
config file; otherwise the default is assumed.
|
config file; otherwise the default is assumed.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("reload", flag.ExitOnError)
|
cmd.Flags().StringP("config", "c", "", "Configuration file (required)")
|
||||||
fs.String("config", "", "Configuration file (required)")
|
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter to apply")
|
||||||
fs.String("adapter", "", "Name of config adapter to apply")
|
cmd.Flags().StringP("address", "", "", "Address of the administration listener, if different from config")
|
||||||
fs.String("address", "", "Address of the administration listener, if different from config")
|
cmd.Flags().BoolP("force", "f", false, "Force config reload, even if it is the same")
|
||||||
fs.Bool("force", false, "Force config reload, even if it is the same")
|
cmd.RunE = WrapCommandFuncForCobra(cmdReload)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "version",
|
Name: "version",
|
||||||
Func: cmdVersion,
|
|
||||||
Short: "Prints the version",
|
Short: "Prints the version",
|
||||||
Long: `
|
Long: `
|
||||||
Prints the version of this Caddy binary.
|
Prints the version of this Caddy binary.
|
||||||
|
@ -217,31 +216,29 @@ detailed version information is printed as given by Go modules.
|
||||||
For more details about the full version string, see the Go module
|
For more details about the full version string, see the Go module
|
||||||
documentation: https://go.dev/doc/modules/version-numbers
|
documentation: https://go.dev/doc/modules/version-numbers
|
||||||
`,
|
`,
|
||||||
|
Func: cmdVersion,
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "list-modules",
|
Name: "list-modules",
|
||||||
Func: cmdListModules,
|
Usage: "[--packages] [--versions] [--skip-standard]",
|
||||||
Usage: "[--packages] [--versions]",
|
|
||||||
Short: "Lists the installed Caddy modules",
|
Short: "Lists the installed Caddy modules",
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("list-modules", flag.ExitOnError)
|
cmd.Flags().BoolP("packages", "", false, "Print package paths")
|
||||||
fs.Bool("packages", false, "Print package paths")
|
cmd.Flags().BoolP("versions", "", false, "Print version information")
|
||||||
fs.Bool("versions", false, "Print version information")
|
cmd.Flags().BoolP("skip-standard", "s", false, "Skip printing standard modules")
|
||||||
fs.Bool("skip-standard", false, "Skip printing standard modules")
|
cmd.RunE = WrapCommandFuncForCobra(cmdListModules)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "build-info",
|
Name: "build-info",
|
||||||
Func: cmdBuildInfo,
|
|
||||||
Short: "Prints information about this build",
|
Short: "Prints information about this build",
|
||||||
|
Func: cmdBuildInfo,
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "environ",
|
Name: "environ",
|
||||||
Func: cmdEnviron,
|
|
||||||
Short: "Prints the environment",
|
Short: "Prints the environment",
|
||||||
Long: `
|
Long: `
|
||||||
Prints the environment as seen by this Caddy process.
|
Prints the environment as seen by this Caddy process.
|
||||||
|
@ -261,11 +258,11 @@ by adding the "--environ" flag.
|
||||||
|
|
||||||
Environments may contain sensitive data.
|
Environments may contain sensitive data.
|
||||||
`,
|
`,
|
||||||
|
Func: cmdEnviron,
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "adapt",
|
Name: "adapt",
|
||||||
Func: cmdAdaptConfig,
|
|
||||||
Usage: "--config <path> [--adapter <name>] [--pretty] [--validate]",
|
Usage: "--config <path> [--adapter <name>] [--pretty] [--validate]",
|
||||||
Short: "Adapts a configuration to Caddy's native JSON",
|
Short: "Adapts a configuration to Caddy's native JSON",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -279,19 +276,17 @@ If --validate is used, the adapted config will be checked for validity.
|
||||||
If the config is invalid, an error will be printed to stderr and a non-
|
If the config is invalid, an error will be printed to stderr and a non-
|
||||||
zero exit status will be returned.
|
zero exit status will be returned.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("adapt", flag.ExitOnError)
|
cmd.Flags().StringP("config", "c", "", "Configuration file to adapt (required)")
|
||||||
fs.String("config", "", "Configuration file to adapt (required)")
|
cmd.Flags().StringP("adapter", "a", "caddyfile", "Name of config adapter")
|
||||||
fs.String("adapter", "caddyfile", "Name of config adapter")
|
cmd.Flags().BoolP("pretty", "p", false, "Format the output for human readability")
|
||||||
fs.Bool("pretty", false, "Format the output for human readability")
|
cmd.Flags().BoolP("validate", "", false, "Validate the output")
|
||||||
fs.Bool("validate", false, "Validate the output")
|
cmd.RunE = WrapCommandFuncForCobra(cmdAdaptConfig)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "validate",
|
Name: "validate",
|
||||||
Func: cmdValidateConfig,
|
|
||||||
Usage: "--config <path> [--adapter <name>] [--envfile <path>]",
|
Usage: "--config <path> [--adapter <name>] [--envfile <path>]",
|
||||||
Short: "Tests whether a configuration file is valid",
|
Short: "Tests whether a configuration file is valid",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -302,18 +297,16 @@ provisioning stages.
|
||||||
If --envfile is specified, an environment file with environment variables in
|
If --envfile is specified, an environment file with environment variables in
|
||||||
the KEY=VALUE format will be loaded into the Caddy process.
|
the KEY=VALUE format will be loaded into the Caddy process.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("validate", flag.ExitOnError)
|
cmd.Flags().StringP("config", "c", "", "Input configuration file")
|
||||||
fs.String("config", "", "Input configuration file")
|
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter")
|
||||||
fs.String("adapter", "", "Name of config adapter")
|
cmd.Flags().StringP("envfile", "", "", "Environment file to load")
|
||||||
fs.String("envfile", "", "Environment file to load")
|
cmd.RunE = WrapCommandFuncForCobra(cmdValidateConfig)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "fmt",
|
Name: "fmt",
|
||||||
Func: cmdFmt,
|
|
||||||
Usage: "[--overwrite] [--diff] [<path>]",
|
Usage: "[--overwrite] [--diff] [<path>]",
|
||||||
Short: "Formats a Caddyfile",
|
Short: "Formats a Caddyfile",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -332,32 +325,28 @@ If you wish you use stdin instead of a regular file, use - as the path.
|
||||||
When reading from stdin, the --overwrite flag has no effect: the result
|
When reading from stdin, the --overwrite flag has no effect: the result
|
||||||
is always printed to stdout.
|
is always printed to stdout.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("fmt", flag.ExitOnError)
|
cmd.Flags().BoolP("overwrite", "w", false, "Overwrite the input file with the results")
|
||||||
fs.Bool("overwrite", false, "Overwrite the input file with the results")
|
cmd.Flags().BoolP("diff", "d", false, "Print the differences between the input file and the formatted output")
|
||||||
fs.Bool("diff", false, "Print the differences between the input file and the formatted output")
|
cmd.RunE = WrapCommandFuncForCobra(cmdFmt)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "upgrade",
|
Name: "upgrade",
|
||||||
Func: cmdUpgrade,
|
|
||||||
Short: "Upgrade Caddy (EXPERIMENTAL)",
|
Short: "Upgrade Caddy (EXPERIMENTAL)",
|
||||||
Long: `
|
Long: `
|
||||||
Downloads an updated Caddy binary with the same modules/plugins at the
|
Downloads an updated Caddy binary with the same modules/plugins at the
|
||||||
latest versions. EXPERIMENTAL: May be changed or removed.
|
latest versions. EXPERIMENTAL: May be changed or removed.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("upgrade", flag.ExitOnError)
|
cmd.Flags().BoolP("keep-backup", "k", false, "Keep the backed up binary, instead of deleting it")
|
||||||
fs.Bool("keep-backup", false, "Keep the backed up binary, instead of deleting it")
|
cmd.RunE = WrapCommandFuncForCobra(cmdUpgrade)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "add-package",
|
Name: "add-package",
|
||||||
Func: cmdAddPackage,
|
|
||||||
Usage: "<packages...>",
|
Usage: "<packages...>",
|
||||||
Short: "Adds Caddy packages (EXPERIMENTAL)",
|
Short: "Adds Caddy packages (EXPERIMENTAL)",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -365,11 +354,10 @@ Downloads an updated Caddy binary with the specified packages (module/plugin)
|
||||||
added. Retains existing packages. Returns an error if the any of packages are
|
added. Retains existing packages. Returns an error if the any of packages are
|
||||||
already included. EXPERIMENTAL: May be changed or removed.
|
already included. EXPERIMENTAL: May be changed or removed.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("add-package", flag.ExitOnError)
|
cmd.Flags().BoolP("keep-backup", "k", false, "Keep the backed up binary, instead of deleting it")
|
||||||
fs.Bool("keep-backup", false, "Keep the backed up binary, instead of deleting it")
|
cmd.RunE = WrapCommandFuncForCobra(cmdAddPackage)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
|
@ -382,31 +370,14 @@ Downloads an updated Caddy binaries without the specified packages (module/plugi
|
||||||
Returns an error if any of the packages are not included.
|
Returns an error if any of the packages are not included.
|
||||||
EXPERIMENTAL: May be changed or removed.
|
EXPERIMENTAL: May be changed or removed.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("remove-package", flag.ExitOnError)
|
cmd.Flags().BoolP("keep-backup", "k", false, "Keep the backed up binary, instead of deleting it")
|
||||||
fs.Bool("keep-backup", false, "Keep the backed up binary, instead of deleting it")
|
cmd.RunE = WrapCommandFuncForCobra(cmdRemovePackage)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "manpage",
|
Name: "manpage",
|
||||||
Func: func(fl Flags) (int, error) {
|
|
||||||
dir := strings.TrimSpace(fl.String("directory"))
|
|
||||||
if dir == "" {
|
|
||||||
return caddy.ExitCodeFailedQuit, fmt.Errorf("designated output directory and specified section are required")
|
|
||||||
}
|
|
||||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
|
||||||
return caddy.ExitCodeFailedQuit, err
|
|
||||||
}
|
|
||||||
if err := doc.GenManTree(rootCmd, &doc.GenManHeader{
|
|
||||||
Title: "Caddy",
|
|
||||||
Section: "8", // https://en.wikipedia.org/wiki/Man_page#Manual_sections
|
|
||||||
}, dir); err != nil {
|
|
||||||
return caddy.ExitCodeFailedQuit, err
|
|
||||||
}
|
|
||||||
return caddy.ExitCodeSuccess, nil
|
|
||||||
},
|
|
||||||
Usage: "--directory <path>",
|
Usage: "--directory <path>",
|
||||||
Short: "Generates the manual pages for Caddy commands",
|
Short: "Generates the manual pages for Caddy commands",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -416,11 +387,25 @@ tagged into section 8 (System Administration).
|
||||||
The manual page files are generated into the directory specified by the
|
The manual page files are generated into the directory specified by the
|
||||||
argument of --directory. If the directory does not exist, it will be created.
|
argument of --directory. If the directory does not exist, it will be created.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("manpage", flag.ExitOnError)
|
cmd.Flags().StringP("directory", "o", "", "The output directory where the manpages are generated")
|
||||||
fs.String("directory", "", "The output directory where the manpages are generated")
|
cmd.RunE = WrapCommandFuncForCobra(func(fl Flags) (int, error) {
|
||||||
return fs
|
dir := strings.TrimSpace(fl.String("directory"))
|
||||||
}(),
|
if dir == "" {
|
||||||
|
return caddy.ExitCodeFailedQuit, fmt.Errorf("designated output directory and specified section are required")
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||||
|
return caddy.ExitCodeFailedQuit, err
|
||||||
|
}
|
||||||
|
if err := doc.GenManTree(rootCmd, &doc.GenManHeader{
|
||||||
|
Title: "Caddy",
|
||||||
|
Section: "8", // https://en.wikipedia.org/wiki/Man_page#Manual_sections
|
||||||
|
}, dir); err != nil {
|
||||||
|
return caddy.ExitCodeFailedQuit, err
|
||||||
|
}
|
||||||
|
return caddy.ExitCodeSuccess, nil
|
||||||
|
})
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// source: https://github.com/spf13/cobra/blob/main/shell_completions.md
|
// source: https://github.com/spf13/cobra/blob/main/shell_completions.md
|
||||||
|
@ -504,7 +489,7 @@ func RegisterCommand(cmd Command) {
|
||||||
if cmd.Name == "" {
|
if cmd.Name == "" {
|
||||||
panic("command name is required")
|
panic("command name is required")
|
||||||
}
|
}
|
||||||
if cmd.Func == nil {
|
if cmd.Func == nil && cmd.CobraFunc == nil {
|
||||||
panic("command function missing")
|
panic("command function missing")
|
||||||
}
|
}
|
||||||
if cmd.Short == "" {
|
if cmd.Short == "" {
|
||||||
|
|
|
@ -18,20 +18,19 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
"github.com/caddyserver/caddy/v2"
|
"github.com/caddyserver/caddy/v2"
|
||||||
caddycmd "github.com/caddyserver/caddy/v2/cmd"
|
caddycmd "github.com/caddyserver/caddy/v2/cmd"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
caddycmd.RegisterCommand(caddycmd.Command{
|
caddycmd.RegisterCommand(caddycmd.Command{
|
||||||
Name: "hash-password",
|
Name: "hash-password",
|
||||||
Func: cmdHashPassword,
|
|
||||||
Usage: "[--algorithm <name>] [--salt <string>] [--plaintext <password>]",
|
Usage: "[--algorithm <name>] [--salt <string>] [--plaintext <password>]",
|
||||||
Short: "Hashes a password and writes base64",
|
Short: "Hashes a password and writes base64",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -50,13 +49,12 @@ be provided (scrypt).
|
||||||
|
|
||||||
Note that scrypt is deprecated. Please use 'bcrypt' instead.
|
Note that scrypt is deprecated. Please use 'bcrypt' instead.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("hash-password", flag.ExitOnError)
|
cmd.Flags().StringP("plaintext", "p", "", "The plaintext password")
|
||||||
fs.String("algorithm", "bcrypt", "Name of the hash algorithm")
|
cmd.Flags().StringP("salt", "s", "", "The password salt")
|
||||||
fs.String("plaintext", "", "The plaintext password")
|
cmd.Flags().StringP("algorithm", "a", "bcrypt", "Name of the hash algorithm")
|
||||||
fs.String("salt", "", "The password salt")
|
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdHashPassword)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ package fileserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
@ -27,13 +26,13 @@ import (
|
||||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
||||||
caddytpl "github.com/caddyserver/caddy/v2/modules/caddyhttp/templates"
|
caddytpl "github.com/caddyserver/caddy/v2/modules/caddyhttp/templates"
|
||||||
"github.com/caddyserver/certmagic"
|
"github.com/caddyserver/certmagic"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
caddycmd.RegisterCommand(caddycmd.Command{
|
caddycmd.RegisterCommand(caddycmd.Command{
|
||||||
Name: "file-server",
|
Name: "file-server",
|
||||||
Func: cmdFileServer,
|
|
||||||
Usage: "[--domain <example.com>] [--root <path>] [--listen <addr>] [--browse] [--access-log]",
|
Usage: "[--domain <example.com>] [--root <path>] [--listen <addr>] [--browse] [--access-log]",
|
||||||
Short: "Spins up a production-ready file server",
|
Short: "Spins up a production-ready file server",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -49,17 +48,16 @@ using this option.
|
||||||
|
|
||||||
If --browse is enabled, requests for folders without an index file will
|
If --browse is enabled, requests for folders without an index file will
|
||||||
respond with a file listing.`,
|
respond with a file listing.`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("file-server", flag.ExitOnError)
|
cmd.Flags().StringP("domain", "d", "", "Domain name at which to serve the files")
|
||||||
fs.String("domain", "", "Domain name at which to serve the files")
|
cmd.Flags().StringP("root", "r", "", "The path to the root of the site")
|
||||||
fs.String("root", "", "The path to the root of the site")
|
cmd.Flags().StringP("listen", "", "", "The address to which to bind the listener")
|
||||||
fs.String("listen", "", "The address to which to bind the listener")
|
cmd.Flags().BoolP("browse", "b", false, "Enable directory browsing")
|
||||||
fs.Bool("browse", false, "Enable directory browsing")
|
cmd.Flags().BoolP("templates", "t", false, "Enable template rendering")
|
||||||
fs.Bool("templates", false, "Enable template rendering")
|
cmd.Flags().BoolP("access-log", "", false, "Enable the access log")
|
||||||
fs.Bool("access-log", false, "Enable the access log")
|
cmd.Flags().BoolP("debug", "v", false, "Enable verbose debug logs")
|
||||||
fs.Bool("debug", false, "Enable verbose debug logs")
|
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdFileServer)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ package reverseproxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -28,14 +27,14 @@ import (
|
||||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
||||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp/headers"
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp/headers"
|
||||||
"github.com/caddyserver/caddy/v2/modules/caddytls"
|
"github.com/caddyserver/caddy/v2/modules/caddytls"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
caddycmd.RegisterCommand(caddycmd.Command{
|
caddycmd.RegisterCommand(caddycmd.Command{
|
||||||
Name: "reverse-proxy",
|
Name: "reverse-proxy",
|
||||||
Func: cmdReverseProxy,
|
Usage: "[--from <addr>] [--to <addr>] [--change-host-header] [--insecure] [--internal-certs] [--disable-redirects] [--access-log]",
|
||||||
Usage: "[--from <addr>] [--to <addr>] [--change-host-header] [--insecure] [--internal-certs] [--disable-redirects]",
|
|
||||||
Short: "A quick and production-ready reverse proxy",
|
Short: "A quick and production-ready reverse proxy",
|
||||||
Long: `
|
Long: `
|
||||||
A simple but production-ready reverse proxy. Useful for quick deployments,
|
A simple but production-ready reverse proxy. Useful for quick deployments,
|
||||||
|
@ -63,17 +62,17 @@ For proxying:
|
||||||
--insecure disables TLS verification with the upstream. WARNING: THIS
|
--insecure disables TLS verification with the upstream. WARNING: THIS
|
||||||
DISABLES SECURITY BY NOT VERIFYING THE UPSTREAM'S CERTIFICATE.
|
DISABLES SECURITY BY NOT VERIFYING THE UPSTREAM'S CERTIFICATE.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("reverse-proxy", flag.ExitOnError)
|
cmd.Flags().StringP("from", "f", "localhost", "Address on which to receive traffic")
|
||||||
fs.String("from", "localhost", "Address on which to receive traffic")
|
cmd.Flags().StringSliceP("to", "t", []string{}, "Upstream address(es) to which traffic should be sent")
|
||||||
fs.Var(&reverseProxyCmdTo, "to", "Upstream address(es) to which traffic should be sent")
|
cmd.Flags().BoolP("change-host-header", "c", false, "Set upstream Host header to address of upstream")
|
||||||
fs.Bool("change-host-header", false, "Set upstream Host header to address of upstream")
|
cmd.Flags().BoolP("insecure", "", false, "Disable TLS verification (WARNING: DISABLES SECURITY BY NOT VERIFYING TLS CERTIFICATES!)")
|
||||||
fs.Bool("insecure", false, "Disable TLS verification (WARNING: DISABLES SECURITY BY NOT VERIFYING TLS CERTIFICATES!)")
|
cmd.Flags().BoolP("disable-redirects", "r", false, "Disable HTTP->HTTPS redirects")
|
||||||
fs.Bool("internal-certs", false, "Use internal CA for issuing certs")
|
cmd.Flags().BoolP("internal-certs", "i", false, "Use internal CA for issuing certs")
|
||||||
fs.Bool("debug", false, "Enable verbose debug logs")
|
cmd.Flags().BoolP("access-log", "", false, "Enable the access log")
|
||||||
fs.Bool("disable-redirects", false, "Disable HTTP->HTTPS redirects")
|
cmd.Flags().BoolP("debug", "v", false, "Enable verbose debug logs")
|
||||||
return fs
|
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdReverseProxy)
|
||||||
}(),
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,14 +82,19 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
|
||||||
from := fs.String("from")
|
from := fs.String("from")
|
||||||
changeHost := fs.Bool("change-host-header")
|
changeHost := fs.Bool("change-host-header")
|
||||||
insecure := fs.Bool("insecure")
|
insecure := fs.Bool("insecure")
|
||||||
internalCerts := fs.Bool("internal-certs")
|
|
||||||
debug := fs.Bool("debug")
|
|
||||||
disableRedir := fs.Bool("disable-redirects")
|
disableRedir := fs.Bool("disable-redirects")
|
||||||
|
internalCerts := fs.Bool("internal-certs")
|
||||||
|
accessLog := fs.Bool("access-log")
|
||||||
|
debug := fs.Bool("debug")
|
||||||
|
|
||||||
httpPort := strconv.Itoa(caddyhttp.DefaultHTTPPort)
|
httpPort := strconv.Itoa(caddyhttp.DefaultHTTPPort)
|
||||||
httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPSPort)
|
httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPSPort)
|
||||||
|
|
||||||
if len(reverseProxyCmdTo) == 0 {
|
to, err := fs.GetStringSlice("to")
|
||||||
|
if err != nil {
|
||||||
|
return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid to flag: %v", err)
|
||||||
|
}
|
||||||
|
if len(to) == 0 {
|
||||||
return caddy.ExitCodeFailedStartup, fmt.Errorf("--to is required")
|
return caddy.ExitCodeFailedStartup, fmt.Errorf("--to is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,9 +123,9 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
|
||||||
|
|
||||||
// set up the upstream address; assume missing information from given parts
|
// set up the upstream address; assume missing information from given parts
|
||||||
// mixing schemes isn't supported, so use first defined (if available)
|
// mixing schemes isn't supported, so use first defined (if available)
|
||||||
toAddresses := make([]string, len(reverseProxyCmdTo))
|
toAddresses := make([]string, len(to))
|
||||||
var toScheme string
|
var toScheme string
|
||||||
for i, toLoc := range reverseProxyCmdTo {
|
for i, toLoc := range to {
|
||||||
addr, scheme, err := parseUpstreamDialAddress(toLoc)
|
addr, scheme, err := parseUpstreamDialAddress(toLoc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid upstream address %s: %v", toLoc, err)
|
return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid upstream address %s: %v", toLoc, err)
|
||||||
|
@ -180,6 +184,9 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
|
||||||
Routes: caddyhttp.RouteList{route},
|
Routes: caddyhttp.RouteList{route},
|
||||||
Listen: []string{":" + fromAddr.Port},
|
Listen: []string{":" + fromAddr.Port},
|
||||||
}
|
}
|
||||||
|
if accessLog {
|
||||||
|
server.Logs = &caddyhttp.ServerLogConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
if fromAddr.Scheme == "http" {
|
if fromAddr.Scheme == "http" {
|
||||||
server.AutoHTTPS = &caddyhttp.AutoHTTPSConfig{Disabled: true}
|
server.AutoHTTPS = &caddyhttp.AutoHTTPSConfig{Disabled: true}
|
||||||
|
@ -238,6 +245,3 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
|
||||||
|
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverseProxyCmdTo holds the parsed values from repeated use of the --to flag.
|
|
||||||
var reverseProxyCmdTo caddycmd.StringSlice
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ package caddyhttp
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -32,6 +31,7 @@ import (
|
||||||
"github.com/caddyserver/caddy/v2/caddyconfig"
|
"github.com/caddyserver/caddy/v2/caddyconfig"
|
||||||
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
|
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
|
||||||
caddycmd "github.com/caddyserver/caddy/v2/cmd"
|
caddycmd "github.com/caddyserver/caddy/v2/cmd"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,7 +39,6 @@ func init() {
|
||||||
caddy.RegisterModule(StaticResponse{})
|
caddy.RegisterModule(StaticResponse{})
|
||||||
caddycmd.RegisterCommand(caddycmd.Command{
|
caddycmd.RegisterCommand(caddycmd.Command{
|
||||||
Name: "respond",
|
Name: "respond",
|
||||||
Func: cmdRespond,
|
|
||||||
Usage: `[--status <code>] [--body <content>] [--listen <addr>] [--access-log] [--debug] [--header "Field: value"] <body|status>`,
|
Usage: `[--status <code>] [--body <content>] [--listen <addr>] [--access-log] [--debug] [--header "Field: value"] <body|status>`,
|
||||||
Short: "Simple, hard-coded HTTP responses for development and testing",
|
Short: "Simple, hard-coded HTTP responses for development and testing",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -71,16 +70,15 @@ Access/request logging and more verbose debug logging can also be enabled.
|
||||||
|
|
||||||
Response headers may be added using the --header flag for each header field.
|
Response headers may be added using the --header flag for each header field.
|
||||||
`,
|
`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("respond", flag.ExitOnError)
|
cmd.Flags().StringP("listen", "l", ":0", "The address to which to bind the listener")
|
||||||
fs.String("listen", ":0", "The address to which to bind the listener")
|
cmd.Flags().IntP("status", "s", http.StatusOK, "The response status code")
|
||||||
fs.Int("status", http.StatusOK, "The response status code")
|
cmd.Flags().StringP("body", "b", "", "The body of the HTTP response")
|
||||||
fs.String("body", "", "The body of the HTTP response")
|
cmd.Flags().BoolP("access-log", "", false, "Enable the access log")
|
||||||
fs.Bool("access-log", false, "Enable the access log")
|
cmd.Flags().BoolP("debug", "v", false, "Enable more verbose debug-level logging")
|
||||||
fs.Bool("debug", false, "Enable more verbose debug-level logging")
|
cmd.Flags().StringSliceP("header", "H", []string{}, "Set a header on the response (format: \"Field: value\")")
|
||||||
fs.Var(&respondCmdHeaders, "header", "Set a header on the response (format: \"Field: value\"")
|
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdRespond)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,8 +316,12 @@ func cmdRespond(fl caddycmd.Flags) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// build headers map
|
// build headers map
|
||||||
|
headers, err := fl.GetStringSlice("header")
|
||||||
|
if err != nil {
|
||||||
|
return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid header flag: %v", err)
|
||||||
|
}
|
||||||
hdr := make(http.Header)
|
hdr := make(http.Header)
|
||||||
for i, h := range respondCmdHeaders {
|
for i, h := range headers {
|
||||||
key, val, found := strings.Cut(h, ":")
|
key, val, found := strings.Cut(h, ":")
|
||||||
key, val = strings.TrimSpace(key), strings.TrimSpace(val)
|
key, val = strings.TrimSpace(key), strings.TrimSpace(val)
|
||||||
if !found || key == "" || val == "" {
|
if !found || key == "" || val == "" {
|
||||||
|
@ -432,9 +434,6 @@ func cmdRespond(fl caddycmd.Flags) (int, error) {
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// respondCmdHeaders holds the parsed values from repeated use of the --header flag.
|
|
||||||
var respondCmdHeaders caddycmd.StringSlice
|
|
||||||
|
|
||||||
// Interface guards
|
// Interface guards
|
||||||
var (
|
var (
|
||||||
_ MiddlewareHandler = (*StaticResponse)(nil)
|
_ MiddlewareHandler = (*StaticResponse)(nil)
|
||||||
|
|
|
@ -18,7 +18,6 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -27,12 +26,12 @@ import (
|
||||||
"github.com/caddyserver/caddy/v2"
|
"github.com/caddyserver/caddy/v2"
|
||||||
caddycmd "github.com/caddyserver/caddy/v2/cmd"
|
caddycmd "github.com/caddyserver/caddy/v2/cmd"
|
||||||
"github.com/smallstep/truststore"
|
"github.com/smallstep/truststore"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
caddycmd.RegisterCommand(caddycmd.Command{
|
caddycmd.RegisterCommand(caddycmd.Command{
|
||||||
Name: "trust",
|
Name: "trust",
|
||||||
Func: cmdTrust,
|
|
||||||
Usage: "[--ca <id>] [--address <listen>] [--config <path> [--adapter <name>]]",
|
Usage: "[--ca <id>] [--address <listen>] [--config <path> [--adapter <name>]]",
|
||||||
Short: "Installs a CA certificate into local trust stores",
|
Short: "Installs a CA certificate into local trust stores",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -53,19 +52,17 @@ This command will attempt to connect to Caddy's admin API running at
|
||||||
'` + caddy.DefaultAdminListen + `' to fetch the root certificate. You may
|
'` + caddy.DefaultAdminListen + `' to fetch the root certificate. You may
|
||||||
explicitly specify the --address, or use the --config flag to load
|
explicitly specify the --address, or use the --config flag to load
|
||||||
the admin address from your config, if not using the default.`,
|
the admin address from your config, if not using the default.`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("trust", flag.ExitOnError)
|
cmd.Flags().StringP("ca", "", "", "The ID of the CA to trust (defaults to 'local')")
|
||||||
fs.String("ca", "", "The ID of the CA to trust (defaults to 'local')")
|
cmd.Flags().StringP("address", "", "", "Address of the administration API listener (if --config is not used)")
|
||||||
fs.String("address", "", "Address of the administration API listener (if --config is not used)")
|
cmd.Flags().StringP("config", "c", "", "Configuration file (if --address is not used)")
|
||||||
fs.String("config", "", "Configuration file (if --address is not used)")
|
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter to apply (if --config is used)")
|
||||||
fs.String("adapter", "", "Name of config adapter to apply (if --config is used)")
|
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdTrust)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
caddycmd.RegisterCommand(caddycmd.Command{
|
caddycmd.RegisterCommand(caddycmd.Command{
|
||||||
Name: "untrust",
|
Name: "untrust",
|
||||||
Func: cmdUntrust,
|
|
||||||
Usage: "[--cert <path>] | [[--ca <id>] [--address <listen>] [--config <path> [--adapter <name>]]]",
|
Usage: "[--cert <path>] | [[--ca <id>] [--address <listen>] [--config <path> [--adapter <name>]]]",
|
||||||
Short: "Untrusts a locally-trusted CA certificate",
|
Short: "Untrusts a locally-trusted CA certificate",
|
||||||
Long: `
|
Long: `
|
||||||
|
@ -89,15 +86,14 @@ will attempt to connect to the Caddy's admin API running at
|
||||||
'` + caddy.DefaultAdminListen + `' to fetch the root certificate.
|
'` + caddy.DefaultAdminListen + `' to fetch the root certificate.
|
||||||
You may explicitly specify the --address, or use the --config flag
|
You may explicitly specify the --address, or use the --config flag
|
||||||
to load the admin address from your config, if not using the default.`,
|
to load the admin address from your config, if not using the default.`,
|
||||||
Flags: func() *flag.FlagSet {
|
CobraFunc: func(cmd *cobra.Command) {
|
||||||
fs := flag.NewFlagSet("untrust", flag.ExitOnError)
|
cmd.Flags().StringP("cert", "p", "", "The path to the CA certificate to untrust")
|
||||||
fs.String("cert", "", "The path to the CA certificate to untrust")
|
cmd.Flags().StringP("ca", "", "", "The ID of the CA to untrust (defaults to 'local')")
|
||||||
fs.String("ca", "", "The ID of the CA to untrust (defaults to 'local')")
|
cmd.Flags().StringP("address", "", "", "Address of the administration API listener (if --config is not used)")
|
||||||
fs.String("address", "", "Address of the administration API listener (if --config is not used)")
|
cmd.Flags().StringP("config", "c", "", "Configuration file (if --address is not used)")
|
||||||
fs.String("config", "", "Configuration file (if --address is not used)")
|
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter to apply (if --config is used)")
|
||||||
fs.String("adapter", "", "Name of config adapter to apply (if --config is used)")
|
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdUntrust)
|
||||||
return fs
|
},
|
||||||
}(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user