Add support for loading receiver configurations from external YAML files, keeping backwards compatibility with inline receivers in the main config.
- New YAML field
receiver_files(list of glob patterns) onConfigstruct - Mutually exclusive with inline
receivers: error if both are set - Glob patterns supported (e.g.
receivers/*.yml), consistent withtemplates - Relative paths resolved against config file directory (same as templates)
- Each file contains a YAML list of
Receiverobjects (one or more per file) - On reload failure for a file: keep previous receivers from that file, log error
- Receiver names must still be globally unique across all files
alertmanager.yml:
receiver_files:
- 'receivers/*.yml'
route:
receiver: team-X
...receivers/team-x.yml:
- name: 'team-X'
webhook_configs:
- url: 'http://example.com/hook'
- name: 'team-X-pager'
pagerduty_configs:
- routing_key: 'secret'config/config.go: AddReceiverFiles []stringfield with yaml tagreceiver_files
config/config.go: New function that reads a single file, parses[]Receiverviayaml.UnmarshalStrict, and returns the receivers- Validates each receiver has a non-empty name
config/config.go: Expands globs, callsLoadReceiverFileper matched file- On per-file failure: logs error, keeps previously loaded receivers for that file (requires a cache parameter or uses a simple map)
- Returns merged
[]Receiverlist - Checks for duplicate names across files
- Error if both
ReceiversandReceiverFilesare non-empty - When
ReceiverFilesis set, skip inline receiver validation (it's empty)
- After
Load(), ifReceiverFilesis set, expand globs (relative to config dir), load receivers, merge intocfg.Receivers - Then the existing validation in
UnmarshalYAML(global defaults, receiver-route checks) can be deferred or re-run after merging - Key insight: receiver validation that applies global defaults (lines 412-676 in
config.go) runs insideUnmarshalYAML, but external receivers won't exist yet at that point. We need to split this:UnmarshalYAMLhandles inline receivers normallyLoadFileloads external receivers, applies the same global-defaults logic, then runscheckReceivervalidation
- Also resolve
ReceiverFilespaths relative to config dir (same as templates) - HTTPConfig directory resolution for externally-loaded receivers already handled since they're merged into
cfg.Receivers
config/coordinator.go: Keep alastReceiversByFile map[string][]Receiverto enable fallback on per-file errors- On reload, pass this map to
LoadReceiverFiles; on success for a file, update the map; on failure, reuse previous entries
config/config_test.go: Test mutual exclusivity error, glob loading, per-file error with fallback, duplicate name detection, global defaults applied to external receivers- Add test data files under
config/testdata/receivers/
amtool check-configshould also validate external receiver files