/
cni.go
106 lines (83 loc) · 2.43 KB
/
cni.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
package cniconfig
import (
"bytes"
"fmt"
"io/ioutil"
"net"
"os"
"path"
"text/template"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
)
type tplData struct {
PodCIDR string
NodePodCIDR string
MTU int
}
func (r *Reconciler) writeCNIConfig(log *zap.Logger, node *corev1.Node, mtu int) error {
_, nodePodCidr, err := net.ParseCIDR(node.Spec.PodCIDR)
if err != nil {
return fmt.Errorf("unable to parse node pod cidr: %w", err)
}
data := tplData{
PodCIDR: r.podNet.String(),
NodePodCIDR: nodePodCidr.String(),
MTU: mtu,
}
files, err := ioutil.ReadDir(path.Clean(r.cni.TemplateDir))
if err != nil {
return fmt.Errorf("unable to list template files: %w", err)
}
for _, file := range files {
sourceFilename := path.Join(r.cni.TemplateDir, file.Name())
// ioutil.ReadDir uses LState which does not follow symlinks - So symlinked directories will return false on IsDir
fileInfo, err := os.Stat(sourceFilename)
if err != nil {
return fmt.Errorf("unable to check file '%s': %w", sourceFilename, err)
}
if fileInfo.IsDir() {
continue
}
targetFilename := path.Join(r.cni.TargetDir, fileInfo.Name())
if err := templateFile(log, sourceFilename, targetFilename, data); err != nil {
return fmt.Errorf("unable to template file '%s': %w", sourceFilename, err)
}
}
return nil
}
func templateFile(parentLog *zap.Logger, sourceFilename, targetFilename string, data tplData) error {
log := parentLog.With(
zap.String("template_source", sourceFilename),
zap.String("template_target", targetFilename),
)
content, err := ioutil.ReadFile(sourceFilename)
if err != nil {
return err
}
log.Debug("successfully read template file")
tpl, err := template.New(path.Base(sourceFilename)).Parse(string(content))
if err != nil {
return err
}
log.Debug("successfully parsed template file")
output := &bytes.Buffer{}
if err := tpl.Execute(output, data); err != nil {
return err
}
log.Debug("successfully executed the template")
currentContent, err := ioutil.ReadFile(targetFilename)
if err != nil && !os.IsNotExist(err) {
return err
}
if bytes.Equal(currentContent, output.Bytes()) {
log.Debug("Not writing CNI config as its already up to date")
return nil
}
log.Info("CNI config does not match desired config, will override it")
if err := ioutil.WriteFile(targetFilename, output.Bytes(), 0644); err != nil {
return err
}
log.Info("Successfully wrote CNI config")
return nil
}