mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-25 01:02:15 +00:00
fix(proxy): treat a config-owned alerting_args as shadowing the stored row
When the config file declares alerting_args at all, the resolver hands the file's dict to every reader and the stored row never reaches one. Reporting a nested field as "db" because the row happens to carry it told the admin a value was in effect that the proxy does not serve: a live proxy answered source "db" for outage_alert_ttl while serving the default. A config-owned parent now reports the field's own default, and the DB is consulted only when the file leaves the parent alone.
This commit is contained in:
parent
a45be4f276
commit
f998ab53d5
2 changed files with 41 additions and 17 deletions
|
|
@ -15996,10 +15996,13 @@ def _nested_setting_source(
|
|||
parent_value: Final = settings.config_value(parent_key)
|
||||
if isinstance(parent_value, Mapping) and field_name in parent_value:
|
||||
return "config"
|
||||
unset_source: Final[FieldSource] = "default" if field_default is not None else "unset"
|
||||
if settings.owned_by_config(parent_key):
|
||||
return unset_source
|
||||
db_value: Final = db_values.get(field_name)
|
||||
if db_value is not None and not (isinstance(db_value, list) and len(db_value) == 0):
|
||||
return "db"
|
||||
return "default" if field_default is not None else "unset"
|
||||
return unset_source
|
||||
|
||||
|
||||
@router.get(
|
||||
|
|
|
|||
|
|
@ -183,37 +183,39 @@ def test_model_settings_method_not_allowed(client, auth_as):
|
|||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_alerting_settings_reports_sources(client, auth_as, monkeypatch):
|
||||
def _alerting_client(monkeypatch, *, yaml_values, db_row, live_args):
|
||||
from litellm.proxy.config_resolvers import SettingsStore
|
||||
|
||||
db_alerting_args = {
|
||||
"daily_report_frequency": 7,
|
||||
"outage_alert_ttl": 99,
|
||||
"region_outage_alert_ttl": [],
|
||||
}
|
||||
|
||||
pc = MagicMock()
|
||||
row = MagicMock()
|
||||
row.param_value = {"alerting_args": db_alerting_args}
|
||||
row.param_value = db_row
|
||||
pc.db.litellm_config.find_first = AsyncMock(return_value=row)
|
||||
monkeypatch.setattr(proxy_server, "prisma_client", pc)
|
||||
|
||||
logging_obj = MagicMock()
|
||||
args_model = MagicMock()
|
||||
args_model.model_dump = MagicMock(return_value={"daily_report_frequency": 3})
|
||||
args_model.model_dump = MagicMock(return_value=live_args)
|
||||
logging_obj.slack_alerting_instance.alerting_args = args_model
|
||||
monkeypatch.setattr(proxy_server, "proxy_logging_obj", logging_obj)
|
||||
|
||||
store = SettingsStore("general_settings")
|
||||
store.load_yaml(
|
||||
{
|
||||
"alerting": ["slack"],
|
||||
"alerting_args": {"daily_report_frequency": 3, "report_check_interval": 300},
|
||||
}
|
||||
)
|
||||
store.apply_db_row("general_settings", {"alerting_args": db_alerting_args})
|
||||
store.load_yaml(yaml_values)
|
||||
store.apply_db_row("general_settings", db_row)
|
||||
monkeypatch.setattr(proxy_server.proxy_config, "settings", store)
|
||||
monkeypatch.setattr(proxy_server, "general_settings", store)
|
||||
return store
|
||||
|
||||
|
||||
def test_alerting_settings_reports_sources(client, auth_as, monkeypatch):
|
||||
_alerting_client(
|
||||
monkeypatch,
|
||||
yaml_values={
|
||||
"alerting": ["slack"],
|
||||
"alerting_args": {"daily_report_frequency": 3, "report_check_interval": 300},
|
||||
},
|
||||
db_row={"alerting_args": {"daily_report_frequency": 7, "outage_alert_ttl": 4242}},
|
||||
live_args={"daily_report_frequency": 3},
|
||||
)
|
||||
|
||||
with auth_as(LitellmUserRoles.PROXY_ADMIN):
|
||||
response = client.get("/alerting/settings")
|
||||
|
|
@ -224,6 +226,25 @@ def test_alerting_settings_reports_sources(client, auth_as, monkeypatch):
|
|||
assert by_name["slack_alerting"]["source"] == "config"
|
||||
assert by_name["daily_report_frequency"]["source"] == "config"
|
||||
assert by_name["report_check_interval"]["source"] == "config"
|
||||
assert by_name["outage_alert_ttl"]["source"] == "default"
|
||||
assert by_name["budget_alert_ttl"]["source"] == "default"
|
||||
|
||||
|
||||
def test_alerting_settings_reports_db_source_when_the_file_omits_alerting_args(client, auth_as, monkeypatch):
|
||||
store = _alerting_client(
|
||||
monkeypatch,
|
||||
yaml_values={"alerting": ["slack"]},
|
||||
db_row={"alerting_args": {"outage_alert_ttl": 4242, "region_outage_alert_ttl": []}},
|
||||
live_args={"outage_alert_ttl": 4242},
|
||||
)
|
||||
|
||||
with auth_as(LitellmUserRoles.PROXY_ADMIN):
|
||||
response = client.get("/alerting/settings")
|
||||
|
||||
assert response.status_code == 200
|
||||
by_name = {entry["field_name"]: entry for entry in response.json()}
|
||||
|
||||
assert store.owned_by_config("alerting_args") is False
|
||||
assert by_name["outage_alert_ttl"]["source"] == "db"
|
||||
assert by_name["region_outage_alert_ttl"]["source"] == "default"
|
||||
assert by_name["budget_alert_ttl"]["source"] == "default"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue