-
Notifications
You must be signed in to change notification settings - Fork 48
/
funcs.go
161 lines (137 loc) · 4.22 KB
/
funcs.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
161
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package renderer
import (
"fmt"
"os"
"strings"
"text/template"
"github.com/Masterminds/sprig/v3"
"github.com/davecgh/go-spew/spew"
"github.com/hashicorp/nomad-pack/internal/pkg/variable/parser"
"github.com/hashicorp/nomad/api"
"golang.org/x/exp/maps"
)
// funcMap instantiates our default template function map with populated
// functions for use within text.Template.
func funcMap(r *Renderer) template.FuncMap {
// The base of the funcmap comes from the template context funcs
f := make(template.FuncMap)
if r != nil && r.pv != nil {
maps.Copy(f, parser.PackTemplateContextFuncs(r.pv.IsV1()))
}
// Copy the sprig funcs into the funcmap.
maps.Copy(f, sprig.TxtFuncMap())
// Add debugging functions. These are useful when debugging templates and
// variables.
f["spewDump"] = spew.Sdump
f["spewPrintf"] = spew.Sprintf
f["customSpew"] = spew.NewDefaultConfig
f["withIndent"] = withIndent
f["withMaxDepth"] = withMaxDepth
f["withDisableMethods"] = withDisableMethods
f["withDisablePointerMethods"] = withDisablePointerMethods
f["withDisablePointerAddresses"] = withDisablePointerAddresses
f["withDisableCapacities"] = withDisableCapacities
f["withContinueOnMethod"] = withContinueOnMethod
f["withDisableMethods"] = withDisableMethods
f["withSortKeys"] = withSortKeys
f["withSpewKeys"] = withSpewKeys
if r != nil && r.Client != nil {
f["nomadNamespaces"] = nomadNamespaces(r.Client)
f["nomadNamespace"] = nomadNamespace(r.Client)
f["nomadRegions"] = nomadRegions(r.Client)
}
// Add additional custom functions.
f["fileContents"] = fileContents
f["toStringList"] = toStringList
return f
}
// fileContents reads the passed path and returns the content as a string.
func fileContents(file string) (string, error) {
content, err := os.ReadFile(file)
if err != nil {
return "", fmt.Errorf("failed to read %s: %v", file, err)
}
return string(content), nil
}
// nomadNamespaces performs a Nomad API query against the namespace endpoint to
// list the namespaces.
func nomadNamespaces(client *api.Client) func() ([]*api.Namespace, error) {
return func() ([]*api.Namespace, error) {
out, _, err := client.Namespaces().List(&api.QueryOptions{})
return out, err
}
}
// nomadNamespace performs a query against the passed namespace.
func nomadNamespace(client *api.Client) func(string) (*api.Namespace, error) {
return func(ns string) (*api.Namespace, error) {
out, _, err := client.Namespaces().Info(ns, &api.QueryOptions{})
return out, err
}
}
// nomadRegions performs a listing of the Nomad regions from the Nomad API. It
// returns these within a list along with any error whilst performing the API
// call.
func nomadRegions(client *api.Client) func() ([]string, error) {
return func() ([]string, error) { return client.Regions().List() }
}
// toStringList takes a list of string and returns the HCL equivalent which is
// useful when templating jobs and params such as datacenters.
func toStringList(l any) (string, error) {
var out strings.Builder
out.WriteRune('[')
switch tl := l.(type) {
case []any:
// If l is a []string, then the caller probably wants that printed
// as a list of quoted elements, JSON style.
for i, v := range tl {
if i > 0 {
out.WriteString(", ")
}
out.WriteString(fmt.Sprintf("%q", v))
}
default:
out.WriteString(fmt.Sprintf("%q", l))
}
out.WriteRune(']')
o := out.String()
return o, nil
}
// Spew helper funcs
func withIndent(in string, s *spew.ConfigState) any {
s.Indent = in
return s
}
func withMaxDepth(in int, s *spew.ConfigState) any {
s.MaxDepth = in
return s
}
func withDisableMethods(s *spew.ConfigState) any {
s.DisableMethods = true
return s
}
func withDisablePointerMethods(s *spew.ConfigState) any {
s.DisablePointerMethods = true
return s
}
func withDisablePointerAddresses(s *spew.ConfigState) any {
s.DisablePointerAddresses = true
return s
}
func withDisableCapacities(s *spew.ConfigState) any {
s.DisableCapacities = true
return s
}
func withContinueOnMethod(s *spew.ConfigState) (any, error) {
s.ContinueOnMethod = true
return s, nil
}
func withSortKeys(s *spew.ConfigState) any {
s.SortKeys = true
return s
}
func withSpewKeys(s *spew.ConfigState) any {
s.SpewKeys = true
return s
}