-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
160 lines (120 loc) · 4.02 KB
/
main.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/fewlinesco/k8s-cfgenerator/cmd/cfgenerator/internal"
"github.com/fewlinesco/k8s-cfgenerator/cmd/cfgenerator/internal/file"
"github.com/fewlinesco/k8s-cfgenerator/cmd/cfgenerator/internal/interpreter"
)
const usageFmt = `Synopsis
%[1]s [-interpreter=plain|jsonnet] [volume-paths ...]
Description
Reads a content (plain text or JSONNET) template and output the result
to a file (as a JSON or plain text).
It reads all files present in 'the volume-paths' folders and for each of
these files, sets the file name as variable name and the content of the
file as value.
Flags
-in=<template-path>|-
A path to the template to use as input. When using "-" input is STDIN.
(Default: -)
-interpreter=plain|jsonnet
When plain, interprets the input as plain text and use gotpl as
variable system.
When jsonnet, interprets the input as JSONNET and use extVar as
variable system.
By default it is set to jsonnet
-out=<file>|-
A path to where to generate the file. When using "-" output is STDOUT.
(Default: -)
Note that you can pass the flag several times if the goal is to write
the configuration in several locations. It can be useful to add an
additional '-out=-' for debugging purpose for example.
Arguments
[volume-paths ...]
a list of folder or files.
When file: the content of the file will be loaded and set in a JSONNET
extVar named with the file name.
When folder: the content of each of the file of the folder will be
loaded and set in a JSONNET extVar named with the file name.
The script doesn't load files in sub folders.
Examples
1. read all files in /data/configmap and /data/secrets and use their name
as JSONNET extvar. Then evaluates STDIN and generate a JSON in STDOUT
$> %[1]s /data/configmap /data/secrets <<EOF
{
api: {
address: '0.0.0.0:' + std.extVar('API_PORT'),
},
database: {
password: std.extVar("DATABASE_PASSWORD"),
username: std.extVar("DATABASE_USERNAME"),
},
}
EOF
2. read all files in /data/configmap and /data/secrets and use their name
as JSONNET extvar. Then evaluates /app/config.jsonnet and generate a
JSON in /app/config.json
$> %[1]s -in /app/confg.jsonnet -out /app/config.json /data/configmap /data/secrets
`
type stringsFlag []string
func (s *stringsFlag) String() string {
return strings.Join(*s, ", ")
}
func (s *stringsFlag) Set(value string) error {
*s = append(*s, value)
return nil
}
func main() {
var cfg = struct {
InterpreterName string
In string
Outs stringsFlag
}{
InterpreterName: "jsonnet",
In: "-",
}
flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), usageFmt, filepath.Base(os.Args[0])) }
flag.StringVar(&cfg.InterpreterName, "interpreter", cfg.InterpreterName, "")
flag.StringVar(&cfg.In, "in", cfg.In, "")
flag.Var(&cfg.Outs, "out", "")
flag.Parse()
if len(cfg.Outs) == 0 {
cfg.Outs = append(cfg.Outs, "-")
}
if err := run(cfg.InterpreterName, cfg.In, cfg.Outs, flag.Args()); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run(interpreterName string, inputPath string, outputPaths []string, volumes []string) error {
runtime, found := interpreter.Get(interpreterName)
if !found {
return fmt.Errorf("unsupported interpreter '%s'", interpreterName)
}
input, err := file.OpenInput(inputPath)
if err != nil {
return fmt.Errorf("can't open input file '%s': %v", inputPath, err)
}
defer input.Close()
content, err := internal.Generate(runtime, input, volumes)
if err != nil {
return fmt.Errorf("can't generate content: %v", err)
}
outputs := make([]*os.File, len(outputPaths))
for i, outputPath := range outputPaths {
output, err := file.OpenOutput(outputPath)
if err != nil {
return fmt.Errorf("can't open output file '%s': %v", outputPath, err)
}
defer output.Close()
outputs[i] = output
}
for i := range outputs {
fmt.Fprint(outputs[i], content)
}
return nil
}