Skip to content

Commit 92a8046

Browse files
committed
Add a basic application template
1 parent 839552c commit 92a8046

File tree

8 files changed

+237
-0
lines changed

8 files changed

+237
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
local app = import '../../lib/app.libsonnet';
2+
local ns = import 'namespace.libsonnet';
3+
4+
app.new(
5+
name='{{ .Name }}',
6+
path='applications/base/{{ .Name }}',
7+
namespace=ns.metadata.name,
8+
).withChart(
9+
name='{{ .Name }}',
10+
repoURL='https://< REPLACE ME >',
11+
targetRevision='0.0.0',
12+
releaseName='{{ .Name }}',
13+
values='values.yaml'
14+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
local ingress = import '../../lib/ingress.libsonnet';
2+
local ns = import 'namespace.libsonnet';
3+
4+
local ingressHost = std.extVar('ingressHost');
5+
local ingressAnnotations = std.parseYaml(std.extVar('ingressAnnotations'));
6+
7+
ingress.new(
8+
name='{{ .Name }}-ingress',
9+
namespace=ns.metadata.name,
10+
host=ingressHost,
11+
serviceName='< REPLACE ME >',
12+
servicePort=0000,
13+
annotations=ingressAnnotations {
14+
'traefik.ingress.kubernetes.io/router.middlewares': 'authentik-ak-outpost@kubernetescrd',
15+
'gethomepage.dev/enabled': 'true',
16+
'gethomepage.dev/name': '{{ .Name }}',
17+
'gethomepage.dev/description': '< REPLACE ME >',
18+
'gethomepage.dev/group': '< REPLACE ME >',
19+
'gethomepage.dev/icon': '< REPLACE ME >',
20+
'gethomepage.dev/podSelector': '',
21+
},
22+
)
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// jsonnet base/{{ .Name }}/main.jsonnet -J vendor
2+
3+
local ns = import 'namespace.libsonnet';
4+
local ingress = import 'ingress.libsonnet';
5+
6+
[ns] + ingress
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
local k = import '../../lib/k.libsonnet';
2+
3+
k.core.v1.namespace.new('{{ .Name }}')

applications/.template/base/values.yaml

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import '../../../base/{{ .Name }}/application.libsonnet'

applications/.template/main.go

+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"fmt"
7+
"html/template"
8+
"os"
9+
"path/filepath"
10+
"sort"
11+
"strings"
12+
)
13+
14+
func main() {
15+
// Prompt the user to enter a value for the name input
16+
var name string
17+
fmt.Print("Enter a value for the name input: ")
18+
fmt.Scanln(&name)
19+
20+
// Define the input and output directories
21+
baseInputDir := "applications/.template/base"
22+
baseOutputDir := filepath.Join("applications/base", name)
23+
24+
// Template all files in the base input directory
25+
err := templateDirectory(baseInputDir, baseOutputDir, name)
26+
if err != nil {
27+
panic(err)
28+
}
29+
30+
// Template all files in each environment directory
31+
envInputDir := "applications/.template/environments"
32+
envOutputDir := "applications/environments/"
33+
err = templateEnvironments(envInputDir, envOutputDir, name)
34+
if err != nil {
35+
panic(err)
36+
}
37+
}
38+
39+
// templateDirectory templates all files in the input directory and writes them to the output directory
40+
func templateDirectory(inputDir string, outputDir string, name string) error {
41+
return templateFiles(inputDir, outputDir, name)
42+
}
43+
44+
// templateEnvironments templates all files in each environment directory and prompts the user to add the output for each environment
45+
func templateEnvironments(inputDir string, outputDir string, name string) error {
46+
envOutputDirEntries, err := os.ReadDir(outputDir)
47+
if err != nil {
48+
return err
49+
}
50+
51+
for _, envOutputDirEntry := range envOutputDirEntries {
52+
if !envOutputDirEntry.IsDir() {
53+
continue
54+
}
55+
56+
envName := envOutputDirEntry.Name()
57+
envOutputPath := filepath.Join(outputDir, envName, name)
58+
59+
if envName == "environments" {
60+
continue
61+
}
62+
63+
// Prompt the user to add the environment output
64+
reader := bufio.NewReader(os.Stdin)
65+
fmt.Printf("Do you want to add the output for the %s environment? (y/n): ", envName)
66+
response, err := reader.ReadString('\n')
67+
if err != nil {
68+
return err
69+
}
70+
71+
// If the user wants to add the output, template all files in the environment directory
72+
if strings.ToLower(strings.TrimSpace(response)) == "y" {
73+
err = templateFiles(inputDir, envOutputPath, name)
74+
if err != nil {
75+
return err
76+
}
77+
78+
// Add an entry to the imports.libsonnet file in the environment
79+
importsFilePath := filepath.Join(outputDir, envName, "imports.libsonnet")
80+
err = addImportToLibsonnet(importsFilePath, name)
81+
if err != nil {
82+
return err
83+
}
84+
}
85+
}
86+
87+
return nil
88+
}
89+
90+
// templateFiles templates all files in the input directory that match the filter function and writes them to the output directory
91+
func templateFiles(inputDir string, outputDir string, name string) error {
92+
return filepath.Walk(inputDir, func(path string, info os.FileInfo, err error) error {
93+
if err != nil {
94+
return err
95+
}
96+
97+
// Skip directories
98+
if info.IsDir() {
99+
return nil
100+
}
101+
102+
// Determine the output path for the current file
103+
relPath, err := filepath.Rel(inputDir, path)
104+
if err != nil {
105+
return err
106+
}
107+
outputPath := filepath.Join(outputDir, relPath)
108+
109+
// Read the input file
110+
inputBytes, err := os.ReadFile(path)
111+
if err != nil {
112+
return err
113+
}
114+
115+
// Parse the input file as a Go template
116+
tmpl, err := template.New(relPath).Parse(string(inputBytes))
117+
if err != nil {
118+
return err
119+
}
120+
121+
// Define the data to be passed to the template
122+
data := struct {
123+
Name string
124+
}{
125+
Name: name,
126+
}
127+
128+
// Render the template with the user input
129+
var outputBuffer bytes.Buffer
130+
err = tmpl.Execute(&outputBuffer, data)
131+
if err != nil {
132+
return err
133+
}
134+
135+
// Write the rendered output to the specified file
136+
err = os.MkdirAll(filepath.Dir(outputPath), 0755)
137+
if err != nil {
138+
return err
139+
}
140+
err = os.WriteFile(outputPath, outputBuffer.Bytes(), 0644)
141+
if err != nil {
142+
return err
143+
}
144+
145+
fmt.Printf("Successfully rendered and saved file to %s\n", outputPath)
146+
147+
return nil
148+
})
149+
}
150+
151+
// addImportToLibsonnet adds an import statement to the imports.libsonnet file
152+
func addImportToLibsonnet(filePath string, name string) error {
153+
file, err := os.OpenFile(filePath, os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
154+
if err != nil {
155+
return err
156+
}
157+
defer file.Close()
158+
159+
// Read the existing imports from the file
160+
importsScanner := bufio.NewScanner(file)
161+
importsScanner.Split(bufio.ScanLines)
162+
var imports []string
163+
for importsScanner.Scan() {
164+
txt := strings.TrimSpace(importsScanner.Text())
165+
if strings.HasPrefix(txt, "import") {
166+
imports = append(imports, txt)
167+
}
168+
}
169+
if err := importsScanner.Err(); err != nil {
170+
return err
171+
}
172+
173+
// Add the new import to the list and sort it alphabetically
174+
newImport := fmt.Sprintf(`import '%s/application.libsonnet',`, name)
175+
imports = append(imports, newImport)
176+
sort.Strings(imports)
177+
178+
// Write the updated imports to the file
179+
file.Truncate(0)
180+
file.Seek(0, 0)
181+
file.WriteString("[\n")
182+
for _, imp := range imports {
183+
file.WriteString(fmt.Sprintf(" %s\n", imp))
184+
}
185+
file.WriteString("]\n")
186+
187+
return nil
188+
}

go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/MacroPower/homelab
2+
3+
go 1.21

0 commit comments

Comments
 (0)