feat(ansible): support include_vars files_matching filter

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 23:41:20 +00:00
parent 5bb3a2f636
commit c1f0af5d5a
2 changed files with 36 additions and 2 deletions

View file

@ -2114,6 +2114,7 @@ func (e *Executor) moduleIncludeVars(args map[string]any) (*TaskResult, error) {
}
dir := getStringArg(args, "dir", "")
name := getStringArg(args, "name", "")
filesMatching := getStringArg(args, "files_matching", "")
hashBehaviour := lower(getStringArg(args, "hash_behaviour", "replace"))
depth := getIntArg(args, "depth", 0)
@ -2148,7 +2149,7 @@ func (e *Executor) moduleIncludeVars(args map[string]any) (*TaskResult, error) {
if dir != "" {
dir = e.resolveLocalPath(dir)
files, err := collectIncludeVarsFiles(dir, depth)
files, err := collectIncludeVarsFiles(dir, depth, filesMatching)
if err != nil {
return nil, err
}
@ -2175,7 +2176,7 @@ func (e *Executor) moduleIncludeVars(args map[string]any) (*TaskResult, error) {
return &TaskResult{Changed: true, Msg: msg}, nil
}
func collectIncludeVarsFiles(dir string, depth int) ([]string, error) {
func collectIncludeVarsFiles(dir string, depth int, filesMatching string) ([]string, error) {
info, err := os.Stat(dir)
if err != nil {
return nil, coreerr.E("Executor.moduleIncludeVars", "read vars dir", err)
@ -2189,6 +2190,14 @@ func collectIncludeVarsFiles(dir string, depth int) ([]string, error) {
depth int
}
var matcher *regexp.Regexp
if filesMatching != "" {
matcher, err = regexp.Compile(filesMatching)
if err != nil {
return nil, coreerr.E("Executor.moduleIncludeVars", "compile files_matching", err)
}
}
var files []string
stack := []dirEntry{{path: dir, depth: 0}}
for len(stack) > 0 {
@ -2213,6 +2222,9 @@ func collectIncludeVarsFiles(dir string, depth int) ([]string, error) {
ext := lower(filepath.Ext(entry.Name()))
if ext == ".yml" || ext == ".yaml" {
if matcher != nil && !matcher.MatchString(entry.Name()) {
continue
}
files = append(files, fullPath)
}
}

View file

@ -998,6 +998,28 @@ func TestModulesAdv_ModuleIncludeVars_Good_RespectsDepthLimit(t *testing.T) {
assert.NotContains(t, result.Msg, joinPath(dir, "nested", "deep", "03-grandchild.yml"))
}
func TestModulesAdv_ModuleIncludeVars_Good_FiltersFilesMatching(t *testing.T) {
dir := t.TempDir()
require.NoError(t, writeTestFile(joinPath(dir, "01-base.yml"), []byte("base_value: base\n"), 0644))
require.NoError(t, writeTestFile(joinPath(dir, "02-extra.yaml"), []byte("extra_value: extra\n"), 0644))
require.NoError(t, writeTestFile(joinPath(dir, "notes.txt"), []byte("ignored: true\n"), 0644))
e := NewExecutor("/tmp")
result, err := e.moduleIncludeVars(map[string]any{
"dir": dir,
"files_matching": `^02-.*\.ya?ml$`,
})
require.NoError(t, err)
assert.True(t, result.Changed)
assert.Equal(t, "extra", e.vars["extra_value"])
_, hasBase := e.vars["base_value"]
assert.False(t, hasBase)
assert.Contains(t, result.Msg, joinPath(dir, "02-extra.yaml"))
assert.NotContains(t, result.Msg, joinPath(dir, "01-base.yml"))
}
// --- sysctl module ---
func TestModulesAdv_ModuleSysctl_Good_ReloadsAfterPersisting(t *testing.T) {