-
Notifications
You must be signed in to change notification settings - Fork 1
/
PuppetConfigParser.go
107 lines (91 loc) · 2.75 KB
/
PuppetConfigParser.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
package puppetconfig
import (
"bytes"
"log"
"os/exec"
"regexp"
"strings"
)
type PuppetConfigParser struct {
log *log.Logger
parsedConfig *PuppetConfig
}
type PuppetConfig struct {
PuppetExecutable string
ConfFile string
ConfDir string
SslDir string
CsrDir string
SignedCertDir string
EnvironmentPath []string
}
func NewPuppetConfigParser(log *log.Logger) *PuppetConfigParser {
return &PuppetConfigParser{
log: log,
parsedConfig: &PuppetConfig{},
}
}
func (ctx PuppetConfigParser) LoadPuppetConfig(puppetExecutable string, puppetConfDir string) *PuppetConfig {
var output bytes.Buffer
ctx.log.Printf("Asking \"%s\" for its configuration...", puppetExecutable)
// Run puppet config print on the main section, then on the server section, with server values taking precedence.
for _, section := range []string{"main", "server"} {
configLoader := exec.Cmd{
Path: puppetExecutable,
Args: []string{puppetExecutable, "config", "print", "--confdir", puppetConfDir, "--section", section},
Stdout: &output,
}
configLoader.Run()
ctx.parseConfig(&output)
output.Reset()
}
// have we read everything we need?
if validateParsedConfig(ctx.parsedConfig) {
ctx.parsedConfig.PuppetExecutable = puppetExecutable
return ctx.parsedConfig
} else {
ctx.log.Print("Output of \"puppet config print\" was not in the correct format.")
ctx.log.Print("Please be sure PuppetExecutable is pointing to a working puppet installation,")
ctx.log.Print("PuppetConfDir is pointing to the systemwide puppet configuration directory,")
ctx.log.Print("and that the user you run spp as has permission to run puppet and read the config file.")
return nil
}
}
func (ctx PuppetConfigParser) parseConfig(configData *bytes.Buffer) {
parsedConfig := ctx.parsedConfig
var err error = nil
var line string
pattern := regexp.MustCompile(`^([a-zA-Z_0-9]+)\s=\s(.*)\n?$`)
for err == nil {
line, err = configData.ReadString('\n')
matches := pattern.FindStringSubmatch(line)
if matches != nil && len(matches) > 0 {
name := matches[1]
value := matches[2]
switch name {
case "ssldir":
parsedConfig.SslDir = value
case "csrdir":
parsedConfig.CsrDir = value
case "signeddir":
parsedConfig.SignedCertDir = value
case "config":
parsedConfig.ConfFile = value
case "confdir":
parsedConfig.ConfDir = value
case "environmentpath":
parsedConfig.EnvironmentPath = strings.Split(value, ":")
}
}
}
}
func validateParsedConfig(cfg *PuppetConfig) bool {
ok := true
ok = ok && cfg.SslDir != ""
ok = ok && cfg.CsrDir != ""
ok = ok && cfg.SignedCertDir != ""
ok = ok && cfg.ConfFile != ""
ok = ok && cfg.ConfDir != ""
ok = ok && len(cfg.EnvironmentPath) != 0
return ok
}