@@ -12,13 +12,24 @@ var _ Executor = &CommandExecutor{}
12
12
13
13
// CommandExecutor handles command invocation targets
14
14
type CommandExecutor struct {
15
- secrets secret.Store
15
+ secrets secret.Store
16
+ passEnvironment bool // pass the Pico process environment to children
17
+ configSecretPath string // path to global secrets to pass to children
18
+ configSecretPrefix string // only pass secrets with this prefix, usually GLOBAL_
16
19
}
17
20
18
21
// NewCommandExecutor creates a new CommandExecutor
19
- func NewCommandExecutor (secrets secret.Store ) CommandExecutor {
22
+ func NewCommandExecutor (
23
+ secrets secret.Store ,
24
+ passEnvironment bool ,
25
+ configSecretPath string ,
26
+ configSecretPrefix string ,
27
+ ) CommandExecutor {
20
28
return CommandExecutor {
21
- secrets : secrets ,
29
+ secrets : secrets ,
30
+ passEnvironment : passEnvironment ,
31
+ configSecretPath : configSecretPath ,
32
+ configSecretPrefix : configSecretPrefix ,
22
33
}
23
34
}
24
35
@@ -34,34 +45,66 @@ func (e *CommandExecutor) Subscribe(bus chan task.ExecutionTask) {
34
45
}
35
46
}
36
47
37
- func (e * CommandExecutor ) execute (
38
- target task.Target ,
48
+ type exec struct {
49
+ path string
50
+ env map [string ]string
51
+ shutdown bool
52
+ passEnvironment bool
53
+ }
54
+
55
+ func (e * CommandExecutor ) prepare (
56
+ name string ,
39
57
path string ,
40
58
shutdown bool ,
41
59
execEnv map [string ]string ,
42
- ) (err error ) {
43
- secrets , err := e .secrets .GetSecretsForTarget (target .Name )
60
+ ) (exec , error ) {
61
+ // get global secrets from the Pico config path in the secret store.
62
+ // only secrets with the prefix are retrieved.
63
+ global , err := secret .GetPrefixedSecrets (e .secrets , e .configSecretPath , e .configSecretPrefix )
44
64
if err != nil {
45
- return errors .Wrap (err , "failed to get secrets for target" )
65
+ return exec {}, errors .Wrap (err , "failed to get global secrets for target" )
66
+ }
67
+
68
+ secrets , err := e .secrets .GetSecretsForTarget (name )
69
+ if err != nil {
70
+ return exec {}, errors .Wrap (err , "failed to get secrets for target" )
46
71
}
47
72
48
73
env := make (map [string ]string )
49
74
50
- // merge execution environment with secrets
75
+ // merge execution environment with secrets in the following order:
76
+ // globals first, then execution environment, then per-target secrets
77
+ for k , v := range global {
78
+ env [k ] = v
79
+ }
51
80
for k , v := range execEnv {
52
81
env [k ] = v
53
82
}
54
83
for k , v := range secrets {
55
84
env [k ] = v
56
85
}
57
86
87
+ return exec {path , env , shutdown , e .passEnvironment }, nil
88
+ }
89
+
90
+ func (e * CommandExecutor ) execute (
91
+ target task.Target ,
92
+ path string ,
93
+ shutdown bool ,
94
+ execEnv map [string ]string ,
95
+ ) (err error ) {
96
+ ex , err := e .prepare (target .Name , path , shutdown , execEnv )
97
+ if err != nil {
98
+ return err
99
+ }
100
+
58
101
zap .L ().Debug ("executing with secrets" ,
59
102
zap .String ("target" , target .Name ),
60
103
zap .Strings ("cmd" , target .Up ),
61
104
zap .String ("url" , target .RepoURL ),
62
105
zap .String ("dir" , path ),
63
- zap .Int ("env" , len ( env ) ),
64
- zap .Int ( "secrets " , len ( secrets ) ))
106
+ zap .Any ("env" , ex . env ),
107
+ zap .Bool ( "passthrough " , e . passEnvironment ))
65
108
66
- return target .Execute (path , env , shutdown )
109
+ return target .Execute (ex . path , ex . env , ex . shutdown , ex . passEnvironment )
67
110
}
0 commit comments