Skip to content

Commit

Permalink
Merge pull request #457 from DopplerHQ/andre/value-types
Browse files Browse the repository at this point in the history
Add support for value types
  • Loading branch information
apazzolini committed May 29, 2024
2 parents 6d63650 + 27a0a8f commit 4e54853
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 29 deletions.
4 changes: 2 additions & 2 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ brews:
commit_author:
name: "Doppler Bot"
email: bot@doppler.com
folder: Formula
directory: Formula
homepage: "https://doppler.com"
description: "The official Doppler CLI for managing your secrets"
install: |-
Expand Down Expand Up @@ -216,4 +216,4 @@ blobs:
-
provider: gs
bucket: dopplerhq_cli_releases
folder: "{{ .Tag }}"
directory: "{{ .Tag }}"
2 changes: 2 additions & 0 deletions pkg/cmd/enclave_secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ func init() {
}
enclaveSecretsCmd.Flags().Bool("raw", false, "print the raw secret value without processing variables")
enclaveSecretsCmd.Flags().Bool("visibility", false, "include secret visibility in table output")
enclaveSecretsCmd.Flags().Bool("type", false, "include secret type in table output")
enclaveSecretsCmd.Flags().Bool("only-names", false, "only print the secret names; omit all values")

enclaveSecretsGetCmd.Flags().StringP("project", "p", "", "enclave project (e.g. backend)")
Expand All @@ -119,6 +120,7 @@ func init() {
enclaveSecretsGetCmd.Flags().Bool("copy", false, "copy the value(s) to your clipboard")
enclaveSecretsGetCmd.Flags().Bool("raw", false, "print the raw secret value without processing variables")
enclaveSecretsGetCmd.Flags().Bool("visibility", false, "include secret visibility in table output")
enclaveSecretsGetCmd.Flags().Bool("type", false, "include secret type in table output")
enclaveSecretsGetCmd.Flags().Bool("no-exit-on-missing-secret", false, "do not exit if unable to find a requested secret")
enclaveSecretsCmd.AddCommand(enclaveSecretsGetCmd)

Expand Down
34 changes: 28 additions & 6 deletions pkg/cmd/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ func secrets(cmd *cobra.Command, args []string) {
jsonFlag := utils.OutputJSON
raw := utils.GetBoolFlag(cmd, "raw")
visibility := utils.GetBoolFlag(cmd, "visibility")
valueType := utils.GetBoolFlag(cmd, "type")
onlyNames := utils.GetBoolFlag(cmd, "only-names")
localConfig := configuration.LocalConfig(cmd)

Expand All @@ -182,7 +183,7 @@ func secrets(cmd *cobra.Command, args []string) {
utils.HandleError(parseErr, "Unable to parse API response")
}

printer.Secrets(secrets, []string{}, jsonFlag, false, raw, false, visibility)
printer.Secrets(secrets, []string{}, jsonFlag, false, raw, false, visibility, valueType)
}
}

Expand All @@ -192,6 +193,7 @@ func getSecrets(cmd *cobra.Command, args []string) {
copy := utils.GetBoolFlag(cmd, "copy")
raw := utils.GetBoolFlag(cmd, "raw")
visibility := utils.GetBoolFlag(cmd, "visibility")
valueType := utils.GetBoolFlag(cmd, "type")
exitOnMissingSecret := !utils.GetBoolFlag(cmd, "no-exit-on-missing-secret")
localConfig := configuration.LocalConfig(cmd)

Expand Down Expand Up @@ -228,7 +230,7 @@ func getSecrets(cmd *cobra.Command, args []string) {
}
}

printer.Secrets(secrets, args, jsonFlag, plain, raw, copy, visibility)
printer.Secrets(secrets, args, jsonFlag, plain, raw, copy, visibility, valueType)
}

func setSecrets(cmd *cobra.Command, args []string) {
Expand All @@ -238,6 +240,8 @@ func setSecrets(cmd *cobra.Command, args []string) {
localConfig := configuration.LocalConfig(cmd)
visibility := cmd.Flag("visibility").Value.String()
visibilityModified := visibility != ""
valueType := cmd.Flag("type").Value.String()
valueTypeModified := valueType != ""

utils.RequireValue("token", localConfig.Token.Value)

Expand Down Expand Up @@ -318,6 +322,11 @@ func setSecrets(cmd *cobra.Command, args []string) {
if visibilityModified {
changeRequest.Visibility = &visibility
}
if valueTypeModified {
changeRequest.ValueType = &models.SecretValueType{
Type: valueType,
}
}
changeRequests = append(changeRequests, changeRequest)
} else if len(args) == 2 && !strings.Contains(args[0], "=") {
// format: 'doppler secrets set KEY value'
Expand All @@ -331,6 +340,11 @@ func setSecrets(cmd *cobra.Command, args []string) {
if visibilityModified {
changeRequest.Visibility = &visibility
}
if valueTypeModified {
changeRequest.ValueType = &models.SecretValueType{
Type: valueType,
}
}
changeRequests = append(changeRequests, changeRequest)
} else {
// format: 'doppler secrets set KEY=value'
Expand All @@ -351,6 +365,11 @@ func setSecrets(cmd *cobra.Command, args []string) {
if visibilityModified {
changeRequest.Visibility = &visibility
}
if valueTypeModified {
changeRequest.ValueType = &models.SecretValueType{
Type: valueType,
}
}
changeRequests = append(changeRequests, changeRequest)
}
}
Expand All @@ -361,7 +380,7 @@ func setSecrets(cmd *cobra.Command, args []string) {
}

if !utils.Silent {
printer.Secrets(response, keys, jsonFlag, false, raw, false, visibilityModified)
printer.Secrets(response, keys, jsonFlag, false, raw, false, visibilityModified, valueTypeModified)
}
}

Expand Down Expand Up @@ -393,7 +412,7 @@ func uploadSecrets(cmd *cobra.Command, args []string) {
}

if !utils.Silent {
printer.Secrets(response, []string{}, jsonFlag, false, raw, false, false)
printer.Secrets(response, []string{}, jsonFlag, false, raw, false, false, false)
}
}

Expand All @@ -417,7 +436,7 @@ func deleteSecrets(cmd *cobra.Command, args []string) {
}

if !utils.Silent {
printer.Secrets(response, []string{}, jsonFlag, false, raw, false, false)
printer.Secrets(response, []string{}, jsonFlag, false, raw, false, false, false)
}
}
}
Expand Down Expand Up @@ -627,6 +646,7 @@ func init() {
}
secretsCmd.Flags().Bool("raw", false, "print the raw secret value without processing variables")
secretsCmd.Flags().Bool("visibility", false, "include secret visibility in table output")
secretsCmd.Flags().Bool("type", false, "include secret type in table output")
secretsCmd.Flags().Bool("only-names", false, "only print the secret names; omit all values")

