forked from TrueCloudLab/certificates
update the help and usage information
This commit is contained in:
parent
f6546f160f
commit
95d4d9c4c1
2 changed files with 195 additions and 54 deletions
29
Gopkg.lock
generated
29
Gopkg.lock
generated
|
@ -123,6 +123,22 @@
|
|||
revision = "15d26544def341f036c5f8dca987a4cbe575032c"
|
||||
version = "v1.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8baa3b16f20963c54e296627ea1dabfd79d1b486f81baf8759e99d73bddf2687"
|
||||
name = "github.com/samfoo/ansi"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "b6bd2ded7189ce35bc02233b554eb56a5146af73"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:def689e73e9252f6f7fe66834a76751a41b767e03daab299e607e7226c58a855"
|
||||
name = "github.com/shurcooL/sanitized_anchor_name"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "86672fcb3f950f35f2e675df2240550f2a50762f"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3f53e9e4dfbb664cd62940c9c4b65a2171c66acd0b7621a1a6b8e78513525a52"
|
||||
name = "github.com/sirupsen/logrus"
|
||||
|
@ -141,7 +157,7 @@
|
|||
|
||||
[[projects]]
|
||||
branch = "ca-commands"
|
||||
digest = "1:41e2386e08278707d5a20237c10a2c82f4658de64593fe070652c11bb3880812"
|
||||
digest = "1:1731f58ec5ba2770296fb304504798c6f06059bd4645fd85f207de7be0b3add0"
|
||||
name = "github.com/smallstep/cli"
|
||||
packages = [
|
||||
"crypto/keys",
|
||||
|
@ -151,11 +167,13 @@
|
|||
"crypto/x509util",
|
||||
"errs",
|
||||
"jose",
|
||||
"pkg/blackfriday",
|
||||
"pkg/x509",
|
||||
"usage",
|
||||
"utils",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "e2cf66cdd8f458a28ed9c5a6efc78fcc5500bdd0"
|
||||
revision = "f6b9a18d11bd82c79876b18e57cd475e87be5fcc"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -190,9 +208,11 @@
|
|||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:5afed8b82638da362e14321ec6175b96351226f6662707801a0ec740bfd29840"
|
||||
digest = "1:acfafa29853fd970d5d5ac6ca3b7350b5aef5999196d32bb9b049e21c8caf726"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"html",
|
||||
"html/atom",
|
||||
"http/httpguts",
|
||||
"http2",
|
||||
"http2/hpack",
|
||||
|
@ -295,9 +315,12 @@
|
|||
"github.com/smallstep/cli/crypto/randutil",
|
||||
"github.com/smallstep/cli/crypto/tlsutil",
|
||||
"github.com/smallstep/cli/crypto/x509util",
|
||||
"github.com/smallstep/cli/errs",
|
||||
"github.com/smallstep/cli/jose",
|
||||
"github.com/smallstep/cli/pkg/x509",
|
||||
"github.com/smallstep/cli/usage",
|
||||
"github.com/tsenart/deadcode",
|
||||
"github.com/urfave/cli",
|
||||
"golang.org/x/net/http2",
|
||||
"gopkg.in/square/go-jose.v2",
|
||||
"gopkg.in/square/go-jose.v2/jwt",
|
||||
|
|
|
@ -2,12 +2,13 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"time"
|
||||
"unicode"
|
||||
|
@ -15,73 +16,170 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"github.com/smallstep/certificates/authority"
|
||||
"github.com/smallstep/certificates/ca"
|
||||
"github.com/smallstep/cli/errs"
|
||||
"github.com/smallstep/cli/usage"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Version is set by an LDFLAG at build time representing the git tag or commit
|
||||
// for the current release
|
||||
var Version = "N/A"
|
||||
// commit and buildTime are filled in during build by the Makefile
|
||||
var (
|
||||
BuildTime = "N/A"
|
||||
Version = "N/A"
|
||||
)
|
||||
|
||||
// BuildTime is set by an LDFLAG at build time representing the timestamp at
|
||||
// the time of build
|
||||
var BuildTime = "N/A"
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s [options] <config.json>\n\n", path.Base(os.Args[0]))
|
||||
flag.PrintDefaults()
|
||||
// Version returns the current version of the binary.
|
||||
func version() string {
|
||||
out := Version
|
||||
if out == "N/A" {
|
||||
out = "0000000-dev"
|
||||
}
|
||||
return fmt.Sprintf("Smallstep CLI/%s (%s/%s)",
|
||||
out, runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
||||
func printVersion() {
|
||||
version, buildTime := Version, BuildTime
|
||||
if version == "N/A" {
|
||||
version = "0000000-dev"
|
||||
// ReleaseDate returns the time of when the binary was built.
|
||||
func releaseDate() string {
|
||||
out := BuildTime
|
||||
if out == "N/A" {
|
||||
out = time.Now().UTC().Format("2006-01-02 15:04 MST")
|
||||
}
|
||||
if buildTime == "N/A" {
|
||||
buildTime = time.Now().UTC().Format("2006-01-02 15:04 MST")
|
||||
}
|
||||
fmt.Printf("Smallstep CA/%s (%s/%s)\n", version, runtime.GOOS, runtime.GOARCH)
|
||||
fmt.Printf("Release Date: %s\n", buildTime)
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// Print version and release date.
|
||||
func printFullVersion() {
|
||||
fmt.Printf("%s\n", version())
|
||||
fmt.Printf("Release Date: %s\n", releaseDate())
|
||||
}
|
||||
|
||||
func main() {
|
||||
var version bool
|
||||
var configFile, passFile string
|
||||
flag.StringVar(&passFile, "password-file", "", "path to file containing a password")
|
||||
flag.BoolVar(&version, "version", false, "print version and exit")
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
// Override global framework components
|
||||
cli.VersionPrinter = func(c *cli.Context) {
|
||||
printFullVersion()
|
||||
}
|
||||
cli.AppHelpTemplate = usage.AppHelpTemplate
|
||||
cli.SubcommandHelpTemplate = usage.SubcommandHelpTemplate
|
||||
cli.CommandHelpTemplate = usage.CommandHelpTemplate
|
||||
cli.HelpPrinter = usage.HelpPrinter
|
||||
cli.FlagNamePrefixer = usage.FlagNamePrefixer
|
||||
cli.FlagStringer = stringifyFlag
|
||||
|
||||
if version {
|
||||
printVersion()
|
||||
os.Exit(0)
|
||||
// Configure cli app
|
||||
app := cli.NewApp()
|
||||
app.Name = "step-ca"
|
||||
app.HelpName = "step-ca"
|
||||
app.Version = version()
|
||||
app.Usage = "an online certificate authority for secure automated certificate management"
|
||||
app.UsageText = `**step-ca** <config> [**--password-file**=<file>] [**--version**]`
|
||||
app.Description = `**step-ca** runs the Step Online Certificate Authority
|
||||
(Step CA) using the given configuration.
|
||||
|
||||
See the README.md for more detailed configuration documentation.
|
||||
|
||||
## POSITIONAL ARGUMENTS
|
||||
|
||||
<config>
|
||||
: File that configures the operation of the Step CA; this file is generated
|
||||
when you initialize the Step CA using 'step ca init'
|
||||
|
||||
## EXIT CODES
|
||||
|
||||
This command will run indefinitely on success and return \>0 if any error occurs.
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
These examples assume that you have already initialized your PKI by running
|
||||
'step ca init'. If you have not completed this step please see the 'Getting Started'
|
||||
section of the README.
|
||||
|
||||
Run the Step CA and prompt for password:
|
||||
'''
|
||||
$ step-ca $STEPPATH/config/ca.json
|
||||
'''
|
||||
|
||||
Run the Step CA and read the password from a file - this is useful for
|
||||
automating deployment:
|
||||
'''
|
||||
$ step-ca $STEPPATH/config/ca.json --password-file ./password.txt
|
||||
'''`
|
||||
app.Flags = append(app.Flags, []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "password-file",
|
||||
Usage: `path to the <file> containing the password to decrypt the
|
||||
intermediate private key.`,
|
||||
},
|
||||
}...)
|
||||
app.Copyright = "(c) 2018 Smallstep Labs, Inc."
|
||||
|
||||
// All non-successful output should be written to stderr
|
||||
app.Writer = os.Stdout
|
||||
app.ErrWriter = os.Stderr
|
||||
app.Commands = []cli.Command{
|
||||
cli.Command{
|
||||
Name: "version",
|
||||
Usage: "Displays the current version of the cli",
|
||||
// Command prints out the current version of the tool
|
||||
Action: func(c *cli.Context) error {
|
||||
printFullVersion()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if flag.NArg() != 1 {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
// Start the golang debug logger if environment variable is set.
|
||||
// See https://golang.org/pkg/net/http/pprof/
|
||||
debugProfAddr := os.Getenv("STEP_PROF_ADDR")
|
||||
if debugProfAddr != "" {
|
||||
go func() {
|
||||
log.Println(http.ListenAndServe(debugProfAddr, nil))
|
||||
}()
|
||||
}
|
||||
|
||||
configFile = flag.Arg(0)
|
||||
config, err := authority.LoadConfiguration(configFile)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
app.Action = func(ctx *cli.Context) error {
|
||||
passFile := ctx.String("password-file")
|
||||
|
||||
var password []byte
|
||||
if passFile != "" {
|
||||
if password, err = ioutil.ReadFile(passFile); err != nil {
|
||||
fatal(errors.Wrapf(err, "error reading %s", passFile))
|
||||
// If zero cmd line args show help, if >1 cmd line args show error.
|
||||
if ctx.NArg() == 0 {
|
||||
return cli.ShowAppHelp(ctx)
|
||||
}
|
||||
password = bytes.TrimRightFunc(password, unicode.IsSpace)
|
||||
if err := errs.NumberOfArguments(ctx, 1); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
configFile := ctx.Args().Get(0)
|
||||
config, err := authority.LoadConfiguration(configFile)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
var password []byte
|
||||
if passFile != "" {
|
||||
if password, err = ioutil.ReadFile(passFile); err != nil {
|
||||
fatal(errors.Wrapf(err, "error reading %s", passFile))
|
||||
}
|
||||
password = bytes.TrimRightFunc(password, unicode.IsSpace)
|
||||
}
|
||||
|
||||
srv, err := ca.New(config, ca.WithConfigFile(configFile), ca.WithPassword(password))
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
go ca.StopReloaderHandler(srv)
|
||||
if err = srv.Run(); err != nil && err != http.ErrServerClosed {
|
||||
fatal(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
srv, err := ca.New(config, ca.WithConfigFile(configFile), ca.WithPassword(password))
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
go ca.StopReloaderHandler(srv)
|
||||
if err = srv.Run(); err != nil && err != http.ErrServerClosed {
|
||||
fatal(err)
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
if os.Getenv("STEPDEBUG") == "1" {
|
||||
fmt.Fprintf(os.Stderr, "%+v\n", err)
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,3 +194,23 @@ func fatal(err error) {
|
|||
}
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
func flagValue(f cli.Flag) reflect.Value {
|
||||
fv := reflect.ValueOf(f)
|
||||
for fv.Kind() == reflect.Ptr {
|
||||
fv = reflect.Indirect(fv)
|
||||
}
|
||||
return fv
|
||||
}
|
||||
|
||||
var placeholderString = regexp.MustCompile(`<.*?>`)
|
||||
|
||||
func stringifyFlag(f cli.Flag) string {
|
||||
fv := flagValue(f)
|
||||
usage := fv.FieldByName("Usage").String()
|
||||
placeholder := placeholderString.FindString(usage)
|
||||
if placeholder == "" {
|
||||
placeholder = "<value>"
|
||||
}
|
||||
return cli.FlagNamePrefixer(fv.FieldByName("Name").String(), placeholder) + "\t" + usage
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue