mirror of
https://github.com/saltstack/salt.git
synced 2025-04-10 14:51:40 +00:00
Add new options to salt cloud for Windows installer
This commit is contained in:
parent
aad71fdbcf
commit
352b83aea7
4 changed files with 127 additions and 21 deletions
2
changelog/61318.added.md
Normal file
2
changelog/61318.added.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
Added two new options, ``win_delay_start`` and ``win_install_dir``, to pass to
|
||||
the Windows installer in salt-cloud
|
|
@ -31,7 +31,6 @@ which Salt Cloud is running. See
|
|||
and using the Salt Minion Windows installer.
|
||||
|
||||
|
||||
|
||||
.. _new-pywinrm:
|
||||
|
||||
Self Signed Certificates with WinRM
|
||||
|
@ -39,18 +38,18 @@ Self Signed Certificates with WinRM
|
|||
|
||||
Salt-Cloud can use versions of ``pywinrm<=0.1.1`` or ``pywinrm>=0.2.1``.
|
||||
|
||||
For versions greater than `0.2.1`, ``winrm_verify_ssl`` needs to be set to
|
||||
`False` if the certificate is self signed and not verifiable.
|
||||
For versions greater than ``0.2.1``, ``winrm_verify_ssl`` needs to be set to
|
||||
``False`` if the certificate is self signed and not verifiable.
|
||||
|
||||
Firewall Settings
|
||||
=================
|
||||
Because Salt Cloud makes use of `smbclient` and `winexe`, port 445 must be open
|
||||
on the target image. This port is not generally open by default on a standard
|
||||
Windows distribution, and care must be taken to use an image in which this port
|
||||
is open, or the Windows firewall is disabled.
|
||||
Because Salt Cloud makes use of ``smbclient`` and ``winexe``, port 445 must be
|
||||
open on the target image. This port is not generally open by default on a
|
||||
standard Windows distribution, and care must be taken to use an image in which
|
||||
this port is open, or the Windows firewall is disabled.
|
||||
|
||||
If supported by the cloud provider, a PowerShell script may be used to open up
|
||||
this port automatically, using the cloud provider's `userdata`. The following
|
||||
this port automatically, using the cloud provider's ``userdata``. The following
|
||||
script would open up port 445, and apply the changes:
|
||||
|
||||
.. code-block:: text
|
||||
|
@ -62,7 +61,7 @@ script would open up port 445, and apply the changes:
|
|||
</powershell>
|
||||
|
||||
For EC2, this script may be saved as a file, and specified in the provider or
|
||||
profile configuration as `userdata_file`. For instance:
|
||||
profile configuration as ``userdata_file``. For instance:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -142,9 +141,9 @@ the following userdata example:
|
|||
Restart-Service winrm
|
||||
</powershell>
|
||||
|
||||
No certificate store is available by default on EC2 images and creating
|
||||
one does not seem possible without an MMC (cannot be automated). To use the
|
||||
default EC2 Windows images the above copies the RDP store.
|
||||
No certificate store is available by default on EC2 images and creating one does
|
||||
not seem possible without an MMC (cannot be automated). To use the default EC2
|
||||
Windows images the above copies the RDP store.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
@ -168,23 +167,42 @@ Setting the installer in ``/etc/salt/cloud.providers``:
|
|||
win_password: letmein
|
||||
smb_port: 445
|
||||
|
||||
The default Windows user is `Administrator`, and the default Windows password
|
||||
The default Windows user is ``Administrator``, and the default Windows password
|
||||
is blank.
|
||||
|
||||
If WinRM is to be used ``use_winrm`` needs to be set to `True`. ``winrm_port``
|
||||
If WinRM is to be used ``use_winrm`` needs to be set to ``True``. ``winrm_port``
|
||||
can be used to specify a custom port (must be HTTPS listener). And
|
||||
``winrm_verify_ssl`` can be set to `False` to use a self signed certificate.
|
||||
``winrm_verify_ssl`` can be set to ``False`` to use a self signed certificate.
|
||||
|
||||
Two new options have been added to allow you to set some additional parameters
|
||||
to pass to the installer. ``win_delay_start`` will set the minion service to
|
||||
start delayed. ``win_install_dir`` will allow you to specify the Salt install
|
||||
location.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
my-softlayer:
|
||||
driver: softlayer
|
||||
user: MYUSER1138
|
||||
apikey: 'e3b68aa711e6deadc62d5b76355674beef7cc3116062ddbacafe5f7e465bfdc9'
|
||||
minion:
|
||||
master: saltmaster.example.com
|
||||
win_installer: /root/Salt-Minion-2014.7.0-AMD64-Setup.exe
|
||||
win_delay_start: True
|
||||
win_install_dir: D:\Program Files\Salt Project\Salt
|
||||
win_username: Administrator
|
||||
win_password: letmein
|
||||
smb_port: 445
|
||||
|
||||
Auto-Generated Passwords on EC2
|
||||
===============================
|
||||
On EC2, when the `win_password` is set to `auto`, Salt Cloud will query EC2 for
|
||||
an auto-generated password. This password is expected to take at least 4 minutes
|
||||
to generate, adding additional time to the deploy process.
|
||||
On EC2, when the ``win_password`` is set to ``auto``, Salt Cloud will query EC2
|
||||
for an auto-generated password. This password is expected to take at least 4
|
||||
minutes to generate, adding additional time to the deploy process.
|
||||
|
||||
When the EC2 API is queried for the auto-generated password, it will be returned
|
||||
in a message encrypted with the specified `keyname`. This requires that the
|
||||
appropriate `private_key` file is also specified. Such a profile configuration
|
||||
in a message encrypted with the specified ``keyname``. This requires that the
|
||||
appropriate ``private_key`` file is also specified. Such a profile configuration
|
||||
might look like:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
|
|
@ -574,6 +574,13 @@ def bootstrap(vm_, opts=None):
|
|||
"smb_port", vm_, opts, default=445
|
||||
)
|
||||
deploy_kwargs["win_installer"] = win_installer
|
||||
deploy_kwargs["win_delay_start"] = salt.config.get_cloud_config_value(
|
||||
"win_delay_start", vm_, opts, default=""
|
||||
)
|
||||
deploy_kwargs["win_install_dir"] = salt.config.get_cloud_config_value(
|
||||
"win_install_dir", vm_, opts, default=""
|
||||
)
|
||||
|
||||
minion = minion_config(opts, vm_)
|
||||
deploy_kwargs["master"] = minion["master"]
|
||||
deploy_kwargs["username"] = salt.config.get_cloud_config_value(
|
||||
|
@ -1236,6 +1243,8 @@ def deploy_windows(
|
|||
port_timeout=15,
|
||||
preseed_minion_keys=None,
|
||||
win_installer=None,
|
||||
win_delay_start=False,
|
||||
win_install_dir="",
|
||||
master=None,
|
||||
tmp_dir="C:\\salttmp",
|
||||
opts=None,
|
||||
|
@ -1357,6 +1366,11 @@ def deploy_windows(
|
|||
f"/master={_format_master_param(master)}",
|
||||
f"/minion-name={name}",
|
||||
]
|
||||
if win_delay_start:
|
||||
args.append("/start-minion-delayed")
|
||||
|
||||
if win_install_dir:
|
||||
args.append(f'/install-dir="{win_install_dir}"')
|
||||
|
||||
if use_winrm:
|
||||
winrm_cmd(winrm_session, cmd, args)
|
||||
|
@ -1423,7 +1437,7 @@ def deploy_windows(
|
|||
if ret_code != 0:
|
||||
return False
|
||||
|
||||
log.debug("Run psexec: sc start salt-minion")
|
||||
log.debug("Run psexec: net start salt-minion")
|
||||
stdout, stderr, ret_code = run_psexec_command(
|
||||
"cmd.exe", "/c net start salt-minion", host, username, password
|
||||
)
|
||||
|
|
|
@ -449,6 +449,78 @@ def test_deploy_windows_programdata_minion_conf():
|
|||
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_deploy_windows_install_delay_start():
|
||||
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
|
||||
) as mock_psexec:
|
||||
minion_conf = {"master": "test-master"}
|
||||
cloud.deploy_windows(
|
||||
host="test",
|
||||
minion_conf=minion_conf,
|
||||
win_installer="install.exe",
|
||||
win_delay_start=True,
|
||||
)
|
||||
mock_psexec.assert_any_call(
|
||||
"c:\\salttemp\\install.exe",
|
||||
"/S /master=None /minion-name=None /start-minion-delayed",
|
||||
"test",
|
||||
"Administrator",
|
||||
None,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_unless_on_windows(reason="Only applicable for Windows.")
|
||||
def test_deploy_windows_install_install_dir():
|
||||
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
|
||||
) as mock_psexec:
|
||||
minion_conf = {"master": "test-master"}
|
||||
cloud.deploy_windows(
|
||||
host="test",
|
||||
minion_conf=minion_conf,
|
||||
win_installer="install.exe",
|
||||
win_install_dir="C:\\salt",
|
||||
)
|
||||
mock_psexec.assert_any_call(
|
||||
"c:\\salttemp\\install.exe",
|
||||
'/S /master=None /minion-name=None /install-dir="C:\\salt"',
|
||||
"test",
|
||||
"Administrator",
|
||||
None,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_unless_on_windows(reason="Only applicable for Windows.")
|
||||
def test_winrm_pinnned_version():
|
||||
"""
|
||||
|
|
Loading…
Add table
Reference in a new issue