Skip to content

Commit 06f43f3

Browse files
authored
fix: ensure sink names are unique (#1599)
1 parent 308098b commit 06f43f3

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

src/robusta/core/model/runner_config.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import base64
2-
from typing import Dict, List, Optional, Union
2+
from typing import Dict, List, Optional, Union, cast
33

44
from pydantic import BaseModel, SecretStr, root_validator, validator
55

@@ -29,6 +29,7 @@
2929
from robusta.model.alert_relabel_config import AlertRelabel
3030
from robusta.model.playbook_definition import PlaybookDefinition
3131
from robusta.utils.base64_utils import is_base64_encoded
32+
from robusta.core.sinks.sink_config import SinkConfigBase
3233

3334

3435
class PlaybookRepo(BaseModel):
@@ -81,6 +82,19 @@ class RunnerConfig(BaseModel):
8182
active_playbooks: Optional[List[PlaybookDefinition]] = []
8283
alert_relabel: Optional[List[AlertRelabel]] = []
8384

85+
@root_validator()
86+
def ensure_unique_sink_name(cls, val: Dict) -> Dict:
87+
if val.get('sinks_config'):
88+
value_set = set()
89+
sinksConfig = cast(List[SinkConfigBase], val.get('sinks_config'))
90+
for sink_config in sinksConfig:
91+
sink_name = sink_config.get_name()
92+
if sink_name in value_set:
93+
raise ValueError(f"Sink name \"{sink_name}\" is already defined. Sink names must be unique.")
94+
95+
value_set.add(sink_name)
96+
return val
97+
8498
@validator("playbook_repos")
8599
def env_var_repo_keys(cls, playbook_repos: Dict[str, PlaybookRepo]):
86100
return {k: RunnerConfig._replace_env_var_in_playbook_repo(v) for k, v in playbook_repos.items()}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
playbook_repos:
2+
chatgpt_robusta_actions:
3+
url: "file:///path/to/kubernetes-chatgpt-bot"
4+
sinks_config:
5+
- slack_sink:
6+
name: my_sink1
7+
slack_channel: my-alert-channel
8+
api_key: "foobar"
9+
scope:
10+
include:
11+
- labels:
12+
- "severity=high"
13+
- "severity=critical"
14+
15+
- slack_sink:
16+
name: my_sink1
17+
slack_channel: my-notification-channel
18+
api_key: "foobar"
19+
scope:
20+
include:
21+
- labels:
22+
- "severity=warning"
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
playbook_repos:
2+
chatgpt_robusta_actions:
3+
url: "file:///path/to/kubernetes-chatgpt-bot"
4+
sinks_config:
5+
- slack_sink:
6+
name: my_sink1
7+
slack_channel: my-alert-channel
8+
api_key: "foobar"
9+
scope:
10+
include:
11+
- labels:
12+
- "severity=high"
13+
- "severity=critical"
14+
15+
- slack_sink:
16+
name: my_sink2
17+
slack_channel: my-notification-channel
18+
api_key: "foobar"
19+
scope:
20+
include:
21+
- labels:
22+
- "severity=warning"

tests/test_config_validation.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import pytest
2+
import yaml
3+
import os
4+
from pydantic import ValidationError
5+
from robusta.core.model.runner_config import RunnerConfig
6+
7+
FIXTURES = os.path.join(os.path.dirname(__file__), "file_fixtures", "config_validation")
8+
FIXTURE_VALID_CONFIG_FILE_PATH = os.path.join(FIXTURES, "valid_config.yaml")
9+
FIXTURE_DUPL_SINKS_NAME_FILE_PATH = os.path.join(FIXTURES, "invalid_dupl_sink_names.yaml")
10+
11+
class TestSinkValidation:
12+
13+
def test_valid_sink_config(self):
14+
with open(FIXTURE_VALID_CONFIG_FILE_PATH) as file:
15+
yaml_content = yaml.safe_load(file)
16+
config = RunnerConfig(**yaml_content)
17+
18+
def test_duplicate_sink_names(self):
19+
with open(FIXTURE_DUPL_SINKS_NAME_FILE_PATH) as file:
20+
yaml_content = yaml.safe_load(file)
21+
with pytest.raises(ValidationError) as validation_error:
22+
config = RunnerConfig(**yaml_content)
23+
assert f'Sink name "my_sink1" is already defined. Sink names must be unique.' in str(validation_error)

0 commit comments

Comments
 (0)