diff --git a/mock_ssh_test.go b/mock_ssh_test.go index 5175808..744a0da 100644 --- a/mock_ssh_test.go +++ b/mock_ssh_test.go @@ -2010,6 +2010,7 @@ func moduleURIWithClient(_ *Executor, client sshRunner, args map[string]any) (*T urlUsername := getStringArg(args, "url_username", "") urlPassword := getStringArg(args, "url_password", "") forceBasicAuth := getBoolArg(args, "force_basic_auth", false) + useProxy := getBoolArg(args, "use_proxy", true) unixSocket := getStringArg(args, "unix_socket", "") followRedirects := lower(getStringArg(args, "follow_redirects", "safe")) src := getStringArg(args, "src", "") @@ -2034,6 +2035,9 @@ func moduleURIWithClient(_ *Executor, client sshRunner, args map[string]any) (*T if unixSocket != "" { curlOpts = append(curlOpts, "--unix-socket", shellQuote(unixSocket)) } + if !useProxy { + curlOpts = append(curlOpts, "--noproxy", shellQuote("*")) + } // Headers if headers, ok := args["headers"].(map[string]any); ok { @@ -2090,6 +2094,9 @@ func moduleURIWithClient(_ *Executor, client sshRunner, args map[string]any) (*T curlOpts = append(curlOpts, "-w", "\\n%{http_code}") cmd := sprintf("curl %s %q", joinStrings(curlOpts, " "), url) + if !useProxy { + cmd = sprintf("curl %s %q || wget --no-proxy -q -O - %q", joinStrings(curlOpts, " "), url, url) + } stdout, stderr, rc, err := client.Run(context.Background(), cmd) if err != nil { return &TaskResult{Failed: true, Msg: err.Error()}, nil diff --git a/modules.go b/modules.go index ee778d7..e969414 100644 --- a/modules.go +++ b/modules.go @@ -1402,6 +1402,7 @@ func (e *Executor) moduleGetURL(ctx context.Context, client sshExecutorClient, a } force := getBoolArg(args, "force", true) + useProxy := getBoolArg(args, "use_proxy", true) checksumSpec := corexTrimSpace(getStringArg(args, "checksum", "")) if !force { @@ -1416,6 +1417,9 @@ func (e *Executor) moduleGetURL(ctx context.Context, client sshExecutorClient, a // Stream to stdout so we can validate checksums before writing the file. cmd := sprintf("curl -fsSL %q || wget -q -O - %q", url, url) + if !useProxy { + cmd = sprintf("curl --noproxy %s -fsSL %q || wget --no-proxy -q -O - %q", shellQuote("*"), url, url) + } stdout, stderr, rc, err := client.Run(ctx, cmd) if err != nil || rc != 0 { return &TaskResult{Failed: true, Msg: stderr, Stdout: stdout, RC: rc}, nil @@ -2031,6 +2035,7 @@ func (e *Executor) moduleURI(ctx context.Context, client sshExecutorClient, args urlUsername := getStringArg(args, "url_username", "") urlPassword := getStringArg(args, "url_password", "") forceBasicAuth := getBoolArg(args, "force_basic_auth", false) + useProxy := getBoolArg(args, "use_proxy", true) unixSocket := getStringArg(args, "unix_socket", "") followRedirects := lower(getStringArg(args, "follow_redirects", "safe")) src := getStringArg(args, "src", "") @@ -2057,6 +2062,9 @@ func (e *Executor) moduleURI(ctx context.Context, client sshExecutorClient, args if unixSocket != "" { curlOpts = append(curlOpts, "--unix-socket", shellQuote(unixSocket)) } + if !useProxy { + curlOpts = append(curlOpts, "--noproxy", shellQuote("*")) + } // Headers if headers, ok := args["headers"].(map[string]any); ok { diff --git a/modules_adv_test.go b/modules_adv_test.go index 81a6550..cf43ee5 100644 --- a/modules_adv_test.go +++ b/modules_adv_test.go @@ -1689,6 +1689,21 @@ func TestModulesAdv_ModuleURI_Good_UsesUnixSocket(t *testing.T) { assert.True(t, mock.hasExecuted(`--unix-socket '/var/run/docker.sock'`)) } +func TestModulesAdv_ModuleURI_Good_DisablesProxyUsage(t *testing.T) { + e, mock := newTestExecutorWithMock("host1") + mock.expectCommand(`curl.*https://example.com/api/health`, "OK\n200", "", 0) + + result, err := moduleURIWithClient(e, mock, map[string]any{ + "url": "https://example.com/api/health", + "use_proxy": false, + }) + + require.NoError(t, err) + assert.False(t, result.Failed) + assert.Equal(t, 200, result.RC) + assert.True(t, mock.hasExecuted(`--noproxy`)) +} + func TestModulesAdv_ModuleURI_Good_UsesSourceFileBody(t *testing.T) { e, mock := newTestExecutorWithMock("host1") require.NoError(t, mock.Upload(context.Background(), newReader("alpha=1&beta=2"), "/tmp/request-body.txt", 0644)) diff --git a/modules_file_test.go b/modules_file_test.go index b9dfaf2..0610cb2 100644 --- a/modules_file_test.go +++ b/modules_file_test.go @@ -996,6 +996,23 @@ func TestModulesFile_ModuleBlockinfile_Good_CustomMarkers(t *testing.T) { assert.True(t, mock.hasExecutedMethod("RunScript", "# END managed by devops")) } +func TestModulesFile_ModuleBlockinfile_Good_CustomMarkerBeginAndEnd(t *testing.T) { + e, mock := newTestExecutorWithMock("host1") + + result, err := e.moduleBlockinfile(context.Background(), mock, map[string]any{ + "path": "/etc/app.conf", + "block": "setting=value", + "marker": "# {mark} managed by app", + "marker_begin": "START", + "marker_end": "STOP", + }) + + require.NoError(t, err) + assert.True(t, result.Changed) + assert.True(t, mock.hasExecutedMethod("RunScript", "# START managed by app")) + assert.True(t, mock.hasExecutedMethod("RunScript", "# STOP managed by app")) +} + func TestModulesFile_ModuleBlockinfile_Good_NewlinePadding(t *testing.T) { e, mock := newTestExecutorWithMock("host1") @@ -1028,6 +1045,22 @@ func TestModulesFile_ModuleBlockinfile_Good_RemoveBlock(t *testing.T) { assert.True(t, mock.hasExecuted(`sed -i '/.*BEGIN ANSIBLE MANAGED BLOCK/,/.*END ANSIBLE MANAGED BLOCK/d'`)) } +func TestModulesFile_ModuleBlockinfile_Good_RemoveBlockWithCustomMarkerBeginAndEnd(t *testing.T) { + e, mock := newTestExecutorWithMock("host1") + + result, err := e.moduleBlockinfile(context.Background(), mock, map[string]any{ + "path": "/etc/app.conf", + "state": "absent", + "marker": "# {mark} managed by app", + "marker_begin": "START", + "marker_end": "STOP", + }) + + require.NoError(t, err) + assert.True(t, result.Changed) + assert.True(t, mock.hasExecuted(`sed -i '/.*START managed by app/,/.*STOP managed by app/d'`)) +} + func TestModulesFile_ModuleBlockinfile_Good_CreateFile(t *testing.T) { e, mock := newTestExecutorWithMock("host1") @@ -1692,6 +1725,22 @@ func TestModulesFile_ModuleGetURL_Good_ForceFalseSkipsExistingDestination(t *tes assert.Equal(t, 0, mock.uploadCount()) } +func TestModulesFile_ModuleGetURL_Good_DisablesProxyUsage(t *testing.T) { + e, mock := newTestExecutorWithMock("host1") + mock.expectCommand(`curl.*https://downloads\.example\.com/app\.tgz`, "downloaded artifact", "", 0) + + result, err := e.moduleGetURL(context.Background(), mock, map[string]any{ + "url": "https://downloads.example.com/app.tgz", + "dest": "/tmp/app.tgz", + "use_proxy": false, + }) + + require.NoError(t, err) + assert.True(t, result.Changed) + assert.True(t, mock.hasExecuted(`--noproxy`)) + assert.True(t, mock.hasExecuted(`wget --no-proxy`)) +} + func TestModulesFile_ModuleGetURL_Bad_ChecksumMismatch(t *testing.T) { e, mock := newTestExecutorWithMock("host1") mock.expectCommand(`curl.*https://downloads\.example\.com/app\.tgz`, "downloaded artifact", "", 0)