Merge pull request '[agent/codex:gpt-5.4-mini] Read ~/spec/code/core/go/ansible/RFC.md fully. Find ONE feat...' (#38) from main into dev
This commit is contained in:
commit
7d0f83349b
3 changed files with 99 additions and 0 deletions
|
|
@ -522,6 +522,8 @@ func executeModuleWithMock(e *Executor, mock *MockSSHClient, host string, task *
|
|||
// Inventory mutation
|
||||
case "ansible.builtin.add_host":
|
||||
return e.moduleAddHost(args)
|
||||
case "ansible.builtin.group_by":
|
||||
return e.moduleGroupBy(args, host)
|
||||
|
||||
// SSH keys
|
||||
case "ansible.posix.authorized_key", "ansible.builtin.authorized_key":
|
||||
|
|
|
|||
55
modules.go
55
modules.go
|
|
@ -131,6 +131,8 @@ func (e *Executor) executeModule(ctx context.Context, host string, client *SSHCl
|
|||
return e.moduleIncludeVars(args)
|
||||
case "ansible.builtin.add_host":
|
||||
return e.moduleAddHost(args)
|
||||
case "ansible.builtin.group_by":
|
||||
return e.moduleGroupBy(args, host)
|
||||
case "ansible.builtin.meta":
|
||||
return e.moduleMeta(args)
|
||||
case "ansible.builtin.setup":
|
||||
|
|
@ -1474,6 +1476,59 @@ func (e *Executor) moduleAddHost(args map[string]any) (*TaskResult, error) {
|
|||
return &TaskResult{Changed: true, Msg: "host added: " + name}, nil
|
||||
}
|
||||
|
||||
func (e *Executor) moduleGroupBy(args map[string]any, host string) (*TaskResult, error) {
|
||||
groupName := getStringArg(args, "key", "")
|
||||
if groupName == "" {
|
||||
groupName = getStringArg(args, "name", "")
|
||||
}
|
||||
if groupName == "" {
|
||||
groupName = getStringArg(args, "_raw_params", "")
|
||||
}
|
||||
if groupName == "" {
|
||||
return nil, coreerr.E("Executor.moduleGroupBy", "key required", nil)
|
||||
}
|
||||
if host == "" {
|
||||
host = getStringArg(args, "inventory_hostname", "")
|
||||
}
|
||||
if host == "" {
|
||||
host = getStringArg(args, "host", "")
|
||||
}
|
||||
if host == "" {
|
||||
return nil, coreerr.E("Executor.moduleGroupBy", "host required", nil)
|
||||
}
|
||||
|
||||
if e.inventory == nil {
|
||||
e.inventory = &Inventory{}
|
||||
}
|
||||
if e.inventory.All == nil {
|
||||
e.inventory.All = &InventoryGroup{}
|
||||
}
|
||||
if e.inventory.All.Children == nil {
|
||||
e.inventory.All.Children = make(map[string]*InventoryGroup)
|
||||
}
|
||||
if e.inventory.All.Hosts == nil {
|
||||
e.inventory.All.Hosts = make(map[string]*Host)
|
||||
}
|
||||
|
||||
hostEntry := e.inventory.All.Hosts[host]
|
||||
if hostEntry == nil {
|
||||
hostEntry = &Host{}
|
||||
e.inventory.All.Hosts[host] = hostEntry
|
||||
}
|
||||
|
||||
group := e.inventory.All.Children[groupName]
|
||||
if group == nil {
|
||||
group = &InventoryGroup{}
|
||||
e.inventory.All.Children[groupName] = group
|
||||
}
|
||||
if group.Hosts == nil {
|
||||
group.Hosts = make(map[string]*Host)
|
||||
}
|
||||
group.Hosts[host] = hostEntry
|
||||
|
||||
return &TaskResult{Changed: true, Msg: "host grouped: " + host + " -> " + groupName}, nil
|
||||
}
|
||||
|
||||
func (e *Executor) moduleMeta(args map[string]any) (*TaskResult, error) {
|
||||
// meta module controls play execution
|
||||
// Most actions are no-ops for us
|
||||
|
|
|
|||
|
|
@ -1103,6 +1103,30 @@ func TestModulesAdv_ModuleAddHost_Good_AddsHostAndGroups(t *testing.T) {
|
|||
assert.Equal(t, "app", GetHostVars(e.inventory, "web2")["role"])
|
||||
}
|
||||
|
||||
func TestModulesAdv_ModuleGroupBy_Good_AddsHostToDerivedGroup(t *testing.T) {
|
||||
e := NewExecutor("/tmp")
|
||||
e.SetInventoryDirect(&Inventory{
|
||||
All: &InventoryGroup{
|
||||
Hosts: map[string]*Host{
|
||||
"web1": {AnsibleHost: "10.0.0.1"},
|
||||
},
|
||||
Children: map[string]*InventoryGroup{},
|
||||
},
|
||||
})
|
||||
|
||||
result, err := e.moduleGroupBy(map[string]any{
|
||||
"key": "role_web",
|
||||
}, "web1")
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.True(t, result.Changed)
|
||||
assert.Equal(t, "host grouped: web1 -> role_web", result.Msg)
|
||||
require.NotNil(t, e.inventory.All.Children["role_web"])
|
||||
assert.Contains(t, e.inventory.All.Children["role_web"].Hosts, "web1")
|
||||
assert.Equal(t, e.inventory.All.Hosts["web1"], e.inventory.All.Children["role_web"].Hosts["web1"])
|
||||
assert.Equal(t, []string{"web1"}, GetHosts(e.inventory, "role_web"))
|
||||
}
|
||||
|
||||
// --- Cross-module dispatch tests for advanced modules ---
|
||||
|
||||
func TestModulesAdv_ExecuteModuleWithMock_Good_DispatchUser(t *testing.T) {
|
||||
|
|
@ -1140,6 +1164,24 @@ func TestModulesAdv_ExecuteModuleWithMock_Good_DispatchGroup(t *testing.T) {
|
|||
assert.True(t, result.Changed)
|
||||
}
|
||||
|
||||
func TestModulesAdv_ExecuteModuleWithMock_Good_DispatchGroupBy(t *testing.T) {
|
||||
e, _ := newTestExecutorWithMock("host1")
|
||||
|
||||
task := &Task{
|
||||
Module: "group_by",
|
||||
Args: map[string]any{
|
||||
"key": "role_app",
|
||||
},
|
||||
}
|
||||
|
||||
result, err := executeModuleWithMock(e, nil, "host1", task)
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.True(t, result.Changed)
|
||||
assert.Contains(t, e.inventory.All.Children, "role_app")
|
||||
assert.Contains(t, e.inventory.All.Children["role_app"].Hosts, "host1")
|
||||
}
|
||||
|
||||
func TestModulesAdv_ExecuteModuleWithMock_Good_DispatchCron(t *testing.T) {
|
||||
e, mock := newTestExecutorWithMock("host1")
|
||||
mock.expectCommand(`crontab`, "", "", 0)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue