github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/runners/secrets/get.go (about) 1 package secrets 2 3 import ( 4 "github.com/ActiveState/cli/internal/keypairs" 5 "github.com/ActiveState/cli/internal/locale" 6 "github.com/ActiveState/cli/internal/output" 7 "github.com/ActiveState/cli/internal/primer" 8 "github.com/ActiveState/cli/pkg/platform/authentication" 9 "github.com/ActiveState/cli/pkg/project" 10 ) 11 12 type getPrimeable interface { 13 primer.Outputer 14 primer.Projecter 15 primer.Configurer 16 primer.Auther 17 } 18 19 // GetRunParams tracks the info required for running Get. 20 type GetRunParams struct { 21 Name string 22 } 23 24 // Get manages the getting execution context. 25 type Get struct { 26 proj *project.Project 27 out output.Outputer 28 cfg keypairs.Configurable 29 auth *authentication.Auth 30 } 31 32 // SecretExport defines important information about a secret that should be 33 // displayed. 34 type SecretExport struct { 35 Name string `json:"name"` 36 Scope string `json:"scope"` 37 Description string `json:"description"` 38 HasValue bool `json:"has_value"` 39 Value string `json:"value,omitempty"` 40 } 41 42 // NewGet prepares a get execution context for use. 43 func NewGet(p getPrimeable) *Get { 44 return &Get{ 45 out: p.Output(), 46 proj: p.Project(), 47 cfg: p.Config(), 48 auth: p.Auth(), 49 } 50 } 51 52 // Run executes the get behavior. 53 func (g *Get) Run(params GetRunParams) error { 54 g.out.Notice(locale.Tr("operating_message", g.proj.NamespaceString(), g.proj.Dir())) 55 if err := checkSecretsAccess(g.proj, g.auth); err != nil { 56 return locale.WrapError(err, "secrets_err_check_access") 57 } 58 59 secret, valuePtr, err := getSecretWithValue(g.proj, params.Name, g.cfg, g.auth) 60 if err != nil { 61 return locale.WrapError(err, "secrets_err_values") 62 } 63 64 data := &getOutput{params.Name, secret, valuePtr} 65 if err := data.Validate(g.out.Type()); err != nil { 66 return locale.WrapError(err, "secrets_err_getout_invalid", "'get secret' output data invalid") 67 } 68 g.out.Print(data) 69 70 return nil 71 } 72 73 type getOutput struct { 74 reqSecret string 75 secret *project.Secret 76 valuePtr *string 77 } 78 79 // Validate returns a directly usable localized error. 80 func (o *getOutput) Validate(format output.Format) error { 81 if !format.IsStructured() && o.valuePtr == nil { 82 return newValuePtrIsNilError(o.reqSecret, o.secret.IsUser()) 83 } 84 return nil 85 } 86 87 func (o *getOutput) MarshalOutput(format output.Format) interface{} { 88 value := "" 89 if o.valuePtr != nil { 90 value = *o.valuePtr 91 } 92 return value 93 } 94 95 func (o *getOutput) MarshalStructured(format output.Format) interface{} { 96 value := "" 97 if o.valuePtr != nil { 98 value = *o.valuePtr 99 } 100 return &SecretExport{ 101 o.secret.Name(), 102 o.secret.Scope(), 103 o.secret.Description(), 104 o.valuePtr != nil, 105 value, 106 } 107 108 } 109 110 func newValuePtrIsNilError(reqSecret string, isUser bool) error { 111 l10nKey := "secrets_err_project_not_defined" 112 l10nVal := "Secret has not been defined: {{.V0}}. Either define it by running 'state secrets set {{.V0}}' or have someone in your organization sync with you by having them run 'state secrets sync'." 113 if isUser { 114 l10nKey = "secrets_err_user_not_defined" 115 l10nVal = "Secret has not been defined: {{.V0}}. Define it by running 'state secrets set {{.V0}}'." 116 } 117 118 return locale.NewError(l10nKey, l10nVal, reqSecret) 119 }