secretsGetCmd.Flags().StringP("project", "p", "", "project (e.g. backend)")
Expand All @@ -641,6 +661,7 @@ func init() {
secretsGetCmd.Flags().Bool("copy", false, "copy the value(s) to your clipboard")
secretsGetCmd.Flags().Bool("raw", false, "print the raw secret value without processing variables")
secretsGetCmd.Flags().Bool("visibility", false, "include secret visibility in table output")
secretsGetCmd.Flags().Bool("type", false, "include secret type in table output")
secretsGetCmd.Flags().Bool("no-exit-on-missing-secret", false, "do not exit if unable to find a requested secret")
secretsCmd.AddCommand(secretsGetCmd)

Expand All @@ -654,7 +675,8 @@ func init() {
}
secretsSetCmd.Flags().Bool("raw", false, "print the raw secret value without processing variables")
secretsSetCmd.Flags().Bool("no-interactive", false, "do not allow entering secret value via interactive mode")
secretsSetCmd.Flags().StringP("visibility", "", "", "visibility (e.g. masked, unmasked, or restricted)")
secretsSetCmd.Flags().String("visibility", "", "visibility (e.g. masked, unmasked, or restricted)")
secretsSetCmd.Flags().String("type", "", "value type (e.g. string, decimal, etc)")
secretsCmd.AddCommand(secretsSetCmd)

secretsUploadCmd.Flags().StringP("project", "p", "", "project (e.g. backend)")
Expand Down
50 changes: 30 additions & 20 deletions pkg/models/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,35 @@ limitations under the License.
*/
package models

type SecretValueType struct {
Type string `json:"type"`
}

// ComputedSecret holds all info about a secret
type ComputedSecret struct {
Name string `json:"name"`
RawValue *string `json:"raw"`
ComputedValue *string `json:"computed"`
RawVisibility string `json:"rawVisibility"`
ComputedVisibility string `json:"computedVisibility"`
Note string `json:"note"`
Name string `json:"name"`
RawValue *string `json:"raw"`
ComputedValue *string `json:"computed"`
RawVisibility string `json:"rawVisibility"`
ComputedVisibility string `json:"computedVisibility"`
RawValueType SecretValueType `json:"rawValueType"`
ComputedValueType SecretValueType `json:"computedValueType"`
Note string `json:"note"`
}

// ChangeRequest can be used to smartly update secrets
type ChangeRequest struct {
Name string `json:"name"`
OriginalName interface{} `json:"originalName"`
Value interface{} `json:"value"`
OriginalValue interface{} `json:"originalValue,omitempty"`
Visibility *string `json:"visibility,omitempty"`
OriginalVisibility *string `json:"originalVisibility,omitempty"`
ShouldPromote *bool `json:"shouldPromote,omitempty"`
ShouldDelete *bool `json:"shouldDelete,omitempty"`
ShouldConverge *bool `json:"shouldConverge,omitempty"`
Name string `json:"name"`
OriginalName interface{} `json:"originalName"`
Value interface{} `json:"value"`
OriginalValue interface{} `json:"originalValue,omitempty"`
Visibility *string `json:"visibility,omitempty"`
OriginalVisibility *string `json:"originalVisibility,omitempty"`
ValueType *SecretValueType `json:"valueType,omitempty"`
OriginalValueType *SecretValueType `json:"originalValueType,omitempty"`
ShouldPromote *bool `json:"shouldPromote,omitempty"`
ShouldDelete *bool `json:"shouldDelete,omitempty"`
ShouldConverge *bool `json:"shouldConverge,omitempty"`
}

// SecretNote contains a secret and its note
Expand Down Expand Up @@ -141,11 +149,13 @@ type APISecretResponse struct {

// APISecret is the object the API returns for a given secret
type APISecret struct {
RawValue *string `json:"raw"`
ComputedValue *string `json:"computed"`
RawVisibility string `json:"rawVisibility"`
ComputedVisibility string `json:"computedVisibility"`
Note string `json:"note"`
RawValue *string `json:"raw"`
ComputedValue *string `json:"computed"`
RawVisibility string `json:"rawVisibility"`
ComputedVisibility string `json:"computedVisibility"`
RawValueType SecretValueType `json:"rawValueType"`
ComputedValueType SecretValueType `json:"computedValueType"`
Note string `json:"note"`
}

type ActorInfo struct {
Expand Down
2 changes: 2 additions & 0 deletions pkg/models/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ func ConvertAPIToComputedSecrets(apiSecrets map[string]APISecret) map[string]Com
ComputedValue: secret.ComputedValue,
RawVisibility: secret.RawVisibility,
ComputedVisibility: secret.ComputedVisibility,
RawValueType: secret.RawValueType,
ComputedValueType: secret.ComputedValueType,
Note: secret.Note,
}
}
Expand Down
16 changes: 15 additions & 1 deletion pkg/printer/enclave.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func ProjectInfo(info models.ProjectInfo, jsonFlag bool) {
}

// Secrets print secrets
func Secrets(secrets map[string]models.ComputedSecret, secretsToPrint []string, jsonFlag bool, plain bool, raw bool, copy bool, visibility bool) {
func Secrets(secrets map[string]models.ComputedSecret, secretsToPrint []string, jsonFlag bool, plain bool, raw bool, copy bool, visibility bool, valueType bool) {
if len(secretsToPrint) == 0 {
for name := range secrets {
secretsToPrint = append(secretsToPrint, name)
Expand Down Expand Up @@ -234,6 +234,7 @@ func Secrets(secrets map[string]models.ComputedSecret, secretsToPrint []string,
secretsMap[name] = map[string]interface{}{
"note": secrets[name].Note,
"computedVisibility": secrets[name].ComputedVisibility,
"computedValueType": secrets[name].ComputedValueType,
}

if secrets[name].ComputedValue != nil {
Expand All @@ -244,6 +245,7 @@ func Secrets(secrets map[string]models.ComputedSecret, secretsToPrint []string,

if raw {
secretsMap[name]["rawVisibility"] = secrets[name].RawVisibility
secretsMap[name]["rawValueType"] = secrets[name].RawValueType
if secrets[name].RawValue != nil {
secretsMap[name]["raw"] = *secrets[name].RawValue
} else {
Expand Down Expand Up @@ -290,11 +292,17 @@ func Secrets(secrets map[string]models.ComputedSecret, secretsToPrint []string,
if visibility {
headers = append(headers, "visibility")
}
if valueType {
headers = append(headers, "type")
}
headers = append(headers, "value")
if raw {
if visibility {
headers = append(headers, "raw visibility")
}
if valueType {
headers = append(headers, "raw type")
}
headers = append(headers, "raw value")
}
headers = append(headers, "note")
Expand All @@ -312,6 +320,9 @@ func Secrets(secrets map[string]models.ComputedSecret, secretsToPrint []string,
if visibility {
row = append(row, secret.ComputedVisibility)
}
if valueType {
row = append(row, secret.ComputedValueType.Type)
}
row = append(row, computedValue)
if raw {
var rawValue string
Expand All @@ -323,6 +334,9 @@ func Secrets(secrets map[string]models.ComputedSecret, secretsToPrint []string,
if visibility {
row = append(row, secret.RawVisibility)
}
if valueType {
row = append(row, secret.RawValueType.Type)
}
row = append(row, rawValue)
}

Expand Down

0 comments on commit 4e54853

Please sign in to comment.