|
9 | 9 | "net" |
10 | 10 | "net/http" |
11 | 11 | "net/url" |
| 12 | + "slices" |
12 | 13 | "strings" |
13 | 14 | "time" |
14 | 15 |
|
@@ -78,6 +79,14 @@ type Setter interface { |
78 | 79 | // belong to the Syslog Agent. If a particular downstream consumer doesn't support some scheme, it should handle the validation itself |
79 | 80 | var allowedSchemes = []string{"syslog", "syslog-tls", "https", "https-batch", "secure-endpoint", "metrics-endpoint", "structured-format"} |
80 | 81 |
|
| 82 | +// nonNetworkSchemes lists schemes used by downstream consumers other than the Syslog Agent as opaque |
| 83 | +// discovery tags on a CUPS binding (e.g. TAS Metric Registrar's documented "structured-format://" and |
| 84 | +// "metrics-endpoint://" convention) rather than as real syslog drain endpoints. Bindings using these |
| 85 | +// schemes aren't guaranteed to have a resolvable, or even present, hostname, so they must be exempt from |
| 86 | +// the syslog-drain-specific network checks below (hostname presence, log type filters, DNS resolution, |
| 87 | +// IP blacklist) - those only make sense for bindings that are actually dialed as drains. |
| 88 | +var nonNetworkSchemes = []string{"secure-endpoint", "metrics-endpoint", "structured-format"} |
| 89 | + |
81 | 90 | func NewPoller( |
82 | 91 | ac client, |
83 | 92 | pi time.Duration, |
@@ -237,39 +246,41 @@ func (bc *bindingChecker) checkBindings(bindings []Binding) []Binding { |
237 | 246 | continue |
238 | 247 | } |
239 | 248 |
|
240 | | - if len(u.Host) == 0 { |
241 | | - bc.rejectBinding(b.Credentials, fmt.Sprintf("No hostname found in syslog drain url %s", anonymousUrl.String()), true) |
242 | | - continue |
243 | | - } |
| 249 | + if !slices.Contains(nonNetworkSchemes, u.Scheme) { |
| 250 | + if len(u.Host) == 0 { |
| 251 | + bc.rejectBinding(b.Credentials, fmt.Sprintf("No hostname found in syslog drain url %s", anonymousUrl.String()), true) |
| 252 | + continue |
| 253 | + } |
244 | 254 |
|
245 | | - if invalidLogFilter(u) { |
246 | | - bc.rejectBinding(b.Credentials, fmt.Sprintf("include-log-types and exclude-log-types cannot be used at the same time in syslog drain url %s", anonymousUrl.String()), true) |
247 | | - continue |
248 | | - } |
| 255 | + if invalidLogFilter(u) { |
| 256 | + bc.rejectBinding(b.Credentials, fmt.Sprintf("include-log-types and exclude-log-types cannot be used at the same time in syslog drain url %s", anonymousUrl.String()), true) |
| 257 | + continue |
| 258 | + } |
249 | 259 |
|
250 | | - sourceTypes := getUnknownSourceTypes(u.Query()) |
251 | | - if sourceTypes != nil { |
252 | | - bc.rejectBinding(b.Credentials, fmt.Sprintf("Unknown log types '%s' in log type filter in syslog drain url %s", strings.Join(sourceTypes, ", "), anonymousUrl.String()), true) |
253 | | - continue |
254 | | - } |
| 260 | + sourceTypes := getUnknownSourceTypes(u.Query()) |
| 261 | + if sourceTypes != nil { |
| 262 | + bc.rejectBinding(b.Credentials, fmt.Sprintf("Unknown log types '%s' in log type filter in syslog drain url %s", strings.Join(sourceTypes, ", "), anonymousUrl.String()), true) |
| 263 | + continue |
| 264 | + } |
255 | 265 |
|
256 | | - _, exists := bc.failedHostsCache.Get(u.Host) |
257 | | - if exists { |
258 | | - bc.rejectBinding(b.Credentials, fmt.Sprintf("Skipped resolve ip address for syslog drain with url %s due to prior failure", anonymousUrl.String()), false) |
259 | | - continue |
260 | | - } |
| 266 | + _, exists := bc.failedHostsCache.Get(u.Host) |
| 267 | + if exists { |
| 268 | + bc.rejectBinding(b.Credentials, fmt.Sprintf("Skipped resolve ip address for syslog drain with url %s due to prior failure", anonymousUrl.String()), false) |
| 269 | + continue |
| 270 | + } |
261 | 271 |
|
262 | | - ip, err := bc.checker.ResolveAddr(u.Host) |
263 | | - if err != nil { |
264 | | - bc.failedHostsCache.Set(u.Host, true) |
265 | | - bc.rejectBinding(b.Credentials, fmt.Sprintf("Cannot resolve ip address for syslog drain with url %s", anonymousUrl.String()), true) |
266 | | - continue |
267 | | - } |
| 272 | + ip, err := bc.checker.ResolveAddr(u.Host) |
| 273 | + if err != nil { |
| 274 | + bc.failedHostsCache.Set(u.Host, true) |
| 275 | + bc.rejectBinding(b.Credentials, fmt.Sprintf("Cannot resolve ip address for syslog drain with url %s", anonymousUrl.String()), true) |
| 276 | + continue |
| 277 | + } |
268 | 278 |
|
269 | | - err = bc.checker.CheckBlacklist(ip) |
270 | | - if err != nil { |
271 | | - bc.rejectBinding(b.Credentials, fmt.Sprintf("Resolved ip address for syslog drain with url %s is blacklisted", anonymousUrl.String()), true, true) |
272 | | - continue |
| 279 | + err = bc.checker.CheckBlacklist(ip) |
| 280 | + if err != nil { |
| 281 | + bc.rejectBinding(b.Credentials, fmt.Sprintf("Resolved ip address for syslog drain with url %s is blacklisted", anonymousUrl.String()), true, true) |
| 282 | + continue |
| 283 | + } |
273 | 284 | } |
274 | 285 |
|
275 | 286 | var validCredentials []Credentials |
@@ -316,13 +327,7 @@ func sendAppLogMessage(msg string, apps []App, appLogClient v2.LogClient, logger |
316 | 327 | } |
317 | 328 |
|
318 | 329 | func invalidScheme(scheme string) bool { |
319 | | - for _, s := range allowedSchemes { |
320 | | - if s == scheme { |
321 | | - return false |
322 | | - } |
323 | | - } |
324 | | - |
325 | | - return true |
| 330 | + return !slices.Contains(allowedSchemes, scheme) |
326 | 331 | } |
327 | 332 |
|
328 | 333 | // invalidLogFilter checks if both include-log-types and exclude-log-types are set |
|
0 commit comments