From 8c1f4af11e4b14a900cd6ca5c7d1441fe34c086a Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 02:32:49 +0000 Subject: [PATCH] feat(ansible): add uri timeout and cert controls Co-Authored-By: Virgil --- mock_ssh_test.go | 10 ++++++++++ modules.go | 10 ++++++++++ modules_adv_test.go | 17 +++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/mock_ssh_test.go b/mock_ssh_test.go index 4412348..0ad1279 100644 --- a/mock_ssh_test.go +++ b/mock_ssh_test.go @@ -1658,6 +1658,8 @@ func moduleURIWithClient(_ *Executor, client sshRunner, args map[string]any) (*T method := getStringArg(args, "method", "GET") bodyFormat := lower(getStringArg(args, "body_format", "")) returnContent := getBoolArg(args, "return_content", false) + timeout := getIntArg(args, "timeout", 0) + validateCerts := getBoolArg(args, "validate_certs", true) if url == "" { return nil, mockError("moduleURIWithClient", "uri: url required") @@ -1674,6 +1676,10 @@ func moduleURIWithClient(_ *Executor, client sshRunner, args map[string]any) (*T } } + if !validateCerts { + curlOpts = append(curlOpts, "-k") + } + // Body if body := args["body"]; body != nil { bodyText, err := renderURIBody(body, bodyFormat) @@ -1693,6 +1699,10 @@ func moduleURIWithClient(_ *Executor, client sshRunner, args map[string]any) (*T } } + if timeout > 0 { + curlOpts = append(curlOpts, "--max-time", strconv.Itoa(timeout)) + } + // Status code curlOpts = append(curlOpts, "-w", "\\n%{http_code}") diff --git a/modules.go b/modules.go index 41ffec5..6943e77 100644 --- a/modules.go +++ b/modules.go @@ -1277,6 +1277,8 @@ func (e *Executor) moduleURI(ctx context.Context, client sshExecutorClient, args method := getStringArg(args, "method", "GET") bodyFormat := lower(getStringArg(args, "body_format", "")) returnContent := getBoolArg(args, "return_content", false) + timeout := getIntArg(args, "timeout", 0) + validateCerts := getBoolArg(args, "validate_certs", true) if url == "" { return nil, coreerr.E("Executor.moduleURI", "url required", nil) @@ -1293,6 +1295,10 @@ func (e *Executor) moduleURI(ctx context.Context, client sshExecutorClient, args } } + if !validateCerts { + curlOpts = append(curlOpts, "-k") + } + // Body if body := args["body"]; body != nil { bodyText, err := renderURIBody(body, bodyFormat) @@ -1312,6 +1318,10 @@ func (e *Executor) moduleURI(ctx context.Context, client sshExecutorClient, args } } + if timeout > 0 { + curlOpts = append(curlOpts, "--max-time", strconv.Itoa(timeout)) + } + // Status code curlOpts = append(curlOpts, "-w", "\\n%{http_code}") diff --git a/modules_adv_test.go b/modules_adv_test.go index 17f7400..86c33cd 100644 --- a/modules_adv_test.go +++ b/modules_adv_test.go @@ -1370,6 +1370,23 @@ func TestModulesAdv_ModuleURI_Good_JSONBodyFormat(t *testing.T) { assert.True(t, mock.containsSubstring("Content-Type: application/json")) } +func TestModulesAdv_ModuleURI_Good_TimeoutAndInsecureSkipVerify(t *testing.T) { + e, mock := newTestExecutorWithMock("host1") + mock.expectCommand(`curl`, "OK\n200", "", 0) + + result, err := moduleURIWithClient(e, mock, map[string]any{ + "url": "https://insecure.example.com/health", + "timeout": 15, + "validate_certs": false, + }) + + require.NoError(t, err) + assert.False(t, result.Failed) + assert.Equal(t, 200, result.RC) + assert.True(t, mock.containsSubstring("-k")) + assert.True(t, mock.containsSubstring("--max-time 15")) +} + func TestModulesAdv_ModuleURI_Good_MultipleExpectedStatuses(t *testing.T) { e, mock := newTestExecutorWithMock("host1") mock.expectCommand(`curl`, "\n202", "", 0)