From 6f9900e0594201f490870e91d06503e87baa557d Mon Sep 17 00:00:00 2001 From: Virgil Date: Wed, 1 Apr 2026 06:46:12 +0000 Subject: [PATCH] feat(ansible): honour delegate_to for task execution Co-Authored-By: Virgil --- executor.go | 14 ++++++++++++-- executor_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/executor.go b/executor.go index 259e550..42042e9 100644 --- a/executor.go +++ b/executor.go @@ -420,10 +420,20 @@ func (e *Executor) runTaskOnHost(ctx context.Context, host string, task *Task, p } } + // delegate_to changes the execution target but keeps the task context + // anchored to the original host for templating and registration. + executionHost := host + if task.Delegate != "" { + executionHost = e.templateString(task.Delegate, host, task) + if executionHost == "" { + executionHost = host + } + } + // Get SSH client - client, err := e.getClient(host, play) + client, err := e.getClient(executionHost, play) if err != nil { - return coreerr.E("Executor.runTaskOnHost", sprintf("get client for %s", host), err) + return coreerr.E("Executor.runTaskOnHost", sprintf("get client for %s", executionHost), err) } // Handle loops diff --git a/executor_test.go b/executor_test.go index d65812f..27c2722 100644 --- a/executor_test.go +++ b/executor_test.go @@ -283,6 +283,32 @@ func TestExecutor_RunPlay_Good_RunOnceTaskOnlyRunsOnFirstHost(t *testing.T) { assert.False(t, ok) } +func TestExecutor_RunTaskOnHost_Good_DelegateToUsesDelegateHostClient(t *testing.T) { + e := NewExecutor("/tmp") + e.SetInventoryDirect(&Inventory{ + All: &InventoryGroup{ + Hosts: map[string]*Host{ + "source": {}, + }, + }, + }) + + task := &Task{ + Name: "delegated debug", + Module: "debug", + Args: map[string]any{"msg": "ok"}, + Delegate: "delegate-host", + } + play := &Play{} + + require.NoError(t, e.runTaskOnHost(context.Background(), "source", task, play)) + + _, ok := e.clients["delegate-host"] + assert.True(t, ok) + _, ok = e.clients["source"] + assert.False(t, ok) +} + func TestExecutor_RunPlay_Good_PlayTagsApplyToUntaggedTasks(t *testing.T) { e := NewExecutor("/tmp") e.SetInventoryDirect(&Inventory{ -- 2.45.3