From 0545e1d33b6dee22dd4f3fd78224c3f8ac7afdfb Mon Sep 17 00:00:00 2001 From: Jason Ertel Date: Tue, 11 Nov 2025 16:55:00 -0500 Subject: [PATCH] add support to so-yaml for using yaml file content for values --- salt/manager/tools/sbin/so-yaml.py | 12 +++++++++--- salt/manager/tools/sbin/so-yaml_test.py | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/salt/manager/tools/sbin/so-yaml.py b/salt/manager/tools/sbin/so-yaml.py index 275032ee0..4c8544893 100755 --- a/salt/manager/tools/sbin/so-yaml.py +++ b/salt/manager/tools/sbin/so-yaml.py @@ -26,8 +26,8 @@ def showUsage(args): print(' Where:', file=sys.stderr) print(' YAML_FILE - Path to the file that will be modified. Ex: /opt/so/conf/service/conf.yaml', file=sys.stderr) print(' KEY - YAML key, does not support \' or " characters at this time. Ex: level1.level2', file=sys.stderr) - print(' VALUE - Value to set for a given key', file=sys.stderr) - print(' LISTITEM - Item to append to a given key\'s list value', file=sys.stderr) + print(' VALUE - Value to set for a given key. Can be a literal value or file: to load from a YAML file.', file=sys.stderr) + print(' LISTITEM - Item to append to a given key\'s list value. Can be a literal value or file: to load from a YAML file.', file=sys.stderr) sys.exit(1) @@ -58,7 +58,13 @@ def appendItem(content, key, listItem): def convertType(value): - if isinstance(value, str) and len(value) > 0 and (not value.startswith("0") or len(value) == 1): + if isinstance(value, str) and value.startswith("file:"): + path = value[5:] # Remove "file:" prefix + if not os.path.exists(path): + print(f"File '{path}' does not exist.", file=sys.stderr) + sys.exit(1) + return loadYaml(path) + elif isinstance(value, str) and len(value) > 0 and (not value.startswith("0") or len(value) == 1): if "." in value: try: value = float(value) diff --git a/salt/manager/tools/sbin/so-yaml_test.py b/salt/manager/tools/sbin/so-yaml_test.py index 5ca46cb68..0346f0c3c 100644 --- a/salt/manager/tools/sbin/so-yaml_test.py +++ b/salt/manager/tools/sbin/so-yaml_test.py @@ -361,6 +361,29 @@ class TestRemove(unittest.TestCase): self.assertEqual(soyaml.convertType("FALSE"), False) self.assertEqual(soyaml.convertType(""), "") + def test_convert_file(self): + import tempfile + import os + + # Create a temporary YAML file + with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f: + f.write("test:\n - name: hi\n color: blue\n") + temp_file = f.name + + try: + result = soyaml.convertType(f"file:{temp_file}") + expected = {"test": [{"name": "hi", "color": "blue"}]} + self.assertEqual(result, expected) + finally: + os.unlink(temp_file) + + def test_convert_file_nonexistent(self): + with patch('sys.exit', new=MagicMock()) as sysmock: + with patch('sys.stderr', new=StringIO()) as mock_stderr: + soyaml.convertType("file:/nonexistent/file.yaml") + sysmock.assert_called_once_with(1) + self.assertIn("File '/nonexistent/file.yaml' does not exist.", mock_stderr.getvalue()) + def test_get_int(self): with patch('sys.stdout', new=StringIO()) as mock_stdout: filename = "/tmp/so-yaml_test-get.yaml"