protect config.telemetry access with fallback to empty dict (#1427)

* protect config.telemetry access with fallback to empty dict

If the YAML config does not include a telemetry section, three
spots in main() crash with KeyError because they access
config.telemetry directly. Everything else in the file uses
get_yaml_item_value which handles missing keys gracefully.

Added config.telemetry = get_yaml_item_value(config, telemetry, {})
before the first usage. This ensures the key always exists as at
least an empty dict, protecting all downstream .get() calls and
assignments (archive_path, run_tag, telemetry_group, etc.).

Wrote a test that passes a config without a telemetry section and
asserts main() returns -1 (no kubeconfig) instead of crashing
with KeyError.

Signed-off-by: Sahil Lenka <sahillenka44@gmail.com>

* clean up test imports and prevent filesystem side effects

Remove unused imports (Mock, get_yaml_item_value). Add
rollback_versions_directory to mock config so the test
does not write ~/.krkn/rollback to disk.

Signed-off-by: Sahil Lenka <sahillenka44@gmail.com>

---------

Signed-off-by: Sahil Lenka <sahillenka44@gmail.com>
Co-authored-by: Paige Patton <64206430+paigerube14@users.noreply.github.com>
This commit is contained in:
Sahil Lenka
2026-08-03 12:00:44 -04:00
committed by GitHub
co-authored by Paige Patton
parent 84b360c83b
commit be36abd53d
2 changed files with 33 additions and 0 deletions
+1
View File
@@ -206,6 +206,7 @@ def main(options, command: Optional[str], out: Optional[dict] = None) -> int:
check_critical_alerts = get_yaml_item_value(
config["performance_monitoring"], "check_critical_alerts", False
)
config["telemetry"] = get_yaml_item_value(config, "telemetry", {})
telemetry_api_url = config["telemetry"].get("api_url", "")
telemetry_enabled = config["telemetry"].get("enabled", True)
+32
View File
@@ -0,0 +1,32 @@
import unittest
from unittest.mock import patch, mock_open
from types import SimpleNamespace
from run_kraken import main
class TestRunKraken(unittest.TestCase):
@patch('run_kraken.yaml.safe_load')
@patch('run_kraken.os.path.isfile')
@patch('builtins.open', new_callable=mock_open)
def test_main_without_telemetry_config(self, mock_file, mock_isfile, mock_yaml_load):
"""
Test that main() doesn't crash when config has no telemetry section
"""
mock_isfile.side_effect = lambda p: p == "/fake/config.yaml"
mock_yaml_load.return_value = {
"kraken": {"rollback_versions_directory": "/tmp/krkn-test-rollback"},
"tunings": {},
"performance_monitoring": {},
"elastic": {},
}
options = SimpleNamespace(cfg="/fake/config.yaml")
result = main(options, None)
self.assertEqual(result, -1)
if __name__ == "__main__":
unittest.main()