-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrender.go
123 lines (105 loc) · 2.69 KB
/
render.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package topology // import "github.com/nathanaelle/wireguard-topology"
import (
"fmt"
"io"
"io/ioutil"
"path/filepath"
"text/template"
)
type (
Template interface {
Execute(template string, dest io.Writer, data interface{}) (err error)
}
tmpls struct {
templates map[string]*template.Template
}
NetCluster struct {
Ifaces map[string]*WGInterface
}
WGInterface struct {
Host string
Address string
LocalIP string
Iface string
PrivateKey string
ListenPort uint16
FirewallMark uint32
Peers map[string]*WGPeer
Templates []string
Misc map[string]interface{}
}
WGPeer struct {
Host string
PublicKey string
PreSharedKey string
AllowedIPs string
Address string
PeerIP string
EndPoint string
PersistentKeepalive uint16
}
)
// LoadTemplates compiles all the available templates in a folder (not the subfolders)
// a template is a file with the extension .tmpl
func LoadTemplates(dir string) (Template, error) {
var err error
t := &tmpls{
templates: make(map[string]*template.Template),
}
if dir == "" {
return t, nil
}
files, err := ioutil.ReadDir(dir)
if err != nil {
return nil, fmt.Errorf("can't read %q : %v", dir, err)
}
for _, file := range files {
if file.IsDir() {
continue
}
if file.Size() == 0 {
continue
}
if filepath.Ext(file.Name()) != ".tmpl" {
continue
}
fileData, err := ioutil.ReadFile(filepath.Join(dir, file.Name()))
if err != nil {
return nil, fmt.Errorf("can't read template %q : %v", file.Name(), err)
}
tmplName := file.Name()
tmplName = tmplName[0 : len(tmplName)-5]
t.templates[tmplName], err = template.New(tmplName).Parse(string(fileData))
if err != nil {
return nil, fmt.Errorf("can't parse template %q : %v", file.Name(), err)
}
}
return t, nil
}
func (t *tmpls) Execute(template string, dest io.Writer, data interface{}) error {
if tmpl, ok := t.templates[template]; ok {
return tmpl.Execute(dest, data)
}
return fmt.Errorf("can't load template %q", template)
}
//Render applys templates on the data and export the result in output
func Render(output Output, t Template, clusters map[string]*NetCluster) error {
for _, cluster := range clusters {
for _, wgiface := range cluster.Ifaces {
if err := output.AddFolder(wgiface.Host); err != nil {
return err
}
for _, template := range wgiface.Templates {
writecloser, err := output.AddEntry(wgiface.Host, template)
if err != nil {
return err
}
defer writecloser.Close()
if err := t.Execute(template, writecloser, wgiface); err != nil {
return err
}
}
}
}
return nil
}