From 9a7a3b00dca9d4aed1fccad5f8684633df780f56 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Sun, 29 Oct 2023 11:52:53 +0100 Subject: [PATCH] EventManager commands: allow to retrieve env vars from the process env Signed-off-by: Nicola Murino --- internal/common/eventmanager.go | 10 ++- internal/common/protocol_test.go | 97 +++++++++++++++++++++++++++++ templates/webadmin/eventaction.html | 2 +- 3 files changed, 107 insertions(+), 2 deletions(-) diff --git a/internal/common/eventmanager.go b/internal/common/eventmanager.go index 7865ad44..30951502 100644 --- a/internal/common/eventmanager.go +++ b/internal/common/eventmanager.go @@ -1464,7 +1464,15 @@ func executeCommandRuleAction(c dataprovider.EventActionCommandConfig, params *E cmd := exec.CommandContext(ctx, c.Cmd, args...) cmd.Env = []string{} for _, keyVal := range c.EnvVars { - cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", keyVal.Key, replaceWithReplacer(keyVal.Value, replacer))) + if keyVal.Value == "$" { + val := os.Getenv(keyVal.Key) + if val == "" { + eventManagerLog(logger.LevelDebug, "empty value for environment variable %q", keyVal.Key) + } + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", keyVal.Key, val)) + } else { + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", keyVal.Key, replaceWithReplacer(keyVal.Value, replacer))) + } } startTime := time.Now() diff --git a/internal/common/protocol_test.go b/internal/common/protocol_test.go index 871906e2..a4ff236f 100644 --- a/internal/common/protocol_test.go +++ b/internal/common/protocol_test.go @@ -4869,6 +4869,92 @@ func TestEventRulePreDownloadUpload(t *testing.T) { assert.NoError(t, err) } +func TestEventActionCommandEnvVars(t *testing.T) { + if runtime.GOOS == osWindows { + t.Skip("this test is not available on Windows") + } + envName := "MY_ENV" + uploadScriptPath := filepath.Join(os.TempDir(), "upload.sh") + + err := os.WriteFile(uploadScriptPath, getUploadScriptEnvContent(envName), 0755) + assert.NoError(t, err) + a1 := dataprovider.BaseEventAction{ + Name: "action1", + Type: dataprovider.ActionTypeCommand, + Options: dataprovider.BaseEventActionOptions{ + CmdConfig: dataprovider.EventActionCommandConfig{ + Cmd: uploadScriptPath, + Timeout: 10, + EnvVars: []dataprovider.KeyValue{ + { + Key: envName, + Value: "$", + }, + }, + }, + }, + } + action1, _, err := httpdtest.AddEventAction(a1, http.StatusCreated) + assert.NoError(t, err) + + r1 := dataprovider.EventRule{ + Name: "test rule1", + Status: 1, + Trigger: dataprovider.EventTriggerFsEvent, + Conditions: dataprovider.EventConditions{ + FsEvents: []string{"upload"}, + }, + Actions: []dataprovider.EventAction{ + { + BaseEventAction: dataprovider.BaseEventAction{ + Name: action1.Name, + }, + Order: 1, + Options: dataprovider.EventActionOptions{ + ExecuteSync: true, + }, + }, + }, + } + rule1, _, err := httpdtest.AddEventRule(r1, http.StatusCreated) + assert.NoError(t, err) + + user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated) + assert.NoError(t, err) + + conn, client, err := getSftpClient(user) + if assert.NoError(t, err) { + defer conn.Close() + defer client.Close() + + err = writeSFTPFileNoCheck(testFileName, 100, client) + assert.Error(t, err) + } + + os.Setenv(envName, "1") + defer os.Unsetenv(envName) + + conn, client, err = getSftpClient(user) + if assert.NoError(t, err) { + defer conn.Close() + defer client.Close() + + err = writeSFTPFileNoCheck(testFileName, 100, client) + assert.NoError(t, err) + } + + _, err = httpdtest.RemoveEventRule(rule1, http.StatusOK) + assert.NoError(t, err) + _, err = httpdtest.RemoveEventAction(action1, http.StatusOK) + assert.NoError(t, err) + _, err = httpdtest.RemoveUser(user, http.StatusOK) + assert.NoError(t, err) + err = os.RemoveAll(user.GetHomeDir()) + assert.NoError(t, err) + err = os.Remove(uploadScriptPath) + assert.NoError(t, err) +} + func TestFsActionCopy(t *testing.T) { a1 := dataprovider.BaseEventAction{ Name: "a1", @@ -8828,6 +8914,17 @@ func writeSFTPFileNoCheck(name string, size int64, client *sftp.Client) error { return f.Close() } +func getUploadScriptEnvContent(envVar string) []byte { + content := []byte("#!/bin/sh\n\n") + content = append(content, []byte(fmt.Sprintf("if [ -z \"$%s\" ]\n", envVar))...) + content = append(content, []byte("then\n")...) + content = append(content, []byte(" exit 1\n")...) + content = append(content, []byte("else\n")...) + content = append(content, []byte(" exit 0\n")...) + content = append(content, []byte("fi\n")...) + return content +} + func getUploadScriptContent(movedPath, logFilePath string, exitStatus int) []byte { content := []byte("#!/bin/sh\n\n") content = append(content, []byte("sleep 1\n")...) diff --git a/templates/webadmin/eventaction.html b/templates/webadmin/eventaction.html index 4ad10902..5704d1bf 100644 --- a/templates/webadmin/eventaction.html +++ b/templates/webadmin/eventaction.html @@ -407,7 +407,7 @@ along with this program. If not, see . Environment variables
-
Placeholders are supported in values.
+
Placeholders are supported in values. Setting the value to "$" without quotes means retrieving the key from the environment.
{{range $idx, $val := .Action.Options.CmdConfig.EnvVars}}