You've already forked step-ca-cli
mirror of
https://github.com/smallstep/cli.git
synced 2025-08-07 16:02:54 +03:00
Add flag --force on all commands using utils.WriteFile
Fixes smallstep/ca-component#121
This commit is contained in:
@@ -7,10 +7,12 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/ca"
|
"github.com/smallstep/certificates/ca"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/config"
|
"github.com/smallstep/cli/config"
|
||||||
"github.com/smallstep/cli/crypto/pemutil"
|
"github.com/smallstep/cli/crypto/pemutil"
|
||||||
"github.com/smallstep/cli/crypto/pki"
|
"github.com/smallstep/cli/crypto/pki"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@@ -18,7 +20,7 @@ import (
|
|||||||
func bootstrapCommand() cli.Command {
|
func bootstrapCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "bootstrap",
|
Name: "bootstrap",
|
||||||
Action: cli.ActionFunc(bootstrapAction),
|
Action: command.ActionFunc(bootstrapAction),
|
||||||
Usage: "initializes the environment to use the CA commands",
|
Usage: "initializes the environment to use the CA commands",
|
||||||
UsageText: "**step ca bootstrap** [**--ca-url**=<uri>] [**--fingerprint**=<fingerprint>]",
|
UsageText: "**step ca bootstrap** [**--ca-url**=<uri>] [**--fingerprint**=<fingerprint>]",
|
||||||
Description: `**step ca bootstrap** downloads the root certificate from the certificate
|
Description: `**step ca bootstrap** downloads the root certificate from the certificate
|
||||||
@@ -30,7 +32,7 @@ url, the root certificate location and its fingerprint.
|
|||||||
|
|
||||||
After the bootstrap, ca commands do not need to specify the flags
|
After the bootstrap, ca commands do not need to specify the flags
|
||||||
--ca-url, --root or --fingerprint if we want to use the same environment.`,
|
--ca-url, --root or --fingerprint if we want to use the same environment.`,
|
||||||
Flags: []cli.Flag{caURLFlag, fingerprintFlag},
|
Flags: []cli.Flag{caURLFlag, fingerprintFlag, flags.Force},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,9 +14,11 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/api"
|
"github.com/smallstep/certificates/api"
|
||||||
"github.com/smallstep/certificates/ca"
|
"github.com/smallstep/certificates/ca"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/crypto/pemutil"
|
"github.com/smallstep/cli/crypto/pemutil"
|
||||||
"github.com/smallstep/cli/crypto/pki"
|
"github.com/smallstep/cli/crypto/pki"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/jose"
|
"github.com/smallstep/cli/jose"
|
||||||
"github.com/smallstep/cli/ui"
|
"github.com/smallstep/cli/ui"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
@@ -26,7 +28,7 @@ import (
|
|||||||
func newCertificateCommand() cli.Command {
|
func newCertificateCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "certificate",
|
Name: "certificate",
|
||||||
Action: cli.ActionFunc(newCertificateAction),
|
Action: command.ActionFunc(newCertificateAction),
|
||||||
Usage: "generates a new certificate pair signed by the root certificate",
|
Usage: "generates a new certificate pair signed by the root certificate",
|
||||||
UsageText: `**step ca certificate** <hostname> <crt-file> <key-file>
|
UsageText: `**step ca certificate** <hostname> <crt-file> <key-file>
|
||||||
[**--token**=<token>] [**--ca-url**=<uri>] [**--root**=<file>]
|
[**--token**=<token>] [**--ca-url**=<uri>] [**--root**=<file>]
|
||||||
@@ -63,6 +65,7 @@ $ step ca certificate --token $TOKEN --not-after=1h internal.example.com interna
|
|||||||
rootFlag,
|
rootFlag,
|
||||||
notBeforeFlag,
|
notBeforeFlag,
|
||||||
notAfterFlag,
|
notAfterFlag,
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,7 +73,7 @@ $ step ca certificate --token $TOKEN --not-after=1h internal.example.com interna
|
|||||||
func signCertificateCommand() cli.Command {
|
func signCertificateCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "sign",
|
Name: "sign",
|
||||||
Action: cli.ActionFunc(signCertificateAction),
|
Action: command.ActionFunc(signCertificateAction),
|
||||||
Usage: "generates a new certificate signing a certificate request",
|
Usage: "generates a new certificate signing a certificate request",
|
||||||
UsageText: `**step ca sign** <csr-file> <crt-file>
|
UsageText: `**step ca sign** <csr-file> <crt-file>
|
||||||
[**--token**=<token>] [**--ca-url**=<uri>] [**--root**=<file>]
|
[**--token**=<token>] [**--ca-url**=<uri>] [**--root**=<file>]
|
||||||
@@ -104,6 +107,7 @@ $ step ca sign --token $TOKEN --not-after=1h internal.csr internal.crt
|
|||||||
rootFlag,
|
rootFlag,
|
||||||
notBeforeFlag,
|
notBeforeFlag,
|
||||||
notAfterFlag,
|
notAfterFlag,
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,7 +115,7 @@ $ step ca sign --token $TOKEN --not-after=1h internal.csr internal.crt
|
|||||||
func renewCertificateCommand() cli.Command {
|
func renewCertificateCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "renew",
|
Name: "renew",
|
||||||
Action: cli.ActionFunc(renewCertificateAction),
|
Action: command.ActionFunc(renewCertificateAction),
|
||||||
Usage: "renew a valid certificate",
|
Usage: "renew a valid certificate",
|
||||||
UsageText: `**step ca renew** <crt-file> <key-file>
|
UsageText: `**step ca renew** <crt-file> <key-file>
|
||||||
[**--ca-url**=<uri>] [**--root**=<file>]
|
[**--ca-url**=<uri>] [**--root**=<file>]
|
||||||
@@ -176,10 +180,7 @@ sequence of decimal numbers, each with optional fraction and a unit suffix, such
|
|||||||
as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms",
|
as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms",
|
||||||
"s", "m", "h".`,
|
"s", "m", "h".`,
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
flags.Force,
|
||||||
Name: "f,force",
|
|
||||||
Usage: "Force the overwrite of files without asking.",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -464,7 +465,7 @@ func renewCertificateAction(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
data := append(pem.EncodeToMemory(serverBlock), pem.EncodeToMemory(caBlock)...)
|
data := append(pem.EncodeToMemory(serverBlock), pem.EncodeToMemory(caBlock)...)
|
||||||
|
|
||||||
if err := utils.WriteFileForce(outFile, data, 0600, ctx.Bool("force")); err != nil {
|
if err := utils.WriteFile(outFile, data, 0600); err != nil {
|
||||||
return errs.FileError(err, outFile)
|
return errs.FileError(err, outFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,15 +7,17 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/smallstep/certificates/ca"
|
"github.com/smallstep/certificates/ca"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/crypto/pemutil"
|
"github.com/smallstep/cli/crypto/pemutil"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
func rootComand() cli.Command {
|
func rootComand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "root",
|
Name: "root",
|
||||||
Action: cli.ActionFunc(rootAction),
|
Action: command.ActionFunc(rootAction),
|
||||||
Usage: "downloads and validates the root certificate",
|
Usage: "downloads and validates the root certificate",
|
||||||
UsageText: `**step ca root** <root-file>
|
UsageText: `**step ca root** <root-file>
|
||||||
[**--ca-url**=<uri>] [**--fingerprint**=<fingerprint>]`,
|
[**--ca-url**=<uri>] [**--fingerprint**=<fingerprint>]`,
|
||||||
@@ -50,6 +52,7 @@ $ step ca root root_ca.crt \
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
caURLFlag,
|
caURLFlag,
|
||||||
fingerprintFlag,
|
fingerprintFlag,
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,9 +10,11 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/authority"
|
"github.com/smallstep/certificates/authority"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/crypto/pki"
|
"github.com/smallstep/cli/crypto/pki"
|
||||||
"github.com/smallstep/cli/crypto/randutil"
|
"github.com/smallstep/cli/crypto/randutil"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/jose"
|
"github.com/smallstep/cli/jose"
|
||||||
"github.com/smallstep/cli/token"
|
"github.com/smallstep/cli/token"
|
||||||
"github.com/smallstep/cli/token/provision"
|
"github.com/smallstep/cli/token/provision"
|
||||||
@@ -30,7 +32,7 @@ type provisionersSelect struct {
|
|||||||
func newTokenCommand() cli.Command {
|
func newTokenCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "token",
|
Name: "token",
|
||||||
Action: cli.ActionFunc(newTokenAction),
|
Action: command.ActionFunc(newTokenAction),
|
||||||
Usage: "generates an OTT granting access to the CA",
|
Usage: "generates an OTT granting access to the CA",
|
||||||
UsageText: `**step ca token** <hostname>
|
UsageText: `**step ca token** <hostname>
|
||||||
[--**kid**=<kid>] [--**issuer**=<issuer>] [**--ca-url**=<uri>] [**--root**=<file>]
|
[--**kid**=<kid>] [--**issuer**=<issuer>] [**--ca-url**=<uri>] [**--root**=<file>]
|
||||||
@@ -117,6 +119,7 @@ the certificate authority.`,
|
|||||||
Usage: `Creates a token without contacting the certificate authority. Offline mode
|
Usage: `Creates a token without contacting the certificate authority. Offline mode
|
||||||
requires the flags <--kid>, <--issuer>, <--key>, <--ca-url>, and <--root>.`,
|
requires the flags <--kid>, <--issuer>, <--key>, <--ca-url>, and <--root>.`,
|
||||||
},
|
},
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,14 +5,17 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
func bundleCommand() cli.Command {
|
func bundleCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "bundle",
|
Name: "bundle",
|
||||||
Action: cli.ActionFunc(bundleAction),
|
Action: command.ActionFunc(bundleAction),
|
||||||
Usage: `bundle a certificate with intermediate certificate(s) needed for certificate path validation.`,
|
Usage: `bundle a certificate with intermediate certificate(s) needed for certificate path validation.`,
|
||||||
UsageText: `**step certificate bundle** <crt_file> <ca> <bundle_file>`,
|
UsageText: `**step certificate bundle** <crt_file> <ca> <bundle_file>`,
|
||||||
Description: `**step certificate bundle** bundles a certificate
|
Description: `**step certificate bundle** bundles a certificate
|
||||||
@@ -41,6 +44,7 @@ Bundle a certificate with the intermediate certificate authority (issuer):
|
|||||||
$ step certificate bundle foo.crt intermediate-ca.crt foo-bundle.crt
|
$ step certificate bundle foo.crt intermediate-ca.crt foo-bundle.crt
|
||||||
'''
|
'''
|
||||||
`,
|
`,
|
||||||
|
Flags: []cli.Flag{flags.Force},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +74,7 @@ func bundleAction(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chainFile := ctx.Args().Get(2)
|
chainFile := ctx.Args().Get(2)
|
||||||
if err := ioutil.WriteFile(chainFile,
|
if err := utils.WriteFile(chainFile,
|
||||||
append(pem.EncodeToMemory(crtBlock), pem.EncodeToMemory(caBlock)...), 0600); err != nil {
|
append(pem.EncodeToMemory(crtBlock), pem.EncodeToMemory(caBlock)...), 0600); err != nil {
|
||||||
return errs.FileError(err, chainFile)
|
return errs.FileError(err, chainFile)
|
||||||
}
|
}
|
||||||
|
@@ -4,13 +4,14 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/crypto/keys"
|
"github.com/smallstep/cli/crypto/keys"
|
||||||
"github.com/smallstep/cli/crypto/pemutil"
|
"github.com/smallstep/cli/crypto/pemutil"
|
||||||
"github.com/smallstep/cli/crypto/x509util"
|
"github.com/smallstep/cli/crypto/x509util"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
x509 "github.com/smallstep/cli/pkg/x509"
|
x509 "github.com/smallstep/cli/pkg/x509"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@@ -19,7 +20,7 @@ import (
|
|||||||
func createCommand() cli.Command {
|
func createCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "create",
|
Name: "create",
|
||||||
Action: cli.ActionFunc(createAction),
|
Action: command.ActionFunc(createAction),
|
||||||
Usage: "create a certificate or certificate signing request",
|
Usage: "create a certificate or certificate signing request",
|
||||||
UsageText: `**step certificate create** <subject> <crt_file> <key_file>
|
UsageText: `**step certificate create** <subject> <crt_file> <key_file>
|
||||||
[**ca**=<issuer-cert>] [**ca-key**=<issuer-key>] [**--csr**]
|
[**ca**=<issuer-cert>] [**ca-key**=<issuer-key>] [**--csr**]
|
||||||
@@ -192,6 +193,7 @@ unset, default is P-256 for EC keys and Ed25519 for OKP keys.
|
|||||||
: Ed25519 Curve
|
: Ed25519 Curve
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,8 +322,7 @@ func createAction(ctx *cli.Context) error {
|
|||||||
return errs.NewError("unexpected type: %s", typ)
|
return errs.NewError("unexpected type: %s", typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.WriteFile(crtFile, pem.EncodeToMemory(pubPEM),
|
if err := utils.WriteFile(crtFile, pem.EncodeToMemory(pubPEM), 0600); err != nil {
|
||||||
os.FileMode(0600)); err != nil {
|
|
||||||
return errs.FileError(err, crtFile)
|
return errs.FileError(err, crtFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,7 +7,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@@ -15,7 +17,7 @@ import (
|
|||||||
func formatCommand() cli.Command {
|
func formatCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "format",
|
Name: "format",
|
||||||
Action: cli.ActionFunc(formatAction),
|
Action: command.ActionFunc(formatAction),
|
||||||
Usage: `reformat certificate.`,
|
Usage: `reformat certificate.`,
|
||||||
UsageText: `**step certificate format** <crt_file> [**--out**=<path>]`,
|
UsageText: `**step certificate format** <crt_file> [**--out**=<path>]`,
|
||||||
Description: `**step certificate format** prints the certificate in
|
Description: `**step certificate format** prints the certificate in
|
||||||
@@ -55,6 +57,7 @@ $ step certificate format foo.pem --out foo.der
|
|||||||
Name: "out",
|
Name: "out",
|
||||||
Usage: `Path to write the reformatted result.`,
|
Usage: `Path to write the reformatted result.`,
|
||||||
},
|
},
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ import (
|
|||||||
const IgnoreEnvVar = "STEP_IGNORE_ENV_VAR"
|
const IgnoreEnvVar = "STEP_IGNORE_ENV_VAR"
|
||||||
|
|
||||||
var cmds []cli.Command
|
var cmds []cli.Command
|
||||||
|
var currentContext *cli.Context
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
os.Unsetenv(IgnoreEnvVar)
|
os.Unsetenv(IgnoreEnvVar)
|
||||||
@@ -40,6 +41,19 @@ func Retrieve() []cli.Command {
|
|||||||
return cmds
|
return cmds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionFunc returns a cli.ActionFunc that stores the context.
|
||||||
|
func ActionFunc(fn cli.ActionFunc) cli.ActionFunc {
|
||||||
|
return func(ctx *cli.Context) error {
|
||||||
|
currentContext = ctx
|
||||||
|
return fn(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsForce returns if the force flag was passed
|
||||||
|
func IsForce() bool {
|
||||||
|
return currentContext != nil && currentContext.Bool("force")
|
||||||
|
}
|
||||||
|
|
||||||
// getConfigVars load the defaults.json file and sets the flags if they are not
|
// getConfigVars load the defaults.json file and sets the flags if they are not
|
||||||
// already set or the EnvVar is set to IgnoreEnvVar.
|
// already set or the EnvVar is set to IgnoreEnvVar.
|
||||||
//
|
//
|
||||||
|
@@ -9,8 +9,10 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/crypto/pemutil"
|
"github.com/smallstep/cli/crypto/pemutil"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/jose"
|
"github.com/smallstep/cli/jose"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
)
|
)
|
||||||
@@ -18,7 +20,7 @@ import (
|
|||||||
func changePassCommand() cli.Command {
|
func changePassCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "change-pass",
|
Name: "change-pass",
|
||||||
Action: cli.ActionFunc(changePassAction),
|
Action: command.ActionFunc(changePassAction),
|
||||||
Usage: "Change password of an encrypted private key (PEM or JWK format)",
|
Usage: "Change password of an encrypted private key (PEM or JWK format)",
|
||||||
UsageText: `**step crypto change-pass** <key-file> [**--out**=<file>]`,
|
UsageText: `**step crypto change-pass** <key-file> [**--out**=<file>]`,
|
||||||
Description: `**step crypto change-pass** extracts the private key from
|
Description: `**step crypto change-pass** extracts the private key from
|
||||||
@@ -56,6 +58,7 @@ $ step crypto change-pass key.jwk --out new-key.jwk
|
|||||||
Name: "out,output-file",
|
Name: "out,output-file",
|
||||||
Usage: "The <file> new encrypted key path. Default to overwriting the <key> positional argument",
|
Usage: "The <file> new encrypted key path. Default to overwriting the <key> positional argument",
|
||||||
},
|
},
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,8 +9,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/crypto/randutil"
|
"github.com/smallstep/cli/crypto/randutil"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/jose"
|
"github.com/smallstep/cli/jose"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@@ -26,7 +28,7 @@ const (
|
|||||||
func createCommand() cli.Command {
|
func createCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "create",
|
Name: "create",
|
||||||
Action: cli.ActionFunc(createAction),
|
Action: command.ActionFunc(createAction),
|
||||||
Usage: "create a JWK (JSON Web Key)",
|
Usage: "create a JWK (JSON Web Key)",
|
||||||
UsageText: `**step crypto jwk create** <public-jwk-file> <private-jwk-file>
|
UsageText: `**step crypto jwk create** <public-jwk-file> <private-jwk-file>
|
||||||
[**--kty**=<type>] [**--alg**=<algorithm>] [**--use**=<use>]
|
[**--kty**=<type>] [**--alg**=<algorithm>] [**--use**=<use>]
|
||||||
@@ -397,12 +399,9 @@ existing <pem-file> instead of creating a new key.`,
|
|||||||
key material will be written to disk unencrypted. This is not
|
key material will be written to disk unencrypted. This is not
|
||||||
recommended. Requires **--insecure** flag.`,
|
recommended. Requires **--insecure** flag.`,
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
flags.Subtle,
|
||||||
Name: "subtle",
|
flags.Insecure,
|
||||||
},
|
flags.Force,
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "insecure",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,9 +10,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/crypto/pemutil"
|
"github.com/smallstep/cli/crypto/pemutil"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@@ -20,7 +21,7 @@ import (
|
|||||||
func formatCommand() cli.Command {
|
func formatCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "format",
|
Name: "format",
|
||||||
Action: cli.ActionFunc(formatAction),
|
Action: command.ActionFunc(formatAction),
|
||||||
Usage: `reformat certificate.`,
|
Usage: `reformat certificate.`,
|
||||||
UsageText: `**step crypto key format** <key_file> [**--out**=<path>]`,
|
UsageText: `**step crypto key format** <key_file> [**--out**=<path>]`,
|
||||||
Description: `**step crypto key format** prints the key in
|
Description: `**step crypto key format** prints the key in
|
||||||
@@ -66,6 +67,7 @@ $ step crypto key format foo-key.pem --out foo-key.der
|
|||||||
Name: "password-file",
|
Name: "password-file",
|
||||||
Usage: `location of file containing passphrase to decrypt private key`,
|
Usage: `location of file containing passphrase to decrypt private key`,
|
||||||
},
|
},
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,9 +5,11 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/crypto/keys"
|
"github.com/smallstep/cli/crypto/keys"
|
||||||
"github.com/smallstep/cli/crypto/pemutil"
|
"github.com/smallstep/cli/crypto/pemutil"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/jose"
|
"github.com/smallstep/cli/jose"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@@ -16,7 +18,7 @@ import (
|
|||||||
func createKeyPairCommand() cli.Command {
|
func createKeyPairCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "keypair",
|
Name: "keypair",
|
||||||
Action: cli.ActionFunc(createAction),
|
Action: command.ActionFunc(createAction),
|
||||||
Usage: "generate a public / private keypair in PEM format.",
|
Usage: "generate a public / private keypair in PEM format.",
|
||||||
UsageText: `**step crypto keypair** <pub_file> <priv_file>
|
UsageText: `**step crypto keypair** <pub_file> <priv_file>
|
||||||
[**--curve**=<curve>] [**--no-password**] [**--size**=<size>]
|
[**--curve**=<curve>] [**--no-password**] [**--size**=<size>]
|
||||||
@@ -135,6 +137,7 @@ existing <jwk-file> instead of creating a new key.`,
|
|||||||
Sensitive key material will be written to disk unencrypted. This is not
|
Sensitive key material will be written to disk unencrypted. This is not
|
||||||
recommended. Requires **--insecure** flag.`,
|
recommended. Requires **--insecure** flag.`,
|
||||||
},
|
},
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"golang.org/x/crypto/nacl/box"
|
"golang.org/x/crypto/nacl/box"
|
||||||
@@ -93,7 +95,7 @@ message
|
|||||||
func boxKeypairCommand() cli.Command {
|
func boxKeypairCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "keypair",
|
Name: "keypair",
|
||||||
Action: cli.ActionFunc(boxKeypairAction),
|
Action: command.ActionFunc(boxKeypairAction),
|
||||||
Usage: "generate a key for use with seal and open",
|
Usage: "generate a key for use with seal and open",
|
||||||
UsageText: "**step crypto nacl box keypair** <pub-file> <priv-file>",
|
UsageText: "**step crypto nacl box keypair** <pub-file> <priv-file>",
|
||||||
Description: `Generates a new public/private keypair suitable for use with seal and open.
|
Description: `Generates a new public/private keypair suitable for use with seal and open.
|
||||||
@@ -110,6 +112,7 @@ For examples, see **step help crypto nacl box**.
|
|||||||
|
|
||||||
<priv-file>
|
<priv-file>
|
||||||
: The path to write the encrypted private key.`,
|
: The path to write the encrypted private key.`,
|
||||||
|
Flags: []cli.Flag{flags.Force},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,7 +7,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"golang.org/x/crypto/nacl/sign"
|
"golang.org/x/crypto/nacl/sign"
|
||||||
@@ -65,7 +67,7 @@ message
|
|||||||
func signKeypairCommand() cli.Command {
|
func signKeypairCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "keypair",
|
Name: "keypair",
|
||||||
Action: cli.ActionFunc(signKeypairAction),
|
Action: command.ActionFunc(signKeypairAction),
|
||||||
Usage: "generates a pair for use with sign and open",
|
Usage: "generates a pair for use with sign and open",
|
||||||
UsageText: "**step crypto nacl sign keypair** <pub-file> <priv-file>",
|
UsageText: "**step crypto nacl sign keypair** <pub-file> <priv-file>",
|
||||||
Description: `**step crypto nacl sign keypair** generates a secret key and a corresponding
|
Description: `**step crypto nacl sign keypair** generates a secret key and a corresponding
|
||||||
@@ -74,6 +76,7 @@ public key valid for verifying and signing messages.
|
|||||||
This command uses an implementation of NaCl's crypto_sign_keypair function.
|
This command uses an implementation of NaCl's crypto_sign_keypair function.
|
||||||
|
|
||||||
For examples, see **step help crypto nacl sign**.`,
|
For examples, see **step help crypto nacl sign**.`,
|
||||||
|
Flags: []cli.Flag{flags.Force},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,7 +8,9 @@ import (
|
|||||||
|
|
||||||
"github.com/pquerna/otp"
|
"github.com/pquerna/otp"
|
||||||
"github.com/pquerna/otp/totp"
|
"github.com/pquerna/otp/totp"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"github.com/smallstep/cli/errs"
|
"github.com/smallstep/cli/errs"
|
||||||
|
"github.com/smallstep/cli/flags"
|
||||||
"github.com/smallstep/cli/utils"
|
"github.com/smallstep/cli/utils"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@@ -16,7 +18,7 @@ import (
|
|||||||
func generateCommand() cli.Command {
|
func generateCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "generate",
|
Name: "generate",
|
||||||
Action: cli.ActionFunc(generateAction),
|
Action: command.ActionFunc(generateAction),
|
||||||
Usage: "one-time password",
|
Usage: "one-time password",
|
||||||
UsageText: `**step crypto otp generate**`,
|
UsageText: `**step crypto otp generate**`,
|
||||||
Description: `**step crypto otp generate** does TOTP and HTOP`,
|
Description: `**step crypto otp generate** does TOTP and HTOP`,
|
||||||
@@ -61,6 +63,7 @@ https://github.com/google/google-authenticator/wiki/Key-Uri-Format`,
|
|||||||
Name: "qr",
|
Name: "qr",
|
||||||
Usage: `Write a QR code to the specified path`,
|
Usage: `Write a QR code to the specified path`,
|
||||||
},
|
},
|
||||||
|
flags.Force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -300,7 +299,7 @@ func (p *PKI) Save() error {
|
|||||||
return errors.Wrapf(err, "error marshalling %s", p.config)
|
return errors.Wrapf(err, "error marshalling %s", p.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = ioutil.WriteFile(p.config, b, 0666); err != nil {
|
if err = utils.WriteFile(p.config, b, 0666); err != nil {
|
||||||
return errs.FileError(err, p.config)
|
return errs.FileError(err, p.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
205
flags/flags.go
205
flags/flags.go
@@ -1,206 +1,21 @@
|
|||||||
package flags
|
package flags
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OldPasswordFile returns a flag for receiving an old password
|
// Subtle is the flag required for delicate operations.
|
||||||
func OldPasswordFile(usage string) cli.Flag {
|
var Subtle = cli.BoolFlag{
|
||||||
if usage == "" {
|
Name: "subtle",
|
||||||
usage = "The path to the `FILE` containing the old encryption password"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cli.StringFlag{
|
// Insecure is the flag required on insecure operations
|
||||||
Name: "old-password-file, o",
|
var Insecure = cli.BoolFlag{
|
||||||
Usage: usage,
|
Name: "insecure",
|
||||||
EnvVar: "STEP_OLD_PASSWORD_FILE",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPasswordFile returns a flag for receiving a new password
|
// Force is a cli.Flag used to overwrite files.
|
||||||
func NewPasswordFile(usage string) cli.Flag {
|
var Force = cli.BoolFlag{
|
||||||
if usage == "" {
|
Name: "f,force",
|
||||||
usage = "The path to the `FILE` containing the new encryption password"
|
Usage: "Force the overwrite of files without asking.",
|
||||||
}
|
|
||||||
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "new-password-file, n",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_NEW_PASSWORD_FILE",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bits returns a flag for receiving the number of bits in generating a key
|
|
||||||
func Bits(usage string, value int) cli.Flag {
|
|
||||||
if usage == "" {
|
|
||||||
usage = "Number of bits used to generate the private key"
|
|
||||||
}
|
|
||||||
|
|
||||||
if value == 0 {
|
|
||||||
value = 256
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli.IntFlag{
|
|
||||||
Name: "bits, b",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_BITS",
|
|
||||||
Value: value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Action returns a flag for receiving an action out of several possibilities
|
|
||||||
func Action(usage string, possibilities []string, value string) cli.Flag {
|
|
||||||
usage = fmt.Sprintf("%s (Options: %s)", usage, strings.Join(possibilities, ", "))
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "action, a",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_ACTION",
|
|
||||||
Value: value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type returns a flag for receiving a type of thing to create out of several
|
|
||||||
// possibilties
|
|
||||||
func Type(usage string, possibilities []string, value string) cli.Flag {
|
|
||||||
usage = fmt.Sprintf("%s (Options: %s)", usage, strings.Join(possibilities, ", "))
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "type, t",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_TYPE",
|
|
||||||
Value: value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alg returns a flag for receiving the type of algorithm to use when performing an operation
|
|
||||||
func Alg(usage string, possibilities []string, value string) cli.Flag {
|
|
||||||
usage = fmt.Sprintf("%s (Options: %s)", usage, strings.Join(possibilities, ", "))
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "alg",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_ALG",
|
|
||||||
Value: value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RootCertificate returns a flag for specifying the path to a root certificate
|
|
||||||
func RootCertificate(usage string) cli.Flag {
|
|
||||||
if usage == "" {
|
|
||||||
usage = "The file `PATH` to the root certificate"
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "root, r",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_ROOT_CERTIFICATE",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PasswordFile returns a flag for specifying the path to a file containing a password
|
|
||||||
func PasswordFile(usage string) cli.Flag {
|
|
||||||
if usage == "" {
|
|
||||||
usage = "Path to file containing a password"
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "password-file, p",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_PASSWORD_FILE",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// OutputFile returns a flag for specifying the path inwhich to write output too
|
|
||||||
func OutputFile(usage string) cli.Flag {
|
|
||||||
if usage == "" {
|
|
||||||
usage = "Path to where the output should be written"
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "output-file, o",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_OUTPUT_FILE",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Number returns a flag for collecting the number of something to create
|
|
||||||
func Number(usage string) cli.Flag {
|
|
||||||
if usage == "" {
|
|
||||||
usage = "The `NUMBER` of entities to create"
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "number, n",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_NUMBER",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prefix returns a flag for prefixing to the name of an entity during creation
|
|
||||||
func Prefix(usage, value string) cli.Flag {
|
|
||||||
if usage == "" {
|
|
||||||
usage = "The `PREFIX` to apply to the names of all created entities"
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "prefix, p",
|
|
||||||
Usage: usage,
|
|
||||||
Value: value,
|
|
||||||
EnvVar: "STEP_PREFIX",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// OAuthProvider returns a flag for allowing the user to select an oauth provider
|
|
||||||
func OAuthProvider(usage string, providers []string, value string) cli.Flag {
|
|
||||||
usage = fmt.Sprintf("%s (Options: %s)", usage, strings.Join(providers, ", "))
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "provider, idp",
|
|
||||||
Usage: usage,
|
|
||||||
Value: value,
|
|
||||||
EnvVar: "STEP_PROVIDER",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Email returns a flag allowing the user to specify their email
|
|
||||||
func Email(usage string) cli.Flag {
|
|
||||||
if usage == "" {
|
|
||||||
usage = "Email to use"
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli.StringFlag{
|
|
||||||
Name: "email, e",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_EMAIL",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Console returns a flag allowing the user to specify whether or not they want
|
|
||||||
// to remain entirely in the console
|
|
||||||
func Console(usage string) cli.Flag {
|
|
||||||
if usage == "" {
|
|
||||||
usage = "Whether or not to remain entirely in the console to complete the action"
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli.BoolFlag{
|
|
||||||
Name: "console, c",
|
|
||||||
Usage: usage,
|
|
||||||
EnvVar: "STEP_CONSOLE",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limit returns a flag for limiting the results return by a command
|
|
||||||
func Limit(usage string, value int) cli.Flag {
|
|
||||||
if usage == "" {
|
|
||||||
usage = "The maximum `NUMBER` of results to return"
|
|
||||||
}
|
|
||||||
if value == 0 {
|
|
||||||
value = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli.IntFlag{
|
|
||||||
Name: "limit, l",
|
|
||||||
Usage: usage,
|
|
||||||
Value: value,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/cli/command"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,19 +22,12 @@ var (
|
|||||||
ErrIsDir = errors.New("file is a directory")
|
ErrIsDir = errors.New("file is a directory")
|
||||||
)
|
)
|
||||||
|
|
||||||
// WriteFile wraps ioutil.WriteFile with a prompt to overwrite a file if the
|
// WriteFile wraps ioutil.WriteFile with a prompt to overwrite a file if
|
||||||
// file exists. It returns ErrFileExists if the user picks to not overwrite
|
|
||||||
// the file.
|
|
||||||
func WriteFile(filename string, data []byte, perm os.FileMode) error {
|
|
||||||
return WriteFileForce(filename, data, perm, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteFileForce wraps ioutil.WriteFile with a prompt to overwrite a file if
|
|
||||||
// the file exists. It returns ErrFileExists if the user picks to not overwrite
|
// the file exists. It returns ErrFileExists if the user picks to not overwrite
|
||||||
// the file. If force is set to true, the prompt will not be presented and the
|
// the file. If force is set to true, the prompt will not be presented and the
|
||||||
// file if exists will be overwritten.
|
// file if exists will be overwritten.
|
||||||
func WriteFileForce(filename string, data []byte, perm os.FileMode, force bool) error {
|
func WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
if force {
|
if command.IsForce() {
|
||||||
return ioutil.WriteFile(filename, data, perm)
|
return ioutil.WriteFile(filename, data, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user