feat(ansible): support proxy disabling for uri and get_url

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-03 15:24:33 +00:00
parent 79c01ab325
commit 65917f028c
4 changed files with 79 additions and 0 deletions

View file

@ -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

View file

@ -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 {

View file

@ -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))

View file

@ -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)