diff --git a/changelog/62968.fixed b/changelog/62968.fixed new file mode 100644 index 00000000000..891c319c423 --- /dev/null +++ b/changelog/62968.fixed @@ -0,0 +1 @@ +Issue #62968: Fix issue where cloud deployments were putting the keys in the wrong location on Windows hosts diff --git a/changelog/63024.fixed b/changelog/63024.fixed new file mode 100644 index 00000000000..e3544b9bc14 --- /dev/null +++ b/changelog/63024.fixed @@ -0,0 +1 @@ +Issue #63024: Fix issue where grains and config data were being place in the wrong location on Windows hosts diff --git a/tests/pytests/unit/utils/test_cloud.py b/tests/pytests/unit/utils/test_cloud.py index 12b76786d31..3ed38031dd2 100644 --- a/tests/pytests/unit/utils/test_cloud.py +++ b/tests/pytests/unit/utils/test_cloud.py @@ -206,6 +206,225 @@ def test_deploy_windows_custom_port(): mock.assert_called_once_with("test", "Administrator", None, 1234) +@pytest.mark.skip_unless_on_windows(reason="Only applicable for Windows.") +def test_deploy_windows_programdata(): + """ + Test deploy_windows with a custom port + """ + mock_true = MagicMock(return_value=True) + mock_tuple = MagicMock(return_value=(0, 0, 0)) + mock_conn = MagicMock() + + with patch("salt.utils.smb", MagicMock()) as mock_smb: + mock_smb.get_conn.return_value = mock_conn + mock_smb.mkdirs.return_value = None + mock_smb.put_file.return_value = None + mock_smb.delete_file.return_value = None + mock_smb.delete_directory.return_value = None + with patch( + "time.sleep", MagicMock() + ), patch.object( + cloud, "wait_for_port", mock_true + ), patch.object( + cloud, "fire_event", MagicMock() + ), patch.object( + cloud, "wait_for_psexecsvc", mock_true + ), patch.object( + cloud, "run_psexec_command", mock_tuple + ): + cloud.deploy_windows(host="test", win_installer="") + expected = "ProgramData/Salt Project/Salt/conf/pki/minion" + mock_smb.mkdirs.assert_called_with(expected, conn=mock_conn) + + +@pytest.mark.skip_unless_on_windows(reason="Only applicable for Windows.") +def test_deploy_windows_programdata_minion_pub(): + """ + Test deploy_windows with a custom port + """ + mock_true = MagicMock(return_value=True) + mock_tuple = MagicMock(return_value=(0, 0, 0)) + mock_conn = MagicMock() + + with patch("salt.utils.smb", MagicMock()) as mock_smb: + mock_smb.get_conn.return_value = mock_conn + mock_smb.mkdirs.return_value = None + mock_smb.put_file.return_value = None + mock_smb.put_str.return_value = None + mock_smb.delete_file.return_value = None + mock_smb.delete_directory.return_value = None + with patch( + "time.sleep", MagicMock() + ), patch.object( + cloud, "wait_for_port", mock_true + ), patch.object( + cloud, "fire_event", MagicMock() + ), patch.object( + cloud, "wait_for_psexecsvc", mock_true + ), patch.object( + cloud, "run_psexec_command", mock_tuple + ): + cloud.deploy_windows(host="test", minion_pub="pub", win_installer="") + expected = ( + "ProgramData\\Salt Project\\Salt\\conf\\pki\\minion\\minion.pub" + ) + mock_smb.put_str.assert_called_with("pub", expected, conn=mock_conn) + + +@pytest.mark.skip_unless_on_windows(reason="Only applicable for Windows.") +def test_deploy_windows_programdata_minion_pem(): + """ + Test deploy_windows with a custom port + """ + mock_true = MagicMock(return_value=True) + mock_tuple = MagicMock(return_value=(0, 0, 0)) + mock_conn = MagicMock() + + with patch("salt.utils.smb", MagicMock()) as mock_smb: + mock_smb.get_conn.return_value = mock_conn + mock_smb.mkdirs.return_value = None + mock_smb.put_file.return_value = None + mock_smb.put_str.return_value = None + mock_smb.delete_file.return_value = None + mock_smb.delete_directory.return_value = None + with patch( + "time.sleep", MagicMock() + ), patch.object( + cloud, "wait_for_port", mock_true + ), patch.object( + cloud, "fire_event", MagicMock() + ), patch.object( + cloud, "wait_for_psexecsvc", mock_true + ), patch.object( + cloud, "run_psexec_command", mock_tuple + ): + cloud.deploy_windows(host="test", minion_pem="pem", win_installer="") + expected = ( + "ProgramData\\Salt Project\\Salt\\conf\\pki\\minion\\minion.pem" + ) + mock_smb.put_str.assert_called_with("pem", expected, conn=mock_conn) + + +@pytest.mark.skip_unless_on_windows(reason="Only applicable for Windows.") +def test_deploy_windows_programdata_master_sign_pub_file(): + """ + Test deploy_windows with a custom port + """ + mock_true = MagicMock(return_value=True) + mock_tuple = MagicMock(return_value=(0, 0, 0)) + mock_conn = MagicMock() + + with patch("salt.utils.smb", MagicMock()) as mock_smb: + mock_smb.get_conn.return_value = mock_conn + mock_smb.mkdirs.return_value = None + mock_smb.put_file.return_value = None + mock_smb.put_str.return_value = None + mock_smb.delete_file.return_value = None + mock_smb.delete_directory.return_value = None + with patch( + "time.sleep", MagicMock() + ), patch.object( + cloud, "wait_for_port", mock_true + ), patch.object( + cloud, "fire_event", MagicMock() + ), patch.object( + cloud, "wait_for_psexecsvc", mock_true + ), patch.object( + cloud, "run_psexec_command", mock_tuple + ): + cloud.deploy_windows( + host="test", master_sign_pub_file="test.txt", win_installer="" + ) + expected = ( + "ProgramData\\Salt Project\\Salt\\conf\\pki\\minion\\master_sign.pub" + ) + called = False + for call in mock_smb.put_file.mock_calls: + if expected in call[1]: + called = True + assert called + + +@pytest.mark.skip_unless_on_windows(reason="Only applicable for Windows.") +def test_deploy_windows_programdata_minion_conf_grains(): + """ + Test deploy_windows with a custom port + """ + mock_true = MagicMock(return_value=True) + mock_tuple = MagicMock(return_value=(0, 0, 0)) + mock_conn = MagicMock() + + with patch("salt.utils.smb", MagicMock()) as mock_smb: + mock_smb.get_conn.return_value = mock_conn + mock_smb.mkdirs.return_value = None + mock_smb.put_file.return_value = None + mock_smb.put_str.return_value = None + mock_smb.delete_file.return_value = None + mock_smb.delete_directory.return_value = None + with patch( + "time.sleep", MagicMock() + ), patch.object( + cloud, "wait_for_port", mock_true + ), patch.object( + cloud, "fire_event", MagicMock() + ), patch.object( + cloud, "wait_for_psexecsvc", mock_true + ), patch.object( + cloud, "run_psexec_command", mock_tuple + ): + minion_conf = {"grains": {"spongebob": "squarepants"}} + cloud.deploy_windows( + host="test", minion_conf=minion_conf, win_installer="" + ) + expected = "ProgramData\\Salt Project\\Salt\\conf\\grains" + called = False + for call in mock_smb.put_str.mock_calls: + if expected in call[1]: + called = True + assert called + + +@pytest.mark.skip_unless_on_windows(reason="Only applicable for Windows.") +def test_deploy_windows_programdata_minion_conf(): + """ + Test deploy_windows with a custom port + """ + mock_true = MagicMock(return_value=True) + mock_tuple = MagicMock(return_value=(0, 0, 0)) + mock_conn = MagicMock() + + with patch("salt.utils.smb", MagicMock()) as mock_smb: + mock_smb.get_conn.return_value = mock_conn + mock_smb.mkdirs.return_value = None + mock_smb.put_file.return_value = None + mock_smb.put_str.return_value = None + mock_smb.delete_file.return_value = None + mock_smb.delete_directory.return_value = None + with patch( + "time.sleep", MagicMock() + ), patch.object( + cloud, "wait_for_port", mock_true + ), patch.object( + cloud, "fire_event", MagicMock() + ), patch.object( + cloud, "wait_for_psexecsvc", mock_true + ), patch.object( + cloud, "run_psexec_command", mock_tuple + ): + minion_conf = {"master": "test-master"} + cloud.deploy_windows( + host="test", minion_conf=minion_conf, win_installer="" + ) + config = ( + "ipc_mode: tcp\r\n" + "master: test-master\r\n" + "multiprocessing: true\r\n" + "pki_dir: /conf/pki/minion\r\n" + ) + expected = "ProgramData\\Salt Project\\Salt\\conf\\minion" + mock_smb.put_str.assert_called_with(config, expected, conn=mock_conn) + + @pytest.mark.skip_unless_on_windows(reason="Only applicable for Windows.") def test_winrm_pinnned_version(): """