From 5f6205011cf895575db918b75ee73ea34be2247f Mon Sep 17 00:00:00 2001 From: Virgil Date: Wed, 1 Apr 2026 23:21:50 +0000 Subject: [PATCH] fix(ansible): honour play var precedence --- executor.go | 6 +++--- executor_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/executor.go b/executor.go index 6084caa..7c8a939 100644 --- a/executor.go +++ b/executor.go @@ -1533,9 +1533,9 @@ func (e *Executor) getClient(host string, play *Play) (sshExecutorClient, error) // Merge with play vars for k, v := range e.vars { - if _, exists := vars[k]; !exists { - vars[k] = v - } + // Executor-scoped vars include play vars and extra vars, so they must + // override inventory values when they target the same key. + vars[k] = v } // Build SSH config diff --git a/executor_test.go b/executor_test.go index 20528db..ee6bd49 100644 --- a/executor_test.go +++ b/executor_test.go @@ -103,6 +103,30 @@ func TestExecutor_GetHosts_Good_WithLimit(t *testing.T) { assert.Contains(t, hosts, "host2") } +func TestExecutor_GetClient_Good_PlayVarsOverrideInventoryVars(t *testing.T) { + e := NewExecutor("/tmp") + e.SetInventoryDirect(&Inventory{ + All: &InventoryGroup{ + Hosts: map[string]*Host{ + "host1": { + AnsibleHost: "10.0.0.10", + AnsibleUser: "inventory-user", + }, + }, + }, + }) + e.SetVar("ansible_host", "10.0.0.20") + e.SetVar("ansible_user", "play-user") + + client, err := e.getClient("host1", &Play{}) + require.NoError(t, err) + + sshClient, ok := client.(*SSHClient) + require.True(t, ok) + assert.Equal(t, "10.0.0.20", sshClient.host) + assert.Equal(t, "play-user", sshClient.user) +} + // --- matchesTags --- func TestExecutor_MatchesTags_Good_NoTagsFilter(t *testing.T) {