feat(engine): add checkHostByName to resolve hostnames with DNS error handling

Signed-off-by: Asma Bahri <asmabahri084@gmail.com>
pull/30859/head
Asma Bahri 1 month ago
parent 30404b4173
commit 75467572e9
No known key found for this signature in database
GPG Key ID: 38FD09F32A332938

@ -259,6 +259,9 @@ func (e Engine) initFunMap(t *template.Template) {
funcMap["getHostByName"] = func(_ string) string { funcMap["getHostByName"] = func(_ string) string {
return "" return ""
} }
funcMap["checkHostByName"] = func(_ string) string {
return ""
}
} }
// Set custom template funcs // Set custom template funcs

@ -60,6 +60,7 @@ func funcMap() template.FuncMap {
"mustToJson": mustToJSON, "mustToJson": mustToJSON,
"fromJson": fromJSON, "fromJson": fromJSON,
"fromJsonArray": fromJSONArray, "fromJsonArray": fromJSONArray,
"checkHostByName": checkHostByName,
// This is a placeholder for the "include" function, which is // This is a placeholder for the "include" function, which is
// late-bound to a template. By declaring it here, we preserve the // late-bound to a template. By declaring it here, we preserve the
@ -232,3 +233,34 @@ func fromJSONArray(str string) []interface{} {
} }
return a return a
} }
// checkHostByName resolves a hostname to its first IP address.
//
// - If the host is found, it returns the IP address.
// - If the host does not exist (NXDOMAIN), it returns an empty string.
// - If DNS fails for other reasons (SERVFAIL, timeout, etc.), it returns an error and aborts rendering.
//
// This function was introduced because Sprig's getHostByName silently swallows DNS errors.
// It retries DNS resolution up to 3 times on transient errors, with a 15-second delay between attempts.
func checkHostByName(name string) (string, error) {
var lastErr error
for tries := 3; tries > 0; tries-- {
addrs, err := net.LookupHost(name)
if err == nil && len(addrs) > 0 {
return addrs[0], nil
}
lastErr = err
dnsErr, ok := err.(*net.DNSError)
if !ok {
return "", fmt.Errorf("checkHostByName: DNS error: %v", err)
}
if dnsErr.IsNotFound {
return "", nil // NXDOMAIN is not considered fatal
}
time.Sleep(15 * time.Second)
}
return "", fmt.Errorf("checkHostByName: DNS resolution failed for %s: %v", name, lastErr)
}

Loading…
Cancel
Save