diff --git a/cmd/unicreds/main.go b/cmd/unicreds/main.go index 0f02ad0..7cb7349 100644 --- a/cmd/unicreds/main.go +++ b/cmd/unicreds/main.go @@ -29,18 +29,18 @@ var ( cmdList = app.Command("list", "List all credentials names and version.") - cmdPut = app.Command("put", "Put a credential in the store.") - cmdPutName = cmdPut.Arg("credential", "The name of the credential to get.").Required().String() + cmdPut = app.Command("put", "Put a credential into the store.") + cmdPutName = cmdPut.Arg("credential", "The name of the credential to store.").Required().String() cmdPutSecret = cmdPut.Arg("value", "The value of the credential to store.").Required().String() cmdPutVersion = cmdPut.Arg("version", "Version to store with the credential.").Int() - cmdPutFile = app.Command("put-file", "Put a credential in the store.") - cmdPutFileName = cmdPutFile.Arg("credential", "The name of the credential to get.").Required().String() + cmdPutFile = app.Command("put-file", "Put a credential from a file into the store.") + cmdPutFileName = cmdPutFile.Arg("credential", "The name of the credential to store.").Required().String() cmdPutFileSecretPath = cmdPutFile.Arg("value", "Path to file containing the credential to store.").Required().String() cmdPutFileVersion = cmdPutFile.Arg("version", "Version to store with the credential.").Int() cmdDelete = app.Command("delete", "Delete a credential from the store.") - cmdDeleteName = cmdDelete.Arg("credential", "The name of the credential to get.").Required().String() + cmdDeleteName = cmdDelete.Arg("credential", "The name of the credential to delete.").Required().String() // Version app version Version = "1.0.0" @@ -102,14 +102,14 @@ func main() { } table := unicreds.NewTable(os.Stdout) - table.SetHeaders([]string{"Name", "Version"}) + table.SetHeaders([]string{"Name", "Version", "Created-At"}) if *csv { table.SetFormat(unicreds.TableFormatCSV) } for _, cred := range creds { - table.Write([]string{cred.Name, cred.Version}) + table.Write([]string{cred.Name, cred.Version, cred.CreatedAtDate()}) } table.Render() case cmdGetAll.FullCommand(): diff --git a/ds.go b/ds.go index bb275d4..5606616 100644 --- a/ds.go +++ b/ds.go @@ -19,6 +19,10 @@ const ( // KmsKey default KMS key alias name KmsKey = "alias/credstash" + // CreatedAtNotAvailable returned to indicate the created at field is missing + // from the secret + CreatedAtNotAvailable = "Not Available" + tableCreateTimeout = 30 * time.Second ) @@ -46,11 +50,21 @@ func SetDynamoDBConfig(config *aws.Config) { // Credential managed credential information type Credential struct { - Name string `ds:"name"` - Version string `ds:"version"` - Key string `ds:"key"` - Contents string `ds:"contents"` - Hmac string `ds:"hmac"` + Name string `ds:"name"` + Version string `ds:"version"` + Key string `ds:"key"` + Contents string `ds:"contents"` + Hmac string `ds:"hmac"` + CreatedAt int64 `ds:"created_at"` +} + +// CreatedAtDate convert the timestamp field to a date string +func (c *Credential) CreatedAtDate() string { + if c.CreatedAt == 0 { + return CreatedAtNotAvailable + } + tm := time.Unix(c.CreatedAt, 0) + return tm.String() } // DecryptedCredential managed credential information @@ -150,6 +164,7 @@ func ListSecrets() ([]*DecryptedCredential, error) { aws.String("key"), aws.String("contents"), aws.String("hmac"), + aws.String("created_at"), }, ConsistentRead: aws.Bool(true), }) @@ -202,11 +217,12 @@ func PutSecret(name, secret, version string) error { b64ctext := base64.StdEncoding.EncodeToString(ctext) cred := &Credential{ - Name: name, - Version: version, - Key: base64.StdEncoding.EncodeToString(wrappedKey), - Contents: b64ctext, - Hmac: b64hmac, + Name: name, + Version: version, + Key: base64.StdEncoding.EncodeToString(wrappedKey), + Contents: b64ctext, + Hmac: b64hmac, + CreatedAt: time.Now().Unix(), } data, err := Encode(cred)