Omit duplicate passwd and group entries in syncuser overlay

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
Jonathon Anderson
2025-02-10 19:11:52 -07:00
parent a686ddb7ad
commit 21333482e6
10 changed files with 171 additions and 45 deletions

View File

@@ -130,3 +130,34 @@ func importSoftlink(lnk string) string {
func softlink(target string) string {
return fmt.Sprintf("{{ /* softlink \"%s\" */ }}", target)
}
// UniqueField returns a filtered version of a multi-line input string. input is
// expected to be a field-separated format with one record per line (terminated
// by `\n`). Order of lines is preserved, with the first matching line taking
// precedence.
//
// For example, parsing /etc/passwd filter /etc/passwd for unique user names:
//
// Lines without the index field (e.g., blank lines) are always included in the
// output.
//
// UniqueField(":", 0, passwdContent)
func UniqueField(sep string, index int, input string) string {
inputLines := strings.Split(input, "\n")
var outputLines []string
found := make(map[string]bool)
for _, line := range inputLines {
inputFields := strings.Split(line, sep)
if len(inputFields) > index {
field := inputFields[index]
if field != "" {
if found[field] {
continue
}
found[field] = true
}
}
outputLines = append(outputLines, line)
}
return strings.Join(outputLines, "\n")
}

View File

@@ -59,3 +59,50 @@ func Test_createIgnitionJson(t *testing.T) {
node := nodeInfos[0]
assert.JSONEq(t, expected_json, createIgnitionJson(&node))
}
func Test_UniqueField(t *testing.T) {
tests := map[string]struct {
input string
sep string
field int
output string
}{
"empty": {
input: ``,
sep: ":",
field: 0,
output: ``,
},
"unique input": {
input: `
name1:aaaa
name2:bbbb
`,
sep: ":",
field: 0,
output: `
name1:aaaa
name2:bbbb
`,
},
"duplicate field": {
input: `
name1: aaaa
name1: bbbb
`,
sep: ":",
field: 0,
output: `
name1: aaaa
`,
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
assert.Equal(t, tt.output, UniqueField(tt.sep, tt.field, tt.input))
})
}
}

View File

@@ -500,6 +500,7 @@ func RenderTemplateFile(fileName string, data TemplateStruct) (
backupFile = false
return ""
},
"UniqueField": UniqueField,
}
// Merge sprig.FuncMap with our FuncMap