Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for value types #457

Merged
merged 4 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading