88 "encoding/json"
99 "errors"
1010 "fmt"
11- "io/ioutil"
1211 "net"
1312 "net/http"
1413 "os"
@@ -24,6 +23,7 @@ import (
2423 "github.com/hashicorp/vault-lambda-extension/internal/config"
2524 "github.com/hashicorp/vault-lambda-extension/internal/extension"
2625 "github.com/hashicorp/vault-lambda-extension/internal/proxy"
26+ "github.com/hashicorp/vault-lambda-extension/internal/runmode"
2727 "github.com/hashicorp/vault-lambda-extension/internal/vault"
2828 "github.com/hashicorp/vault/api"
2929)
@@ -33,19 +33,36 @@ func main() {
3333 Level : hclog .LevelFromString (os .Getenv (config .VaultLogLevel )),
3434 })
3535
36- err := realMain (logger .Named (config .VaultLogLevel ))
37- if err != nil {
36+ runMode := runmode .ModeDefault
37+ if runModeEnv := os .Getenv (config .VaultRunMode ); runModeEnv != "" {
38+ runMode = runmode .ParseMode (runModeEnv )
39+ }
40+
41+ h := newHandler (logger .Named (config .ExtensionName ), runMode )
42+ if err := h .handle (); err != nil {
3843 logger .Error ("Fatal error, exiting" , "error" , err )
3944 os .Exit (1 )
4045 }
4146}
4247
43- func realMain (logger hclog.Logger ) error {
48+ func newHandler (logger hclog.Logger , runMode runmode.Mode ) * handler {
49+ return & handler {
50+ logger : logger ,
51+ runMode : runMode ,
52+ }
53+ }
54+
55+ type handler struct {
56+ logger hclog.Logger
57+ runMode runmode.Mode
58+ }
59+
60+ func (h * handler ) handle () error {
4461 ctx , cancel := context .WithCancel (context .Background ())
4562 defer cancel ()
4663
4764 var wg sync.WaitGroup
48- srv , err := runExtension (ctx , logger , & wg )
65+ cleanup , err := h . runExtension (ctx , & wg )
4966 if err != nil {
5067 return err
5168 }
@@ -57,16 +74,16 @@ func realMain(logger hclog.Logger) error {
5774 interruptChannel := make (chan os.Signal , 1 )
5875 signal .Notify (interruptChannel , syscall .SIGTERM , syscall .SIGINT )
5976 select {
60- case s := <- interruptChannel :
61- logger .Info ("Received signal, exiting" , "signal" , s )
77+ case sig := <- interruptChannel :
78+ h . logger .Info ("Received signal, exiting" , "signal" , sig )
6279 case <- shutdownChannel :
63- logger .Info ("Received shutdown event, exiting" )
80+ h . logger .Info ("Received shutdown event, exiting" )
6481 }
6582
6683 cancel ()
67- if err := srv . Shutdown (context .Background ()); err != nil {
84+ if err := cleanup (context .Background ()); err != nil {
6885 // Error from closing listeners, or context timeout:
69- logger .Error ("HTTP server shutdown error" , "error" , err )
86+ h . logger .Error ("HTTP server shutdown error" , "error" , err )
7087 }
7188 }()
7289
@@ -76,20 +93,20 @@ func realMain(logger hclog.Logger) error {
7693 return err
7794 }
7895
79- processEvents (ctx , logger , extensionClient )
96+ processEvents (ctx , h . logger , extensionClient )
8097
8198 // Once processEvents returns, signal that it's time to shutdown.
8299 shutdownChannel <- struct {}{}
83100
84101 // Ensure we wait for the HTTP server to gracefully shut down.
85102 wg .Wait ()
86- logger .Info ("Graceful shutdown complete" )
103+ h . logger .Info ("Graceful shutdown complete" )
87104
88105 return nil
89106}
90107
91- func runExtension (ctx context.Context , logger hclog. Logger , wg * sync.WaitGroup ) (* http. Server , error ) {
92- logger .Info ("Initialising" )
108+ func ( h * handler ) runExtension (ctx context.Context , wg * sync.WaitGroup ) (func (context. Context ) error , error ) {
109+ h . logger .Info ("Initialising" )
93110
94111 authConfig := config .AuthConfigFromEnv ()
95112 vaultConfig := api .DefaultConfig ()
@@ -114,7 +131,7 @@ func runExtension(ctx context.Context, logger hclog.Logger, wg *sync.WaitGroup)
114131 } else {
115132 ses = session .Must (session .NewSession ())
116133 }
117- client , err := vault .NewClient (config .ExtensionName , config .ExtensionVersion , logger .Named ("vault-client" ), vaultConfig , authConfig , ses )
134+ client , err := vault .NewClient (config .ExtensionName , config .ExtensionVersion , h . logger .Named ("vault-client" ), vaultConfig , authConfig , ses )
118135 if err != nil {
119136 return nil , fmt .Errorf ("error getting client: %w" , err )
120137 } else if client == nil {
@@ -135,34 +152,41 @@ func runExtension(ctx context.Context, logger hclog.Logger, wg *sync.WaitGroup)
135152
136153 client .VaultClient = client .VaultClient .WithRequestCallbacks (api .RequireState (newState ), vault .UserAgentRequestCallback (uaFunc )).WithResponseCallbacks ()
137154
138- err = writePreconfiguredSecrets (client .VaultClient )
139- if err != nil {
140- return nil , err
155+ if h .runMode .HasModeFile () {
156+ if err := writePreconfiguredSecrets (client .VaultClient ); err != nil {
157+ return nil , err
158+ }
141159 }
142160
143161 // clear out eventual consistency helpers
144162 client .VaultClient = client .VaultClient .WithRequestCallbacks ().WithResponseCallbacks ()
145163
146- ln , err := net .Listen ("tcp" , "127.0.0.1:8200" )
147- if err != nil {
148- return nil , fmt .Errorf ("failed to listen on port 8200: %w" , err )
149- }
150- srv := proxy .New (logger .Named ("proxy" ), client , config .CacheConfigFromEnv ())
151- wg .Add (1 )
152- go func () {
153- defer wg .Done ()
154- logger .Info ("Starting HTTP proxy server" )
155- err = srv .Serve (ln )
156- if err != http .ErrServerClosed {
157- logger .Error ("HTTP server shutdown unexpectedly" , "error" , err )
164+ cleanupFunc := func (context.Context ) error { return nil }
165+ if h .runMode .HasModeProxy () {
166+ ln , err := net .Listen ("tcp" , "127.0.0.1:8200" )
167+ if err != nil {
168+ return nil , fmt .Errorf ("failed to listen on port 8200: %w" , err )
158169 }
159- }()
160-
161- logger .Info ("Initialised" )
170+ srv := proxy .New (h .logger .Named ("proxy" ), client , config .CacheConfigFromEnv ())
171+ wg .Add (1 )
172+ go func () {
173+ defer wg .Done ()
174+ h .logger .Info ("Starting HTTP proxy server" )
175+ err = srv .Serve (ln )
176+ if err != http .ErrServerClosed {
177+ h .logger .Error ("HTTP server shutdown unexpectedly" , "error" , err )
178+ }
179+ }()
180+ cleanupFunc = func (ctx context.Context ) error {
181+ return srv .Shutdown (ctx )
182+ }
183+ }
162184
163- return srv , nil
185+ h .logger .Info ("Initialised" )
186+ return cleanupFunc , nil
164187}
165188
189+ // writePreconfiguredSecrets writes secrets to disk.
166190func writePreconfiguredSecrets (client * api.Client ) error {
167191 configuredSecrets , err := config .ParseConfiguredSecrets ()
168192 if err != nil {
@@ -178,18 +202,18 @@ func writePreconfiguredSecrets(client *api.Client) error {
178202
179203 content , err := json .MarshalIndent (secret , "" , " " )
180204 if err != nil {
181- return err
205+ return fmt . Errorf ( "unable to marshal json: %w" , err )
182206 }
207+
183208 dir := path .Dir (s .FilePath )
184209 if _ , err = os .Stat (dir ); os .IsNotExist (err ) {
185- err = os .MkdirAll (dir , 0755 )
186- if err != nil {
210+ if err := os .MkdirAll (dir , 0755 ); err != nil {
187211 return fmt .Errorf ("failed to create directory %q for secret %s: %s" , dir , s .Name (), err )
188212 }
189213 }
190- err = ioutil . WriteFile ( s . FilePath , content , 0644 )
191- if err != nil {
192- return err
214+
215+ if err := os . WriteFile ( s . FilePath , content , 0644 ); err != nil {
216+ return fmt . Errorf ( "error writing file: %w" , err )
193217 }
194218 }
195219
0 commit comments