1 // Config: parse templates.yaml and expand templates
3 // SPDX-License-Identifier: GPL-3.0-or-later
4 // Copyright (C) 2021-2024 Simon Ruderich
18 "ruderich.org/simon/safcm"
21 func LoadTemplates(group string, files map[string]*safcm.File,
22 host string, groups []string,
23 allHosts *Hosts, allGroups map[string][]string) error {
25 path := filepath.Join(group, "templates.yaml")
27 var templates []string
28 x, err := os.ReadFile(path)
30 if os.IsNotExist(err) {
35 err = yaml.UnmarshalStrict(x, &templates)
37 return fmt.Errorf("%s: failed to load: %v", path, err)
40 groupsMap := make(map[string]bool)
41 for _, x := range groups {
44 allHostsMap := make(map[string]bool)
45 for x := range allHosts.Map {
48 allGroupsMap := make(map[string]bool)
49 for x := range allGroups {
50 allGroupsMap[x] = true
53 for _, x := range templates {
56 return fmt.Errorf("%s: %q does not exist in files/",
59 if f.Mode.Type() != 0 /* regular file */ {
60 return fmt.Errorf("%s: %q is not a regular file",
64 tmplPath := filepath.Join(group, "files", x)
66 // Parse and expand template
68 tmpl, err := template.New(tmplPath).Parse(string(f.Data))
70 return fmt.Errorf("%s: invalid %v", path, err)
72 err = tmpl.Execute(&buf, &templateArgs{
75 allHosts: allHostsMap,
76 allGroups: allGroupsMap,
79 return fmt.Errorf("%s: %v", path, err)
87 // templateArgs is passed to .Execute() of the template.
88 type templateArgs struct {
90 groups map[string]bool
91 allHosts map[string]bool
92 allGroups map[string]bool
95 // TODO: extend data passed to template
97 func (t *templateArgs) IsHost(host string) bool {
98 // Don't permit invalid hosts to detect typos
99 if !t.allHosts[host] {
100 panic(fmt.Sprintf("host %q does not exist", host))
102 return t.host == host
104 func (t *templateArgs) InGroup(group string) bool {
105 // Don't permit invalid groups to detect typos; detected groups cannot
107 if group != GroupAll &&
108 !t.allGroups[group] &&
109 !t.allHosts[group] &&
110 !strings.HasPrefix(group, GroupDetectedPrefix) {
111 panic(fmt.Sprintf("group %q does not exist", group))
113 return t.groups[group]