diff --git a/.gitignore b/.gitignore index 3a54a0c..7945ee9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ dist tests testdata +manpages # ---> Go # If you prefer the allow list template instead of the deny list, see community template: diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 21f858c..b52344e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -24,9 +24,10 @@ before: - sh -c 'go run . completion bash > completions/https-wrench.bash' - sh -c 'go run . completion zsh > completions/https-wrench.zsh' - sh -c 'go run . completion fish > completions/https-wrench.fish' - # - rm -rf manpages - # - mkdir manpages - # - sh -c 'go run . man | gzip -c > manpages/https-wrench.1.gz' + - rm -rf manpages + - mkdir manpages + - sh -c 'go run . man --dest-dir manpages' + - sh -c 'gzip manpages/*' builds: - env: @@ -48,7 +49,7 @@ archives: - README.md - LICENSE - completions/* - # - man/* + - manpages/* nfpms: - maintainer: Zeno Belli @@ -62,12 +63,34 @@ nfpms: contents: - src: completions/https-wrench.bash dst: /etc/bash_completion.d/https-wrench + - src: completions/https-wrench.fish dst: /usr/share/fish/vendor_completions.d/https-wrench.fish + - src: completions/https-wrench.zsh dst: /usr/share/zsh/site-functions/_https-wrench - # - src: ./manpages/https-wrench.1.gz - # dst: /usr/share/man/man1/https-.1.gz + + - src: manpages/https-wrench.1.gz + dst: /usr/share/man/man1/https-wrench.1.gz + + - src: manpages/https-wrench-requests.1.gz + dst: /usr/share/man/man1/https-wrench-requests.1.gz + + - src: manpages/https-wrench-certinfo.1.gz + dst: /usr/share/man/man1/https-wrench-certinfo.1.gz + + - src: manpages/https-wrench-completion.1.gz + dst: /usr/share/man/man1/https-wrench-completion.1.gz + + - src: manpages/https-wrench-completion-bash.1.gz + dst: /usr/share/man/man1/https-wrench-completion-bash.1.gz + + - src: manpages/https-wrench-completion-fish.1.gz + dst: /usr/share/man/man1/https-wrench-completion-fish.1.gz + + - src: manpages/https-wrench-completion-zsh.1.gz + dst: /usr/share/man/man1/https-wrench-completion-zsh.1.gz + release: "1" dockers: @@ -130,6 +153,12 @@ homebrew_casks: description: https-wrench license: MIT skip_upload: false + + manpages: + - ./manpages/https-wrench.1.gz + - ./manpages/https-wrench-requests.1.gz + - ./manpages/https-wrench-certinfo.1.gz + completions: bash: "completions/{{ .ProjectName }}.bash" zsh: "completions/{{ .ProjectName }}.zsh" @@ -146,11 +175,13 @@ nix: license: mit extra_install: |- + installManPage ./manpages/https-wrench.1.gz + installManPage ./manpages/https-wrench-certinfo.1.gz + installManPage ./manpages/https-wrench-requests.1.gz installShellCompletion --cmd https-wrench \ --bash <($out/bin/https-wrench completion bash) \ --fish <($out/bin/https-wrench completion fish) \ --zsh <($out/bin/https-wrench completion zsh) - # installManPage ./manpages/foo.1.gz changelog: sort: asc diff --git a/cmd/certinfo.go b/cmd/certinfo.go index c14e345..3a6f312 100644 --- a/cmd/certinfo.go +++ b/cmd/certinfo.go @@ -20,28 +20,31 @@ var ( var certinfoCmd = &cobra.Command{ Use: "certinfo", - Short: "Show info about PEM certificates and keys", + Short: "Shows information about PEM certificates and keys", Long: ` -HTTPS Wrench certinfo: show info about PEM certificates and keys. +HTTPS Wrench certinfo: shows information about PEM certificates and keys. + +https-wrench certinfo can fetch certificates from a TLS endpoint, read from a PEM bundle file, and check if a +private key matches any of the certificates. -Certinfo can fetch certificates from a TLS endpoint, read from a PEM bundle file, and check if a private -key matches any of the certificates. The certificates can be verified against the system root CAs or a custom CA bundle file. + The validation can be skipped. + If the private key is password protected, the password can be provided via the CERTINFO_PKEY_PW environment variable or will be prompted on stdin. Examples: - certinfo --tls-endpoint example.com:443 - certinfo --cert-bundle ./bundle.pem --key-file ./key.pem - certinfo --cert-bundle ./bundle.pem - certinfo --key-file ./key.pem - certinfo --tls-endpoint example.com:443 --key-file ./key.pem - certinfo --tls-endpoint example.com:443 --cert-bundle ./bundle.pem --key-file ./key.pem - certinfo --tls-endpoint example.com:443 --tls-servername www.example.com - certinfo --tls-endpoint [2001:db8::1]:443 --tls-insecure - certinfo --ca-bundle ./ca-bundle.pem --tls-endpoint example.com:443 - certinfo --ca-bundle ./ca-bundle.pem --cert-bundle ./bundle.pem --key-file ./key.pem + https-wrench certinfo --tls-endpoint example.com:443 + https-wrench certinfo --cert-bundle ./bundle.pem --key-file ./key.pem + https-wrench certinfo --cert-bundle ./bundle.pem + https-wrench certinfo --key-file ./key.pem + https-wrench certinfo --tls-endpoint example.com:443 --key-file ./key.pem + https-wrench certinfo --tls-endpoint example.com:443 --cert-bundle ./bundle.pem --key-file ./key.pem + https-wrench certinfo --tls-endpoint example.com:443 --tls-servername www.example.com + https-wrench certinfo --tls-endpoint [2001:db8::1]:443 --tls-insecure + https-wrench certinfo --ca-bundle ./ca-bundle.pem --tls-endpoint example.com:443 + https-wrench certinfo --ca-bundle ./ca-bundle.pem --cert-bundle ./bundle.pem --key-file ./key.pem `, Run: func(cmd *cobra.Command, args []string) { caBundleValue := viper.GetString("ca-bundle") diff --git a/cmd/man.go b/cmd/man.go new file mode 100644 index 0000000..41c664a --- /dev/null +++ b/cmd/man.go @@ -0,0 +1,42 @@ +/* +Copyright © 2025 Zeno Belli +*/ + +package cmd + +import ( + "fmt" + "time" + + "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" +) + +var manPagesDestDir string + +var manCmd = &cobra.Command{ + Use: "man", + Short: "create manpages for HTTPS Wrench", + Long: "Create manpages for HTTPS Wrench commands", + Hidden: true, + Run: func(_ *cobra.Command, _ []string) { + now := time.Now() + rootHeader := &doc.GenManHeader{ + Title: "HTTPS-WRENCH", + Section: "1", + Date: &now, + Source: "https-wrench", + } + err := doc.GenManTree(rootCmd, rootHeader, manPagesDestDir) + if err != nil { + fmt.Print(err) + return + } + }, +} + +func init() { + rootCmd.AddCommand(manCmd) + manCmd.Flags().StringVar(&manPagesDestDir, "dest-dir", + ".", "Destination directory for the man pages files") +} diff --git a/cmd/requests.go b/cmd/requests.go index 010d953..8a55705 100644 --- a/cmd/requests.go +++ b/cmd/requests.go @@ -25,7 +25,21 @@ var requestsCmd = &cobra.Command{ Use: "requests", Short: "Make HTTPS requests defined in the YAML configuration file", Long: ` -HTTPS Wrench requests: make HTTPS requests defined in the YAML configuration file`, +https-wrench requests is the subcommand that does HTTPS requests according to the configuration +pointed by the --config flag. + +A sample configuration can be generated as a starting point (--show-sample-config). + +The Github repository has more configuration examples: +https://github.com/xenOs76/https-wrench/tree/main/assets/examples + +It also provides a JSON schema that can be used to validate new configuration files: +https://github.com/xenOs76/https-wrench/blob/main/https-wrench.schema.json + +Examples: + https-wrench requests --show-sample-config > https-wrench-sample-config.yaml + https-wrench requests --config https-wrench-sample-config.yaml + `, Run: func(cmd *cobra.Command, args []string) { versionRequested := viper.GetBool("version") diff --git a/cmd/root.go b/cmd/root.go index 4a23f12..4276a4a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -49,7 +49,20 @@ var rootCmd = &cobra.Command{ Use: "https-wrench", Short: "HTTPS Wrench, a tool to make HTTPS requests based on a YAML configuration file", Long: ` -HTTPS Wrench, a tool to make HTTPS requests based on a YAML configuration file`, +HTTPS Wrench is mainly a tool to make HTTPS requests based on a YAML configuration file. + +https-wrench has two subcommands: requests and certinfo. + +requests is the subcommand that does HTTPS requests according to the configuration provided +by the --config flag. + +certinfo is a subcommand that reads information from PEM certificates and keys. The certificates +can be read from local files or TLS enabled endpoints. + +certinfo can compare public keys extracted from certificates and private keys to check if they match. + +HTTPS Wrench is distributed with an open source license and available at the following address: +https://github.com/xenOs76/https-wrench`, Run: func(cmd *cobra.Command, args []string) { showVersion, _ := cmd.Flags().GetBool("version") diff --git a/devenv.nix b/devenv.nix index 7a24514..2f0dfd6 100644 --- a/devenv.nix +++ b/devenv.nix @@ -37,7 +37,7 @@ ".gitignore" ".envrc" "internal/certinfo/common_handlers.go" - "completions" + "completions/*" ]; hooks = { shellcheck.enable = true; @@ -238,6 +238,11 @@ ./dist/https-wrench certinfo | grep "help for certinfo" ''; + scripts.test-requests-show-sample-config.exec = '' + gum format "## test request show sample config" + ./dist/https-wrench requests --show-sample-config| grep 'requests:' + ''; + scripts.test-requests-sample-config.exec = '' gum format "## test request with sample config" ./dist/https-wrench requests --config ./cmd/embedded/config-example.yaml @@ -504,6 +509,7 @@ gum format "## Requests tests" # test-requests-sample-config + test-requests-show-sample-config test-requests-k3s test-requests-methods test-requests-timeout diff --git a/go.mod b/go.mod index 89a602f..5bde940 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/clipperhouse/displaywidth v0.6.0 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/uax29/v2 v2.3.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dlclark/regexp2 v1.11.5 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect @@ -42,6 +43,7 @@ require ( github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.12.0 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect diff --git a/go.sum b/go.sum index e8b2d85..6d56eb0 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,7 @@ github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfa github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -73,6 +74,7 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=