Normalize and elaborate on the command line help.

Ensures that the notary command line help text start with capital
letters, and add information about hardware keys and online/offline operation.

Signed-off-by: Ying Li <ying.li@docker.com>
Signed-off-by: David Lawrence <david.lawrence@docker.com>

Signed-off-by: Ying Li <ying.li@docker.com> (github: endophage)
This commit is contained in:
Ying Li 2015-11-07 22:41:47 -08:00 committed by David Lawrence
parent 313ae80345
commit 087f13ae7d
4 changed files with 82 additions and 80 deletions

View File

@ -25,13 +25,13 @@ func init() {
var cmdCert = &cobra.Command{ var cmdCert = &cobra.Command{
Use: "cert", Use: "cert",
Short: "Operates on certificates.", Short: "Operates on certificates.",
Long: `operations on certificates.`, Long: `Operations on certificates.`,
} }
var cmdCertList = &cobra.Command{ var cmdCertList = &cobra.Command{
Use: "list", Use: "list",
Short: "Lists certificates.", Short: "Lists certificates.",
Long: "lists root certificates known to notary.", Long: "Lists root certificates known to notary.",
Run: certList, Run: certList,
} }
@ -41,7 +41,7 @@ var certRemoveYes bool
var cmdCertRemove = &cobra.Command{ var cmdCertRemove = &cobra.Command{
Use: "remove [ certID ]", Use: "remove [ certID ]",
Short: "Removes the certificate with the given cert ID.", Short: "Removes the certificate with the given cert ID.",
Long: "remove the certificate with the given cert ID from the local host.", Long: "Remove the certificate with the given cert ID from the local host.",
Run: certRemove, Run: certRemove,
} }
@ -51,7 +51,7 @@ func certRemove(cmd *cobra.Command, args []string) {
// If the user provided -g and a cert ID, also show usage // If the user provided -g and a cert ID, also show usage
if (len(args) < 1 && certRemoveGUN == "") || (len(args) > 0 && certRemoveGUN != "") { if (len(args) < 1 && certRemoveGUN == "") || (len(args) > 0 && certRemoveGUN != "") {
cmd.Usage() cmd.Usage()
fatalf("must specify the cert ID or the GUN of the certificates to remove") fatalf("Must specify the cert ID or the GUN of the certificates to remove")
} }
parseConfig() parseConfig()
@ -59,11 +59,11 @@ func certRemove(cmd *cobra.Command, args []string) {
keysPath := filepath.Join(trustDir, notary.PrivDir) keysPath := filepath.Join(trustDir, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever)
if err != nil { if err != nil {
fatalf("failed to create private key store in directory: %s", keysPath) fatalf("Failed to create private key store in directory: %s", keysPath)
} }
keyStoreManager, err := keystoremanager.NewKeyStoreManager(trustDir, fileKeyStore) keyStoreManager, err := keystoremanager.NewKeyStoreManager(trustDir, fileKeyStore)
if err != nil { if err != nil {
fatalf("failed to create a new truststore manager with directory: %s", trustDir) fatalf("Failed to create a new truststore manager with directory: %s", trustDir)
} }
var certsToRemove []*x509.Certificate var certsToRemove []*x509.Certificate
@ -73,12 +73,12 @@ func certRemove(cmd *cobra.Command, args []string) {
certID := args[0] certID := args[0]
// This is an invalid ID // This is an invalid ID
if len(certID) != idSize { if len(certID) != idSize {
fatalf("invalid certificate ID provided: %s", certID) fatalf("Invalid certificate ID provided: %s", certID)
} }
// Attempt to find this certificates // Attempt to find this certificates
cert, err := keyStoreManager.TrustedCertificateStore().GetCertificateByCertID(certID) cert, err := keyStoreManager.TrustedCertificateStore().GetCertificateByCertID(certID)
if err != nil { if err != nil {
fatalf("unable to retrieve certificate with cert ID: %s", certID) fatalf("Unable to retrieve certificate with cert ID: %s", certID)
} }
certsToRemove = append(certsToRemove, cert) certsToRemove = append(certsToRemove, cert)
} else { } else {
@ -104,7 +104,7 @@ func certRemove(cmd *cobra.Command, args []string) {
if !certRemoveYes { if !certRemoveYes {
confirmed := askConfirm() confirmed := askConfirm()
if !confirmed { if !confirmed {
fatalf("aborting action.") fatalf("Aborting action.")
} }
} }
@ -112,7 +112,7 @@ func certRemove(cmd *cobra.Command, args []string) {
for _, cert := range certsToRemove { for _, cert := range certsToRemove {
err = keyStoreManager.TrustedCertificateStore().RemoveCert(cert) err = keyStoreManager.TrustedCertificateStore().RemoveCert(cert)
if err != nil { if err != nil {
fatalf("failed to remove root certificate for %s", cert.Subject.CommonName) fatalf("Failed to remove root certificate for %s", cert.Subject.CommonName)
} }
} }
} }
@ -128,11 +128,11 @@ func certList(cmd *cobra.Command, args []string) {
keysPath := filepath.Join(trustDir, notary.PrivDir) keysPath := filepath.Join(trustDir, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever)
if err != nil { if err != nil {
fatalf("failed to create private key store in directory: %s", keysPath) fatalf("Failed to create private key store in directory: %s", keysPath)
} }
keyStoreManager, err := keystoremanager.NewKeyStoreManager(trustDir, fileKeyStore) keyStoreManager, err := keystoremanager.NewKeyStoreManager(trustDir, fileKeyStore)
if err != nil { if err != nil {
fatalf("failed to create a new truststore manager with directory: %s", trustDir) fatalf("Failed to create a new truststore manager with directory: %s", trustDir)
} }
cmd.Println("") cmd.Println("")
@ -147,7 +147,7 @@ func printCert(cmd *cobra.Command, cert *x509.Certificate) {
timeDifference := cert.NotAfter.Sub(time.Now()) timeDifference := cert.NotAfter.Sub(time.Now())
certID, err := trustmanager.FingerprintCert(cert) certID, err := trustmanager.FingerprintCert(cert)
if err != nil { if err != nil {
fatalf("could not fingerprint certificate: %v", err) fatalf("Could not fingerprint certificate: %v", err)
} }
cmd.Printf("%s %s (expires in: %v days)\n", cert.Subject.CommonName, certID, math.Floor(timeDifference.Hours()/24)) cmd.Printf("%s %s (expires in: %v days)\n", cert.Subject.CommonName, certID, math.Floor(timeDifference.Hours()/24))

View File

@ -22,10 +22,10 @@ func init() {
cmdKey.AddCommand(cmdKeyList) cmdKey.AddCommand(cmdKeyList)
cmdKey.AddCommand(cmdKeyGenerateRootKey) cmdKey.AddCommand(cmdKeyGenerateRootKey)
cmdKeyExport.Flags().StringVarP(&keysExportGUN, "gun", "g", "", "Globally unique name to export keys for") cmdKeyExport.Flags().StringVarP(&keysExportGUN, "gun", "g", "", "Globally Unique Name to export keys for")
cmdKey.AddCommand(cmdKeyExport) cmdKey.AddCommand(cmdKeyExport)
cmdKey.AddCommand(cmdKeyExportRoot) cmdKey.AddCommand(cmdKeyExportRoot)
cmdKeyExportRoot.Flags().BoolVarP(&keysExportRootChangePassphrase, "change-passphrase", "p", false, "set a new passphrase for the key being exported") cmdKeyExportRoot.Flags().BoolVarP(&keysExportRootChangePassphrase, "change-passphrase", "p", false, "Set a new passphrase for the key being exported")
cmdKey.AddCommand(cmdKeyImport) cmdKey.AddCommand(cmdKeyImport)
cmdKey.AddCommand(cmdKeyImportRoot) cmdKey.AddCommand(cmdKeyImportRoot)
cmdKey.AddCommand(cmdRotateKey) cmdKey.AddCommand(cmdRotateKey)
@ -34,27 +34,27 @@ func init() {
var cmdKey = &cobra.Command{ var cmdKey = &cobra.Command{
Use: "key", Use: "key",
Short: "Operates on keys.", Short: "Operates on keys.",
Long: `operations on private keys.`, Long: `Operations on private keys.`,
} }
var cmdKeyList = &cobra.Command{ var cmdKeyList = &cobra.Command{
Use: "list", Use: "list",
Short: "Lists keys.", Short: "Lists keys.",
Long: "lists keys known to notary.", Long: "Lists all keys known to notary.",
Run: keysList, Run: keysList,
} }
var cmdRotateKey = &cobra.Command{ var cmdRotateKey = &cobra.Command{
Use: "rotate [ GUN ]", Use: "rotate [ GUN ]",
Short: "Rotate all keys for role.", Short: "Rotate all the signing (non-root) keys for the given Globally Unique Name.",
Long: "Removes all old keys for the given role and generates 1 new key.", Long: "Removes all old signing (non-root) keys for the given Globally Unique Name, and generates new ones. This only makes local changes - please use then `notary publish` to push the key rotation changes to the remote server.",
Run: keysRotate, Run: keysRotate,
} }
var cmdKeyGenerateRootKey = &cobra.Command{ var cmdKeyGenerateRootKey = &cobra.Command{
Use: "generate [ algorithm ]", Use: "generate [ algorithm ]",
Short: "Generates a new root key with a given algorithm.", Short: "Generates a new root key with a given algorithm.",
Long: "generates a new root key with a given algorithm.", Long: "Generates a new root key with a given algorithm. If a hardware smartcard is available, the key will be stored both on hardware and on disk. Please make sure to back up the key that is written to disk, and to then take the on-disk key offline.",
Run: keysGenerateRootKey, Run: keysGenerateRootKey,
} }
@ -63,7 +63,7 @@ var keysExportGUN string
var cmdKeyExport = &cobra.Command{ var cmdKeyExport = &cobra.Command{
Use: "export [ filename ]", Use: "export [ filename ]",
Short: "Exports keys to a ZIP file.", Short: "Exports keys to a ZIP file.",
Long: "exports a collection of keys. The keys are reencrypted with a new passphrase. The output is a ZIP file.", Long: "Exports a collection of keys. The keys are reencrypted with a new passphrase. The output is a ZIP file. If the --gun option is passed, only signing keys and no root keys will be exported. Does not work on keys that are only in hardware (smartcards).",
Run: keysExport, Run: keysExport,
} }
@ -72,21 +72,21 @@ var keysExportRootChangePassphrase bool
var cmdKeyExportRoot = &cobra.Command{ var cmdKeyExportRoot = &cobra.Command{
Use: "export-root [ keyID ] [ filename ]", Use: "export-root [ keyID ] [ filename ]",
Short: "Exports given root key to a file.", Short: "Exports given root key to a file.",
Long: "exports a root key, without reencrypting. The output is a PEM file.", Long: "Exports a root key, without reencrypting. The output is a PEM file. Does not work on keys that are only in hardware (smartcards).",
Run: keysExportRoot, Run: keysExportRoot,
} }
var cmdKeyImport = &cobra.Command{ var cmdKeyImport = &cobra.Command{
Use: "import [ filename ]", Use: "import [ filename ]",
Short: "Imports keys from a ZIP file.", Short: "Imports keys from a ZIP file.",
Long: "imports one or more keys from a ZIP file.", Long: "Imports one or more keys from a ZIP file. If a hardware smartcard is available, the root key will be imported into the smartcard but not to disk.",
Run: keysImport, Run: keysImport,
} }
var cmdKeyImportRoot = &cobra.Command{ var cmdKeyImportRoot = &cobra.Command{
Use: "import-root [ filename ]", Use: "import-root [ filename ]",
Short: "Imports root key.", Short: "Imports root key.",
Long: "imports a root key from a PEM file.", Long: "Imports a root key from a PEM file. If a hardware smartcard is available, the root key will be imported into the smartcard but not to disk.",
Run: keysImportRoot, Run: keysImportRoot,
} }
@ -101,7 +101,7 @@ func keysList(cmd *cobra.Command, args []string) {
keysPath := filepath.Join(trustDir, notary.PrivDir) keysPath := filepath.Join(trustDir, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever)
if err != nil { if err != nil {
fatalf("failed to create private key store in directory: %s", keysPath) fatalf("Failed to create private key store in directory: %s", keysPath)
} }
yubiStore, _ := api.NewYubiKeyStore(fileKeyStore, retriever) yubiStore, _ := api.NewYubiKeyStore(fileKeyStore, retriever)
var cs signed.CryptoService var cs signed.CryptoService
@ -144,7 +144,7 @@ func keysList(cmd *cobra.Command, args []string) {
func keysGenerateRootKey(cmd *cobra.Command, args []string) { func keysGenerateRootKey(cmd *cobra.Command, args []string) {
if len(args) < 1 { if len(args) < 1 {
cmd.Usage() cmd.Usage()
fatalf("must specify an Algorithm (RSA, ECDSA)") fatalf("Must specify an Algorithm (RSA, ECDSA)")
} }
algorithm := args[0] algorithm := args[0]
@ -154,7 +154,7 @@ func keysGenerateRootKey(cmd *cobra.Command, args []string) {
} }
if !allowedCiphers[strings.ToLower(algorithm)] { if !allowedCiphers[strings.ToLower(algorithm)] {
fatalf("algorithm not allowed, possible values are: RSA, ECDSA") fatalf("Algorithm not allowed, possible values are: RSA, ECDSA")
} }
parseConfig() parseConfig()
@ -162,7 +162,7 @@ func keysGenerateRootKey(cmd *cobra.Command, args []string) {
keysPath := filepath.Join(trustDir, notary.PrivDir) keysPath := filepath.Join(trustDir, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever)
if err != nil { if err != nil {
fatalf("failed to create private key store in directory: %s", keysPath) fatalf("Failed to create private key store in directory: %s", keysPath)
} }
yubiStore, err := api.NewYubiKeyStore(fileKeyStore, retriever) yubiStore, err := api.NewYubiKeyStore(fileKeyStore, retriever)
var cs signed.CryptoService var cs signed.CryptoService
@ -175,7 +175,7 @@ func keysGenerateRootKey(cmd *cobra.Command, args []string) {
pubKey, err := cs.Create(data.CanonicalRootRole, algorithm) pubKey, err := cs.Create(data.CanonicalRootRole, algorithm)
if err != nil { if err != nil {
fatalf("failed to create a new root key: %v", err) fatalf("Failed to create a new root key: %v", err)
} }
cmd.Printf("Generated new %s root key with keyID: %s\n", algorithm, pubKey.ID()) cmd.Printf("Generated new %s root key with keyID: %s\n", algorithm, pubKey.ID())
@ -185,7 +185,7 @@ func keysGenerateRootKey(cmd *cobra.Command, args []string) {
func keysExport(cmd *cobra.Command, args []string) { func keysExport(cmd *cobra.Command, args []string) {
if len(args) < 1 { if len(args) < 1 {
cmd.Usage() cmd.Usage()
fatalf("must specify output filename for export") fatalf("Must specify output filename for export")
} }
exportFilename := args[0] exportFilename := args[0]
@ -195,13 +195,13 @@ func keysExport(cmd *cobra.Command, args []string) {
keysPath := filepath.Join(trustDir, notary.PrivDir) keysPath := filepath.Join(trustDir, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever)
if err != nil { if err != nil {
fatalf("failed to create private key store in directory: %s", keysPath) fatalf("Failed to create private key store in directory: %s", keysPath)
} }
cs := cryptoservice.NewCryptoService("", fileKeyStore) cs := cryptoservice.NewCryptoService("", fileKeyStore)
exportFile, err := os.Create(exportFilename) exportFile, err := os.Create(exportFilename)
if err != nil { if err != nil {
fatalf("error creating output file: %v", err) fatalf("Error creating output file: %v", err)
} }
// Must use a different passphrase retriever to avoid caching the // Must use a different passphrase retriever to avoid caching the
@ -217,7 +217,7 @@ func keysExport(cmd *cobra.Command, args []string) {
if err != nil { if err != nil {
os.Remove(exportFilename) os.Remove(exportFilename)
fatalf("error exporting keys: %v", err) fatalf("Error exporting keys: %v", err)
} }
} }
@ -225,14 +225,14 @@ func keysExport(cmd *cobra.Command, args []string) {
func keysExportRoot(cmd *cobra.Command, args []string) { func keysExportRoot(cmd *cobra.Command, args []string) {
if len(args) < 2 { if len(args) < 2 {
cmd.Usage() cmd.Usage()
fatalf("must specify key ID and output filename for export") fatalf("Must specify key ID and output filename for export")
} }
keyID := args[0] keyID := args[0]
exportFilename := args[1] exportFilename := args[1]
if len(keyID) != idSize { if len(keyID) != idSize {
fatalf("please specify a valid root key ID") fatalf("Please specify a valid root key ID")
} }
parseConfig() parseConfig()
@ -240,13 +240,13 @@ func keysExportRoot(cmd *cobra.Command, args []string) {
keysPath := filepath.Join(trustDir, notary.PrivDir) keysPath := filepath.Join(trustDir, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever)
if err != nil { if err != nil {
fatalf("failed to create private key store in directory: %s", keysPath) fatalf("Failed to create private key store in directory: %s", keysPath)
} }
cs := cryptoservice.NewCryptoService("", fileKeyStore) cs := cryptoservice.NewCryptoService("", fileKeyStore)
exportFile, err := os.Create(exportFilename) exportFile, err := os.Create(exportFilename)
if err != nil { if err != nil {
fatalf("error creating output file: %v", err) fatalf("Error creating output file: %v", err)
} }
if keysExportRootChangePassphrase { if keysExportRootChangePassphrase {
// Must use a different passphrase retriever to avoid caching the // Must use a different passphrase retriever to avoid caching the
@ -259,7 +259,7 @@ func keysExportRoot(cmd *cobra.Command, args []string) {
exportFile.Close() exportFile.Close()
if err != nil { if err != nil {
os.Remove(exportFilename) os.Remove(exportFilename)
fatalf("error exporting root key: %v", err) fatalf("Error exporting root key: %v", err)
} }
} }
@ -267,7 +267,7 @@ func keysExportRoot(cmd *cobra.Command, args []string) {
func keysImport(cmd *cobra.Command, args []string) { func keysImport(cmd *cobra.Command, args []string) {
if len(args) < 1 { if len(args) < 1 {
cmd.Usage() cmd.Usage()
fatalf("must specify input filename for import") fatalf("Must specify input filename for import")
} }
importFilename := args[0] importFilename := args[0]
@ -277,20 +277,20 @@ func keysImport(cmd *cobra.Command, args []string) {
keysPath := filepath.Join(trustDir, notary.PrivDir) keysPath := filepath.Join(trustDir, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever)
if err != nil { if err != nil {
fatalf("failed to create private key store in directory: %s", keysPath) fatalf("Failed to create private key store in directory: %s", keysPath)
} }
cs := cryptoservice.NewCryptoService("", fileKeyStore) cs := cryptoservice.NewCryptoService("", fileKeyStore)
zipReader, err := zip.OpenReader(importFilename) zipReader, err := zip.OpenReader(importFilename)
if err != nil { if err != nil {
fatalf("opening file for import: %v", err) fatalf("Opening file for import: %v", err)
} }
defer zipReader.Close() defer zipReader.Close()
err = cs.ImportKeysZip(zipReader.Reader) err = cs.ImportKeysZip(zipReader.Reader)
if err != nil { if err != nil {
fatalf("error importing keys: %v", err) fatalf("Error importing keys: %v", err)
} }
} }
@ -298,7 +298,7 @@ func keysImport(cmd *cobra.Command, args []string) {
func keysImportRoot(cmd *cobra.Command, args []string) { func keysImportRoot(cmd *cobra.Command, args []string) {
if len(args) != 1 { if len(args) != 1 {
cmd.Usage() cmd.Usage()
fatalf("must specify input filename for import") fatalf("Must specify input filename for import")
} }
importFilename := args[0] importFilename := args[0]
@ -308,7 +308,7 @@ func keysImportRoot(cmd *cobra.Command, args []string) {
keysPath := filepath.Join(trustDir, notary.PrivDir) keysPath := filepath.Join(trustDir, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever)
if err != nil { if err != nil {
fatalf("failed to create private key store in directory: %s", keysPath) fatalf("Failed to create private key store in directory: %s", keysPath)
} }
yubiStore, err := api.NewYubiKeyStore(fileKeyStore, retriever) yubiStore, err := api.NewYubiKeyStore(fileKeyStore, retriever)
var cs signed.CryptoService var cs signed.CryptoService
@ -321,14 +321,14 @@ func keysImportRoot(cmd *cobra.Command, args []string) {
importFile, err := os.Open(importFilename) importFile, err := os.Open(importFilename)
if err != nil { if err != nil {
fatalf("opening file for import: %v", err) fatalf("Opening file for import: %v", err)
} }
defer importFile.Close() defer importFile.Close()
err = cs.ImportRootKey(importFile) err = cs.ImportRootKey(importFile)
if err != nil { if err != nil {
fatalf("error importing root key: %v", err) fatalf("Error importing root key: %v", err)
} }
} }
@ -341,7 +341,7 @@ func printKey(cmd *cobra.Command, keyPath, alias string) {
func keysRotate(cmd *cobra.Command, args []string) { func keysRotate(cmd *cobra.Command, args []string) {
if len(args) < 1 { if len(args) < 1 {
cmd.Usage() cmd.Usage()
fatalf("must specify a GUN and target") fatalf("Must specify a GUN and target")
} }
parseConfig() parseConfig()

View File

@ -47,10 +47,10 @@ func parseConfig() {
// Get home directory for current user // Get home directory for current user
homeDir, err := homedir.Dir() homeDir, err := homedir.Dir()
if err != nil { if err != nil {
fatalf("cannot get current user home directory: %v", err) fatalf("Cannot get current user home directory: %v", err)
} }
if homeDir == "" { if homeDir == "" {
fatalf("cannot get current user home directory") fatalf("Cannot get current user home directory")
} }
trustDir = filepath.Join(homeDir, filepath.Dir(configDir)) trustDir = filepath.Join(homeDir, filepath.Dir(configDir))
@ -80,7 +80,7 @@ func parseConfig() {
logrus.Debugf("configuration file not found, using defaults") logrus.Debugf("configuration file not found, using defaults")
// Ignore if the configuration file doesn't exist, we can use the defaults // Ignore if the configuration file doesn't exist, we can use the defaults
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
fatalf("fatal error config file: %v", err) fatalf("Fatal error config file: %v", err)
} }
} }
} }
@ -97,9 +97,9 @@ func setupCommand(notaryCmd *cobra.Command) {
notaryCmd.AddCommand(versionCmd) notaryCmd.AddCommand(versionCmd)
notaryCmd.PersistentFlags().StringVarP(&trustDir, "trustdir", "d", "", "directory where the trust data is persisted to") notaryCmd.PersistentFlags().StringVarP(&trustDir, "trustdir", "d", "", "Directory where the trust data is persisted to")
notaryCmd.PersistentFlags().StringVarP(&configFile, "configFile", "c", "", "path to the configuration file to use") notaryCmd.PersistentFlags().StringVarP(&configFile, "configFile", "c", "", "Path to the configuration file to use")
notaryCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output") notaryCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Verbose output")
notaryCmd.PersistentFlags().StringVarP(&remoteTrustServer, "server", "s", "", "Remote trust server location") notaryCmd.PersistentFlags().StringVarP(&remoteTrustServer, "server", "s", "", "Remote trust server location")
notaryCmd.AddCommand(cmdKey) notaryCmd.AddCommand(cmdKey)
@ -117,8 +117,8 @@ func setupCommand(notaryCmd *cobra.Command) {
func main() { func main() {
var notaryCmd = &cobra.Command{ var notaryCmd = &cobra.Command{
Use: "notary", Use: "notary",
Short: "notary allows the creation of trusted collections.", Short: "Notary allows the creation of trusted collections.",
Long: "notary allows the creation and management of collections of signed targets, allowing the signing and validation of arbitrary content.", Long: "Notary allows the creation and management of collections of signed targets, allowing the signing and validation of arbitrary content.",
} }
setupCommand(notaryCmd) setupCommand(notaryCmd)
notaryCmd.Execute() notaryCmd.Execute()

View File

@ -27,64 +27,64 @@ import (
var cmdTufList = &cobra.Command{ var cmdTufList = &cobra.Command{
Use: "list [ GUN ]", Use: "list [ GUN ]",
Short: "Lists targets for a trusted collection.", Short: "Lists targets for a remote trusted collection.",
Long: "Lists all targets for a trusted collection identified by the Globally Unique Name.", Long: "Lists all targets for a remote trusted collection identified by the Globally Unique Name. This is an online operation.",
Run: tufList, Run: tufList,
} }
var cmdTufAdd = &cobra.Command{ var cmdTufAdd = &cobra.Command{
Use: "add [ GUN ] <target> <file>", Use: "add [ GUN ] <target> <file>",
Short: "adds the file as a target to the trusted collection.", Short: "Adds the file as a target to the trusted collection.",
Long: "adds the file as a target to the local trusted collection identified by the Globally Unique Name.", Long: "Adds the file as a target to the local trusted collection identified by the Globally Unique Name. This is an offline operation. Please then use `publish` to push the changes to the remote trusted collection.",
Run: tufAdd, Run: tufAdd,
} }
var cmdTufRemove = &cobra.Command{ var cmdTufRemove = &cobra.Command{
Use: "remove [ GUN ] <target>", Use: "remove [ GUN ] <target>",
Short: "Removes a target from a trusted collection.", Short: "Removes a target from a trusted collection.",
Long: "removes a target from the local trusted collection identified by the Globally Unique Name.", Long: "Removes a target from the local trusted collection identified by the Globally Unique Name. This is an offline operation. Please then use `publish` to push the changes to the remote trusted collection.",
Run: tufRemove, Run: tufRemove,
} }
var cmdTufInit = &cobra.Command{ var cmdTufInit = &cobra.Command{
Use: "init [ GUN ]", Use: "init [ GUN ]",
Short: "initializes a local trusted collection.", Short: "Initializes a local trusted collection.",
Long: "initializes a local trusted collection identified by the Globally Unique Name.", Long: "Initializes a local trusted collection identified by the Globally Unique Name. This is an online operation.",
Run: tufInit, Run: tufInit,
} }
var cmdTufLookup = &cobra.Command{ var cmdTufLookup = &cobra.Command{
Use: "lookup [ GUN ] <target>", Use: "lookup [ GUN ] <target>",
Short: "Looks up a specific target in a trusted collection.", Short: "Looks up a specific target in a remote trusted collection.",
Long: "looks up a specific target in a trusted collection identified by the Globally Unique Name.", Long: "Looks up a specific target in a remote trusted collection identified by the Globally Unique Name.",
Run: tufLookup, Run: tufLookup,
} }
var cmdTufPublish = &cobra.Command{ var cmdTufPublish = &cobra.Command{
Use: "publish [ GUN ]", Use: "publish [ GUN ]",
Short: "publishes the local trusted collection.", Short: "Publishes the local trusted collection.",
Long: "publishes the local trusted collection identified by the Globally Unique Name, sending the local changes to a remote trusted server.", Long: "Publishes the local trusted collection identified by the Globally Unique Name, sending the local changes to a remote trusted server.",
Run: tufPublish, Run: tufPublish,
} }
var cmdTufStatus = &cobra.Command{ var cmdTufStatus = &cobra.Command{
Use: "status [ GUN ]", Use: "status [ GUN ]",
Short: "displays status of unpublished changes to the local trusted collection.", Short: "Displays status of unpublished changes to the local trusted collection.",
Long: "displays status of unpublished changes to the local trusted collection identified by the Globally Unique Name.", Long: "Displays status of unpublished changes to the local trusted collection identified by the Globally Unique Name.",
Run: tufStatus, Run: tufStatus,
} }
var cmdVerify = &cobra.Command{ var cmdVerify = &cobra.Command{
Use: "verify [ GUN ] <target>", Use: "verify [ GUN ] <target>",
Short: "verifies if the content is included in the trusted collection", Short: "Verifies if the content is included in the remote trusted collection",
Long: "verifies if the data passed in STDIN is included in the trusted collection identified by the Global Unique Name.", Long: "Verifies if the data passed in STDIN is included in the remote trusted collection identified by the Global Unique Name.",
Run: verify, Run: verify,
} }
func tufAdd(cmd *cobra.Command, args []string) { func tufAdd(cmd *cobra.Command, args []string) {
if len(args) < 3 { if len(args) < 3 {
cmd.Usage() cmd.Usage()
fatalf("must specify a GUN, target, and path to target data") fatalf("Must specify a GUN, target, and path to target data")
} }
gun := args[0] gun := args[0]
@ -107,7 +107,9 @@ func tufAdd(cmd *cobra.Command, args []string) {
if err != nil { if err != nil {
fatalf(err.Error()) fatalf(err.Error())
} }
cmd.Printf("Addition of %s to %s staged for next publish.\n", targetName, gun) cmd.Printf(
"Addition of target \"%s\" to repository \"%s\" staged for next publish.\n",
targetName, gun)
} }
func tufInit(cmd *cobra.Command, args []string) { func tufInit(cmd *cobra.Command, args []string) {
@ -150,7 +152,7 @@ func tufInit(cmd *cobra.Command, args []string) {
func tufList(cmd *cobra.Command, args []string) { func tufList(cmd *cobra.Command, args []string) {
if len(args) < 1 { if len(args) < 1 {
cmd.Usage() cmd.Usage()
fatalf("must specify a GUN") fatalf("Must specify a GUN")
} }
gun := args[0] gun := args[0]
parseConfig() parseConfig()
@ -175,7 +177,7 @@ func tufList(cmd *cobra.Command, args []string) {
func tufLookup(cmd *cobra.Command, args []string) { func tufLookup(cmd *cobra.Command, args []string) {
if len(args) < 2 { if len(args) < 2 {
cmd.Usage() cmd.Usage()
fatalf("must specify a GUN and target") fatalf("Must specify a GUN and target")
} }
gun := args[0] gun := args[0]
targetName := args[1] targetName := args[1]
@ -251,7 +253,7 @@ func tufPublish(cmd *cobra.Command, args []string) {
func tufRemove(cmd *cobra.Command, args []string) { func tufRemove(cmd *cobra.Command, args []string) {
if len(args) < 2 { if len(args) < 2 {
cmd.Usage() cmd.Usage()
fatalf("must specify a GUN and target") fatalf("Must specify a GUN and target")
} }
gun := args[0] gun := args[0]
targetName := args[1] targetName := args[1]
@ -274,14 +276,14 @@ func tufRemove(cmd *cobra.Command, args []string) {
func verify(cmd *cobra.Command, args []string) { func verify(cmd *cobra.Command, args []string) {
if len(args) < 2 { if len(args) < 2 {
cmd.Usage() cmd.Usage()
fatalf("must specify a GUN and target") fatalf("Must specify a GUN and target")
} }
parseConfig() parseConfig()
// Reads all of the data on STDIN // Reads all of the data on STDIN
payload, err := ioutil.ReadAll(os.Stdin) payload, err := ioutil.ReadAll(os.Stdin)
if err != nil { if err != nil {
fatalf("error reading content from STDIN: %v", err) fatalf("Error reading content from STDIN: %v", err)
} }
gun := args[0] gun := args[0]
@ -399,14 +401,14 @@ func tokenAuth(baseTransport *http.Transport, gun string, readOnly bool) http.Ro
trustServerURL := getRemoteTrustServer() trustServerURL := getRemoteTrustServer()
endpoint, err := url.Parse(trustServerURL) endpoint, err := url.Parse(trustServerURL)
if err != nil { if err != nil {
fatalf("could not parse remote trust server url (%s): %s", trustServerURL, err.Error()) fatalf("Could not parse remote trust server url (%s): %s", trustServerURL, err.Error())
} }
if endpoint.Scheme == "" { if endpoint.Scheme == "" {
fatalf("trust server url has to be in the form of http(s)://URL:PORT. Got: %s", trustServerURL) fatalf("Trust server url has to be in the form of http(s)://URL:PORT. Got: %s", trustServerURL)
} }
subPath, err := url.Parse("v2/") subPath, err := url.Parse("v2/")
if err != nil { if err != nil {
fatalf("failed to parse v2 subpath. This error should not have been reached. Please report it as an issue at https://github.com/docker/notary/issues: %s", err.Error()) fatalf("Failed to parse v2 subpath. This error should not have been reached. Please report it as an issue at https://github.com/docker/notary/issues: %s", err.Error())
} }
endpoint = endpoint.ResolveReference(subPath) endpoint = endpoint.ResolveReference(subPath)
req, err := http.NewRequest("GET", endpoint.String(), nil) req, err := http.NewRequest("GET", endpoint.String(), nil)