mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 09:23:56 +00:00
Merge remote-tracking branch 'remotes/origin/2017.7' into SuperPommeDeTerre-patch-#26995
This commit is contained in:
commit
50ee3d5682
18
conf/master
18
conf/master
@ -302,6 +302,9 @@
|
|||||||
# public keys from the minions. Note that this is insecure.
|
# public keys from the minions. Note that this is insecure.
|
||||||
#auto_accept: False
|
#auto_accept: False
|
||||||
|
|
||||||
|
# The size of key that should be generated when creating new keys.
|
||||||
|
#keysize: 2048
|
||||||
|
|
||||||
# Time in minutes that an incoming public key with a matching name found in
|
# Time in minutes that an incoming public key with a matching name found in
|
||||||
# pki_dir/minion_autosign/keyid is automatically accepted. Expired autosign keys
|
# pki_dir/minion_autosign/keyid is automatically accepted. Expired autosign keys
|
||||||
# are removed when the master checks the minion_autosign directory.
|
# are removed when the master checks the minion_autosign directory.
|
||||||
@ -959,6 +962,21 @@
|
|||||||
#pillar_cache_backend: disk
|
#pillar_cache_backend: disk
|
||||||
|
|
||||||
|
|
||||||
|
###### Reactor Settings #####
|
||||||
|
###########################################
|
||||||
|
# Define a salt reactor. See https://docs.saltstack.com/en/latest/topics/reactor/
|
||||||
|
#reactor: []
|
||||||
|
|
||||||
|
#Set the TTL for the cache of the reactor configuration.
|
||||||
|
#reactor_refresh_interval: 60
|
||||||
|
|
||||||
|
#Configure the number of workers for the runner/wheel in the reactor.
|
||||||
|
#reactor_worker_threads: 10
|
||||||
|
|
||||||
|
#Define the queue size for workers in the reactor.
|
||||||
|
#reactor_worker_hwm: 10000
|
||||||
|
|
||||||
|
|
||||||
##### Syndic settings #####
|
##### Syndic settings #####
|
||||||
##########################################
|
##########################################
|
||||||
# The Salt syndic is used to pass commands through a master from a higher
|
# The Salt syndic is used to pass commands through a master from a higher
|
||||||
|
18
conf/minion
18
conf/minion
@ -620,6 +620,9 @@
|
|||||||
# you do so at your own risk!
|
# you do so at your own risk!
|
||||||
#open_mode: False
|
#open_mode: False
|
||||||
|
|
||||||
|
# The size of key that should be generated when creating new keys.
|
||||||
|
#keysize: 2048
|
||||||
|
|
||||||
# Enable permissive access to the salt keys. This allows you to run the
|
# Enable permissive access to the salt keys. This allows you to run the
|
||||||
# master or minion as root, but have a non-root group be given access to
|
# master or minion as root, but have a non-root group be given access to
|
||||||
# your pki_dir. To make the access explicit, root must belong to the group
|
# your pki_dir. To make the access explicit, root must belong to the group
|
||||||
@ -661,6 +664,21 @@
|
|||||||
# ssl_version: PROTOCOL_TLSv1_2
|
# ssl_version: PROTOCOL_TLSv1_2
|
||||||
|
|
||||||
|
|
||||||
|
###### Reactor Settings #####
|
||||||
|
###########################################
|
||||||
|
# Define a salt reactor. See https://docs.saltstack.com/en/latest/topics/reactor/
|
||||||
|
#reactor: []
|
||||||
|
|
||||||
|
#Set the TTL for the cache of the reactor configuration.
|
||||||
|
#reactor_refresh_interval: 60
|
||||||
|
|
||||||
|
#Configure the number of workers for the runner/wheel in the reactor.
|
||||||
|
#reactor_worker_threads: 10
|
||||||
|
|
||||||
|
#Define the queue size for workers in the reactor.
|
||||||
|
#reactor_worker_hwm: 10000
|
||||||
|
|
||||||
|
|
||||||
###### Thread settings #####
|
###### Thread settings #####
|
||||||
###########################################
|
###########################################
|
||||||
# Disable multiprocessing support, by default when a minion receives a
|
# Disable multiprocessing support, by default when a minion receives a
|
||||||
|
10
doc/conf.py
10
doc/conf.py
@ -245,9 +245,9 @@ on_saltstack = 'SALT_ON_SALTSTACK' in os.environ
|
|||||||
project = 'Salt'
|
project = 'Salt'
|
||||||
|
|
||||||
version = salt.version.__version__
|
version = salt.version.__version__
|
||||||
latest_release = '2016.11.6' # latest release
|
latest_release = '2017.7.1' # latest release
|
||||||
previous_release = '2016.3.6' # latest release from previous branch
|
previous_release = '2016.11.7' # latest release from previous branch
|
||||||
previous_release_dir = '2016.3' # path on web server for previous branch
|
previous_release_dir = '2016.11' # path on web server for previous branch
|
||||||
next_release = '' # next release
|
next_release = '' # next release
|
||||||
next_release_dir = '' # path on web server for next release branch
|
next_release_dir = '' # path on web server for next release branch
|
||||||
|
|
||||||
@ -258,8 +258,8 @@ if on_saltstack:
|
|||||||
copyright = time.strftime("%Y")
|
copyright = time.strftime("%Y")
|
||||||
|
|
||||||
# < --- START do not merge these settings to other branches START ---> #
|
# < --- START do not merge these settings to other branches START ---> #
|
||||||
build_type = 'develop' # latest, previous, develop, next
|
build_type = 'latest' # latest, previous, develop, next
|
||||||
release = version # version, latest_release, previous_release
|
release = latest_release # version, latest_release, previous_release
|
||||||
# < --- END do not merge these settings to other branches END ---> #
|
# < --- END do not merge these settings to other branches END ---> #
|
||||||
|
|
||||||
# Set google custom search engine
|
# Set google custom search engine
|
||||||
|
26
doc/faq.rst
26
doc/faq.rst
@ -321,7 +321,27 @@ Restart using states
|
|||||||
********************
|
********************
|
||||||
|
|
||||||
Now we can apply the workaround to restart the Minion in reliable way.
|
Now we can apply the workaround to restart the Minion in reliable way.
|
||||||
The following example works on both UNIX-like and Windows operating systems:
|
The following example works on UNIX-like operating systems:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{%- if grains['os'] != 'Windows' %
|
||||||
|
Restart Salt Minion:
|
||||||
|
cmd.run:
|
||||||
|
- name: 'salt-call --local service.restart salt-minion'
|
||||||
|
- bg: True
|
||||||
|
- onchanges:
|
||||||
|
- pkg: Upgrade Salt Minion
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
Note that restarting the ``salt-minion`` service on Windows operating systems is
|
||||||
|
not always necessary when performing an upgrade. The installer stops the
|
||||||
|
``salt-minion`` service, removes it, deletes the contents of the ``\salt\bin``
|
||||||
|
directory, installs the new code, re-creates the ``salt-minion`` service, and
|
||||||
|
starts it (by default). The restart step **would** be necessary during the
|
||||||
|
upgrade process, however, if the minion config was edited after the upgrade or
|
||||||
|
installation. If a minion restart is necessary, the state above can be edited
|
||||||
|
as follows:
|
||||||
|
|
||||||
.. code-block:: jinja
|
.. code-block:: jinja
|
||||||
|
|
||||||
@ -337,8 +357,8 @@ The following example works on both UNIX-like and Windows operating systems:
|
|||||||
- pkg: Upgrade Salt Minion
|
- pkg: Upgrade Salt Minion
|
||||||
|
|
||||||
However, it requires more advanced tricks to upgrade from legacy version of
|
However, it requires more advanced tricks to upgrade from legacy version of
|
||||||
Salt (before ``2016.3.0``), where executing commands in the background is not
|
Salt (before ``2016.3.0``) on UNIX-like operating systems, where executing
|
||||||
supported:
|
commands in the background is not supported:
|
||||||
|
|
||||||
.. code-block:: jinja
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@ Output Options
|
|||||||
|
|
||||||
Write the output to the specified file.
|
Write the output to the specified file.
|
||||||
|
|
||||||
|
.. option:: --out-file-append, --output-file-append
|
||||||
|
|
||||||
|
Append the output to the specified file.
|
||||||
|
|
||||||
.. option:: --no-color
|
.. option:: --no-color
|
||||||
|
|
||||||
Disable all colored output
|
Disable all colored output
|
||||||
@ -46,3 +50,14 @@ Output Options
|
|||||||
|
|
||||||
``green`` denotes success, ``red`` denotes failure, ``blue`` denotes
|
``green`` denotes success, ``red`` denotes failure, ``blue`` denotes
|
||||||
changes and success and ``yellow`` denotes a expected future change in configuration.
|
changes and success and ``yellow`` denotes a expected future change in configuration.
|
||||||
|
|
||||||
|
.. option:: --state-output=STATE_OUTPUT, --state_output=STATE_OUTPUT
|
||||||
|
|
||||||
|
Override the configured state_output value for minion
|
||||||
|
output. One of 'full', 'terse', 'mixed', 'changes' or
|
||||||
|
'filter'. Default: 'none'.
|
||||||
|
|
||||||
|
.. option:: --state-verbose=STATE_VERBOSE, --state_verbose=STATE_VERBOSE
|
||||||
|
|
||||||
|
Override the configured state_verbose value for minion
|
||||||
|
output. Set to True or False. Default: none.
|
||||||
|
@ -94,64 +94,6 @@ The user to run the Salt processes
|
|||||||
|
|
||||||
user: root
|
user: root
|
||||||
|
|
||||||
.. conf_master:: max_open_files
|
|
||||||
|
|
||||||
``max_open_files``
|
|
||||||
------------------
|
|
||||||
|
|
||||||
Default: ``100000``
|
|
||||||
|
|
||||||
Each minion connecting to the master uses AT LEAST one file descriptor, the
|
|
||||||
master subscription connection. If enough minions connect you might start
|
|
||||||
seeing on the console(and then salt-master crashes):
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
Too many open files (tcp_listener.cpp:335)
|
|
||||||
Aborted (core dumped)
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
max_open_files: 100000
|
|
||||||
|
|
||||||
By default this value will be the one of `ulimit -Hn`, i.e., the hard limit for
|
|
||||||
max open files.
|
|
||||||
|
|
||||||
To set a different value than the default one, uncomment, and configure this
|
|
||||||
setting. Remember that this value CANNOT be higher than the hard limit. Raising
|
|
||||||
the hard limit depends on the OS and/or distribution, a good way to find the
|
|
||||||
limit is to search the internet for something like this:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
raise max open files hard limit debian
|
|
||||||
|
|
||||||
.. conf_master:: worker_threads
|
|
||||||
|
|
||||||
``worker_threads``
|
|
||||||
------------------
|
|
||||||
|
|
||||||
Default: ``5``
|
|
||||||
|
|
||||||
The number of threads to start for receiving commands and replies from minions.
|
|
||||||
If minions are stalling on replies because you have many minions, raise the
|
|
||||||
worker_threads value.
|
|
||||||
|
|
||||||
Worker threads should not be put below 3 when using the peer system, but can
|
|
||||||
drop down to 1 worker otherwise.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
When the master daemon starts, it is expected behaviour to see
|
|
||||||
multiple salt-master processes, even if 'worker_threads' is set to '1'. At
|
|
||||||
a minimum, a controlling process will start along with a Publisher, an
|
|
||||||
EventPublisher, and a number of MWorker processes will be started. The
|
|
||||||
number of MWorker processes is tuneable by the 'worker_threads'
|
|
||||||
configuration value while the others are not.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
worker_threads: 5
|
|
||||||
|
|
||||||
.. conf_master:: ret_port
|
.. conf_master:: ret_port
|
||||||
|
|
||||||
``ret_port``
|
``ret_port``
|
||||||
@ -946,6 +888,74 @@ to socket concurrently.
|
|||||||
|
|
||||||
sock_pool_size: 15
|
sock_pool_size: 15
|
||||||
|
|
||||||
|
.. conf_master:: ipc_mode
|
||||||
|
|
||||||
|
``ipc_mode``
|
||||||
|
------------
|
||||||
|
|
||||||
|
Default: ``ipc``
|
||||||
|
|
||||||
|
The ipc strategy. (i.e., sockets versus tcp, etc.) Windows platforms lack
|
||||||
|
POSIX IPC and must rely on TCP based inter-process communications. ``ipc_mode``
|
||||||
|
is set to ``tcp`` by default on Windows.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
ipc_mode: ipc
|
||||||
|
|
||||||
|
.. conf_master::
|
||||||
|
|
||||||
|
``tcp_master_pub_port``
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Default: ``4512``
|
||||||
|
|
||||||
|
The TCP port on which events for the master should be published if ``ipc_mode`` is TCP.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_master_pub_port: 4512
|
||||||
|
|
||||||
|
.. conf_master:: tcp_master_pull_port
|
||||||
|
|
||||||
|
``tcp_master_pull_port``
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Default: ``4513``
|
||||||
|
|
||||||
|
The TCP port on which events for the master should be pulled if ``ipc_mode`` is TCP.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_master_pull_port: 4513
|
||||||
|
|
||||||
|
.. conf_master:: tcp_master_publish_pull
|
||||||
|
|
||||||
|
``tcp_master_publish_pull``
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Default: ``4514``
|
||||||
|
|
||||||
|
The TCP port on which events for the master should be pulled fom and then republished onto
|
||||||
|
the event bus on the master.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_master_publish_pull: 4514
|
||||||
|
|
||||||
|
.. conf_master:: tcp_master_workers
|
||||||
|
|
||||||
|
``tcp_master_workers``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Default: ``4515``
|
||||||
|
|
||||||
|
The TCP port for ``mworkers`` to connect to on the master.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_master_workers: 4515
|
||||||
|
|
||||||
|
|
||||||
.. _salt-ssh-configuration:
|
.. _salt-ssh-configuration:
|
||||||
|
|
||||||
@ -1192,6 +1202,19 @@ public keys from minions.
|
|||||||
|
|
||||||
auto_accept: False
|
auto_accept: False
|
||||||
|
|
||||||
|
.. conf_master:: keysize
|
||||||
|
|
||||||
|
``keysize``
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Default: ``2048``
|
||||||
|
|
||||||
|
The size of key that should be generated when creating new keys.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
keysize: 2048
|
||||||
|
|
||||||
.. conf_master:: autosign_timeout
|
.. conf_master:: autosign_timeout
|
||||||
|
|
||||||
``autosign_timeout``
|
``autosign_timeout``
|
||||||
@ -1236,6 +1259,24 @@ minion IDs for which keys will automatically be rejected. Will override both
|
|||||||
membership in the :conf_master:`autosign_file` and the
|
membership in the :conf_master:`autosign_file` and the
|
||||||
:conf_master:`auto_accept` setting.
|
:conf_master:`auto_accept` setting.
|
||||||
|
|
||||||
|
.. conf_master:: permissive_pki_access
|
||||||
|
|
||||||
|
``permissive_pki_access``
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Default: ``False``
|
||||||
|
|
||||||
|
Enable permissive access to the salt keys. This allows you to run the
|
||||||
|
master or minion as root, but have a non-root group be given access to
|
||||||
|
your pki_dir. To make the access explicit, root must belong to the group
|
||||||
|
you've given access to. This is potentially quite insecure. If an autosign_file
|
||||||
|
is specified, enabling permissive_pki_access will allow group access to that
|
||||||
|
specific file.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
permissive_pki_access: False
|
||||||
|
|
||||||
.. conf_master:: publisher_acl
|
.. conf_master:: publisher_acl
|
||||||
|
|
||||||
``publisher_acl``
|
``publisher_acl``
|
||||||
@ -1278,6 +1319,20 @@ This is completely disabled by default.
|
|||||||
- cmd.*
|
- cmd.*
|
||||||
- test.echo
|
- test.echo
|
||||||
|
|
||||||
|
.. conf_master:: sudo_acl
|
||||||
|
|
||||||
|
``sudo_acl``
|
||||||
|
------------
|
||||||
|
|
||||||
|
Default: ``False``
|
||||||
|
|
||||||
|
Enforce ``publisher_acl`` and ``publisher_acl_blacklist`` when users have sudo
|
||||||
|
access to the salt command.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
sudo_acl: False
|
||||||
|
|
||||||
.. conf_master:: external_auth
|
.. conf_master:: external_auth
|
||||||
|
|
||||||
``external_auth``
|
``external_auth``
|
||||||
@ -1462,6 +1517,19 @@ Do not disable this unless it is absolutely clear what this does.
|
|||||||
|
|
||||||
rotate_aes_key: True
|
rotate_aes_key: True
|
||||||
|
|
||||||
|
.. conf_master:: publish_session
|
||||||
|
|
||||||
|
``publish_session``
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Default: ``86400``
|
||||||
|
|
||||||
|
The number of seconds between AES key rotations on the master.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
publish_session: Default: 86400
|
||||||
|
|
||||||
.. conf_master:: ssl
|
.. conf_master:: ssl
|
||||||
|
|
||||||
``ssl``
|
``ssl``
|
||||||
@ -1492,6 +1560,24 @@ constant names without ssl module prefix: ``CERT_REQUIRED`` or ``PROTOCOL_SSLv23
|
|||||||
``allow_minion_key_revoke``
|
``allow_minion_key_revoke``
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
Default: ``False``
|
||||||
|
|
||||||
|
By default, the master deletes its cache of minion data when the key for that
|
||||||
|
minion is removed. To preserve the cache after key deletion, set
|
||||||
|
``preserve_minion_cache`` to True.
|
||||||
|
|
||||||
|
WARNING: This may have security implications if compromised minions auth with
|
||||||
|
a previous deleted minion ID.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
preserve_minion_cache: False
|
||||||
|
|
||||||
|
.. conf_master:: allow_minion_key_revoke
|
||||||
|
|
||||||
|
``allow_minion_key_revoke``
|
||||||
|
---------------------------
|
||||||
|
|
||||||
Default: ``True``
|
Default: ``True``
|
||||||
|
|
||||||
Controls whether a minion can request its own key revocation. When True
|
Controls whether a minion can request its own key revocation. When True
|
||||||
@ -1504,6 +1590,127 @@ the master will drop the request and the minion's key will remain accepted.
|
|||||||
rotate_aes_key: True
|
rotate_aes_key: True
|
||||||
|
|
||||||
|
|
||||||
|
Master Large Scale Tuning Settings
|
||||||
|
==================================
|
||||||
|
|
||||||
|
.. conf_master:: max_open_files
|
||||||
|
|
||||||
|
``max_open_files``
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Default: ``100000``
|
||||||
|
|
||||||
|
Each minion connecting to the master uses AT LEAST one file descriptor, the
|
||||||
|
master subscription connection. If enough minions connect you might start
|
||||||
|
seeing on the console(and then salt-master crashes):
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
Too many open files (tcp_listener.cpp:335)
|
||||||
|
Aborted (core dumped)
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
max_open_files: 100000
|
||||||
|
|
||||||
|
By default this value will be the one of `ulimit -Hn`, i.e., the hard limit for
|
||||||
|
max open files.
|
||||||
|
|
||||||
|
To set a different value than the default one, uncomment, and configure this
|
||||||
|
setting. Remember that this value CANNOT be higher than the hard limit. Raising
|
||||||
|
the hard limit depends on the OS and/or distribution, a good way to find the
|
||||||
|
limit is to search the internet for something like this:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
raise max open files hard limit debian
|
||||||
|
|
||||||
|
.. conf_master:: worker_threads
|
||||||
|
|
||||||
|
``worker_threads``
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Default: ``5``
|
||||||
|
|
||||||
|
The number of threads to start for receiving commands and replies from minions.
|
||||||
|
If minions are stalling on replies because you have many minions, raise the
|
||||||
|
worker_threads value.
|
||||||
|
|
||||||
|
Worker threads should not be put below 3 when using the peer system, but can
|
||||||
|
drop down to 1 worker otherwise.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
When the master daemon starts, it is expected behaviour to see
|
||||||
|
multiple salt-master processes, even if 'worker_threads' is set to '1'. At
|
||||||
|
a minimum, a controlling process will start along with a Publisher, an
|
||||||
|
EventPublisher, and a number of MWorker processes will be started. The
|
||||||
|
number of MWorker processes is tuneable by the 'worker_threads'
|
||||||
|
configuration value while the others are not.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
worker_threads: 5
|
||||||
|
|
||||||
|
.. conf_master:: pub_hwm
|
||||||
|
|
||||||
|
``pub_hwm``
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Default: ``1000``
|
||||||
|
|
||||||
|
The zeromq high water mark on the publisher interface.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
pub_hwm: 1000
|
||||||
|
|
||||||
|
.. conf_master:: zmq_backlog
|
||||||
|
|
||||||
|
``zmq_backlog``
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Default: ``1000``
|
||||||
|
|
||||||
|
The listen queue size of the ZeroMQ backlog.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
zmq_backlog: 1000
|
||||||
|
|
||||||
|
.. conf_master:: salt_event_pub_hwm
|
||||||
|
.. conf_master:: event_publisher_pub_hwm
|
||||||
|
|
||||||
|
``salt_event_pub_hwm`` and ``event_publisher_pub_hwm``
|
||||||
|
------------------------------------------------------
|
||||||
|
|
||||||
|
These two ZeroMQ High Water Mark settings, ``salt_event_pub_hwm`` and
|
||||||
|
``event_publisher_pub_hwm`` are significant for masters with thousands of
|
||||||
|
minions. When these are insufficiently high it will manifest in random
|
||||||
|
responses missing in the CLI and even missing from the job cache. Masters
|
||||||
|
that have fast CPUs and many cores with appropriate ``worker_threads``
|
||||||
|
will not need these set as high.
|
||||||
|
|
||||||
|
The ZeroMQ high-water-mark for the ``SaltEvent`` pub socket default is:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
salt_event_pub_hwm: 20000
|
||||||
|
|
||||||
|
The ZeroMQ high-water-mark for the ``EventPublisher`` pub socket default is:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
event_publisher_pub_hwm: 10000
|
||||||
|
|
||||||
|
As an example, on single master deployment with 8,000 minions, 2.4GHz CPUs,
|
||||||
|
24 cores, and 32GiB memory has these settings:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
salt_event_pub_hwm: 128000
|
||||||
|
event_publisher_pub_hwm: 64000
|
||||||
|
|
||||||
|
|
||||||
.. _master-module-management:
|
.. _master-module-management:
|
||||||
|
|
||||||
Master Module Management
|
Master Module Management
|
||||||
@ -3179,6 +3386,26 @@ configuration.
|
|||||||
|
|
||||||
pillar_opts: False
|
pillar_opts: False
|
||||||
|
|
||||||
|
.. conf_master:: pillar_safe_render_error
|
||||||
|
|
||||||
|
``pillar_safe_render_error``
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Default: ``True``
|
||||||
|
|
||||||
|
The pillar_safe_render_error option prevents the master from passing pillar
|
||||||
|
render errors to the minion. This is set on by default because the error could
|
||||||
|
contain templating data which would give that minion information it shouldn't
|
||||||
|
have, like a password! When set ``True`` the error message will only show:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
Rendering SLS 'my.sls' failed. Please see master log for details.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
pillar_safe_render_error: True
|
||||||
|
|
||||||
.. _master-configuration-ext-pillar:
|
.. _master-configuration-ext-pillar:
|
||||||
|
|
||||||
.. conf_master:: ext_pillar
|
.. conf_master:: ext_pillar
|
||||||
@ -3849,6 +4076,62 @@ can be utilized:
|
|||||||
pillar_cache_backend: disk
|
pillar_cache_backend: disk
|
||||||
|
|
||||||
|
|
||||||
|
Master Reactor Settings
|
||||||
|
=======================
|
||||||
|
|
||||||
|
.. conf_master:: reactor
|
||||||
|
|
||||||
|
``reactor``
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Default: ``[]``
|
||||||
|
|
||||||
|
Defines a salt reactor. See the :ref:`Reactor <reactor>` documentation for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
reactor: []
|
||||||
|
|
||||||
|
.. conf_master:: reactor_refresh_interval
|
||||||
|
|
||||||
|
``reactor_refresh_interval``
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Default: ``60``
|
||||||
|
|
||||||
|
The TTL for the cache of the reactor configuration.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
reactor_refresh_interval: 60
|
||||||
|
|
||||||
|
.. conf_master:: reactor_worker_threads
|
||||||
|
|
||||||
|
``reactor_worker_threads``
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Default: ``10``
|
||||||
|
|
||||||
|
The number of workers for the runner/wheel in the reactor.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
reactor_worker_threads: 10
|
||||||
|
|
||||||
|
.. conf_master:: reactor_worker_hwm
|
||||||
|
|
||||||
|
``reactor_worker_hwm``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Default: ``10000``
|
||||||
|
|
||||||
|
The queue size for workers in the reactor.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
reactor_worker_hwm: 10000
|
||||||
|
|
||||||
|
|
||||||
.. _syndic-server-settings:
|
.. _syndic-server-settings:
|
||||||
|
|
||||||
Syndic Server Settings
|
Syndic Server Settings
|
||||||
@ -4315,6 +4598,63 @@ option then the master will log a warning message.
|
|||||||
- /etc/roles/webserver
|
- /etc/roles/webserver
|
||||||
|
|
||||||
|
|
||||||
|
Keepalive Settings
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. conf_master:: tcp_keepalive
|
||||||
|
|
||||||
|
``tcp_keepalive``
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Default: ``True``
|
||||||
|
|
||||||
|
The tcp keepalive interval to set on TCP ports. This setting can be used to tune Salt
|
||||||
|
connectivity issues in messy network environments with misbehaving firewalls.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_keepalive: True
|
||||||
|
|
||||||
|
.. conf_master:: tcp_keepalive_cnt
|
||||||
|
|
||||||
|
``tcp_keepalive_cnt``
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Default: ``-1``
|
||||||
|
|
||||||
|
Sets the ZeroMQ TCP keepalive count. May be used to tune issues with minion disconnects.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_keepalive_cnt: -1
|
||||||
|
|
||||||
|
.. conf_master:: tcp_keepalive_idle
|
||||||
|
|
||||||
|
``tcp_keepalive_idle``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Default: ``300``
|
||||||
|
|
||||||
|
Sets ZeroMQ TCP keepalive idle. May be used to tune issues with minion disconnects.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_keepalive_idle: 300
|
||||||
|
|
||||||
|
.. conf_master:: tcp_keepalive_intvl
|
||||||
|
|
||||||
|
``tcp_keepalive_intvl``
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Default: ``-1``
|
||||||
|
|
||||||
|
Sets ZeroMQ TCP keepalive interval. May be used to tune issues with minion disconnects.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_keepalive_intvl': -1
|
||||||
|
|
||||||
|
|
||||||
.. _winrepo-master-config-opts:
|
.. _winrepo-master-config-opts:
|
||||||
|
|
||||||
Windows Software Repo Settings
|
Windows Software Repo Settings
|
||||||
@ -4453,7 +4793,7 @@ URL of the repository:
|
|||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
winrepo_remotes:
|
winrepo_remotes_ng:
|
||||||
- '<commit_id> https://github.com/saltstack/salt-winrepo-ng.git'
|
- '<commit_id> https://github.com/saltstack/salt-winrepo-ng.git'
|
||||||
|
|
||||||
Replace ``<commit_id>`` with the SHA1 hash of a commit ID. Specifying a commit
|
Replace ``<commit_id>`` with the SHA1 hash of a commit ID. Specifying a commit
|
||||||
|
@ -750,6 +750,20 @@ seconds each iteration.
|
|||||||
|
|
||||||
acceptance_wait_time_max: 0
|
acceptance_wait_time_max: 0
|
||||||
|
|
||||||
|
.. conf_minion:: rejected_retry
|
||||||
|
|
||||||
|
``rejected_retry``
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Default: ``False``
|
||||||
|
|
||||||
|
If the master rejects the minion's public key, retry instead of exiting.
|
||||||
|
Rejected keys will be handled the same as waiting on acceptance.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
rejected_retry: False
|
||||||
|
|
||||||
.. conf_minion:: random_reauth_delay
|
.. conf_minion:: random_reauth_delay
|
||||||
|
|
||||||
``random_reauth_delay``
|
``random_reauth_delay``
|
||||||
@ -1180,7 +1194,7 @@ If certain returners should be disabled, this is the place
|
|||||||
.. conf_minion:: enable_whitelist_modules
|
.. conf_minion:: enable_whitelist_modules
|
||||||
|
|
||||||
``whitelist_modules``
|
``whitelist_modules``
|
||||||
----------------------------
|
---------------------
|
||||||
|
|
||||||
Default: ``[]`` (Module whitelisting is disabled. Adding anything to the config option
|
Default: ``[]`` (Module whitelisting is disabled. Adding anything to the config option
|
||||||
will cause only the listed modules to be enabled. Modules not in the list will
|
will cause only the listed modules to be enabled. Modules not in the list will
|
||||||
@ -1272,6 +1286,20 @@ A list of extra directories to search for Salt renderers
|
|||||||
render_dirs:
|
render_dirs:
|
||||||
- /var/lib/salt/renderers
|
- /var/lib/salt/renderers
|
||||||
|
|
||||||
|
.. conf_minion:: utils_dirs
|
||||||
|
|
||||||
|
``utils_dirs``
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Default: ``[]``
|
||||||
|
|
||||||
|
A list of extra directories to search for Salt utilities
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
utils_dirs:
|
||||||
|
- /var/lib/salt/utils
|
||||||
|
|
||||||
.. conf_minion:: cython_enable
|
.. conf_minion:: cython_enable
|
||||||
|
|
||||||
``cython_enable``
|
``cython_enable``
|
||||||
@ -1320,6 +1348,20 @@ below.
|
|||||||
providers:
|
providers:
|
||||||
service: systemd
|
service: systemd
|
||||||
|
|
||||||
|
.. conf_minion:: modules_max_memory
|
||||||
|
|
||||||
|
``modules_max_memory``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Default: ``-1``
|
||||||
|
|
||||||
|
Specify a max size (in bytes) for modules on import. This feature is currently
|
||||||
|
only supported on *nix operating systems and requires psutil.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
modules_max_memory: -1
|
||||||
|
|
||||||
.. conf_minion:: extmod_whitelist
|
.. conf_minion:: extmod_whitelist
|
||||||
.. conf_minion:: extmod_blacklist
|
.. conf_minion:: extmod_blacklist
|
||||||
|
|
||||||
@ -1345,8 +1387,8 @@ whitelist an empty list.
|
|||||||
modules:
|
modules:
|
||||||
- specific_module
|
- specific_module
|
||||||
|
|
||||||
|
|
||||||
Valid options:
|
Valid options:
|
||||||
|
|
||||||
- beacons
|
- beacons
|
||||||
- clouds
|
- clouds
|
||||||
- sdb
|
- sdb
|
||||||
@ -1492,6 +1534,52 @@ environment lacks one.
|
|||||||
|
|
||||||
default_top: dev
|
default_top: dev
|
||||||
|
|
||||||
|
.. conf_minion:: startup_states
|
||||||
|
|
||||||
|
``startup_states``
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Default: ``''``
|
||||||
|
|
||||||
|
States to run when the minion daemon starts. To enable, set ``startup_states`` to:
|
||||||
|
|
||||||
|
- ``highstate``: Execute state.highstate
|
||||||
|
- ``sls``: Read in the sls_list option and execute the named sls files
|
||||||
|
- ``top``: Read top_file option and execute based on that file on the Master
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
startup_states: ''
|
||||||
|
|
||||||
|
.. conf_minion:: sls_list
|
||||||
|
|
||||||
|
``sls_list``
|
||||||
|
------------
|
||||||
|
|
||||||
|
Default: ``[]``
|
||||||
|
|
||||||
|
List of states to run when the minion starts up if ``startup_states`` is set to ``sls``.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
sls_list:
|
||||||
|
- edit.vim
|
||||||
|
- hyper
|
||||||
|
|
||||||
|
.. conf_minion:: top_file
|
||||||
|
|
||||||
|
``top_file``
|
||||||
|
------------
|
||||||
|
|
||||||
|
Default: ``''``
|
||||||
|
|
||||||
|
Top file to execute if ``startup_states`` is set to ``top``.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
top_file: ''
|
||||||
|
|
||||||
|
|
||||||
State Management Settings
|
State Management Settings
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
@ -1508,7 +1596,7 @@ The default renderer used for local state executions
|
|||||||
|
|
||||||
renderer: yaml_jinja
|
renderer: yaml_jinja
|
||||||
|
|
||||||
.. conf_master:: test
|
.. conf_minion:: test
|
||||||
|
|
||||||
``test``
|
``test``
|
||||||
--------
|
--------
|
||||||
@ -2026,6 +2114,35 @@ before the initial key exchange. The master fingerprint can be found by running
|
|||||||
|
|
||||||
master_finger: 'ba:30:65:2a:d6:9e:20:4f:d8:b2:f3:a7:d4:65:11:13'
|
master_finger: 'ba:30:65:2a:d6:9e:20:4f:d8:b2:f3:a7:d4:65:11:13'
|
||||||
|
|
||||||
|
.. conf_minion:: keysize
|
||||||
|
|
||||||
|
``keysize``
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Default: ``2048``
|
||||||
|
|
||||||
|
The size of key that should be generated when creating new keys.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
keysize: 2048
|
||||||
|
|
||||||
|
.. conf_minion:: permissive_pki_access
|
||||||
|
|
||||||
|
``permissive_pki_access``
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Default: ``False``
|
||||||
|
|
||||||
|
Enable permissive access to the salt keys. This allows you to run the
|
||||||
|
master or minion as root, but have a non-root group be given access to
|
||||||
|
your pki_dir. To make the access explicit, root must belong to the group
|
||||||
|
you've given access to. This is potentially quite insecure.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
permissive_pki_access: False
|
||||||
|
|
||||||
.. conf_minion:: verify_master_pubkey_sign
|
.. conf_minion:: verify_master_pubkey_sign
|
||||||
|
|
||||||
``verify_master_pubkey_sign``
|
``verify_master_pubkey_sign``
|
||||||
@ -2133,7 +2250,7 @@ blocked. If `cmd_whitelist_glob` is NOT SET, then all shell commands are permitt
|
|||||||
- 'cat /etc/fstab'
|
- 'cat /etc/fstab'
|
||||||
|
|
||||||
|
|
||||||
.. conf_master:: ssl
|
.. conf_minion:: ssl
|
||||||
|
|
||||||
``ssl``
|
``ssl``
|
||||||
-------
|
-------
|
||||||
@ -2159,6 +2276,62 @@ constant names without ssl module prefix: ``CERT_REQUIRED`` or ``PROTOCOL_SSLv23
|
|||||||
ssl_version: PROTOCOL_TLSv1_2
|
ssl_version: PROTOCOL_TLSv1_2
|
||||||
|
|
||||||
|
|
||||||
|
Reactor Settings
|
||||||
|
================
|
||||||
|
|
||||||
|
.. conf_minion:: reactor
|
||||||
|
|
||||||
|
``reactor``
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Default: ``[]``
|
||||||
|
|
||||||
|
Defines a salt reactor. See the :ref:`Reactor <reactor>` documentation for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
reactor: []
|
||||||
|
|
||||||
|
.. conf_minion:: reactor_refresh_interval
|
||||||
|
|
||||||
|
``reactor_refresh_interval``
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Default: ``60``
|
||||||
|
|
||||||
|
The TTL for the cache of the reactor configuration.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
reactor_refresh_interval: 60
|
||||||
|
|
||||||
|
.. conf_minion:: reactor_worker_threads
|
||||||
|
|
||||||
|
``reactor_worker_threads``
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Default: ``10``
|
||||||
|
|
||||||
|
The number of workers for the runner/wheel in the reactor.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
reactor_worker_threads: 10
|
||||||
|
|
||||||
|
.. conf_minion:: reactor_worker_hwm
|
||||||
|
|
||||||
|
``reactor_worker_hwm``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Default: ``10000``
|
||||||
|
|
||||||
|
The queue size for workers in the reactor.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
reactor_worker_hwm: 10000
|
||||||
|
|
||||||
|
|
||||||
Thread Settings
|
Thread Settings
|
||||||
===============
|
===============
|
||||||
|
|
||||||
@ -2429,6 +2602,62 @@ option then the minion will log a warning message.
|
|||||||
- /etc/roles/webserver
|
- /etc/roles/webserver
|
||||||
|
|
||||||
|
|
||||||
|
Keepalive Settings
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. conf_minion:: tcp_keepalive
|
||||||
|
|
||||||
|
``tcp_keepalive``
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Default: ``True``
|
||||||
|
|
||||||
|
The tcp keepalive interval to set on TCP ports. This setting can be used to tune Salt
|
||||||
|
connectivity issues in messy network environments with misbehaving firewalls.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_keepalive: True
|
||||||
|
|
||||||
|
.. conf_minion:: tcp_keepalive_cnt
|
||||||
|
|
||||||
|
``tcp_keepalive_cnt``
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Default: ``-1``
|
||||||
|
|
||||||
|
Sets the ZeroMQ TCP keepalive count. May be used to tune issues with minion disconnects.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_keepalive_cnt: -1
|
||||||
|
|
||||||
|
.. conf_minion:: tcp_keepalive_idle
|
||||||
|
|
||||||
|
``tcp_keepalive_idle``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Default: ``300``
|
||||||
|
|
||||||
|
Sets ZeroMQ TCP keepalive idle. May be used to tune issues with minion disconnects.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_keepalive_idle: 300
|
||||||
|
|
||||||
|
.. conf_minion:: tcp_keepalive_intvl
|
||||||
|
|
||||||
|
``tcp_keepalive_intvl``
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Default: ``-1``
|
||||||
|
|
||||||
|
Sets ZeroMQ TCP keepalive interval. May be used to tune issues with minion disconnects.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
tcp_keepalive_intvl': -1
|
||||||
|
|
||||||
|
|
||||||
Frozen Build Update Settings
|
Frozen Build Update Settings
|
||||||
============================
|
============================
|
||||||
@ -2530,6 +2759,36 @@ out.
|
|||||||
|
|
||||||
winrepo_dir: 'D:\winrepo'
|
winrepo_dir: 'D:\winrepo'
|
||||||
|
|
||||||
|
.. conf_minion:: winrepo_dir_ng
|
||||||
|
|
||||||
|
``winrepo_dir_ng``
|
||||||
|
------------------
|
||||||
|
|
||||||
|
.. versionadded:: 2015.8.0
|
||||||
|
A new :ref:`ng <windows-package-manager>` repo was added.
|
||||||
|
|
||||||
|
Default: ``/srv/salt/win/repo-ng``
|
||||||
|
|
||||||
|
Location on the minion where the :conf_minion:`winrepo_remotes_ng` are checked
|
||||||
|
out for 2015.8.0 and later minions.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
winrepo_dir_ng: /srv/salt/win/repo-ng
|
||||||
|
|
||||||
|
.. conf_minion:: winrepo_source_dir
|
||||||
|
|
||||||
|
``winrepo_source_dir``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Default: ``salt://win/repo-ng/``
|
||||||
|
|
||||||
|
The source location for the winrepo sls files.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
winrepo_source_dir: salt://win/repo-ng/
|
||||||
|
|
||||||
.. conf_minion:: winrepo_cachefile
|
.. conf_minion:: winrepo_cachefile
|
||||||
.. conf_minion:: win_repo_cachefile
|
.. conf_minion:: win_repo_cachefile
|
||||||
|
|
||||||
@ -2582,3 +2841,33 @@ URL of the repository:
|
|||||||
Replace ``<commit_id>`` with the SHA1 hash of a commit ID. Specifying a commit
|
Replace ``<commit_id>`` with the SHA1 hash of a commit ID. Specifying a commit
|
||||||
ID is useful in that it allows one to revert back to a previous version in the
|
ID is useful in that it allows one to revert back to a previous version in the
|
||||||
event that an error is introduced in the latest revision of the repo.
|
event that an error is introduced in the latest revision of the repo.
|
||||||
|
|
||||||
|
.. conf_minion:: winrepo_remotes_ng
|
||||||
|
|
||||||
|
``winrepo_remotes_ng``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
.. versionadded:: 2015.8.0
|
||||||
|
A new :ref:`ng <windows-package-manager>` repo was added.
|
||||||
|
|
||||||
|
Default: ``['https://github.com/saltstack/salt-winrepo-ng.git']``
|
||||||
|
|
||||||
|
List of git repositories to checkout and include in the winrepo for
|
||||||
|
2015.8.0 and later minions.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
winrepo_remotes_ng:
|
||||||
|
- https://github.com/saltstack/salt-winrepo-ng.git
|
||||||
|
|
||||||
|
To specify a specific revision of the repository, prepend a commit ID to the
|
||||||
|
URL of the repository:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
winrepo_remotes_ng:
|
||||||
|
- '<commit_id> https://github.com/saltstack/salt-winrepo-ng.git'
|
||||||
|
|
||||||
|
Replace ``<commit_id>`` with the SHA1 hash of a commit ID. Specifying a commit
|
||||||
|
ID is useful in that it allows one to revert back to a previous version in the
|
||||||
|
event that an error is introduced in the latest revision of the repo.
|
||||||
|
@ -195,6 +195,7 @@ execution modules
|
|||||||
keyboard
|
keyboard
|
||||||
keystone
|
keystone
|
||||||
kmod
|
kmod
|
||||||
|
kubernetes
|
||||||
launchctl
|
launchctl
|
||||||
layman
|
layman
|
||||||
ldap3
|
ldap3
|
||||||
|
6
doc/ref/modules/all/salt.modules.kubernetes.rst
Normal file
6
doc/ref/modules/all/salt.modules.kubernetes.rst
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
=======================
|
||||||
|
salt.modules.kubernetes
|
||||||
|
=======================
|
||||||
|
|
||||||
|
.. automodule:: salt.modules.kubernetes
|
||||||
|
:members:
|
@ -405,6 +405,29 @@ similar to the following:
|
|||||||
return __virtualname__
|
return __virtualname__
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
The ``__virtual__()`` function can return a ``True`` or ``False`` boolean, a tuple,
|
||||||
|
or a string. If it returns a ``True`` value, this ``__virtualname__`` module-level
|
||||||
|
attribute can be set as seen in the above example. This is the string that the module
|
||||||
|
should be referred to as.
|
||||||
|
|
||||||
|
When ``__virtual__()`` returns a tuple, the first item should be a boolean and the
|
||||||
|
second should be a string. This is typically done when the module should not load. The
|
||||||
|
first value of the tuple is ``False`` and the second is the error message to display
|
||||||
|
for why the module did not load.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def __virtual__():
|
||||||
|
'''
|
||||||
|
Only load if git exists on the system
|
||||||
|
'''
|
||||||
|
if salt.utils.which('git') is None:
|
||||||
|
return (False,
|
||||||
|
'The git execution module cannot be loaded: git unavailable.')
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
=============
|
=============
|
||||||
|
@ -135,6 +135,7 @@ state modules
|
|||||||
keyboard
|
keyboard
|
||||||
keystone
|
keystone
|
||||||
kmod
|
kmod
|
||||||
|
kubernetes
|
||||||
layman
|
layman
|
||||||
ldap
|
ldap
|
||||||
libcloud_dns
|
libcloud_dns
|
||||||
|
6
doc/ref/states/all/salt.states.kubernetes.rst
Normal file
6
doc/ref/states/all/salt.states.kubernetes.rst
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
======================
|
||||||
|
salt.states.kubernetes
|
||||||
|
======================
|
||||||
|
|
||||||
|
.. automodule:: salt.states.kubernetes
|
||||||
|
:members:
|
@ -519,7 +519,8 @@ runas
|
|||||||
|
|
||||||
.. versionadded:: 2017.7.0
|
.. versionadded:: 2017.7.0
|
||||||
|
|
||||||
The ``runas`` global option is used to set the user which will be used to run the command in the ``cmd.run`` module.
|
The ``runas`` global option is used to set the user which will be used to run
|
||||||
|
the command in the ``cmd.run`` module.
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
@ -532,6 +533,26 @@ The ``runas`` global option is used to set the user which will be used to run th
|
|||||||
|
|
||||||
In the above state, the pip command run by ``cmd.run`` will be run by the daniel user.
|
In the above state, the pip command run by ``cmd.run`` will be run by the daniel user.
|
||||||
|
|
||||||
|
runas_password
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. versionadded:: 2017.7.2
|
||||||
|
|
||||||
|
The ``runas_password`` global option is used to set the password used by the
|
||||||
|
runas global option. This is required by ``cmd.run`` on Windows when ``runas``
|
||||||
|
is specified. It will be set when ``runas_password`` is defined in the state.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
run_script:
|
||||||
|
cmd.run:
|
||||||
|
- name: Powershell -NonInteractive -ExecutionPolicy Bypass -File C:\\Temp\\script.ps1
|
||||||
|
- runas: frank
|
||||||
|
- runas_password: supersecret
|
||||||
|
|
||||||
|
In the above state, the Powershell script run by ``cmd.run`` will be run by the
|
||||||
|
frank user with the password ``supersecret``.
|
||||||
|
|
||||||
.. _requisites-require-in:
|
.. _requisites-require-in:
|
||||||
.. _requisites-watch-in:
|
.. _requisites-watch-in:
|
||||||
.. _requisites-onchanges-in:
|
.. _requisites-onchanges-in:
|
||||||
|
@ -78,6 +78,7 @@ parameters are discussed in more detail below.
|
|||||||
# RHEL -> ec2-user
|
# RHEL -> ec2-user
|
||||||
# CentOS -> ec2-user
|
# CentOS -> ec2-user
|
||||||
# Ubuntu -> ubuntu
|
# Ubuntu -> ubuntu
|
||||||
|
# Debian -> admin
|
||||||
#
|
#
|
||||||
ssh_username: ec2-user
|
ssh_username: ec2-user
|
||||||
|
|
||||||
|
@ -371,7 +371,6 @@ both.
|
|||||||
compute_name: cloudServersOpenStack
|
compute_name: cloudServersOpenStack
|
||||||
protocol: ipv4
|
protocol: ipv4
|
||||||
compute_region: DFW
|
compute_region: DFW
|
||||||
protocol: ipv4
|
|
||||||
user: myuser
|
user: myuser
|
||||||
tenant: 5555555
|
tenant: 5555555
|
||||||
password: mypass
|
password: mypass
|
||||||
|
@ -64,7 +64,9 @@ automatically installed salt-cloud for you. Use your distribution's package
|
|||||||
manager to install the ``salt-cloud`` package from the same repo that you
|
manager to install the ``salt-cloud`` package from the same repo that you
|
||||||
used to install Salt. These repos will automatically be setup by Salt Bootstrap.
|
used to install Salt. These repos will automatically be setup by Salt Bootstrap.
|
||||||
|
|
||||||
If there is no salt-cloud package, install with ``pip install salt-cloud``.
|
Alternatively, the ``-L`` option can be passed to the `Salt Bootstrap`_ script when
|
||||||
|
installing Salt. The ``-L`` option will install ``salt-cloud`` and the required
|
||||||
|
``libcloud`` package.
|
||||||
|
|
||||||
.. _`Salt Bootstrap`: https://github.com/saltstack/salt-bootstrap
|
.. _`Salt Bootstrap`: https://github.com/saltstack/salt-bootstrap
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@ automatically installed salt-cloud for you. Use your distribution's package
|
|||||||
manager to install the ``salt-cloud`` package from the same repo that you
|
manager to install the ``salt-cloud`` package from the same repo that you
|
||||||
used to install Salt. These repos will automatically be setup by Salt Bootstrap.
|
used to install Salt. These repos will automatically be setup by Salt Bootstrap.
|
||||||
|
|
||||||
If there is no salt-cloud package, install with ``pip install salt-cloud``.
|
Alternatively, the ``-L`` option can be passed to the `Salt Bootstrap`_ script when
|
||||||
|
installing Salt. The ``-L`` option will install ``salt-cloud`` and the required
|
||||||
|
``libcloud`` package.
|
||||||
|
|
||||||
.. _`Salt Bootstrap`: https://github.com/saltstack/salt-bootstrap
|
.. _`Salt Bootstrap`: https://github.com/saltstack/salt-bootstrap
|
||||||
|
|
||||||
|
154
doc/topics/installation/eos.rst
Normal file
154
doc/topics/installation/eos.rst
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
=========================================
|
||||||
|
Arista EOS Salt minion installation guide
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
The Salt minion for Arista EOS is distributed as a SWIX extension and can be installed directly on the switch. The EOS network operating system is based on old Fedora distributions and the installation of the ``salt-minion`` requires backports. This SWIX extension contains the necessary backports, together with the Salt basecode.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This SWIX extension has been tested on Arista DCS-7280SE-68-R, running EOS 4.17.5M and vEOS 4.18.3F.
|
||||||
|
|
||||||
|
Important Notes
|
||||||
|
===============
|
||||||
|
|
||||||
|
This package is in beta, make sure to test it carefully before running it in production.
|
||||||
|
|
||||||
|
If confirmed working correctly, please report and add a note on this page with the platform model and EOS version.
|
||||||
|
|
||||||
|
If you want to uninstall this package, please refer to the uninstalling_ section.
|
||||||
|
|
||||||
|
Installation from the Official SaltStack Repository
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
Download the swix package and save it to flash.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos#copy https://salt-eos.netops.life/salt-eos-latest.swix flash:
|
||||||
|
veos#copy https://salt-eos.netops.life/startup.sh flash:
|
||||||
|
|
||||||
|
Install the Extension
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Copy the Salt package to extension
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos#copy flash:salt-eos-latest.swix extension:
|
||||||
|
|
||||||
|
Install the SWIX
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos#extension salt-eos-latest.swix force
|
||||||
|
|
||||||
|
Verify the installation
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos#show extensions | include salt-eos
|
||||||
|
salt-eos-2017-07-19.swix 1.0.11/1.fc25 A, F 27
|
||||||
|
|
||||||
|
Change the Salt master IP address or FQDN, by edit the variable (SALT_MASTER)
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos#bash vi /mnt/flash/startup.sh
|
||||||
|
|
||||||
|
Make sure you enable the eAPI with unix-socket
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos(config)#management api http-commands
|
||||||
|
protocol unix-socket
|
||||||
|
no shutdown
|
||||||
|
|
||||||
|
Post-installation tasks
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Generate Keys and host record and start Salt minion
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos#bash
|
||||||
|
#sudo /mnt/flash/startup.sh
|
||||||
|
|
||||||
|
``salt-minion`` should be running
|
||||||
|
|
||||||
|
Copy the installed extensions to boot-extensions
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos#copy installed-extensions boot-extensions
|
||||||
|
|
||||||
|
Apply event-handler to let EOS start salt-minion during boot-up
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos(config)#event-handler boot-up-script
|
||||||
|
trigger on-boot
|
||||||
|
action bash sudo /mnt/flash/startup.sh
|
||||||
|
|
||||||
|
For more specific installation details of the ``salt-minion``, please refer to :ref:`Configuring Salt<configuring-salt>`.
|
||||||
|
|
||||||
|
.. _uninstalling:
|
||||||
|
|
||||||
|
Uninstalling
|
||||||
|
============
|
||||||
|
|
||||||
|
If you decide to uninstall this package, the following steps are recommended for safety:
|
||||||
|
|
||||||
|
1. Remove the extension from boot-extensions
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos#bash rm /mnt/flash/boot-extensions
|
||||||
|
|
||||||
|
2. Remove the extension from extensions folder
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos#bash rm /mnt/flash/.extensions/salt-eos-latest.swix
|
||||||
|
|
||||||
|
2. Remove boot-up script
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
veos(config)#no event-handler boot-up-script
|
||||||
|
|
||||||
|
Additional Information
|
||||||
|
======================
|
||||||
|
|
||||||
|
This SWIX extension contains the following RPM packages:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
libsodium-1.0.11-1.fc25.i686.rpm
|
||||||
|
libstdc++-6.2.1-2.fc25.i686.rpm
|
||||||
|
openpgm-5.2.122-6.fc24.i686.rpm
|
||||||
|
python-Jinja2-2.8-0.i686.rpm
|
||||||
|
python-PyYAML-3.12-0.i686.rpm
|
||||||
|
python-babel-0.9.6-5.fc18.noarch.rpm
|
||||||
|
python-backports-1.0-3.fc18.i686.rpm
|
||||||
|
python-backports-ssl_match_hostname-3.4.0.2-1.fc18.noarch.rpm
|
||||||
|
python-backports_abc-0.5-0.i686.rpm
|
||||||
|
python-certifi-2016.9.26-0.i686.rpm
|
||||||
|
python-chardet-2.0.1-5.fc18.noarch.rpm
|
||||||
|
python-crypto-1.4.1-1.noarch.rpm
|
||||||
|
python-crypto-2.6.1-1.fc18.i686.rpm
|
||||||
|
python-futures-3.1.1-1.noarch.rpm
|
||||||
|
python-jtextfsm-0.3.1-0.noarch.rpm
|
||||||
|
python-kitchen-1.1.1-2.fc18.noarch.rpm
|
||||||
|
python-markupsafe-0.18-1.fc18.i686.rpm
|
||||||
|
python-msgpack-python-0.4.8-0.i686.rpm
|
||||||
|
python-napalm-base-0.24.3-1.noarch.rpm
|
||||||
|
python-napalm-eos-0.6.0-1.noarch.rpm
|
||||||
|
python-netaddr-0.7.18-0.noarch.rpm
|
||||||
|
python-pyeapi-0.7.0-0.noarch.rpm
|
||||||
|
python-salt-2017.7.0_1414_g2fb986f-1.noarch.rpm
|
||||||
|
python-singledispatch-3.4.0.3-0.i686.rpm
|
||||||
|
python-six-1.10.0-0.i686.rpm
|
||||||
|
python-tornado-4.4.2-0.i686.rpm
|
||||||
|
python-urllib3-1.5-7.fc18.noarch.rpm
|
||||||
|
python2-zmq-15.3.0-2.fc25.i686.rpm
|
||||||
|
zeromq-4.1.4-5.fc25.i686.rpm
|
@ -46,6 +46,7 @@ These guides go into detail how to install Salt on a given platform.
|
|||||||
|
|
||||||
arch
|
arch
|
||||||
debian
|
debian
|
||||||
|
eos
|
||||||
fedora
|
fedora
|
||||||
freebsd
|
freebsd
|
||||||
gentoo
|
gentoo
|
||||||
|
@ -335,7 +335,7 @@ Returns:
|
|||||||
|
|
||||||
.. versionadded:: 2017.7.0
|
.. versionadded:: 2017.7.0
|
||||||
|
|
||||||
Wraps a text around quoutes.
|
This text will be wrapped in quotes.
|
||||||
|
|
||||||
|
|
||||||
.. jinja_ref:: regex_search
|
.. jinja_ref:: regex_search
|
||||||
@ -750,19 +750,43 @@ Returns:
|
|||||||
|
|
||||||
Check a whitelist and/or blacklist to see if the value matches it.
|
Check a whitelist and/or blacklist to see if the value matches it.
|
||||||
|
|
||||||
Example:
|
This filter can be used with either a whitelist or a blacklist individually,
|
||||||
|
or a whitelist and a blacklist can be passed simultaneously.
|
||||||
|
|
||||||
|
If whitelist is used alone, value membership is checked against the
|
||||||
|
whitelist only. If the value is found, the function returns ``True``.
|
||||||
|
Otherwise, it returns ``False``.
|
||||||
|
|
||||||
|
If blacklist is used alone, value membership is checked against the
|
||||||
|
blacklist only. If the value is found, the function returns ``False``.
|
||||||
|
Otherwise, it returns ``True``.
|
||||||
|
|
||||||
|
If both a whitelist and a blacklist are provided, value membership in the
|
||||||
|
blacklist will be examined first. If the value is not found in the blacklist,
|
||||||
|
then the whitelist is checked. If the value isn't found in the whitelist,
|
||||||
|
the function returns ``False``.
|
||||||
|
|
||||||
|
Whitelist Example:
|
||||||
|
|
||||||
.. code-block:: jinja
|
.. code-block:: jinja
|
||||||
|
|
||||||
{{ 5 | check_whitelist_blacklist(whitelist=[5, 6, 7]) }}
|
{{ 5 | check_whitelist_blacklist(whitelist=[5, 6, 7]) }}
|
||||||
{{ 5 | check_whitelist_blacklist(blacklist=[5, 6, 7]) }}
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
True
|
True
|
||||||
|
|
||||||
|
Blacklist Example:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{{ 5 | check_whitelist_blacklist(blacklist=[5, 6, 7]) }}
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
False
|
||||||
|
|
||||||
.. jinja_ref:: date_format
|
.. jinja_ref:: date_format
|
||||||
|
|
||||||
@ -825,6 +849,13 @@ Example:
|
|||||||
|
|
||||||
{{ 'wall of text' | to_bytes }}
|
{{ 'wall of text' | to_bytes }}
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This option may have adverse effects when using the default renderer, ``yaml_jinja``.
|
||||||
|
This is due to the fact that YAML requires proper handling in regard to special
|
||||||
|
characters. Please see the section on :ref:`YAML ASCII support <yaml_plain_ascii>`
|
||||||
|
in the :ref:`YAML Idiosyncracies <yaml-idiosyncrasies>` documentation for more
|
||||||
|
information.
|
||||||
|
|
||||||
.. jinja_ref:: json_decode_list
|
.. jinja_ref:: json_decode_list
|
||||||
|
|
||||||
@ -876,16 +907,22 @@ Returns:
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
.. versionadded:: 2017.7.0
|
.. versionadded:: 2017.7.0
|
||||||
|
.. versionadded:: Oxygen
|
||||||
|
Renamed from ``rand_str`` to ``random_hash`` to more accurately describe
|
||||||
|
what the filter does.
|
||||||
|
|
||||||
Generate a random string and applies a hash. Default hashing: md5.
|
Generates a random number between 1 and the number passed to the filter, and
|
||||||
|
then hashes it. The default hash type is the one specified by the minion's
|
||||||
|
:conf_minion:`hash_type` config option, but an alternate hash type can be
|
||||||
|
passed to the filter as an argument.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: jinja
|
.. code-block:: jinja
|
||||||
|
|
||||||
{% set passwd_length = 17 %}
|
{% set num_range = 99999999 %}
|
||||||
{{ passwd_length | rand_str }}
|
{{ num_range | rand_str }}
|
||||||
{{ passwd_length | rand_str('sha512') }}
|
{{ num_range | rand_str('sha512') }}
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
@ -1186,7 +1223,7 @@ Example:
|
|||||||
|
|
||||||
.. code-block:: jinja
|
.. code-block:: jinja
|
||||||
|
|
||||||
{{ ['192.168.0.1', 'foo', 'bar', 'fe80::'] | ipv4 }}
|
{{ ['192.168.0.1', 'foo', 'bar', 'fe80::'] | ipv6 }}
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
@ -1202,7 +1239,12 @@ Returns:
|
|||||||
|
|
||||||
.. versionadded:: 2017.7.0
|
.. versionadded:: 2017.7.0
|
||||||
|
|
||||||
Return the list of hosts within a networks.
|
Return the list of hosts within a networks. This utility works for both IPv4 and IPv6.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When running this command with a large IPv6 network, the command will
|
||||||
|
take a long time to gather all of the hosts.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@ -1224,7 +1266,7 @@ Returns:
|
|||||||
|
|
||||||
.. versionadded:: 2017.7.0
|
.. versionadded:: 2017.7.0
|
||||||
|
|
||||||
Return the size of the network.
|
Return the size of the network. This utility works for both IPv4 and IPv6.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@ -1284,6 +1326,13 @@ Example:
|
|||||||
|
|
||||||
{{ '00:11:22:33:44:55' | mac_str_to_bytes }}
|
{{ '00:11:22:33:44:55' | mac_str_to_bytes }}
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This option may have adverse effects when using the default renderer, ``yaml_jinja``.
|
||||||
|
This is due to the fact that YAML requires proper handling in regard to special
|
||||||
|
characters. Please see the section on :ref:`YAML ASCII support <yaml_plain_ascii>`
|
||||||
|
in the :ref:`YAML Idiosyncracies <yaml-idiosyncrasies>` documentation for more
|
||||||
|
information.
|
||||||
|
|
||||||
.. jinja_ref:: dns_check
|
.. jinja_ref:: dns_check
|
||||||
|
|
||||||
|
5
doc/topics/releases/2016.11.7.rst
Normal file
5
doc/topics/releases/2016.11.7.rst
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
============================
|
||||||
|
Salt 2016.11.7 Release Notes
|
||||||
|
============================
|
||||||
|
|
||||||
|
Version 2016.11.7 is a bugfix release for :ref:`2016.11.0 <release-2016-11-0>`.
|
@ -28,8 +28,6 @@ The following salt-cloud drivers have known issues running with Python 3. These
|
|||||||
|
|
||||||
- Joyent
|
- Joyent
|
||||||
|
|
||||||
- Any driver that relies on the `apache-libcloud` library such as cloudstack, dimenstiondata, gce, nova, and openstack
|
|
||||||
|
|
||||||
- When running under Python 3, users who require Unicode support should ensure that a locale is set on their machines.
|
- When running under Python 3, users who require Unicode support should ensure that a locale is set on their machines.
|
||||||
Users using the `C` locale are advised to switch to a UTF-aware locale to ensure proper functionality with Salt with Python 3.
|
Users using the `C` locale are advised to switch to a UTF-aware locale to ensure proper functionality with Salt with Python 3.
|
||||||
|
|
||||||
@ -124,13 +122,12 @@ State Module Changes
|
|||||||
# After
|
# After
|
||||||
run_something:
|
run_something:
|
||||||
module.run:
|
module.run:
|
||||||
mymodule.something:
|
- mymodule.something:
|
||||||
- name: some name
|
- name: some name
|
||||||
- first_arg: one
|
- first_arg: one
|
||||||
- second_arg: two
|
- second_arg: two
|
||||||
- do_stuff: True
|
- do_stuff: True
|
||||||
|
|
||||||
|
|
||||||
Since a lot of users are already using :py:func:`module.run
|
Since a lot of users are already using :py:func:`module.run
|
||||||
<salt.states.module.run>` states, this new behavior must currently be
|
<salt.states.module.run>` states, this new behavior must currently be
|
||||||
explicitly turned on, to allow users to take their time updating their SLS
|
explicitly turned on, to allow users to take their time updating their SLS
|
||||||
@ -138,6 +135,36 @@ State Module Changes
|
|||||||
the next feature release of Salt (Oxygen) and the old usage will no longer be
|
the next feature release of Salt (Oxygen) and the old usage will no longer be
|
||||||
supported at that time.
|
supported at that time.
|
||||||
|
|
||||||
|
Another feature of the new :py:func:`module.run <salt.states.module.run>` is that
|
||||||
|
it allows calling many functions in a single batch, such as:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
run_something:
|
||||||
|
module.run:
|
||||||
|
- mymodule.function_without_parameters:
|
||||||
|
- mymodule.another_function:
|
||||||
|
- myparam
|
||||||
|
- my_other_param
|
||||||
|
|
||||||
|
In a rare case that you have a function that needs to be called several times but
|
||||||
|
with the different parameters, an additional feature of "tagging" is to the
|
||||||
|
rescue. In order to tag a function, use a colon delimeter. For example:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
run_something:
|
||||||
|
module.run:
|
||||||
|
- mymodule.same_function:1:
|
||||||
|
- mymodule.same_function:2:
|
||||||
|
- myparam
|
||||||
|
- my_other_param
|
||||||
|
- mymodule.same_function:3:
|
||||||
|
- foo: bar
|
||||||
|
|
||||||
|
The example above will run `mymodule.same_function` three times with the
|
||||||
|
different parameters.
|
||||||
|
|
||||||
To enable the new behavior for :py:func:`module.run <salt.states.module.run>`,
|
To enable the new behavior for :py:func:`module.run <salt.states.module.run>`,
|
||||||
add the following to the minion config file:
|
add the following to the minion config file:
|
||||||
|
|
||||||
@ -145,6 +172,7 @@ State Module Changes
|
|||||||
|
|
||||||
use_superseded:
|
use_superseded:
|
||||||
- module.run
|
- module.run
|
||||||
|
|
||||||
- The default for the ``fingerprint_hash_type`` option used in the ``present``
|
- The default for the ``fingerprint_hash_type`` option used in the ``present``
|
||||||
function in the :mod:`ssh <salt.states.ssh_know_hosts>` state changed from
|
function in the :mod:`ssh <salt.states.ssh_know_hosts>` state changed from
|
||||||
``md5`` to ``sha256``.
|
``md5`` to ``sha256``.
|
||||||
@ -678,6 +706,7 @@ Execution modules
|
|||||||
- :mod:`salt.modules.grafana4 <salt.modules.grafana4>`
|
- :mod:`salt.modules.grafana4 <salt.modules.grafana4>`
|
||||||
- :mod:`salt.modules.heat <salt.modules.heat>`
|
- :mod:`salt.modules.heat <salt.modules.heat>`
|
||||||
- :mod:`salt.modules.icinga2 <salt.modules.icinga2>`
|
- :mod:`salt.modules.icinga2 <salt.modules.icinga2>`
|
||||||
|
- :mod:`salt.modules.kubernetes <salt.modules.kubernetes>`
|
||||||
- :mod:`salt.modules.logmod <salt.modules.logmod>`
|
- :mod:`salt.modules.logmod <salt.modules.logmod>`
|
||||||
- :mod:`salt.modules.mattermost <salt.modules.mattermost>`
|
- :mod:`salt.modules.mattermost <salt.modules.mattermost>`
|
||||||
- :mod:`salt.modules.namecheap_dns <salt.modules.namecheap_dns>`
|
- :mod:`salt.modules.namecheap_dns <salt.modules.namecheap_dns>`
|
||||||
@ -756,6 +785,7 @@ States
|
|||||||
- :mod:`salt.states.icinga2 <salt.states.icinga2>`
|
- :mod:`salt.states.icinga2 <salt.states.icinga2>`
|
||||||
- :mod:`salt.states.influxdb_continuous_query <salt.states.influxdb_continuous_query>`
|
- :mod:`salt.states.influxdb_continuous_query <salt.states.influxdb_continuous_query>`
|
||||||
- :mod:`salt.states.influxdb_retention_policy <salt.states.influxdb_retention_policy>`
|
- :mod:`salt.states.influxdb_retention_policy <salt.states.influxdb_retention_policy>`
|
||||||
|
- :mod:`salt.states.kubernetes <salt.states.kubernetes>`
|
||||||
- :mod:`salt.states.logadm <salt.states.logadm>`
|
- :mod:`salt.states.logadm <salt.states.logadm>`
|
||||||
- :mod:`salt.states.logrotate <salt.states.logrotate>`
|
- :mod:`salt.states.logrotate <salt.states.logrotate>`
|
||||||
- :mod:`salt.states.msteams <salt.states.msteams>`
|
- :mod:`salt.states.msteams <salt.states.msteams>`
|
||||||
@ -945,3 +975,13 @@ The ``glusterfs`` state had the following function removed:
|
|||||||
The ``openvswitch_port`` state had the following change:
|
The ``openvswitch_port`` state had the following change:
|
||||||
|
|
||||||
- The ``type`` option was removed from the ``present`` function. Please use ``tunnel_type`` instead.
|
- The ``type`` option was removed from the ``present`` function. Please use ``tunnel_type`` instead.
|
||||||
|
|
||||||
|
Build Notes
|
||||||
|
===========
|
||||||
|
|
||||||
|
Windows Installer Packages
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Windows Installer packages have been patched with the following PR: 42347_
|
||||||
|
|
||||||
|
.. _42347: https://github.com/saltstack/salt/pull/42347
|
||||||
|
@ -8,7 +8,7 @@ Installing/Testing a Salt Release Candidate
|
|||||||
|
|
||||||
It's time for a new feature release of Salt! Follow the instructions below to
|
It's time for a new feature release of Salt! Follow the instructions below to
|
||||||
install the latest release candidate of Salt, and try :ref:`all the shiny new
|
install the latest release candidate of Salt, and try :ref:`all the shiny new
|
||||||
features <release-2016-11-0>`! Be sure to report any bugs you find on `Github
|
features <release-2017-7-0>`! Be sure to report any bugs you find on `Github
|
||||||
<https://github.com/saltstack/salt/issues/new/>`_.
|
<https://github.com/saltstack/salt/issues/new/>`_.
|
||||||
|
|
||||||
Installing Using Packages
|
Installing Using Packages
|
||||||
@ -32,32 +32,12 @@ Builds for a few platforms are available as part of the RC at https://repo.salts
|
|||||||
|
|
||||||
Available builds:
|
Available builds:
|
||||||
|
|
||||||
- Amazon Linux
|
- Ubuntu16
|
||||||
- Debian 8
|
- Redhat7
|
||||||
- macOS
|
|
||||||
- RHEL 7
|
|
||||||
- SmartOS (see below)
|
|
||||||
- Ubuntu 16.04
|
|
||||||
- Windows
|
- Windows
|
||||||
|
|
||||||
.. FreeBSD
|
.. FreeBSD
|
||||||
|
|
||||||
SmartOS
|
|
||||||
-------
|
|
||||||
Release candidate builds for SmartOS are available at http://pkg.blackdot.be/extras/salt-2016.11rc/.
|
|
||||||
|
|
||||||
On a base64 2015Q4-x86_64 based native zone the package can be installed by the following:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
pfexec pkg_add -U https://pkg.blackdot.be/extras/salt-2016.11rc/salt-2016.11.0rc2_2015Q4_x86_64.tgz
|
|
||||||
|
|
||||||
When using the 2016Q2-tools release on the global zone by the following:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
pfexec pkg_add -U https://pkg.blackdot.be/extras/salt-2016.11rc/salt-2016.11.0rc2_2016Q2_TOOLS.tgz
|
|
||||||
|
|
||||||
Installing Using Bootstrap
|
Installing Using Bootstrap
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
@ -67,14 +47,14 @@ You can install a release candidate of Salt using `Salt Bootstrap
|
|||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
curl -o install_salt.sh -L https://bootstrap.saltstack.com
|
curl -o install_salt.sh -L https://bootstrap.saltstack.com
|
||||||
sudo sh install_salt.sh -P git v2016.11.0rc2
|
sudo sh install_salt.sh -P git v2017.7.0rc1
|
||||||
|
|
||||||
If you want to also install a master using Salt Bootstrap, use the ``-M`` flag:
|
If you want to also install a master using Salt Bootstrap, use the ``-M`` flag:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
curl -o install_salt.sh -L https://bootstrap.saltstack.com
|
curl -o install_salt.sh -L https://bootstrap.saltstack.com
|
||||||
sudo sh install_salt.sh -P -M git v2016.11.0rc2
|
sudo sh install_salt.sh -P -M git v2017.7.0rc1
|
||||||
|
|
||||||
If you want to install only a master and not a minion using Salt Bootstrap, use
|
If you want to install only a master and not a minion using Salt Bootstrap, use
|
||||||
the ``-M`` and ``-N`` flags:
|
the ``-M`` and ``-N`` flags:
|
||||||
@ -82,13 +62,13 @@ the ``-M`` and ``-N`` flags:
|
|||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
curl -o install_salt.sh -L https://bootstrap.saltstack.com
|
curl -o install_salt.sh -L https://bootstrap.saltstack.com
|
||||||
sudo sh install_salt.sh -P -M -N git v2016.11.0rc2
|
sudo sh install_salt.sh -P -M -N git v2017.7.0rc1
|
||||||
|
|
||||||
Installing Using PyPI
|
Installing Using PyPI
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Installing from the `source archive
|
Installing from the `source archive
|
||||||
<https://pypi.python.org/packages/7a/87/3b29ac215208bed9559d6c4df24175ddd1d52e62c5c00ae3afb3b7d9144d/salt-2016.11.0rc2.tar.gz>`_ on
|
<https://pypi.python.org/packages/5c/cf/13c14f8bcd7b5076b9a8c3580f9582c1c4ea8b0458793ac6744ea66c0baf/salt-2017.7.0rc1.tar.gz>`_ on
|
||||||
`PyPI <https://pypi.python.org/pypi>`_ is fairly straightforward.
|
`PyPI <https://pypi.python.org/pypi>`_ is fairly straightforward.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@ -126,4 +106,4 @@ Then install salt using the following command:
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
sudo pip install salt==2016.11.0rc2
|
sudo pip install salt==2017.7.0rc1
|
||||||
|
@ -64,7 +64,8 @@ Deploy ssh key for salt-ssh
|
|||||||
===========================
|
===========================
|
||||||
|
|
||||||
By default, salt-ssh will generate key pairs for ssh, the default path will be
|
By default, salt-ssh will generate key pairs for ssh, the default path will be
|
||||||
/etc/salt/pki/master/ssh/salt-ssh.rsa
|
``/etc/salt/pki/master/ssh/salt-ssh.rsa``. The key generation happens when you run
|
||||||
|
``salt-ssh`` for the first time.
|
||||||
|
|
||||||
You can use ssh-copy-id, (the OpenSSH key deployment tool) to deploy keys to your servers.
|
You can use ssh-copy-id, (the OpenSSH key deployment tool) to deploy keys to your servers.
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ hit `Enter`. Also, you can convert tabs to 2 spaces by these commands in Vim:
|
|||||||
|
|
||||||
Indentation
|
Indentation
|
||||||
===========
|
===========
|
||||||
|
|
||||||
The suggested syntax for YAML files is to use 2 spaces for indentation,
|
The suggested syntax for YAML files is to use 2 spaces for indentation,
|
||||||
but YAML will follow whatever indentation system that the individual file
|
but YAML will follow whatever indentation system that the individual file
|
||||||
uses. Indentation of two spaces works very well for SLS files given the
|
uses. Indentation of two spaces works very well for SLS files given the
|
||||||
@ -112,8 +113,24 @@ PyYAML will load these values as boolean ``True`` or ``False``. Un-capitalized
|
|||||||
versions will also be loaded as booleans (``true``, ``false``, ``yes``, ``no``,
|
versions will also be loaded as booleans (``true``, ``false``, ``yes``, ``no``,
|
||||||
``on``, and ``off``). This can be especially problematic when constructing
|
``on``, and ``off``). This can be especially problematic when constructing
|
||||||
Pillar data. Make sure that your Pillars which need to use the string versions
|
Pillar data. Make sure that your Pillars which need to use the string versions
|
||||||
of these values are enclosed in quotes. Pillars will be parsed twice by salt,
|
of these values are enclosed in quotes. Pillars will be parsed twice by salt,
|
||||||
so you'll need to wrap your values in multiple quotes, for example '"false"'.
|
so you'll need to wrap your values in multiple quotes, including double quotation
|
||||||
|
marks (``" "``) and single quotation marks (``' '``). Note that spaces are included
|
||||||
|
in the quotation type examples for clarity.
|
||||||
|
|
||||||
|
Multiple quoting examples looks like this:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
- '"false"'
|
||||||
|
- "'True'"
|
||||||
|
- "'YES'"
|
||||||
|
- '"No"'
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When using multiple quotes in this manner, they must be different. Using ``"" ""``
|
||||||
|
or ``'' ''`` won't work in this case (spaces are included in examples for clarity).
|
||||||
|
|
||||||
The '%' Sign
|
The '%' Sign
|
||||||
============
|
============
|
||||||
@ -248,8 +265,10 @@ Alternatively, they can be defined the "old way", or with multiple
|
|||||||
- require:
|
- require:
|
||||||
- user: fred
|
- user: fred
|
||||||
|
|
||||||
YAML support only plain ASCII
|
.. _yaml_plain_ascii:
|
||||||
=============================
|
|
||||||
|
YAML supports only plain ASCII
|
||||||
|
==============================
|
||||||
|
|
||||||
According to YAML specification, only ASCII characters can be used.
|
According to YAML specification, only ASCII characters can be used.
|
||||||
|
|
||||||
|
@ -166,13 +166,15 @@ Ubuntu 14.04 LTS and Debian Wheezy (7.x) also have a compatible version packaged
|
|||||||
|
|
||||||
# apt-get install python-git
|
# apt-get install python-git
|
||||||
|
|
||||||
If your master is running an older version (such as Ubuntu 12.04 LTS or Debian
|
GitPython_ requires the ``git`` CLI utility to work. If installed from a system
|
||||||
Squeeze), then you will need to install GitPython using either pip_ or
|
package, then git should already be installed, but if installed via pip_ then
|
||||||
easy_install (it is recommended to use pip). Version 0.3.2.RC1 is now marked as
|
it may still be necessary to install git separately. For MacOS users,
|
||||||
the stable release in PyPI, so it should be a simple matter of running ``pip
|
GitPython_ comes bundled in with the Salt installer, but git must still be
|
||||||
install GitPython`` (or ``easy_install GitPython``) as root.
|
installed for it to work properly. Git can be installed in several ways,
|
||||||
|
including by installing XCode_.
|
||||||
|
|
||||||
.. _`pip`: http://www.pip-installer.org/
|
.. _pip: http://www.pip-installer.org/
|
||||||
|
.. _XCode: https://developer.apple.com/xcode/
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ To pass through a file that contains jinja + yaml templating (the default):
|
|||||||
method='POST',
|
method='POST',
|
||||||
data_file='/srv/salt/somefile.jinja',
|
data_file='/srv/salt/somefile.jinja',
|
||||||
data_render=True,
|
data_render=True,
|
||||||
template_data={'key1': 'value1', 'key2': 'value2'}
|
template_dict={'key1': 'value1', 'key2': 'value2'}
|
||||||
)
|
)
|
||||||
|
|
||||||
To pass through a file that contains mako templating:
|
To pass through a file that contains mako templating:
|
||||||
@ -123,7 +123,7 @@ To pass through a file that contains mako templating:
|
|||||||
data_file='/srv/salt/somefile.mako',
|
data_file='/srv/salt/somefile.mako',
|
||||||
data_render=True,
|
data_render=True,
|
||||||
data_renderer='mako',
|
data_renderer='mako',
|
||||||
template_data={'key1': 'value1', 'key2': 'value2'}
|
template_dict={'key1': 'value1', 'key2': 'value2'}
|
||||||
)
|
)
|
||||||
|
|
||||||
Because this function uses Salt's own rendering system, any Salt renderer can
|
Because this function uses Salt's own rendering system, any Salt renderer can
|
||||||
@ -140,7 +140,7 @@ However, this can be changed to ``master`` if necessary.
|
|||||||
method='POST',
|
method='POST',
|
||||||
data_file='/srv/salt/somefile.jinja',
|
data_file='/srv/salt/somefile.jinja',
|
||||||
data_render=True,
|
data_render=True,
|
||||||
template_data={'key1': 'value1', 'key2': 'value2'},
|
template_dict={'key1': 'value1', 'key2': 'value2'},
|
||||||
opts=__opts__
|
opts=__opts__
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ However, this can be changed to ``master`` if necessary.
|
|||||||
method='POST',
|
method='POST',
|
||||||
data_file='/srv/salt/somefile.jinja',
|
data_file='/srv/salt/somefile.jinja',
|
||||||
data_render=True,
|
data_render=True,
|
||||||
template_data={'key1': 'value1', 'key2': 'value2'},
|
template_dict={'key1': 'value1', 'key2': 'value2'},
|
||||||
node='master'
|
node='master'
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -170,11 +170,11 @@ a Python dict.
|
|||||||
header_file='/srv/salt/headers.jinja',
|
header_file='/srv/salt/headers.jinja',
|
||||||
header_render=True,
|
header_render=True,
|
||||||
header_renderer='jinja',
|
header_renderer='jinja',
|
||||||
template_data={'key1': 'value1', 'key2': 'value2'}
|
template_dict={'key1': 'value1', 'key2': 'value2'}
|
||||||
)
|
)
|
||||||
|
|
||||||
Because much of the data that would be templated between headers and data may be
|
Because much of the data that would be templated between headers and data may be
|
||||||
the same, the ``template_data`` is the same for both. Correcting possible
|
the same, the ``template_dict`` is the same for both. Correcting possible
|
||||||
variable name collisions is up to the user.
|
variable name collisions is up to the user.
|
||||||
|
|
||||||
Authentication
|
Authentication
|
||||||
|
@ -75,7 +75,7 @@ The default location for the pillar is in /srv/pillar.
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The pillar location can be configured via the `pillar_roots` option inside
|
The pillar location can be configured via the ``pillar_roots`` option inside
|
||||||
the master configuration file. It must not be in a subdirectory of the state
|
the master configuration file. It must not be in a subdirectory of the state
|
||||||
tree or file_roots. If the pillar is under file_roots, any pillar targeting
|
tree or file_roots. If the pillar is under file_roots, any pillar targeting
|
||||||
can be bypassed by minions.
|
can be bypassed by minions.
|
||||||
@ -242,7 +242,7 @@ set in the minion's pillar, then the default of ``httpd`` will be used.
|
|||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Under the hood, pillar is just a Python dict, so Python dict methods such
|
Under the hood, pillar is just a Python dict, so Python dict methods such
|
||||||
as `get` and `items` can be used.
|
as ``get`` and ``items`` can be used.
|
||||||
|
|
||||||
Pillar Makes Simple States Grow Easily
|
Pillar Makes Simple States Grow Easily
|
||||||
======================================
|
======================================
|
||||||
@ -303,6 +303,18 @@ Where the vimrc source location can now be changed via pillar:
|
|||||||
|
|
||||||
Ensuring that the right vimrc is sent out to the correct minions.
|
Ensuring that the right vimrc is sent out to the correct minions.
|
||||||
|
|
||||||
|
The pillar top file must include a reference to the new sls pillar file:
|
||||||
|
|
||||||
|
``/srv/pillar/top.sls``:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
base:
|
||||||
|
'*':
|
||||||
|
- pkg
|
||||||
|
- edit.vim
|
||||||
|
|
||||||
|
|
||||||
Setting Pillar Data on the Command Line
|
Setting Pillar Data on the Command Line
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ types like so:
|
|||||||
|
|
||||||
salt '*' mymodule.observe_the_awesomeness
|
salt '*' mymodule.observe_the_awesomeness
|
||||||
'''
|
'''
|
||||||
print __utils__['foo.bar']()
|
return __utils__['foo.bar']()
|
||||||
|
|
||||||
Utility modules, like any other kind of Salt extension, support using a
|
Utility modules, like any other kind of Salt extension, support using a
|
||||||
:ref:`__virtual__ function <modules-virtual-name>` to conditionally load them,
|
:ref:`__virtual__ function <modules-virtual-name>` to conditionally load them,
|
||||||
@ -81,11 +81,56 @@ the ``foo`` utility module with a ``__virtual__`` function.
|
|||||||
def bar():
|
def bar():
|
||||||
return 'baz'
|
return 'baz'
|
||||||
|
|
||||||
|
Also you could even write your utility modules in object oriented fashion:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
My utils module
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This module contains common functions for use in my other custom types.
|
||||||
|
'''
|
||||||
|
|
||||||
|
class Foo(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def bar(self):
|
||||||
|
return 'baz'
|
||||||
|
|
||||||
|
And import them into other custom modules:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
My awesome execution module
|
||||||
|
---------------------------
|
||||||
|
'''
|
||||||
|
|
||||||
|
import mymodule
|
||||||
|
|
||||||
|
def observe_the_awesomeness():
|
||||||
|
'''
|
||||||
|
Prints information from my utility module
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' mymodule.observe_the_awesomeness
|
||||||
|
'''
|
||||||
|
foo = mymodule.Foo()
|
||||||
|
return foo.bar()
|
||||||
|
|
||||||
These are, of course, contrived examples, but they should serve to show some of
|
These are, of course, contrived examples, but they should serve to show some of
|
||||||
the possibilities opened up by writing utility modules. Keep in mind though
|
the possibilities opened up by writing utility modules. Keep in mind though
|
||||||
that States still have access to all of the execution modules, so it is not
|
that states still have access to all of the execution modules, so it is not
|
||||||
necessary to write a utility module to make a function available to both a
|
necessary to write a utility module to make a function available to both a
|
||||||
state and an execution module. One good use case for utililty modules is one
|
state and an execution module. One good use case for utility modules is one
|
||||||
where it is necessary to invoke the same function from a custom :ref:`outputter
|
where it is necessary to invoke the same function from a custom :ref:`outputter
|
||||||
<all-salt.output>`/returner, as well as an execution module.
|
<all-salt.output>`/returner, as well as an execution module.
|
||||||
|
|
||||||
|
@ -86,9 +86,9 @@ sudo $PKGRESOURCES/build_env.sh $PYVER
|
|||||||
# Install Salt
|
# Install Salt
|
||||||
############################################################################
|
############################################################################
|
||||||
echo -n -e "\033]0;Build: Install Salt\007"
|
echo -n -e "\033]0;Build: Install Salt\007"
|
||||||
sudo rm -rm $SRCDIR/build
|
sudo rm -rf $SRCDIR/build
|
||||||
sudo rm -rm $SRCDIR/dist
|
sudo rm -rf $SRCDIR/dist
|
||||||
sudo $PYTHON $SRCDIR/setup.py install
|
sudo $PYTHON $SRCDIR/setup.py build -e "$PYTHON -E -s" install
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
# Build Package
|
# Build Package
|
||||||
|
@ -7,7 +7,7 @@ CherryPy==11.0.0
|
|||||||
click==6.7
|
click==6.7
|
||||||
enum34==1.1.6
|
enum34==1.1.6
|
||||||
gitdb==0.6.4
|
gitdb==0.6.4
|
||||||
GitPython==2.1.5
|
GitPython==2.1.1
|
||||||
idna==2.5
|
idna==2.5
|
||||||
ipaddress==1.0.18
|
ipaddress==1.0.18
|
||||||
Jinja2==2.9.6
|
Jinja2==2.9.6
|
||||||
|
@ -110,6 +110,13 @@ if not %errorLevel%==0 (
|
|||||||
)
|
)
|
||||||
@echo.
|
@echo.
|
||||||
|
|
||||||
|
:: Remove build and dist directories
|
||||||
|
@echo %0 :: Remove build and dist directories...
|
||||||
|
@echo ---------------------------------------------------------------------
|
||||||
|
rd /s /q "%SrcDir%\build"
|
||||||
|
rd /s /q "%SrcDir%\dist"
|
||||||
|
@echo.
|
||||||
|
|
||||||
:: Install Current Version of salt
|
:: Install Current Version of salt
|
||||||
@echo %0 :: Install Current Version of salt...
|
@echo %0 :: Install Current Version of salt...
|
||||||
@echo ---------------------------------------------------------------------
|
@echo ---------------------------------------------------------------------
|
||||||
|
@ -108,9 +108,9 @@ xcopy /E /Q "%PyDir%" "%BinDir%\"
|
|||||||
@echo Copying configs to buildenv\conf...
|
@echo Copying configs to buildenv\conf...
|
||||||
@echo ----------------------------------------------------------------------
|
@echo ----------------------------------------------------------------------
|
||||||
@echo xcopy /E /Q "%SrcDir%\conf\master" "%CnfDir%\"
|
@echo xcopy /E /Q "%SrcDir%\conf\master" "%CnfDir%\"
|
||||||
xcopy /Q "%SrcDir%\conf\master" "%CnfDir%\"
|
xcopy /Q /Y "%SrcDir%\conf\master" "%CnfDir%\"
|
||||||
@echo xcopy /E /Q "%SrcDir%\conf\minion" "%CnfDir%\"
|
@echo xcopy /E /Q "%SrcDir%\conf\minion" "%CnfDir%\"
|
||||||
xcopy /Q "%SrcDir%\conf\minion" "%CnfDir%\"
|
xcopy /Q /Y "%SrcDir%\conf\minion" "%CnfDir%\"
|
||||||
@echo.
|
@echo.
|
||||||
|
|
||||||
@echo Copying VCRedist to Prerequisites
|
@echo Copying VCRedist to Prerequisites
|
||||||
@ -582,6 +582,10 @@ If Exist "%BinDir%\Scripts\salt-run*"^
|
|||||||
If Exist "%BldDir%\salt-run.bat"^
|
If Exist "%BldDir%\salt-run.bat"^
|
||||||
del /Q "%BldDir%\salt-run.bat" 1>nul
|
del /Q "%BldDir%\salt-run.bat" 1>nul
|
||||||
|
|
||||||
|
:: Remove the master config file
|
||||||
|
if Exist "%CnfDir%\master"^
|
||||||
|
del /Q "%CnfDir%\master" 1>nul
|
||||||
|
|
||||||
:: Make the Salt Minion Installer
|
:: Make the Salt Minion Installer
|
||||||
makensis.exe /DSaltVersion=%Version% /DPythonVersion=%Python% "%InsDir%\Salt-Minion-Setup.nsi"
|
makensis.exe /DSaltVersion=%Version% /DPythonVersion=%Python% "%InsDir%\Salt-Minion-Setup.nsi"
|
||||||
@echo.
|
@echo.
|
||||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
|||||||
Set Script=%SaltDir%\bin\Scripts\salt-call
|
Set Script=%SaltDir%\bin\Scripts\salt-call
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
|||||||
Set Script=%SaltDir%\bin\Scripts\salt-cp
|
Set Script=%SaltDir%\bin\Scripts\salt-cp
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
|||||||
Set Script=%SaltDir%\bin\Scripts\salt-key
|
Set Script=%SaltDir%\bin\Scripts\salt-key
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
|||||||
Set Script=%SaltDir%\bin\Scripts\salt-master
|
Set Script=%SaltDir%\bin\Scripts\salt-master
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -12,5 +12,4 @@ Set Script=%SaltDir%\bin\Scripts\salt-minion
|
|||||||
net stop salt-minion
|
net stop salt-minion
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" -l debug
|
"%Python%" -E -s "%Script%" -l debug
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
|||||||
Set Script=%SaltDir%\bin\Scripts\salt-minion
|
Set Script=%SaltDir%\bin\Scripts\salt-minion
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
|||||||
Set Script=%SaltDir%\bin\Scripts\salt-run
|
Set Script=%SaltDir%\bin\Scripts\salt-run
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
|||||||
Set Script=%SaltDir%\bin\Scripts\salt
|
Set Script=%SaltDir%\bin\Scripts\salt
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -379,13 +379,12 @@ Section -Post
|
|||||||
WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "Path" "$INSTDIR\bin\"
|
WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "Path" "$INSTDIR\bin\"
|
||||||
|
|
||||||
; Register the Salt-Minion Service
|
; Register the Salt-Minion Service
|
||||||
nsExec::Exec "nssm.exe install salt-minion $INSTDIR\bin\python.exe $INSTDIR\bin\Scripts\salt-minion -c $INSTDIR\conf -l quiet"
|
nsExec::Exec "nssm.exe install salt-minion $INSTDIR\bin\python.exe -E -s $INSTDIR\bin\Scripts\salt-minion -c $INSTDIR\conf -l quiet"
|
||||||
nsExec::Exec "nssm.exe set salt-minion AppEnvironmentExtra PYTHONHOME="
|
|
||||||
nsExec::Exec "nssm.exe set salt-minion Description Salt Minion from saltstack.com"
|
nsExec::Exec "nssm.exe set salt-minion Description Salt Minion from saltstack.com"
|
||||||
nsExec::Exec "nssm.exe set salt-minion Start SERVICE_AUTO_START"
|
nsExec::Exec "nssm.exe set salt-minion Start SERVICE_AUTO_START"
|
||||||
nsExec::Exec "nssm.exe set salt-minion AppNoConsole 1"
|
nsExec::Exec "nssm.exe set salt-minion AppNoConsole 1"
|
||||||
|
nsExec::Exec "nssm.exe set salt-minion AppStopMethodConsole 24000"
|
||||||
RMDir /R "$INSTDIR\var\cache\salt" ; removing cache from old version
|
nsExec::Exec "nssm.exe set salt-minion AppStopMethodWindow 2000"
|
||||||
|
|
||||||
Call updateMinionConfig
|
Call updateMinionConfig
|
||||||
|
|
||||||
|
7
salt/cache/redis_cache.py
vendored
7
salt/cache/redis_cache.py
vendored
@ -115,7 +115,7 @@ from salt.exceptions import SaltCacheError
|
|||||||
|
|
||||||
__virtualname__ = 'redis'
|
__virtualname__ = 'redis'
|
||||||
__func_alias__ = {
|
__func_alias__ = {
|
||||||
'list_': 'list'
|
'ls': 'list'
|
||||||
}
|
}
|
||||||
|
|
||||||
log = logging.getLogger(__file__)
|
log = logging.getLogger(__file__)
|
||||||
@ -145,6 +145,9 @@ def __virtual__():
|
|||||||
# helper functions -- will not be exported
|
# helper functions -- will not be exported
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def init_kwargs(kwargs):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def _get_redis_cache_opts():
|
def _get_redis_cache_opts():
|
||||||
'''
|
'''
|
||||||
@ -415,7 +418,7 @@ def flush(bank, key=None):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def list_(bank):
|
def ls(bank):
|
||||||
'''
|
'''
|
||||||
Lists entries stored in the specified bank.
|
Lists entries stored in the specified bank.
|
||||||
'''
|
'''
|
||||||
|
@ -544,6 +544,7 @@ class LocalClient(object):
|
|||||||
{'stewart': {...}}
|
{'stewart': {...}}
|
||||||
'''
|
'''
|
||||||
if 'expr_form' in kwargs:
|
if 'expr_form' in kwargs:
|
||||||
|
import salt
|
||||||
salt.utils.warn_until(
|
salt.utils.warn_until(
|
||||||
'Fluorine',
|
'Fluorine',
|
||||||
'The target type should be passed using the \'tgt_type\' '
|
'The target type should be passed using the \'tgt_type\' '
|
||||||
@ -738,7 +739,7 @@ class LocalClient(object):
|
|||||||
ret[mid] = (data if full_return
|
ret[mid] = (data if full_return
|
||||||
else data.get('ret', {}))
|
else data.get('ret', {}))
|
||||||
|
|
||||||
for failed in list(set(pub_data['minions']) ^ set(ret)):
|
for failed in list(set(pub_data['minions']) - set(ret)):
|
||||||
ret[failed] = False
|
ret[failed] = False
|
||||||
return ret
|
return ret
|
||||||
finally:
|
finally:
|
||||||
|
@ -405,8 +405,6 @@ class SyncClientMixin(object):
|
|||||||
)
|
)
|
||||||
data['success'] = False
|
data['success'] = False
|
||||||
|
|
||||||
namespaced_event.fire_event(data, 'ret')
|
|
||||||
|
|
||||||
if self.store_job:
|
if self.store_job:
|
||||||
try:
|
try:
|
||||||
salt.utils.job.store_job(
|
salt.utils.job.store_job(
|
||||||
@ -424,6 +422,9 @@ class SyncClientMixin(object):
|
|||||||
log.error('Could not store job cache info. '
|
log.error('Could not store job cache info. '
|
||||||
'Job details for this run may be unavailable.')
|
'Job details for this run may be unavailable.')
|
||||||
|
|
||||||
|
# Outputters _can_ mutate data so write to the job cache first!
|
||||||
|
namespaced_event.fire_event(data, 'ret')
|
||||||
|
|
||||||
# if we fired an event, make sure to delete the event object.
|
# if we fired an event, make sure to delete the event object.
|
||||||
# This will ensure that we call destroy, which will do the 0MQ linger
|
# This will ensure that we call destroy, which will do the 0MQ linger
|
||||||
log.info('Runner completed: {0}'.format(data['jid']))
|
log.info('Runner completed: {0}'.format(data['jid']))
|
||||||
|
@ -467,6 +467,8 @@ class SSH(object):
|
|||||||
for default in self.defaults:
|
for default in self.defaults:
|
||||||
if default not in self.targets[host]:
|
if default not in self.targets[host]:
|
||||||
self.targets[host][default] = self.defaults[default]
|
self.targets[host][default] = self.defaults[default]
|
||||||
|
if 'host' not in self.targets[host]:
|
||||||
|
self.targets[host]['host'] = host
|
||||||
args = (
|
args = (
|
||||||
que,
|
que,
|
||||||
self.opts,
|
self.opts,
|
||||||
|
@ -407,13 +407,14 @@ def list_nodes_full(conn=None, call=None): # pylint: disable=unused-argument
|
|||||||
for group in list_resource_groups():
|
for group in list_resource_groups():
|
||||||
nodes = compconn.virtual_machines.list(group)
|
nodes = compconn.virtual_machines.list(group)
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
|
private_ips, public_ips = __get_ips_from_node(group, node)
|
||||||
ret[node.name] = object_to_dict(node)
|
ret[node.name] = object_to_dict(node)
|
||||||
ret[node.name]['id'] = node.id
|
ret[node.name]['id'] = node.id
|
||||||
ret[node.name]['name'] = node.name
|
ret[node.name]['name'] = node.name
|
||||||
ret[node.name]['size'] = node.hardware_profile.vm_size
|
ret[node.name]['size'] = node.hardware_profile.vm_size
|
||||||
ret[node.name]['state'] = node.provisioning_state
|
ret[node.name]['state'] = node.provisioning_state
|
||||||
ret[node.name]['private_ips'] = node.network_profile.network_interfaces
|
ret[node.name]['private_ips'] = private_ips
|
||||||
ret[node.name]['public_ips'] = node.network_profile.network_interfaces
|
ret[node.name]['public_ips'] = public_ips
|
||||||
ret[node.name]['storage_profile']['data_disks'] = []
|
ret[node.name]['storage_profile']['data_disks'] = []
|
||||||
ret[node.name]['resource_group'] = group
|
ret[node.name]['resource_group'] = group
|
||||||
for disk in node.storage_profile.data_disks:
|
for disk in node.storage_profile.data_disks:
|
||||||
@ -433,6 +434,30 @@ def list_nodes_full(conn=None, call=None): # pylint: disable=unused-argument
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def __get_ips_from_node(resource_group, node):
|
||||||
|
'''
|
||||||
|
List private and public IPs from a VM interface
|
||||||
|
'''
|
||||||
|
global netconn # pylint: disable=global-statement,invalid-name
|
||||||
|
if not netconn:
|
||||||
|
netconn = get_conn(NetworkManagementClient)
|
||||||
|
|
||||||
|
private_ips = []
|
||||||
|
public_ips = []
|
||||||
|
for node_iface in node.network_profile.network_interfaces:
|
||||||
|
node_iface_name = node_iface.id.split('/')[-1]
|
||||||
|
network_interface = netconn.network_interfaces.get(resource_group, node_iface_name)
|
||||||
|
for ip_configuration in network_interface.ip_configurations:
|
||||||
|
if ip_configuration.private_ip_address:
|
||||||
|
private_ips.append(ip_configuration.private_ip_address)
|
||||||
|
if ip_configuration.public_ip_address and ip_configuration.public_ip_address.id:
|
||||||
|
public_iface_name = ip_configuration.public_ip_address.id.split('/')[-1]
|
||||||
|
public_iface = netconn.public_ip_addresses.get(resource_group, public_iface_name)
|
||||||
|
public_ips.append(public_iface.ip_address)
|
||||||
|
|
||||||
|
return private_ips, public_ips
|
||||||
|
|
||||||
|
|
||||||
def list_resource_groups(conn=None, call=None): # pylint: disable=unused-argument
|
def list_resource_groups(conn=None, call=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
List resource groups associated with the account
|
List resource groups associated with the account
|
||||||
|
@ -1030,10 +1030,18 @@ def ssh_interface(vm_):
|
|||||||
Return the ssh_interface type to connect to. Either 'public_ips' (default)
|
Return the ssh_interface type to connect to. Either 'public_ips' (default)
|
||||||
or 'private_ips'.
|
or 'private_ips'.
|
||||||
'''
|
'''
|
||||||
return config.get_cloud_config_value(
|
ret = config.get_cloud_config_value(
|
||||||
'ssh_interface', vm_, __opts__, default='public_ips',
|
'ssh_interface', vm_, __opts__, default='public_ips',
|
||||||
search_global=False
|
search_global=False
|
||||||
)
|
)
|
||||||
|
if ret not in ('public_ips', 'private_ips'):
|
||||||
|
log.warning((
|
||||||
|
'Invalid ssh_interface: {0}. '
|
||||||
|
'Allowed options are ("public_ips", "private_ips"). '
|
||||||
|
'Defaulting to "public_ips".'
|
||||||
|
).format(ret))
|
||||||
|
ret = 'public_ips'
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def get_ssh_gateway_config(vm_):
|
def get_ssh_gateway_config(vm_):
|
||||||
|
@ -1071,10 +1071,10 @@ def query(action=None,
|
|||||||
timenow = datetime.datetime.utcnow()
|
timenow = datetime.datetime.utcnow()
|
||||||
timestamp = timenow.strftime('%a, %d %b %Y %H:%M:%S %Z').strip()
|
timestamp = timenow.strftime('%a, %d %b %Y %H:%M:%S %Z').strip()
|
||||||
with salt.utils.fopen(ssh_keyfile, 'r') as kh_:
|
with salt.utils.fopen(ssh_keyfile, 'r') as kh_:
|
||||||
rsa_key = RSA.importKey(kh_)
|
rsa_key = RSA.importKey(kh_.read())
|
||||||
rsa_ = PKCS1_v1_5.new(rsa_key)
|
rsa_ = PKCS1_v1_5.new(rsa_key)
|
||||||
hash_ = SHA256.new()
|
hash_ = SHA256.new()
|
||||||
hash_.update(timestamp)
|
hash_.update(timestamp.encode(__salt_system_encoding__))
|
||||||
signed = base64.b64encode(rsa_.sign(hash_))
|
signed = base64.b64encode(rsa_.sign(hash_))
|
||||||
keyid = '/{0}/keys/{1}'.format(user.split('/')[0], ssh_keyname)
|
keyid = '/{0}/keys/{1}'.format(user.split('/')[0], ssh_keyname)
|
||||||
|
|
||||||
@ -1085,7 +1085,7 @@ def query(action=None,
|
|||||||
'Date': timestamp,
|
'Date': timestamp,
|
||||||
'Authorization': 'Signature keyId="{0}",algorithm="rsa-sha256" {1}'.format(
|
'Authorization': 'Signature keyId="{0}",algorithm="rsa-sha256" {1}'.format(
|
||||||
keyid,
|
keyid,
|
||||||
signed
|
signed.decode(__salt_system_encoding__)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +135,14 @@ Alternatively, one could use the private IP to connect by specifying:
|
|||||||
ssh_interface: private_ips
|
ssh_interface: private_ips
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When using floating ips from networks, if the OpenStack driver is unable to
|
||||||
|
allocate a new ip address for the server, it will check that for
|
||||||
|
unassociated ip addresses in the floating ip pool. If SaltCloud is running
|
||||||
|
in parallel mode, it is possible that more than one server will attempt to
|
||||||
|
use the same ip address.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Import python libs
|
# Import python libs
|
||||||
@ -855,40 +863,43 @@ def _assign_floating_ips(vm_, conn, kwargs):
|
|||||||
pool = OpenStack_1_1_FloatingIpPool(
|
pool = OpenStack_1_1_FloatingIpPool(
|
||||||
net['floating'], conn.connection
|
net['floating'], conn.connection
|
||||||
)
|
)
|
||||||
for idx in pool.list_floating_ips():
|
try:
|
||||||
if idx.node_id is None:
|
floating.append(pool.create_floating_ip())
|
||||||
floating.append(idx)
|
except Exception as e:
|
||||||
|
log.debug('Cannot allocate IP from floating pool \'%s\'. Checking for unassociated ips.',
|
||||||
|
net['floating'])
|
||||||
|
for idx in pool.list_floating_ips():
|
||||||
|
if idx.node_id is None:
|
||||||
|
floating.append(idx)
|
||||||
|
break
|
||||||
if not floating:
|
if not floating:
|
||||||
try:
|
raise SaltCloudSystemExit(
|
||||||
floating.append(pool.create_floating_ip())
|
'There are no more floating IP addresses '
|
||||||
except Exception as e:
|
'available, please create some more'
|
||||||
raise SaltCloudSystemExit(
|
)
|
||||||
'Floating pool \'{0}\' does not have any more '
|
|
||||||
'please create some more or use a different '
|
|
||||||
'pool.'.format(net['floating'])
|
|
||||||
)
|
|
||||||
# otherwise, attempt to obtain list without specifying pool
|
# otherwise, attempt to obtain list without specifying pool
|
||||||
# this is the same as 'nova floating-ip-list'
|
# this is the same as 'nova floating-ip-list'
|
||||||
elif ssh_interface(vm_) != 'private_ips':
|
elif ssh_interface(vm_) != 'private_ips':
|
||||||
try:
|
try:
|
||||||
# This try/except is here because it appears some
|
# This try/except is here because it appears some
|
||||||
# *cough* Rackspace *cough*
|
|
||||||
# OpenStack providers return a 404 Not Found for the
|
# OpenStack providers return a 404 Not Found for the
|
||||||
# floating ip pool URL if there are no pools setup
|
# floating ip pool URL if there are no pools setup
|
||||||
pool = OpenStack_1_1_FloatingIpPool(
|
pool = OpenStack_1_1_FloatingIpPool(
|
||||||
'', conn.connection
|
'', conn.connection
|
||||||
)
|
)
|
||||||
for idx in pool.list_floating_ips():
|
try:
|
||||||
if idx.node_id is None:
|
floating.append(pool.create_floating_ip())
|
||||||
floating.append(idx)
|
except Exception as e:
|
||||||
|
log.debug('Cannot allocate IP from the default floating pool. Checking for unassociated ips.')
|
||||||
|
for idx in pool.list_floating_ips():
|
||||||
|
if idx.node_id is None:
|
||||||
|
floating.append(idx)
|
||||||
|
break
|
||||||
if not floating:
|
if not floating:
|
||||||
try:
|
log.warning(
|
||||||
floating.append(pool.create_floating_ip())
|
'There are no more floating IP addresses '
|
||||||
except Exception as e:
|
'available, please create some more if necessary'
|
||||||
raise SaltCloudSystemExit(
|
)
|
||||||
'There are no more floating IP addresses '
|
|
||||||
'available, please create some more'
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if str(e).startswith('404'):
|
if str(e).startswith('404'):
|
||||||
pass
|
pass
|
||||||
|
@ -150,7 +150,7 @@ def avail_locations(conn=None, call=None):
|
|||||||
|
|
||||||
ret[img_name] = {}
|
ret[img_name] = {}
|
||||||
for attr in dir(img):
|
for attr in dir(img):
|
||||||
if attr.startswith('_'):
|
if attr.startswith('_') or attr == 'driver':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
attr_value = getattr(img, attr)
|
attr_value = getattr(img, attr)
|
||||||
@ -187,7 +187,7 @@ def avail_images(conn=None, call=None):
|
|||||||
|
|
||||||
ret[img_name] = {}
|
ret[img_name] = {}
|
||||||
for attr in dir(img):
|
for attr in dir(img):
|
||||||
if attr.startswith('_'):
|
if attr.startswith('_') or attr in ('driver', 'get_uuid'):
|
||||||
continue
|
continue
|
||||||
attr_value = getattr(img, attr)
|
attr_value = getattr(img, attr)
|
||||||
if isinstance(attr_value, string_types) and not six.PY3:
|
if isinstance(attr_value, string_types) and not six.PY3:
|
||||||
@ -222,7 +222,7 @@ def avail_sizes(conn=None, call=None):
|
|||||||
|
|
||||||
ret[size_name] = {}
|
ret[size_name] = {}
|
||||||
for attr in dir(size):
|
for attr in dir(size):
|
||||||
if attr.startswith('_'):
|
if attr.startswith('_') or attr in ('driver', 'get_uuid'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -352,7 +352,7 @@ VALID_OPTS = {
|
|||||||
# The TCP port on which minion events should be pulled if ipc_mode is TCP
|
# The TCP port on which minion events should be pulled if ipc_mode is TCP
|
||||||
'tcp_pull_port': int,
|
'tcp_pull_port': int,
|
||||||
|
|
||||||
# The TCP port on which events for the master should be pulled if ipc_mode is TCP
|
# The TCP port on which events for the master should be published if ipc_mode is TCP
|
||||||
'tcp_master_pub_port': int,
|
'tcp_master_pub_port': int,
|
||||||
|
|
||||||
# The TCP port on which events for the master should be pulled if ipc_mode is TCP
|
# The TCP port on which events for the master should be pulled if ipc_mode is TCP
|
||||||
@ -1633,7 +1633,8 @@ DEFAULT_PROXY_MINION_OPTS = {
|
|||||||
'log_file': os.path.join(salt.syspaths.LOGS_DIR, 'proxy'),
|
'log_file': os.path.join(salt.syspaths.LOGS_DIR, 'proxy'),
|
||||||
'add_proxymodule_to_opts': False,
|
'add_proxymodule_to_opts': False,
|
||||||
'proxy_merge_grains_in_module': True,
|
'proxy_merge_grains_in_module': True,
|
||||||
'append_minionid_config_dirs': ['cachedir', 'pidfile', 'default_include'],
|
'extension_modules': os.path.join(salt.syspaths.CACHE_DIR, 'proxy', 'extmods'),
|
||||||
|
'append_minionid_config_dirs': ['cachedir', 'pidfile', 'default_include', 'extension_modules'],
|
||||||
'default_include': 'proxy.d/*.conf',
|
'default_include': 'proxy.d/*.conf',
|
||||||
|
|
||||||
# By default, proxies will preserve the connection.
|
# By default, proxies will preserve the connection.
|
||||||
@ -2282,7 +2283,7 @@ def syndic_config(master_config_path,
|
|||||||
'pki_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules',
|
'pki_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules',
|
||||||
'autosign_file', 'autoreject_file', 'token_dir'
|
'autosign_file', 'autoreject_file', 'token_dir'
|
||||||
]
|
]
|
||||||
for config_key in ('syndic_log_file', 'log_file', 'key_logfile'):
|
for config_key in ('log_file', 'key_logfile', 'syndic_log_file'):
|
||||||
# If this is not a URI and instead a local path
|
# If this is not a URI and instead a local path
|
||||||
if urlparse(opts.get(config_key, '')).scheme == '':
|
if urlparse(opts.get(config_key, '')).scheme == '':
|
||||||
prepend_root_dirs.append(config_key)
|
prepend_root_dirs.append(config_key)
|
||||||
|
@ -373,17 +373,18 @@ class AsyncAuth(object):
|
|||||||
loop_instance_map = AsyncAuth.instance_map[io_loop]
|
loop_instance_map = AsyncAuth.instance_map[io_loop]
|
||||||
|
|
||||||
key = cls.__key(opts)
|
key = cls.__key(opts)
|
||||||
if key not in loop_instance_map:
|
auth = loop_instance_map.get(key)
|
||||||
|
if auth is None:
|
||||||
log.debug('Initializing new AsyncAuth for {0}'.format(key))
|
log.debug('Initializing new AsyncAuth for {0}'.format(key))
|
||||||
# we need to make a local variable for this, as we are going to store
|
# we need to make a local variable for this, as we are going to store
|
||||||
# it in a WeakValueDictionary-- which will remove the item if no one
|
# it in a WeakValueDictionary-- which will remove the item if no one
|
||||||
# references it-- this forces a reference while we return to the caller
|
# references it-- this forces a reference while we return to the caller
|
||||||
new_auth = object.__new__(cls)
|
auth = object.__new__(cls)
|
||||||
new_auth.__singleton_init__(opts, io_loop=io_loop)
|
auth.__singleton_init__(opts, io_loop=io_loop)
|
||||||
loop_instance_map[key] = new_auth
|
loop_instance_map[key] = auth
|
||||||
else:
|
else:
|
||||||
log.debug('Re-using AsyncAuth for {0}'.format(key))
|
log.debug('Re-using AsyncAuth for {0}'.format(key))
|
||||||
return loop_instance_map[key]
|
return auth
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __key(cls, opts, io_loop=None):
|
def __key(cls, opts, io_loop=None):
|
||||||
@ -1009,14 +1010,15 @@ class SAuth(AsyncAuth):
|
|||||||
Only create one instance of SAuth per __key()
|
Only create one instance of SAuth per __key()
|
||||||
'''
|
'''
|
||||||
key = cls.__key(opts)
|
key = cls.__key(opts)
|
||||||
if key not in SAuth.instances:
|
auth = SAuth.instances.get(key)
|
||||||
|
if auth is None:
|
||||||
log.debug('Initializing new SAuth for {0}'.format(key))
|
log.debug('Initializing new SAuth for {0}'.format(key))
|
||||||
new_auth = object.__new__(cls)
|
auth = object.__new__(cls)
|
||||||
new_auth.__singleton_init__(opts)
|
auth.__singleton_init__(opts)
|
||||||
SAuth.instances[key] = new_auth
|
SAuth.instances[key] = auth
|
||||||
else:
|
else:
|
||||||
log.debug('Re-using SAuth for {0}'.format(key))
|
log.debug('Re-using SAuth for {0}'.format(key))
|
||||||
return SAuth.instances[key]
|
return auth
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __key(cls, opts, io_loop=None):
|
def __key(cls, opts, io_loop=None):
|
||||||
|
@ -50,8 +50,8 @@ def start(docker_url='unix://var/run/docker.sock',
|
|||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
engines:
|
engines:
|
||||||
docker_events:
|
- docker_events:
|
||||||
docker_url: unix://var/run/docker.sock
|
docker_url: unix://var/run/docker.sock
|
||||||
|
|
||||||
The config above sets up engines to listen
|
The config above sets up engines to listen
|
||||||
for events from the Docker daemon and publish
|
for events from the Docker daemon and publish
|
||||||
|
@ -14,25 +14,25 @@ keys make the engine interactive.
|
|||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
engines:
|
engines:
|
||||||
- hipchat:
|
- hipchat:
|
||||||
api_url: http://api.hipchat.myteam.com
|
api_url: http://api.hipchat.myteam.com
|
||||||
token: 'XXXXXX'
|
token: 'XXXXXX'
|
||||||
room: 'salt'
|
room: 'salt'
|
||||||
control: True
|
control: True
|
||||||
valid_users:
|
valid_users:
|
||||||
- SomeUser
|
- SomeUser
|
||||||
valid_commands:
|
valid_commands:
|
||||||
- test.ping
|
- test.ping
|
||||||
- cmd.run
|
- cmd.run
|
||||||
- list_jobs
|
- list_jobs
|
||||||
- list_commands
|
- list_commands
|
||||||
aliases:
|
aliases:
|
||||||
list_jobs:
|
list_jobs:
|
||||||
cmd: jobs.list_jobs
|
cmd: jobs.list_jobs
|
||||||
list_commands:
|
list_commands:
|
||||||
cmd: pillar.get salt:engines:hipchat:valid_commands target=saltmaster tgt_type=list
|
cmd: pillar.get salt:engines:hipchat:valid_commands target=saltmaster
|
||||||
max_rooms: 0
|
max_rooms: 0
|
||||||
wait_time: 1
|
wait_time: 1
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
@ -12,13 +12,13 @@ them onto a logstash endpoint via HTTP requests.
|
|||||||
|
|
||||||
engines:
|
engines:
|
||||||
- http_logstash:
|
- http_logstash:
|
||||||
url: http://blabla.com/salt-stuff
|
url: http://blabla.com/salt-stuff
|
||||||
tags:
|
tags:
|
||||||
- salt/job/*/new
|
- salt/job/*/new
|
||||||
- salt/job/*/ret/*
|
- salt/job/*/ret/*
|
||||||
funs:
|
funs:
|
||||||
- probes.results
|
- probes.results
|
||||||
- bgp.config
|
- bgp.config
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
@ -24,6 +24,9 @@ master config.
|
|||||||
:configuration:
|
:configuration:
|
||||||
|
|
||||||
Example configuration
|
Example configuration
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
engines:
|
engines:
|
||||||
- logentries:
|
- logentries:
|
||||||
endpoint: data.logentries.com
|
endpoint: data.logentries.com
|
||||||
|
@ -8,6 +8,9 @@ them onto a logstash endpoint.
|
|||||||
:configuration:
|
:configuration:
|
||||||
|
|
||||||
Example configuration
|
Example configuration
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
engines:
|
engines:
|
||||||
- logstash:
|
- logstash:
|
||||||
host: log.my_network.com
|
host: log.my_network.com
|
||||||
|
@ -7,10 +7,10 @@ Example Config in Master or Minion config
|
|||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
engines:
|
engines:
|
||||||
reactor:
|
- reactor:
|
||||||
refresh_interval: 60
|
refresh_interval: 60
|
||||||
worker_threads: 10
|
worker_threads: 10
|
||||||
worker_hwm: 10000
|
worker_hwm: 10000
|
||||||
|
|
||||||
reactor:
|
reactor:
|
||||||
- 'salt/cloud/*/destroyed':
|
- 'salt/cloud/*/destroyed':
|
||||||
|
@ -8,6 +8,9 @@ events based on the channels they are subscribed to.
|
|||||||
:configuration:
|
:configuration:
|
||||||
|
|
||||||
Example configuration
|
Example configuration
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
engines:
|
engines:
|
||||||
- redis_sentinel:
|
- redis_sentinel:
|
||||||
hosts:
|
hosts:
|
||||||
|
@ -12,44 +12,43 @@ prefaced with a ``!``.
|
|||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
engines:
|
engines:
|
||||||
slack:
|
- slack:
|
||||||
token: 'xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'
|
token: 'xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'
|
||||||
control: True
|
control: True
|
||||||
valid_users:
|
valid_users:
|
||||||
- garethgreenaway
|
- garethgreenaway
|
||||||
valid_commands:
|
valid_commands:
|
||||||
- test.ping
|
- test.ping
|
||||||
- cmd.run
|
- cmd.run
|
||||||
- list_jobs
|
- list_jobs
|
||||||
- list_commands
|
- list_commands
|
||||||
aliases:
|
aliases:
|
||||||
list_jobs:
|
list_jobs:
|
||||||
cmd: jobs.list_jobs
|
cmd: jobs.list_jobs
|
||||||
list_commands:
|
list_commands:
|
||||||
cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster tgt_type=list
|
cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster tgt_type=list
|
||||||
|
|
||||||
:configuration: Example configuration using groups
|
:configuration: Example configuration using groups
|
||||||
.. versionadded: 2017.7.0
|
.. versionadded: 2017.7.0
|
||||||
|
|
||||||
engines:
|
engines:
|
||||||
slack:
|
- slack:
|
||||||
token: 'xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'
|
token: 'xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'
|
||||||
control: True
|
control: True
|
||||||
groups:
|
groups:
|
||||||
gods:
|
gods:
|
||||||
users:
|
users:
|
||||||
- garethgreenaway
|
- garethgreenaway
|
||||||
commands:
|
commands:
|
||||||
- test.ping
|
- test.ping
|
||||||
- cmd.run
|
- cmd.run
|
||||||
- list_jobs
|
- list_jobs
|
||||||
- list_commands
|
- list_commands
|
||||||
aliases:
|
aliases:
|
||||||
list_jobs:
|
list_jobs:
|
||||||
cmd: jobs.list_jobs
|
cmd: jobs.list_jobs
|
||||||
list_commands:
|
list_commands:
|
||||||
cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster tgt_type=list
|
cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster tgt_type=list
|
||||||
|
|
||||||
|
|
||||||
:depends: slackclient
|
:depends: slackclient
|
||||||
'''
|
'''
|
||||||
@ -62,6 +61,7 @@ import logging
|
|||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
import yaml
|
import yaml
|
||||||
|
import ast
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import slackclient
|
import slackclient
|
||||||
@ -246,6 +246,10 @@ def start(token,
|
|||||||
tgt_type = kwargs['tgt_type']
|
tgt_type = kwargs['tgt_type']
|
||||||
del kwargs['tgt_type']
|
del kwargs['tgt_type']
|
||||||
|
|
||||||
|
# Check for pillar string representation of dict and convert it to dict
|
||||||
|
if 'pillar' in kwargs:
|
||||||
|
kwargs.update(pillar=ast.literal_eval(kwargs['pillar']))
|
||||||
|
|
||||||
ret = {}
|
ret = {}
|
||||||
|
|
||||||
if cmd in runner_functions:
|
if cmd in runner_functions:
|
||||||
@ -255,7 +259,7 @@ def start(token,
|
|||||||
# Default to trying to run as a client module.
|
# Default to trying to run as a client module.
|
||||||
else:
|
else:
|
||||||
local = salt.client.LocalClient()
|
local = salt.client.LocalClient()
|
||||||
ret = local.cmd('{0}'.format(target), cmd, args, kwargs, tgt_type='{0}'.format(tgt_type))
|
ret = local.cmd('{0}'.format(target), cmd, arg=args, kwarg=kwargs, tgt_type='{0}'.format(tgt_type))
|
||||||
|
|
||||||
if ret:
|
if ret:
|
||||||
return_text = json.dumps(ret, sort_keys=True, indent=1)
|
return_text = json.dumps(ret, sort_keys=True, indent=1)
|
||||||
|
@ -73,7 +73,7 @@ class SudoExecutor(ModuleExecutorBase):
|
|||||||
'-c', salt.syspaths.CONFIG_DIR,
|
'-c', salt.syspaths.CONFIG_DIR,
|
||||||
'--',
|
'--',
|
||||||
data.get('fun')]
|
data.get('fun')]
|
||||||
if data['fun'] == 'state.sls':
|
if data['fun'] in ('state.sls', 'state.highstate', 'state.apply'):
|
||||||
kwargs['concurrent'] = True
|
kwargs['concurrent'] = True
|
||||||
for arg in args:
|
for arg in args:
|
||||||
self.cmd.append(_cmd_quote(str(arg)))
|
self.cmd.append(_cmd_quote(str(arg)))
|
||||||
|
@ -28,9 +28,6 @@ bytes = bytearray
|
|||||||
# Python 2 does not support exception chaining.
|
# Python 2 does not support exception chaining.
|
||||||
# s/ from None$//
|
# s/ from None$//
|
||||||
|
|
||||||
# Python 2 ranges need to fit in a C long
|
|
||||||
# 'fix' hosts() for IPv6Network
|
|
||||||
|
|
||||||
# When checking for instances of int, also allow Python 2's long.
|
# When checking for instances of int, also allow Python 2's long.
|
||||||
_builtin_isinstance = isinstance
|
_builtin_isinstance = isinstance
|
||||||
|
|
||||||
@ -2259,7 +2256,7 @@ class IPv6Network(_BaseV6, _BaseNetwork):
|
|||||||
"""
|
"""
|
||||||
network = int(self.network_address)
|
network = int(self.network_address)
|
||||||
broadcast = int(self.broadcast_address)
|
broadcast = int(self.broadcast_address)
|
||||||
for x in range(1, broadcast - network + 1):
|
for x in long_range(1, broadcast - network + 1):
|
||||||
yield self._address_class(network + x)
|
yield self._address_class(network + x)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -9,6 +9,7 @@ from __future__ import absolute_import
|
|||||||
import socket
|
import socket
|
||||||
import ctypes
|
import ctypes
|
||||||
import os
|
import os
|
||||||
|
import ipaddress
|
||||||
|
|
||||||
|
|
||||||
class sockaddr(ctypes.Structure):
|
class sockaddr(ctypes.Structure):
|
||||||
@ -31,6 +32,24 @@ else:
|
|||||||
|
|
||||||
|
|
||||||
def inet_pton(address_family, ip_string):
|
def inet_pton(address_family, ip_string):
|
||||||
|
# Verify IP Address
|
||||||
|
# This will catch IP Addresses such as 10.1.2
|
||||||
|
if address_family == socket.AF_INET:
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(ip_string.decode())
|
||||||
|
except ValueError:
|
||||||
|
raise socket.error('illegal IP address string passed to inet_pton')
|
||||||
|
return socket.inet_aton(ip_string)
|
||||||
|
|
||||||
|
# Verify IP Address
|
||||||
|
# The `WSAStringToAddressA` function handles notations used by Berkeley
|
||||||
|
# software which includes 3 part IP Addresses such as `10.1.2`. That's why
|
||||||
|
# the above check is needed to enforce more strict IP Address validation as
|
||||||
|
# used by the `inet_pton` function in Unix.
|
||||||
|
# See the following:
|
||||||
|
# https://stackoverflow.com/a/29286098
|
||||||
|
# Docs for the `inet_addr` function on MSDN
|
||||||
|
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms738563.aspx
|
||||||
addr = sockaddr()
|
addr = sockaddr()
|
||||||
addr.sa_family = address_family
|
addr.sa_family = address_family
|
||||||
addr_size = ctypes.c_int(ctypes.sizeof(addr))
|
addr_size = ctypes.c_int(ctypes.sizeof(addr))
|
||||||
|
@ -1257,7 +1257,7 @@ class RemoteClient(Client):
|
|||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
msg = 'specified file {0} is not present to generate hash: {1}'
|
msg = 'specified file {0} is not present to generate hash: {1}'
|
||||||
log.warning(msg.format(path, err))
|
log.warning(msg.format(path, err))
|
||||||
return {}
|
return {}, None
|
||||||
else:
|
else:
|
||||||
ret = {}
|
ret = {}
|
||||||
hash_type = self.opts.get('hash_type', 'md5')
|
hash_type = self.opts.get('hash_type', 'md5')
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
'''
|
'''
|
||||||
Subversion Fileserver Backend
|
Subversion Fileserver Backend
|
||||||
|
|
||||||
After enabling this backend, branches, and tags in a remote subversion
|
After enabling this backend, branches and tags in a remote subversion
|
||||||
repository are exposed to salt as different environments. To enable this
|
repository are exposed to salt as different environments. To enable this
|
||||||
backend, add ``svn`` to the :conf_master:`fileserver_backend` option in the
|
backend, add ``svn`` to the :conf_master:`fileserver_backend` option in the
|
||||||
Master config file.
|
Master config file.
|
||||||
@ -697,7 +697,7 @@ def file_hash(load, fnd):
|
|||||||
|
|
||||||
def _file_lists(load, form):
|
def _file_lists(load, form):
|
||||||
'''
|
'''
|
||||||
Return a dict containing the file lists for files, dirs, emtydirs and symlinks
|
Return a dict containing the file lists for files, dirs, emptydirs and symlinks
|
||||||
'''
|
'''
|
||||||
if 'env' in load:
|
if 'env' in load:
|
||||||
salt.utils.warn_until(
|
salt.utils.warn_until(
|
||||||
|
@ -984,28 +984,20 @@ def _windows_platform_data():
|
|||||||
|
|
||||||
os_release = platform.release()
|
os_release = platform.release()
|
||||||
info = salt.utils.win_osinfo.get_os_version_info()
|
info = salt.utils.win_osinfo.get_os_version_info()
|
||||||
|
server = {'Vista': '2008Server',
|
||||||
|
'7': '2008ServerR2',
|
||||||
|
'8': '2012Server',
|
||||||
|
'8.1': '2012ServerR2',
|
||||||
|
'10': '2016Server'}
|
||||||
|
|
||||||
# Starting with Python 2.7.12 and 3.5.2 the `platform.uname()` function
|
# Starting with Python 2.7.12 and 3.5.2 the `platform.uname()` function
|
||||||
# started reporting the Desktop version instead of the Server version on
|
# started reporting the Desktop version instead of the Server version on
|
||||||
# Server versions of Windows, so we need to look those up
|
# Server versions of Windows, so we need to look those up
|
||||||
# Check for Python >=2.7.12 or >=3.5.2
|
# So, if you find a Server Platform that's a key in the server
|
||||||
ver = pythonversion()['pythonversion']
|
# dictionary, then lookup the actual Server Release.
|
||||||
if ((six.PY2 and
|
# (Product Type 1 is Desktop, Everything else is Server)
|
||||||
salt.utils.compare_versions(ver, '>=', [2, 7, 12, 'final', 0]))
|
if info['ProductType'] > 1 and os_release in server:
|
||||||
or
|
os_release = server[os_release]
|
||||||
(six.PY3 and
|
|
||||||
salt.utils.compare_versions(ver, '>=', [3, 5, 2, 'final', 0]))):
|
|
||||||
# (Product Type 1 is Desktop, Everything else is Server)
|
|
||||||
if info['ProductType'] > 1:
|
|
||||||
server = {'Vista': '2008Server',
|
|
||||||
'7': '2008ServerR2',
|
|
||||||
'8': '2012Server',
|
|
||||||
'8.1': '2012ServerR2',
|
|
||||||
'10': '2016Server'}
|
|
||||||
os_release = server.get(os_release,
|
|
||||||
'Grain not found. Update lookup table '
|
|
||||||
'in the `_windows_platform_data` '
|
|
||||||
'function in `grains\\core.py`')
|
|
||||||
|
|
||||||
service_pack = None
|
service_pack = None
|
||||||
if info['ServicePackMajor'] > 0:
|
if info['ServicePackMajor'] > 0:
|
||||||
@ -2359,6 +2351,10 @@ def _zpool_data(grains):
|
|||||||
if salt.utils.is_windows() or 'proxyminion' in __opts__:
|
if salt.utils.is_windows() or 'proxyminion' in __opts__:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
# quickly return if NetBSD (ZFS still under development)
|
||||||
|
if salt.utils.is_netbsd():
|
||||||
|
return {}
|
||||||
|
|
||||||
# quickly return if no zpool and zfs command
|
# quickly return if no zpool and zfs command
|
||||||
if not salt.utils.which('zpool'):
|
if not salt.utils.which('zpool'):
|
||||||
return {}
|
return {}
|
||||||
|
@ -194,7 +194,7 @@ def minion_mods(
|
|||||||
generated modules in __context__
|
generated modules in __context__
|
||||||
|
|
||||||
:param dict utils: Utility functions which should be made available to
|
:param dict utils: Utility functions which should be made available to
|
||||||
Salt modules in __utils__. See `utils_dir` in
|
Salt modules in __utils__. See `utils_dirs` in
|
||||||
salt.config for additional information about
|
salt.config for additional information about
|
||||||
configuration.
|
configuration.
|
||||||
|
|
||||||
@ -1094,7 +1094,8 @@ class LazyLoader(salt.utils.lazy.LazyDict):
|
|||||||
virtual_funcs = []
|
virtual_funcs = []
|
||||||
self.virtual_funcs = virtual_funcs
|
self.virtual_funcs = virtual_funcs
|
||||||
|
|
||||||
self.disabled = set(self.opts.get('disable_{0}s'.format(self.tag), []))
|
self.disabled = set(self.opts.get('disable_{0}{1}'.format(
|
||||||
|
self.tag, '' if self.tag[-1] == 's' else 's'), []))
|
||||||
|
|
||||||
self.refresh_file_mapping()
|
self.refresh_file_mapping()
|
||||||
|
|
||||||
|
@ -1251,7 +1251,7 @@ class Minion(MinionBase):
|
|||||||
ret = yield channel.send(load, timeout=timeout)
|
ret = yield channel.send(load, timeout=timeout)
|
||||||
raise tornado.gen.Return(ret)
|
raise tornado.gen.Return(ret)
|
||||||
|
|
||||||
def _fire_master(self, data=None, tag=None, events=None, pretag=None, timeout=60, sync=True):
|
def _fire_master(self, data=None, tag=None, events=None, pretag=None, timeout=60, sync=True, timeout_handler=None):
|
||||||
'''
|
'''
|
||||||
Fire an event on the master, or drop message if unable to send.
|
Fire an event on the master, or drop message if unable to send.
|
||||||
'''
|
'''
|
||||||
@ -1270,10 +1270,6 @@ class Minion(MinionBase):
|
|||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
def timeout_handler(*_):
|
|
||||||
log.info('fire_master failed: master could not be contacted. Request timed out.')
|
|
||||||
return True
|
|
||||||
|
|
||||||
if sync:
|
if sync:
|
||||||
try:
|
try:
|
||||||
self._send_req_sync(load, timeout)
|
self._send_req_sync(load, timeout)
|
||||||
@ -1284,6 +1280,12 @@ class Minion(MinionBase):
|
|||||||
log.info('fire_master failed: {0}'.format(traceback.format_exc()))
|
log.info('fire_master failed: {0}'.format(traceback.format_exc()))
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
if timeout_handler is None:
|
||||||
|
def handle_timeout(*_):
|
||||||
|
log.info('fire_master failed: master could not be contacted. Request timed out.')
|
||||||
|
return True
|
||||||
|
timeout_handler = handle_timeout
|
||||||
|
|
||||||
with tornado.stack_context.ExceptionStackContext(timeout_handler):
|
with tornado.stack_context.ExceptionStackContext(timeout_handler):
|
||||||
self._send_req_async(load, timeout, callback=lambda f: None) # pylint: disable=unexpected-keyword-arg
|
self._send_req_async(load, timeout, callback=lambda f: None) # pylint: disable=unexpected-keyword-arg
|
||||||
return True
|
return True
|
||||||
@ -1985,8 +1987,9 @@ class Minion(MinionBase):
|
|||||||
elif tag.startswith('_minion_mine'):
|
elif tag.startswith('_minion_mine'):
|
||||||
self._mine_send(tag, data)
|
self._mine_send(tag, data)
|
||||||
elif tag.startswith('fire_master'):
|
elif tag.startswith('fire_master'):
|
||||||
log.debug('Forwarding master event tag={tag}'.format(tag=data['tag']))
|
if self.connected:
|
||||||
self._fire_master(data['data'], data['tag'], data['events'], data['pretag'])
|
log.debug('Forwarding master event tag={tag}'.format(tag=data['tag']))
|
||||||
|
self._fire_master(data['data'], data['tag'], data['events'], data['pretag'])
|
||||||
elif tag.startswith(master_event(type='disconnected')) or tag.startswith(master_event(type='failback')):
|
elif tag.startswith(master_event(type='disconnected')) or tag.startswith(master_event(type='failback')):
|
||||||
# if the master disconnect event is for a different master, raise an exception
|
# if the master disconnect event is for a different master, raise an exception
|
||||||
if tag.startswith(master_event(type='disconnected')) and data['master'] != self.opts['master']:
|
if tag.startswith(master_event(type='disconnected')) and data['master'] != self.opts['master']:
|
||||||
@ -2205,13 +2208,15 @@ class Minion(MinionBase):
|
|||||||
if ping_interval > 0 and self.connected:
|
if ping_interval > 0 and self.connected:
|
||||||
def ping_master():
|
def ping_master():
|
||||||
try:
|
try:
|
||||||
if not self._fire_master('ping', 'minion_ping'):
|
def ping_timeout_handler(*_):
|
||||||
if not self.opts.get('auth_safemode', True):
|
if not self.opts.get('auth_safemode', True):
|
||||||
log.error('** Master Ping failed. Attempting to restart minion**')
|
log.error('** Master Ping failed. Attempting to restart minion**')
|
||||||
delay = self.opts.get('random_reauth_delay', 5)
|
delay = self.opts.get('random_reauth_delay', 5)
|
||||||
log.info('delaying random_reauth_delay {0}s'.format(delay))
|
log.info('delaying random_reauth_delay {0}s'.format(delay))
|
||||||
# regular sys.exit raises an exception -- which isn't sufficient in a thread
|
# regular sys.exit raises an exception -- which isn't sufficient in a thread
|
||||||
os._exit(salt.defaults.exitcodes.SALT_KEEPALIVE)
|
os._exit(salt.defaults.exitcodes.SALT_KEEPALIVE)
|
||||||
|
|
||||||
|
self._fire_master('ping', 'minion_ping', sync=False, timeout_handler=ping_timeout_handler)
|
||||||
except Exception:
|
except Exception:
|
||||||
log.warning('Attempt to ping master failed.', exc_on_loglevel=logging.DEBUG)
|
log.warning('Attempt to ping master failed.', exc_on_loglevel=logging.DEBUG)
|
||||||
self.periodic_callbacks['ping'] = tornado.ioloop.PeriodicCallback(ping_master, ping_interval * 1000, io_loop=self.io_loop)
|
self.periodic_callbacks['ping'] = tornado.ioloop.PeriodicCallback(ping_master, ping_interval * 1000, io_loop=self.io_loop)
|
||||||
@ -2226,7 +2231,7 @@ class Minion(MinionBase):
|
|||||||
except Exception:
|
except Exception:
|
||||||
log.critical('The beacon errored: ', exc_info=True)
|
log.critical('The beacon errored: ', exc_info=True)
|
||||||
if beacons and self.connected:
|
if beacons and self.connected:
|
||||||
self._fire_master(events=beacons)
|
self._fire_master(events=beacons, sync=False)
|
||||||
|
|
||||||
self.periodic_callbacks['beacons'] = tornado.ioloop.PeriodicCallback(handle_beacons, loop_interval * 1000, io_loop=self.io_loop)
|
self.periodic_callbacks['beacons'] = tornado.ioloop.PeriodicCallback(handle_beacons, loop_interval * 1000, io_loop=self.io_loop)
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ def execute(context=None, lens=None, commands=(), load_path=None):
|
|||||||
method = METHOD_MAP[cmd]
|
method = METHOD_MAP[cmd]
|
||||||
nargs = arg_map[method]
|
nargs = arg_map[method]
|
||||||
|
|
||||||
parts = salt.utils.shlex_split(arg)
|
parts = salt.utils.shlex_split(arg, posix=False)
|
||||||
|
|
||||||
if len(parts) not in nargs:
|
if len(parts) not in nargs:
|
||||||
err = '{0} takes {1} args: {2}'.format(method, nargs, parts)
|
err = '{0} takes {1} args: {2}'.format(method, nargs, parts)
|
||||||
|
@ -158,7 +158,7 @@ def create_file_system(name,
|
|||||||
import os
|
import os
|
||||||
import base64
|
import base64
|
||||||
creation_token = base64.b64encode(os.urandom(46), ['-', '_'])
|
creation_token = base64.b64encode(os.urandom(46), ['-', '_'])
|
||||||
tags = {"Key": "Name", "Value": name}
|
tags = [{"Key": "Name", "Value": name}]
|
||||||
|
|
||||||
client = _get_conn(key=key, keyid=keyid, profile=profile, region=region)
|
client = _get_conn(key=key, keyid=keyid, profile=profile, region=region)
|
||||||
|
|
||||||
@ -223,10 +223,23 @@ def create_mount_target(filesystemid,
|
|||||||
|
|
||||||
client = _get_conn(key=key, keyid=keyid, profile=profile, region=region)
|
client = _get_conn(key=key, keyid=keyid, profile=profile, region=region)
|
||||||
|
|
||||||
return client.create_mount_point(FileSystemId=filesystemid,
|
if ipaddress is None and securitygroups is None:
|
||||||
SubnetId=subnetid,
|
return client.create_mount_target(FileSystemId=filesystemid,
|
||||||
IpAddress=ipaddress,
|
SubnetId=subnetid)
|
||||||
SecurityGroups=securitygroups)
|
|
||||||
|
if ipaddress is None:
|
||||||
|
return client.create_mount_target(FileSystemId=filesystemid,
|
||||||
|
SubnetId=subnetid,
|
||||||
|
SecurityGroups=securitygroups)
|
||||||
|
if securitygroups is None:
|
||||||
|
return client.create_mount_target(FileSystemId=filesystemid,
|
||||||
|
SubnetId=subnetid,
|
||||||
|
IpAddress=ipaddress)
|
||||||
|
|
||||||
|
return client.create_mount_target(FileSystemId=filesystemid,
|
||||||
|
SubnetId=subnetid,
|
||||||
|
IpAddress=ipaddress,
|
||||||
|
SecurityGroups=securitygroups)
|
||||||
|
|
||||||
|
|
||||||
def create_tags(filesystemid,
|
def create_tags(filesystemid,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
'''
|
'''
|
||||||
Connection module for Amazon ALB
|
Connection module for Amazon ALB
|
||||||
|
|
||||||
.. versionadded:: TBD
|
.. versionadded:: 2017.7.0
|
||||||
|
|
||||||
:configuration: This module accepts explicit elb credentials but can also utilize
|
:configuration: This module accepts explicit elb credentials but can also utilize
|
||||||
IAM roles assigned to the instance through Instance Profiles. Dynamic
|
IAM roles assigned to the instance through Instance Profiles. Dynamic
|
||||||
|
@ -1927,7 +1927,7 @@ def list_policy_versions(policy_name,
|
|||||||
return ret.get('list_policy_versions_response', {}).get('list_policy_versions_result', {}).get('versions')
|
return ret.get('list_policy_versions_response', {}).get('list_policy_versions_result', {}).get('versions')
|
||||||
except boto.exception.BotoServerError as e:
|
except boto.exception.BotoServerError as e:
|
||||||
log.debug(e)
|
log.debug(e)
|
||||||
msg = 'Failed to list {0} policy vesions.'
|
msg = 'Failed to list {0} policy versions.'
|
||||||
log.error(msg.format(policy_name))
|
log.error(msg.format(policy_name))
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -294,6 +294,9 @@ def _run(cmd,
|
|||||||
if runas is None and '__context__' in globals():
|
if runas is None and '__context__' in globals():
|
||||||
runas = __context__.get('runas')
|
runas = __context__.get('runas')
|
||||||
|
|
||||||
|
if password is None and '__context__' in globals():
|
||||||
|
password = __context__.get('runas_password')
|
||||||
|
|
||||||
# Set the default working directory to the home directory of the user
|
# Set the default working directory to the home directory of the user
|
||||||
# salt-minion is running as. Defaults to home directory of user under which
|
# salt-minion is running as. Defaults to home directory of user under which
|
||||||
# the minion is running.
|
# the minion is running.
|
||||||
|
@ -1978,6 +1978,8 @@ def acl_create(consul_url=None, **kwargs):
|
|||||||
Create a new ACL token.
|
Create a new ACL token.
|
||||||
|
|
||||||
:param consul_url: The Consul server URL.
|
:param consul_url: The Consul server URL.
|
||||||
|
:param id: Unique identifier for the ACL to create
|
||||||
|
leave it blank to let consul server generate one
|
||||||
:param name: Meaningful indicator of the ACL's purpose.
|
:param name: Meaningful indicator of the ACL's purpose.
|
||||||
:param type: Type is either client or management. A management
|
:param type: Type is either client or management. A management
|
||||||
token is comparable to a root user and has the
|
token is comparable to a root user and has the
|
||||||
@ -2008,6 +2010,9 @@ def acl_create(consul_url=None, **kwargs):
|
|||||||
else:
|
else:
|
||||||
raise SaltInvocationError('Required argument "name" is missing.')
|
raise SaltInvocationError('Required argument "name" is missing.')
|
||||||
|
|
||||||
|
if 'id' in kwargs:
|
||||||
|
data['ID'] = kwargs['id']
|
||||||
|
|
||||||
if 'type' in kwargs:
|
if 'type' in kwargs:
|
||||||
data['Type'] = kwargs['type']
|
data['Type'] = kwargs['type']
|
||||||
|
|
||||||
@ -2126,7 +2131,7 @@ def acl_delete(consul_url=None, **kwargs):
|
|||||||
ret['res'] = False
|
ret['res'] = False
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
function = 'acl/delete/{0}'.format(kwargs['id'])
|
function = 'acl/destroy/{0}'.format(kwargs['id'])
|
||||||
res = _query(consul_url=consul_url,
|
res = _query(consul_url=consul_url,
|
||||||
data=data,
|
data=data,
|
||||||
method='PUT',
|
method='PUT',
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
'''
|
||||||
Compendium of generic DNS utilities
|
Compendium of generic DNS utilities.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Some functions in the ``dnsutil`` execution module depend on ``dig``.
|
||||||
'''
|
'''
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
@ -232,7 +236,7 @@ def check_ip(ip_addr):
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt ns1 dig.check_ip 127.0.0.1
|
salt ns1 dnsutil.check_ip 127.0.0.1
|
||||||
'''
|
'''
|
||||||
if _has_dig():
|
if _has_dig():
|
||||||
return __salt__['dig.check_ip'](ip_addr)
|
return __salt__['dig.check_ip'](ip_addr)
|
||||||
@ -242,7 +246,7 @@ def check_ip(ip_addr):
|
|||||||
|
|
||||||
def A(host, nameserver=None):
|
def A(host, nameserver=None):
|
||||||
'''
|
'''
|
||||||
Return the A record(s) for `host`.
|
Return the A record(s) for ``host``.
|
||||||
|
|
||||||
Always returns a list.
|
Always returns a list.
|
||||||
|
|
||||||
@ -267,7 +271,7 @@ def A(host, nameserver=None):
|
|||||||
|
|
||||||
def AAAA(host, nameserver=None):
|
def AAAA(host, nameserver=None):
|
||||||
'''
|
'''
|
||||||
Return the AAAA record(s) for `host`.
|
Return the AAAA record(s) for ``host``.
|
||||||
|
|
||||||
Always returns a list.
|
Always returns a list.
|
||||||
|
|
||||||
@ -302,7 +306,7 @@ def NS(domain, resolve=True, nameserver=None):
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt ns1 dig.NS google.com
|
salt ns1 dnsutil.NS google.com
|
||||||
|
|
||||||
'''
|
'''
|
||||||
if _has_dig():
|
if _has_dig():
|
||||||
@ -323,7 +327,7 @@ def SPF(domain, record='SPF', nameserver=None):
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt ns1 dig.SPF google.com
|
salt ns1 dnsutil.SPF google.com
|
||||||
'''
|
'''
|
||||||
if _has_dig():
|
if _has_dig():
|
||||||
return __salt__['dig.SPF'](domain, record, nameserver)
|
return __salt__['dig.SPF'](domain, record, nameserver)
|
||||||
@ -346,7 +350,7 @@ def MX(domain, resolve=False, nameserver=None):
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt ns1 dig.MX google.com
|
salt ns1 dnsutil.MX google.com
|
||||||
'''
|
'''
|
||||||
if _has_dig():
|
if _has_dig():
|
||||||
return __salt__['dig.MX'](domain, resolve, nameserver)
|
return __salt__['dig.MX'](domain, resolve, nameserver)
|
||||||
|
@ -559,6 +559,21 @@ def _prep_pull():
|
|||||||
__context__['docker._pull_status'] = [x[:12] for x in images(all=True)]
|
__context__['docker._pull_status'] = [x[:12] for x in images(all=True)]
|
||||||
|
|
||||||
|
|
||||||
|
def _scrub_links(links, name):
|
||||||
|
'''
|
||||||
|
Remove container name from HostConfig:Links values to enable comparing
|
||||||
|
container configurations correctly.
|
||||||
|
'''
|
||||||
|
if isinstance(links, list):
|
||||||
|
ret = []
|
||||||
|
for l in links:
|
||||||
|
ret.append(l.replace('/{0}/'.format(name), '/', 1))
|
||||||
|
else:
|
||||||
|
ret = links
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def _size_fmt(num):
|
def _size_fmt(num):
|
||||||
'''
|
'''
|
||||||
Format bytes as human-readable file sizes
|
Format bytes as human-readable file sizes
|
||||||
@ -884,8 +899,15 @@ def compare_container(first, second, ignore=None):
|
|||||||
continue
|
continue
|
||||||
val1 = result1[conf_dict][item]
|
val1 = result1[conf_dict][item]
|
||||||
val2 = result2[conf_dict].get(item)
|
val2 = result2[conf_dict].get(item)
|
||||||
if val1 != val2:
|
if item in ('OomKillDisable',):
|
||||||
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
if bool(val1) != bool(val2):
|
||||||
|
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
||||||
|
else:
|
||||||
|
if item == 'Links':
|
||||||
|
val1 = _scrub_links(val1, first)
|
||||||
|
val2 = _scrub_links(val2, second)
|
||||||
|
if val1 != val2:
|
||||||
|
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
||||||
# Check for optionally-present items that were in the second container
|
# Check for optionally-present items that were in the second container
|
||||||
# and not the first.
|
# and not the first.
|
||||||
for item in result2[conf_dict]:
|
for item in result2[conf_dict]:
|
||||||
@ -895,8 +917,15 @@ def compare_container(first, second, ignore=None):
|
|||||||
continue
|
continue
|
||||||
val1 = result1[conf_dict].get(item)
|
val1 = result1[conf_dict].get(item)
|
||||||
val2 = result2[conf_dict][item]
|
val2 = result2[conf_dict][item]
|
||||||
if val1 != val2:
|
if item in ('OomKillDisable',):
|
||||||
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
if bool(val1) != bool(val2):
|
||||||
|
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
||||||
|
else:
|
||||||
|
if item == 'Links':
|
||||||
|
val1 = _scrub_links(val1, first)
|
||||||
|
val2 = _scrub_links(val2, second)
|
||||||
|
if val1 != val2:
|
||||||
|
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@ -978,6 +1007,10 @@ def login(*registries):
|
|||||||
cmd = ['docker', 'login', '-u', username, '-p', password]
|
cmd = ['docker', 'login', '-u', username, '-p', password]
|
||||||
if registry.lower() != 'hub':
|
if registry.lower() != 'hub':
|
||||||
cmd.append(registry)
|
cmd.append(registry)
|
||||||
|
log.debug(
|
||||||
|
'Attempting to login to docker registry \'%s\' as user \'%s\'',
|
||||||
|
registry, username
|
||||||
|
)
|
||||||
login_cmd = __salt__['cmd.run_all'](
|
login_cmd = __salt__['cmd.run_all'](
|
||||||
cmd,
|
cmd,
|
||||||
python_shell=False,
|
python_shell=False,
|
||||||
@ -1803,7 +1836,7 @@ def create(image,
|
|||||||
generate one for you (it will be included in the return data).
|
generate one for you (it will be included in the return data).
|
||||||
|
|
||||||
skip_translate
|
skip_translate
|
||||||
This function translates Salt CLI input into the format which
|
This function translates Salt CLI or SLS input into the format which
|
||||||
docker-py_ expects. However, in the event that Salt's translation logic
|
docker-py_ expects. However, in the event that Salt's translation logic
|
||||||
fails (due to potential changes in the Docker Remote API, or to bugs in
|
fails (due to potential changes in the Docker Remote API, or to bugs in
|
||||||
the translation code), this argument can be used to exert granular
|
the translation code), this argument can be used to exert granular
|
||||||
@ -2071,9 +2104,9 @@ def create(image,
|
|||||||
- ``dns_search="[foo1.domain.tld, foo2.domain.tld]"``
|
- ``dns_search="[foo1.domain.tld, foo2.domain.tld]"``
|
||||||
|
|
||||||
domainname
|
domainname
|
||||||
Set custom DNS search domains
|
The domain name to use for the container
|
||||||
|
|
||||||
Example: ``domainname=domain.tld,domain2.tld``
|
Example: ``domainname=domain.tld``
|
||||||
|
|
||||||
entrypoint
|
entrypoint
|
||||||
Entrypoint for the container. Either a string (e.g. ``"mycmd --arg1
|
Entrypoint for the container. Either a string (e.g. ``"mycmd --arg1
|
||||||
|
@ -710,18 +710,21 @@ def check_hash(path, file_hash):
|
|||||||
|
|
||||||
hash
|
hash
|
||||||
The hash to check against the file specified in the ``path`` argument.
|
The hash to check against the file specified in the ``path`` argument.
|
||||||
For versions 2016.11.4 and newer, the hash can be specified without an
|
|
||||||
|
.. versionchanged:: 2016.11.4
|
||||||
|
|
||||||
|
For this and newer versions the hash can be specified without an
|
||||||
accompanying hash type (e.g. ``e138491e9d5b97023cea823fe17bac22``),
|
accompanying hash type (e.g. ``e138491e9d5b97023cea823fe17bac22``),
|
||||||
but for earlier releases it is necessary to also specify the hash type
|
but for earlier releases it is necessary to also specify the hash type
|
||||||
in the format ``<hash_type>:<hash_value>`` (e.g.
|
in the format ``<hash_type>=<hash_value>`` (e.g.
|
||||||
``md5:e138491e9d5b97023cea823fe17bac22``).
|
``md5=e138491e9d5b97023cea823fe17bac22``).
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt '*' file.check_hash /etc/fstab e138491e9d5b97023cea823fe17bac22
|
salt '*' file.check_hash /etc/fstab e138491e9d5b97023cea823fe17bac22
|
||||||
salt '*' file.check_hash /etc/fstab md5:e138491e9d5b97023cea823fe17bac22
|
salt '*' file.check_hash /etc/fstab md5=e138491e9d5b97023cea823fe17bac22
|
||||||
'''
|
'''
|
||||||
path = os.path.expanduser(path)
|
path = os.path.expanduser(path)
|
||||||
|
|
||||||
@ -1898,6 +1901,7 @@ def replace(path,
|
|||||||
show_changes=True,
|
show_changes=True,
|
||||||
ignore_if_missing=False,
|
ignore_if_missing=False,
|
||||||
preserve_inode=True,
|
preserve_inode=True,
|
||||||
|
backslash_literal=False,
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
.. versionadded:: 0.17.0
|
.. versionadded:: 0.17.0
|
||||||
@ -1998,6 +2002,14 @@ def replace(path,
|
|||||||
filename. Hard links will then share an inode with the backup, instead
|
filename. Hard links will then share an inode with the backup, instead
|
||||||
(if using ``backup`` to create a backup copy).
|
(if using ``backup`` to create a backup copy).
|
||||||
|
|
||||||
|
backslash_literal : False
|
||||||
|
.. versionadded:: 2016.11.7
|
||||||
|
|
||||||
|
Interpret backslashes as literal backslashes for the repl and not
|
||||||
|
escape characters. This will help when using append/prepend so that
|
||||||
|
the backslashes are not interpreted for the repl on the second run of
|
||||||
|
the state.
|
||||||
|
|
||||||
If an equal sign (``=``) appears in an argument to a Salt command it is
|
If an equal sign (``=``) appears in an argument to a Salt command it is
|
||||||
interpreted as a keyword argument in the format ``key=val``. That
|
interpreted as a keyword argument in the format ``key=val``. That
|
||||||
processing can be bypassed in order to pass an equal sign through to the
|
processing can be bypassed in order to pass an equal sign through to the
|
||||||
@ -2094,7 +2106,10 @@ def replace(path,
|
|||||||
if re.search(cpattern, r_data):
|
if re.search(cpattern, r_data):
|
||||||
return True # `with` block handles file closure
|
return True # `with` block handles file closure
|
||||||
else:
|
else:
|
||||||
result, nrepl = re.subn(cpattern, repl, r_data, count)
|
result, nrepl = re.subn(cpattern,
|
||||||
|
repl.replace('\\', '\\\\') if backslash_literal else repl,
|
||||||
|
r_data,
|
||||||
|
count)
|
||||||
|
|
||||||
# found anything? (even if no change)
|
# found anything? (even if no change)
|
||||||
if nrepl > 0:
|
if nrepl > 0:
|
||||||
@ -2148,8 +2163,10 @@ def replace(path,
|
|||||||
r_data = mmap.mmap(r_file.fileno(),
|
r_data = mmap.mmap(r_file.fileno(),
|
||||||
0,
|
0,
|
||||||
access=mmap.ACCESS_READ)
|
access=mmap.ACCESS_READ)
|
||||||
result, nrepl = re.subn(cpattern, repl,
|
result, nrepl = re.subn(cpattern,
|
||||||
r_data, count)
|
repl.replace('\\', '\\\\') if backslash_literal else repl,
|
||||||
|
r_data,
|
||||||
|
count)
|
||||||
try:
|
try:
|
||||||
w_file.write(salt.utils.to_str(result))
|
w_file.write(salt.utils.to_str(result))
|
||||||
except (OSError, IOError) as exc:
|
except (OSError, IOError) as exc:
|
||||||
|
@ -185,15 +185,24 @@ def _git_run(command, cwd=None, user=None, password=None, identity=None,
|
|||||||
identity = [identity]
|
identity = [identity]
|
||||||
|
|
||||||
# try each of the identities, independently
|
# try each of the identities, independently
|
||||||
|
tmp_identity_file = None
|
||||||
for id_file in identity:
|
for id_file in identity:
|
||||||
if 'salt://' in id_file:
|
if 'salt://' in id_file:
|
||||||
_id_file = id_file
|
with salt.utils.files.set_umask(0o077):
|
||||||
id_file = __salt__['cp.cache_file'](id_file, saltenv)
|
tmp_identity_file = salt.utils.mkstemp()
|
||||||
|
_id_file = id_file
|
||||||
|
id_file = __salt__['cp.get_file'](id_file,
|
||||||
|
tmp_identity_file,
|
||||||
|
saltenv)
|
||||||
if not id_file:
|
if not id_file:
|
||||||
log.error('identity {0} does not exist.'.format(_id_file))
|
log.error('identity {0} does not exist.'.format(_id_file))
|
||||||
|
__salt__['file.remove'](tmp_identity_file)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
__salt__['file.set_mode'](id_file, '0600')
|
if user:
|
||||||
|
os.chown(id_file,
|
||||||
|
__salt__['file.user_to_uid'](user),
|
||||||
|
-1)
|
||||||
else:
|
else:
|
||||||
if not __salt__['file.file_exists'](id_file):
|
if not __salt__['file.file_exists'](id_file):
|
||||||
missing_keys.append(id_file)
|
missing_keys.append(id_file)
|
||||||
@ -264,6 +273,11 @@ def _git_run(command, cwd=None, user=None, password=None, identity=None,
|
|||||||
if not salt.utils.is_windows() and 'GIT_SSH' in env:
|
if not salt.utils.is_windows() and 'GIT_SSH' in env:
|
||||||
os.remove(env['GIT_SSH'])
|
os.remove(env['GIT_SSH'])
|
||||||
|
|
||||||
|
# Cleanup the temporary identity file
|
||||||
|
if tmp_identity_file and os.path.exists(tmp_identity_file):
|
||||||
|
log.debug('Removing identity file {0}'.format(tmp_identity_file))
|
||||||
|
__salt__['file.remove'](tmp_identity_file)
|
||||||
|
|
||||||
# If the command was successful, no need to try additional IDs
|
# If the command was successful, no need to try additional IDs
|
||||||
if result['retcode'] == 0:
|
if result['retcode'] == 0:
|
||||||
return result
|
return result
|
||||||
|
@ -35,8 +35,6 @@ def useradd(pwfile, user, password, opts='', runas=None):
|
|||||||
Add a user to htpasswd file using the htpasswd command. If the htpasswd
|
Add a user to htpasswd file using the htpasswd command. If the htpasswd
|
||||||
file does not exist, it will be created.
|
file does not exist, it will be created.
|
||||||
|
|
||||||
.. deprecated:: 2016.3.0
|
|
||||||
|
|
||||||
pwfile
|
pwfile
|
||||||
Path to htpasswd file
|
Path to htpasswd file
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ def create_keytab(name, keytab, enctypes=None):
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt 'kdc.example.com' host/host1.example.com host1.example.com.keytab
|
salt 'kdc.example.com' kerberos.create_keytab host/host1.example.com host1.example.com.keytab
|
||||||
'''
|
'''
|
||||||
ret = {}
|
ret = {}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ or `api_password` parameters when calling a function:
|
|||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
salt '*' kubernetes.nodes api_url=http://k8s-api-server:port api_user=myuser api_password=pass
|
salt '*' kubernetes.nodes api_url=http://k8s-api-server:port api_user=myuser api_password=pass
|
||||||
|
|
||||||
|
.. versionadded: 2017.7.0
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Import Python Futures
|
# Import Python Futures
|
||||||
@ -39,6 +40,14 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_LIBS = False
|
HAS_LIBS = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
# There is an API change in Kubernetes >= 2.0.0.
|
||||||
|
from kubernetes.client import V1beta1Deployment as AppsV1beta1Deployment
|
||||||
|
from kubernetes.client import V1beta1DeploymentSpec as AppsV1beta1DeploymentSpec
|
||||||
|
except ImportError:
|
||||||
|
from kubernetes.client import AppsV1beta1Deployment
|
||||||
|
from kubernetes.client import AppsV1beta1DeploymentSpec
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -761,7 +770,7 @@ def create_deployment(
|
|||||||
'''
|
'''
|
||||||
body = __create_object_body(
|
body = __create_object_body(
|
||||||
kind='Deployment',
|
kind='Deployment',
|
||||||
obj_class=kubernetes.client.V1beta1Deployment,
|
obj_class=AppsV1beta1Deployment,
|
||||||
spec_creator=__dict_to_deployment_spec,
|
spec_creator=__dict_to_deployment_spec,
|
||||||
name=name,
|
name=name,
|
||||||
namespace=namespace,
|
namespace=namespace,
|
||||||
@ -1012,7 +1021,7 @@ def replace_deployment(name,
|
|||||||
'''
|
'''
|
||||||
body = __create_object_body(
|
body = __create_object_body(
|
||||||
kind='Deployment',
|
kind='Deployment',
|
||||||
obj_class=kubernetes.client.V1beta1Deployment,
|
obj_class=AppsV1beta1Deployment,
|
||||||
spec_creator=__dict_to_deployment_spec,
|
spec_creator=__dict_to_deployment_spec,
|
||||||
name=name,
|
name=name,
|
||||||
namespace=namespace,
|
namespace=namespace,
|
||||||
@ -1275,9 +1284,9 @@ def __dict_to_object_meta(name, namespace, metadata):
|
|||||||
|
|
||||||
def __dict_to_deployment_spec(spec):
|
def __dict_to_deployment_spec(spec):
|
||||||
'''
|
'''
|
||||||
Converts a dictionary into kubernetes V1beta1DeploymentSpec instance.
|
Converts a dictionary into kubernetes AppsV1beta1DeploymentSpec instance.
|
||||||
'''
|
'''
|
||||||
spec_obj = kubernetes.client.V1beta1DeploymentSpec()
|
spec_obj = AppsV1beta1DeploymentSpec()
|
||||||
for key, value in iteritems(spec):
|
for key, value in iteritems(spec):
|
||||||
if hasattr(spec_obj, key):
|
if hasattr(spec_obj, key):
|
||||||
setattr(spec_obj, key, value)
|
setattr(spec_obj, key, value)
|
||||||
|
@ -216,7 +216,7 @@ def align_check(device, part_type, partition):
|
|||||||
'Invalid partition passed to partition.align_check'
|
'Invalid partition passed to partition.align_check'
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = 'parted -m -s {0} align-check {1} {2}'.format(
|
cmd = 'parted -m {0} align-check {1} {2}'.format(
|
||||||
device, part_type, partition
|
device, part_type, partition
|
||||||
)
|
)
|
||||||
out = __salt__['cmd.run'](cmd).splitlines()
|
out = __salt__['cmd.run'](cmd).splitlines()
|
||||||
|
@ -257,8 +257,8 @@ def items(*args, **kwargs):
|
|||||||
__opts__,
|
__opts__,
|
||||||
__grains__,
|
__grains__,
|
||||||
__opts__['id'],
|
__opts__['id'],
|
||||||
pillar_override=kwargs.get('pillar'),
|
pillar_override=pillar_override,
|
||||||
pillarenv=kwargs.get('pillarenv') or __opts__['pillarenv'])
|
pillarenv=pillarenv)
|
||||||
|
|
||||||
return pillar.compile_pillar()
|
return pillar.compile_pillar()
|
||||||
|
|
||||||
|
@ -345,9 +345,10 @@ def summary():
|
|||||||
|
|
||||||
def plugin_sync():
|
def plugin_sync():
|
||||||
'''
|
'''
|
||||||
Runs a plugin synch between the puppet master and agent
|
Runs a plugin sync between the puppet master and agent
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt '*' puppet.plugin_sync
|
salt '*' puppet.plugin_sync
|
||||||
|
@ -135,6 +135,7 @@ def _safe_output(line):
|
|||||||
'''
|
'''
|
||||||
return not any([
|
return not any([
|
||||||
line.startswith('Listing') and line.endswith('...'),
|
line.startswith('Listing') and line.endswith('...'),
|
||||||
|
line.startswith('Listing') and '\t' not in line,
|
||||||
'...done' in line,
|
'...done' in line,
|
||||||
line.startswith('WARNING:')
|
line.startswith('WARNING:')
|
||||||
])
|
])
|
||||||
@ -608,11 +609,11 @@ def set_user_tags(name, tags, runas=None):
|
|||||||
if runas is None and not salt.utils.is_windows():
|
if runas is None and not salt.utils.is_windows():
|
||||||
runas = salt.utils.get_user()
|
runas = salt.utils.get_user()
|
||||||
|
|
||||||
if tags and isinstance(tags, (list, tuple)):
|
if not isinstance(tags, (list, tuple)):
|
||||||
tags = ' '.join(tags)
|
tags = [tags]
|
||||||
|
|
||||||
res = __salt__['cmd.run_all'](
|
res = __salt__['cmd.run_all'](
|
||||||
[RABBITMQCTL, 'set_user_tags', name, tags],
|
[RABBITMQCTL, 'set_user_tags', name] + list(tags),
|
||||||
runas=runas,
|
runas=runas,
|
||||||
python_shell=False)
|
python_shell=False)
|
||||||
msg = "Tag(s) set"
|
msg = "Tag(s) set"
|
||||||
|
@ -150,7 +150,9 @@ class Registry(object): # pylint: disable=R0903
|
|||||||
_winreg.REG_DWORD: 'REG_DWORD',
|
_winreg.REG_DWORD: 'REG_DWORD',
|
||||||
_winreg.REG_EXPAND_SZ: 'REG_EXPAND_SZ',
|
_winreg.REG_EXPAND_SZ: 'REG_EXPAND_SZ',
|
||||||
_winreg.REG_MULTI_SZ: 'REG_MULTI_SZ',
|
_winreg.REG_MULTI_SZ: 'REG_MULTI_SZ',
|
||||||
_winreg.REG_SZ: 'REG_SZ'
|
_winreg.REG_SZ: 'REG_SZ',
|
||||||
|
# REG_QWORD isn't in the winreg library
|
||||||
|
11: 'REG_QWORD'
|
||||||
}
|
}
|
||||||
self.opttype_reverse = {
|
self.opttype_reverse = {
|
||||||
_winreg.REG_OPTION_NON_VOLATILE: 'REG_OPTION_NON_VOLATILE',
|
_winreg.REG_OPTION_NON_VOLATILE: 'REG_OPTION_NON_VOLATILE',
|
||||||
|
@ -218,7 +218,7 @@ def uptime():
|
|||||||
with salt.utils.fopen(ut_path) as rfh:
|
with salt.utils.fopen(ut_path) as rfh:
|
||||||
seconds = int(float(rfh.read().split()[0]))
|
seconds = int(float(rfh.read().split()[0]))
|
||||||
elif salt.utils.is_sunos():
|
elif salt.utils.is_sunos():
|
||||||
# note: some flavors/vesions report the host uptime inside a zone
|
# note: some flavors/versions report the host uptime inside a zone
|
||||||
# https://support.oracle.com/epmos/faces/BugDisplay?id=15611584
|
# https://support.oracle.com/epmos/faces/BugDisplay?id=15611584
|
||||||
res = __salt__['cmd.run_all']('kstat -p unix:0:system_misc:boot_time')
|
res = __salt__['cmd.run_all']('kstat -p unix:0:system_misc:boot_time')
|
||||||
if res['retcode'] > 0:
|
if res['retcode'] > 0:
|
||||||
|
@ -1687,9 +1687,6 @@ def check_perms(path,
|
|||||||
perms = changes[user]['perms']
|
perms = changes[user]['perms']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
log.debug('*' * 68)
|
|
||||||
log.debug(perms)
|
|
||||||
log.debug('*' * 68)
|
|
||||||
salt.utils.win_dacl.set_permissions(
|
salt.utils.win_dacl.set_permissions(
|
||||||
path, user, perms, 'deny', applies_to)
|
path, user, perms, 'deny', applies_to)
|
||||||
ret['changes']['deny_perms'][user] = changes[user]
|
ret['changes']['deny_perms'][user] = changes[user]
|
||||||
|
@ -856,7 +856,7 @@ def create_cert_binding(name, site, hostheader='', ipaddress='*', port=443,
|
|||||||
|
|
||||||
new_cert_bindings = list_cert_bindings(site)
|
new_cert_bindings = list_cert_bindings(site)
|
||||||
|
|
||||||
if binding_info not in new_cert_bindings(site):
|
if binding_info not in new_cert_bindings:
|
||||||
log.error('Binding not present: {0}'.format(binding_info))
|
log.error('Binding not present: {0}'.format(binding_info))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -3982,78 +3982,77 @@ def _write_regpol_data(data_to_write,
|
|||||||
gpt_extension_guid: admx registry extension guid for the class
|
gpt_extension_guid: admx registry extension guid for the class
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
if data_to_write:
|
reg_pol_header = u'\u5250\u6765\x01\x00'
|
||||||
reg_pol_header = u'\u5250\u6765\x01\x00'
|
if not os.path.exists(policy_file_path):
|
||||||
if not os.path.exists(policy_file_path):
|
ret = __salt__['file.makedirs'](policy_file_path)
|
||||||
ret = __salt__['file.makedirs'](policy_file_path)
|
with salt.utils.files.fopen(policy_file_path, 'wb') as pol_file:
|
||||||
with salt.utils.fopen(policy_file_path, 'wb') as pol_file:
|
if not data_to_write.startswith(reg_pol_header):
|
||||||
if not data_to_write.startswith(reg_pol_header):
|
pol_file.write(reg_pol_header.encode('utf-16-le'))
|
||||||
pol_file.write(reg_pol_header.encode('utf-16-le'))
|
pol_file.write(data_to_write.encode('utf-16-le'))
|
||||||
pol_file.write(data_to_write.encode('utf-16-le'))
|
try:
|
||||||
try:
|
gpt_ini_data = ''
|
||||||
gpt_ini_data = ''
|
if os.path.exists(gpt_ini_path):
|
||||||
if os.path.exists(gpt_ini_path):
|
with salt.utils.files.fopen(gpt_ini_path, 'rb') as gpt_file:
|
||||||
with salt.utils.fopen(gpt_ini_path, 'rb') as gpt_file:
|
gpt_ini_data = gpt_file.read()
|
||||||
gpt_ini_data = gpt_file.read()
|
if not _regexSearchRegPolData(r'\[General\]\r\n', gpt_ini_data):
|
||||||
if not _regexSearchRegPolData(r'\[General\]\r\n', gpt_ini_data):
|
gpt_ini_data = '[General]\r\n' + gpt_ini_data
|
||||||
gpt_ini_data = '[General]\r\n' + gpt_ini_data
|
if _regexSearchRegPolData(r'{0}='.format(re.escape(gpt_extension)), gpt_ini_data):
|
||||||
if _regexSearchRegPolData(r'{0}='.format(re.escape(gpt_extension)), gpt_ini_data):
|
# ensure the line contains the ADM guid
|
||||||
# ensure the line contains the ADM guid
|
gpt_ext_loc = re.search(r'^{0}=.*\r\n'.format(re.escape(gpt_extension)),
|
||||||
gpt_ext_loc = re.search(r'^{0}=.*\r\n'.format(re.escape(gpt_extension)),
|
gpt_ini_data,
|
||||||
gpt_ini_data,
|
re.IGNORECASE | re.MULTILINE)
|
||||||
re.IGNORECASE | re.MULTILINE)
|
gpt_ext_str = gpt_ini_data[gpt_ext_loc.start():gpt_ext_loc.end()]
|
||||||
gpt_ext_str = gpt_ini_data[gpt_ext_loc.start():gpt_ext_loc.end()]
|
if not _regexSearchRegPolData(r'{0}'.format(re.escape(gpt_extension_guid)),
|
||||||
if not _regexSearchRegPolData(r'{0}'.format(re.escape(gpt_extension_guid)),
|
gpt_ext_str):
|
||||||
gpt_ext_str):
|
gpt_ext_str = gpt_ext_str.split('=')
|
||||||
gpt_ext_str = gpt_ext_str.split('=')
|
gpt_ext_str[1] = gpt_extension_guid + gpt_ext_str[1]
|
||||||
gpt_ext_str[1] = gpt_extension_guid + gpt_ext_str[1]
|
gpt_ext_str = '='.join(gpt_ext_str)
|
||||||
gpt_ext_str = '='.join(gpt_ext_str)
|
gpt_ini_data = gpt_ini_data[0:gpt_ext_loc.start()] + gpt_ext_str + gpt_ini_data[gpt_ext_loc.end():]
|
||||||
gpt_ini_data = gpt_ini_data[0:gpt_ext_loc.start()] + gpt_ext_str + gpt_ini_data[gpt_ext_loc.end():]
|
else:
|
||||||
else:
|
general_location = re.search(r'^\[General\]\r\n',
|
||||||
general_location = re.search(r'^\[General\]\r\n',
|
gpt_ini_data,
|
||||||
gpt_ini_data,
|
re.IGNORECASE | re.MULTILINE)
|
||||||
re.IGNORECASE | re.MULTILINE)
|
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
||||||
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
gpt_ini_data[general_location.start():general_location.end()],
|
||||||
gpt_ini_data[general_location.start():general_location.end()],
|
gpt_extension, gpt_extension_guid,
|
||||||
gpt_extension, gpt_extension_guid,
|
gpt_ini_data[general_location.end():])
|
||||||
gpt_ini_data[general_location.end():])
|
# https://technet.microsoft.com/en-us/library/cc978247.aspx
|
||||||
# https://technet.microsoft.com/en-us/library/cc978247.aspx
|
if _regexSearchRegPolData(r'Version=', gpt_ini_data):
|
||||||
if _regexSearchRegPolData(r'Version=', gpt_ini_data):
|
version_loc = re.search(r'^Version=.*\r\n',
|
||||||
version_loc = re.search(r'^Version=.*\r\n',
|
gpt_ini_data,
|
||||||
gpt_ini_data,
|
re.IGNORECASE | re.MULTILINE)
|
||||||
re.IGNORECASE | re.MULTILINE)
|
version_str = gpt_ini_data[version_loc.start():version_loc.end()]
|
||||||
version_str = gpt_ini_data[version_loc.start():version_loc.end()]
|
version_str = version_str.split('=')
|
||||||
version_str = version_str.split('=')
|
version_nums = struct.unpack('>2H', struct.pack('>I', int(version_str[1])))
|
||||||
version_nums = struct.unpack('>2H', struct.pack('>I', int(version_str[1])))
|
if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower():
|
||||||
if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower():
|
version_nums = (version_nums[0], version_nums[1] + 1)
|
||||||
version_nums = (version_nums[0], version_nums[1] + 1)
|
elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower():
|
||||||
elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower():
|
version_nums = (version_nums[0] + 1, version_nums[1])
|
||||||
version_nums = (version_nums[0] + 1, version_nums[1])
|
version_num = struct.unpack('>I', struct.pack('>2H', *version_nums))[0]
|
||||||
version_num = struct.unpack('>I', struct.pack('>2H', *version_nums))[0]
|
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
||||||
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
gpt_ini_data[0:version_loc.start()],
|
||||||
gpt_ini_data[0:version_loc.start()],
|
'Version', version_num,
|
||||||
'Version', version_num,
|
gpt_ini_data[version_loc.end():])
|
||||||
gpt_ini_data[version_loc.end():])
|
else:
|
||||||
else:
|
general_location = re.search(r'^\[General\]\r\n',
|
||||||
general_location = re.search(r'^\[General\]\r\n',
|
gpt_ini_data,
|
||||||
gpt_ini_data,
|
re.IGNORECASE | re.MULTILINE)
|
||||||
re.IGNORECASE | re.MULTILINE)
|
if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower():
|
||||||
if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower():
|
version_nums = (0, 1)
|
||||||
version_nums = (0, 1)
|
elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower():
|
||||||
elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower():
|
version_nums = (1, 0)
|
||||||
version_nums = (1, 0)
|
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
||||||
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
gpt_ini_data[general_location.start():general_location.end()],
|
||||||
gpt_ini_data[general_location.start():general_location.end()],
|
'Version',
|
||||||
'Version',
|
int("{0}{1}".format(str(version_nums[0]).zfill(4), str(version_nums[1]).zfill(4)), 16),
|
||||||
int("{0}{1}".format(str(version_nums[0]).zfill(4), str(version_nums[1]).zfill(4)), 16),
|
gpt_ini_data[general_location.end():])
|
||||||
gpt_ini_data[general_location.end():])
|
if gpt_ini_data:
|
||||||
if gpt_ini_data:
|
with salt.utils.files.fopen(gpt_ini_path, 'wb') as gpt_file:
|
||||||
with salt.utils.fopen(gpt_ini_path, 'wb') as gpt_file:
|
gpt_file.write(gpt_ini_data)
|
||||||
gpt_file.write(gpt_ini_data)
|
except Exception as e:
|
||||||
except Exception as e:
|
msg = 'An error occurred attempting to write to {0}, the exception was {1}'.format(
|
||||||
msg = 'An error occurred attempting to write to {0}, the exception was {1}'.format(
|
gpt_ini_path, e)
|
||||||
gpt_ini_path, e)
|
raise CommandExecutionError(msg)
|
||||||
raise CommandExecutionError(msg)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = 'An error occurred attempting to write to {0}, the exception was {1}'.format(policy_file_path, e)
|
msg = 'An error occurred attempting to write to {0}, the exception was {1}'.format(policy_file_path, e)
|
||||||
raise CommandExecutionError(msg)
|
raise CommandExecutionError(msg)
|
||||||
|
@ -945,27 +945,63 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
|
|||||||
packages listed under ``pkgs`` will be installed via a single
|
packages listed under ``pkgs`` will be installed via a single
|
||||||
command.
|
command.
|
||||||
|
|
||||||
|
You can specify a version by passing the item as a dict:
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# will install the latest version of foo and bar
|
||||||
|
salt '*' pkg.install pkgs='["foo", "bar"]'
|
||||||
|
|
||||||
|
# will install the latest version of foo and version 1.2.3 of bar
|
||||||
|
salt '*' pkg.install pkgs='["foo", {"bar": "1.2.3"}]'
|
||||||
|
|
||||||
Kwargs:
|
Kwargs:
|
||||||
|
|
||||||
version (str):
|
version (str):
|
||||||
The specific version to install. If omitted, the latest version
|
The specific version to install. If omitted, the latest version will
|
||||||
will be installed. If passed with multiple install, the version
|
be installed. Recommend for use when installing a single package.
|
||||||
will apply to all packages. Recommended for single installation
|
|
||||||
only.
|
If passed with a list of packages in the ``pkgs`` parameter, the
|
||||||
|
version will be ignored.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# Version is ignored
|
||||||
|
salt '*' pkg.install pkgs="['foo', 'bar']" version=1.2.3
|
||||||
|
|
||||||
|
If passed with a comma seperated list in the ``name`` parameter, the
|
||||||
|
version will apply to all packages in the list.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# Version 1.2.3 will apply to packages foo and bar
|
||||||
|
salt '*' pkg.install foo,bar version=1.2.3
|
||||||
|
|
||||||
cache_file (str):
|
cache_file (str):
|
||||||
A single file to copy down for use with the installer. Copied to
|
A single file to copy down for use with the installer. Copied to the
|
||||||
the same location as the installer. Use this over ``cache_dir`` if
|
same location as the installer. Use this over ``cache_dir`` if there
|
||||||
there are many files in the directory and you only need a specific
|
are many files in the directory and you only need a specific file
|
||||||
file and don't want to cache additional files that may reside in
|
and don't want to cache additional files that may reside in the
|
||||||
the installer directory. Only applies to files on ``salt://``
|
installer directory. Only applies to files on ``salt://``
|
||||||
|
|
||||||
cache_dir (bool):
|
cache_dir (bool):
|
||||||
True will copy the contents of the installer directory. This is
|
True will copy the contents of the installer directory. This is
|
||||||
useful for installations that are not a single file. Only applies
|
useful for installations that are not a single file. Only applies to
|
||||||
to directories on ``salt://``
|
directories on ``salt://``
|
||||||
|
|
||||||
saltenv (str): Salt environment. Default 'base'
|
extra_install_flags (str):
|
||||||
|
Additional install flags that will be appended to the
|
||||||
|
``install_flags`` defined in the software definition file. Only
|
||||||
|
applies when single package is passed.
|
||||||
|
|
||||||
|
saltenv (str):
|
||||||
|
Salt environment. Default 'base'
|
||||||
|
|
||||||
report_reboot_exit_codes (bool):
|
report_reboot_exit_codes (bool):
|
||||||
If the installer exits with a recognized exit code indicating that
|
If the installer exits with a recognized exit code indicating that
|
||||||
@ -1061,13 +1097,22 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
|
|||||||
# "sources" argument
|
# "sources" argument
|
||||||
pkg_params = __salt__['pkg_resource.parse_targets'](name, pkgs, **kwargs)[0]
|
pkg_params = __salt__['pkg_resource.parse_targets'](name, pkgs, **kwargs)[0]
|
||||||
|
|
||||||
|
if len(pkg_params) > 1:
|
||||||
|
if kwargs.get('extra_install_flags') is not None:
|
||||||
|
log.warning('\'extra_install_flags\' argument will be ignored for '
|
||||||
|
'multiple package targets')
|
||||||
|
|
||||||
|
# Windows expects an Options dictionary containing 'version'
|
||||||
|
for pkg in pkg_params:
|
||||||
|
pkg_params[pkg] = {'version': pkg_params[pkg]}
|
||||||
|
|
||||||
if pkg_params is None or len(pkg_params) == 0:
|
if pkg_params is None or len(pkg_params) == 0:
|
||||||
log.error('No package definition found')
|
log.error('No package definition found')
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
if not pkgs and len(pkg_params) == 1:
|
if not pkgs and len(pkg_params) == 1:
|
||||||
# Only use the 'version' param if 'name' was not specified as a
|
# Only use the 'version' param if a single item was passed to the 'name'
|
||||||
# comma-separated list
|
# parameter
|
||||||
pkg_params = {
|
pkg_params = {
|
||||||
name: {
|
name: {
|
||||||
'version': kwargs.get('version'),
|
'version': kwargs.get('version'),
|
||||||
@ -1092,11 +1137,15 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
|
|||||||
ret[pkg_name] = 'Unable to locate package {0}'.format(pkg_name)
|
ret[pkg_name] = 'Unable to locate package {0}'.format(pkg_name)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Get the version number passed or the latest available
|
# Get the version number passed or the latest available (must be a string)
|
||||||
version_num = ''
|
version_num = ''
|
||||||
if options:
|
if options:
|
||||||
if options.get('version') is not None:
|
version_num = options.get('version', '')
|
||||||
version_num = str(options.get('version'))
|
# Using the salt cmdline with version=5.3 might be interpreted
|
||||||
|
# as a float it must be converted to a string in order for
|
||||||
|
# string matching to work.
|
||||||
|
if not isinstance(version_num, six.string_types) and version_num is not None:
|
||||||
|
version_num = str(version_num)
|
||||||
|
|
||||||
if not version_num:
|
if not version_num:
|
||||||
version_num = _get_latest_pkg_version(pkginfo)
|
version_num = _get_latest_pkg_version(pkginfo)
|
||||||
@ -1423,6 +1472,11 @@ def remove(name=None, pkgs=None, version=None, **kwargs):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if version_num is not None:
|
if version_num is not None:
|
||||||
|
# Using the salt cmdline with version=5.3 might be interpreted
|
||||||
|
# as a float it must be converted to a string in order for
|
||||||
|
# string matching to work.
|
||||||
|
if not isinstance(version_num, six.string_types) and version_num is not None:
|
||||||
|
version_num = str(version_num)
|
||||||
if version_num not in pkginfo and 'latest' in pkginfo:
|
if version_num not in pkginfo and 'latest' in pkginfo:
|
||||||
version_num = 'latest'
|
version_num = 'latest'
|
||||||
elif 'latest' in pkginfo:
|
elif 'latest' in pkginfo:
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
'''
|
||||||
Microsoft certificate management via the Pki PowerShell module.
|
Microsoft certificate management via the PKI Client PowerShell module.
|
||||||
|
https://technet.microsoft.com/en-us/itpro/powershell/windows/pkiclient/pkiclient
|
||||||
|
|
||||||
|
The PKI Client PowerShell module is only available on Windows 8+ and Windows
|
||||||
|
Server 2012+.
|
||||||
|
https://technet.microsoft.com/en-us/library/hh848636(v=wps.620).aspx
|
||||||
|
|
||||||
:platform: Windows
|
:platform: Windows
|
||||||
|
|
||||||
|
:depends:
|
||||||
|
- PowerShell 4
|
||||||
|
- PKI Client Module (Windows 8+ / Windows Server 2012+)
|
||||||
|
|
||||||
.. versionadded:: 2016.11.0
|
.. versionadded:: 2016.11.0
|
||||||
'''
|
'''
|
||||||
# Import python libs
|
# Import python libs
|
||||||
@ -29,11 +38,17 @@ __virtualname__ = 'win_pki'
|
|||||||
|
|
||||||
def __virtual__():
|
def __virtual__():
|
||||||
'''
|
'''
|
||||||
Only works on Windows systems with the PKI PowerShell module installed.
|
Requires Windows
|
||||||
|
Requires Windows 8+ / Windows Server 2012+
|
||||||
|
Requires PowerShell
|
||||||
|
Requires PKI Client PowerShell module installed.
|
||||||
'''
|
'''
|
||||||
if not salt.utils.is_windows():
|
if not salt.utils.is_windows():
|
||||||
return False, 'Only available on Windows Systems'
|
return False, 'Only available on Windows Systems'
|
||||||
|
|
||||||
|
if salt.utils.version_cmp(__grains__['osversion'], '6.2.9200') == -1:
|
||||||
|
return False, 'Only available on Windows 8+ / Windows Server 2012 +'
|
||||||
|
|
||||||
if not __salt__['cmd.shell_info']('powershell')['installed']:
|
if not __salt__['cmd.shell_info']('powershell')['installed']:
|
||||||
return False, 'Powershell not available'
|
return False, 'Powershell not available'
|
||||||
|
|
||||||
|
@ -303,6 +303,11 @@ def get_community_names():
|
|||||||
# Windows SNMP service GUI.
|
# Windows SNMP service GUI.
|
||||||
if isinstance(current_values, list):
|
if isinstance(current_values, list):
|
||||||
for current_value in current_values:
|
for current_value in current_values:
|
||||||
|
|
||||||
|
# Ignore error values
|
||||||
|
if not isinstance(current_value, dict):
|
||||||
|
continue
|
||||||
|
|
||||||
permissions = str()
|
permissions = str()
|
||||||
for permission_name in _PERMISSION_TYPES:
|
for permission_name in _PERMISSION_TYPES:
|
||||||
if current_value['vdata'] == _PERMISSION_TYPES[permission_name]:
|
if current_value['vdata'] == _PERMISSION_TYPES[permission_name]:
|
||||||
|
@ -37,6 +37,7 @@ except ImportError:
|
|||||||
import salt.utils
|
import salt.utils
|
||||||
import salt.utils.locales
|
import salt.utils.locales
|
||||||
import salt.ext.six as six
|
import salt.ext.six as six
|
||||||
|
from salt.exceptions import CommandExecutionError
|
||||||
|
|
||||||
# Set up logging
|
# Set up logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -622,7 +623,11 @@ def join_domain(domain,
|
|||||||
.. versionadded:: 2015.8.2/2015.5.7
|
.. versionadded:: 2015.8.2/2015.5.7
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Dictionary if successful, otherwise False
|
dict: Dictionary if successful
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
CommandExecutionError: Raises an error if _join_domain returns anything
|
||||||
|
other than 0
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
@ -655,6 +660,56 @@ def join_domain(domain,
|
|||||||
account_ou = account_ou.split('\\')
|
account_ou = account_ou.split('\\')
|
||||||
account_ou = ''.join(account_ou)
|
account_ou = ''.join(account_ou)
|
||||||
|
|
||||||
|
err = _join_domain(domain=domain, username=username, password=password,
|
||||||
|
account_ou=account_ou, account_exists=account_exists)
|
||||||
|
|
||||||
|
if not err:
|
||||||
|
ret = {'Domain': domain,
|
||||||
|
'Restart': False}
|
||||||
|
if restart:
|
||||||
|
ret['Restart'] = reboot()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
raise CommandExecutionError(win32api.FormatMessage(err).rstrip())
|
||||||
|
|
||||||
|
|
||||||
|
def _join_domain(domain,
|
||||||
|
username=None,
|
||||||
|
password=None,
|
||||||
|
account_ou=None,
|
||||||
|
account_exists=False):
|
||||||
|
'''
|
||||||
|
Helper function to join the domain.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
domain (str): The domain to which the computer should be joined, e.g.
|
||||||
|
``example.com``
|
||||||
|
|
||||||
|
username (str): Username of an account which is authorized to join
|
||||||
|
computers to the specified domain. Need to be either fully qualified
|
||||||
|
like ``user@domain.tld`` or simply ``user``
|
||||||
|
|
||||||
|
password (str): Password of the specified user
|
||||||
|
|
||||||
|
account_ou (str): The DN of the OU below which the account for this
|
||||||
|
computer should be created when joining the domain, e.g.
|
||||||
|
``ou=computers,ou=departm_432,dc=my-company,dc=com``
|
||||||
|
|
||||||
|
account_exists (bool): If set to ``True`` the computer will only join
|
||||||
|
the domain if the account already exists. If set to ``False`` the
|
||||||
|
computer account will be created if it does not exist, otherwise it
|
||||||
|
will use the existing account. Default is False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int:
|
||||||
|
|
||||||
|
:param domain:
|
||||||
|
:param username:
|
||||||
|
:param password:
|
||||||
|
:param account_ou:
|
||||||
|
:param account_exists:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
NETSETUP_JOIN_DOMAIN = 0x1 # pylint: disable=invalid-name
|
NETSETUP_JOIN_DOMAIN = 0x1 # pylint: disable=invalid-name
|
||||||
NETSETUP_ACCOUNT_CREATE = 0x2 # pylint: disable=invalid-name
|
NETSETUP_ACCOUNT_CREATE = 0x2 # pylint: disable=invalid-name
|
||||||
NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x20 # pylint: disable=invalid-name
|
NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x20 # pylint: disable=invalid-name
|
||||||
@ -670,23 +725,13 @@ def join_domain(domain,
|
|||||||
pythoncom.CoInitialize()
|
pythoncom.CoInitialize()
|
||||||
conn = wmi.WMI()
|
conn = wmi.WMI()
|
||||||
comp = conn.Win32_ComputerSystem()[0]
|
comp = conn.Win32_ComputerSystem()[0]
|
||||||
err = comp.JoinDomainOrWorkgroup(Name=domain,
|
|
||||||
Password=password,
|
|
||||||
UserName=username,
|
|
||||||
AccountOU=account_ou,
|
|
||||||
FJoinOptions=join_options)
|
|
||||||
|
|
||||||
# you have to do this because JoinDomainOrWorkgroup returns a strangely
|
# Return the results of the command as an error
|
||||||
# formatted value that looks like (0,)
|
# JoinDomainOrWorkgroup returns a strangely formatted value that looks like
|
||||||
if not err[0]:
|
# (0,) so return the first item
|
||||||
ret = {'Domain': domain,
|
return comp.JoinDomainOrWorkgroup(
|
||||||
'Restart': False}
|
Name=domain, Password=password, UserName=username, AccountOU=account_ou,
|
||||||
if restart:
|
FJoinOptions=join_options)[0]
|
||||||
ret['Restart'] = reboot()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
log.error(win32api.FormatMessage(err[0]).rstrip())
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def unjoin_domain(username=None,
|
def unjoin_domain(username=None,
|
||||||
@ -919,7 +964,11 @@ def set_system_date_time(years=None,
|
|||||||
seconds (int): Seconds digit: 0 - 59
|
seconds (int): Seconds digit: 0 - 59
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if successful, otherwise False.
|
bool: True if successful
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
CommandExecutionError: Raises an error if ``SetLocalTime`` function
|
||||||
|
fails
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
@ -972,12 +1021,15 @@ def set_system_date_time(years=None,
|
|||||||
system_time.wSecond = int(seconds)
|
system_time.wSecond = int(seconds)
|
||||||
system_time_ptr = ctypes.pointer(system_time)
|
system_time_ptr = ctypes.pointer(system_time)
|
||||||
succeeded = ctypes.windll.kernel32.SetLocalTime(system_time_ptr)
|
succeeded = ctypes.windll.kernel32.SetLocalTime(system_time_ptr)
|
||||||
return succeeded is not 0
|
if succeeded is not 0:
|
||||||
except OSError:
|
return True
|
||||||
|
else:
|
||||||
|
log.error('Failed to set local time')
|
||||||
|
raise CommandExecutionError(
|
||||||
|
win32api.FormatMessage(succeeded).rstrip())
|
||||||
|
except OSError as err:
|
||||||
log.error('Failed to set local time')
|
log.error('Failed to set local time')
|
||||||
return False
|
raise CommandExecutionError(err)
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def get_system_date():
|
def get_system_date():
|
||||||
|
@ -2,6 +2,49 @@
|
|||||||
'''
|
'''
|
||||||
Module for managing Windows Updates using the Windows Update Agent.
|
Module for managing Windows Updates using the Windows Update Agent.
|
||||||
|
|
||||||
|
List updates on the system using the following functions:
|
||||||
|
|
||||||
|
- :ref:`available`
|
||||||
|
- :ref:`list`
|
||||||
|
|
||||||
|
This is an easy way to find additional information about updates available to
|
||||||
|
to the system, such as the GUID, KB number, or description.
|
||||||
|
|
||||||
|
Once you have the GUID or a KB number for the update you can get information
|
||||||
|
about the update, download, install, or uninstall it using these functions:
|
||||||
|
|
||||||
|
- :ref:`get`
|
||||||
|
- :ref:`download`
|
||||||
|
- :ref:`install`
|
||||||
|
- :ref:`uninstall`
|
||||||
|
|
||||||
|
The get function expects a name in the form of a GUID, KB, or Title and should
|
||||||
|
return information about a single update. The other functions accept either a
|
||||||
|
single item or a list of items for downloading/installing/uninstalling a
|
||||||
|
specific list of items.
|
||||||
|
|
||||||
|
The :ref:`list` and :ref:`get` functions are utility functions. In addition to
|
||||||
|
returning information about updates they can also download and install updates
|
||||||
|
by setting ``download=True`` or ``install=True``. So, with :ref:`list` for
|
||||||
|
example, you could run the function with the filters you want to see what is
|
||||||
|
available. Then just add ``install=True`` to install everything on that list.
|
||||||
|
|
||||||
|
If you want to download, install, or uninstall specific updates, use
|
||||||
|
:ref:`download`, :ref:`install`, or :ref:`uninstall`. To update your system
|
||||||
|
with the latest updates use :ref:`list` and set ``install=True``
|
||||||
|
|
||||||
|
You can also adjust the Windows Update settings using the :ref:`set_wu_settings`
|
||||||
|
function. This function is only supported on the following operating systems:
|
||||||
|
|
||||||
|
- Windows Vista / Server 2008
|
||||||
|
- Windows 7 / Server 2008R2
|
||||||
|
- Windows 8 / Server 2012
|
||||||
|
- Windows 8.1 / Server 2012R2
|
||||||
|
|
||||||
|
As of Windows 10 and Windows Server 2016, the ability to modify the Windows
|
||||||
|
Update settings has been restricted. The settings can be modified in the Local
|
||||||
|
Group Policy using the ``lgpo`` module.
|
||||||
|
|
||||||
.. versionadded:: 2015.8.0
|
.. versionadded:: 2015.8.0
|
||||||
|
|
||||||
:depends:
|
:depends:
|
||||||
@ -54,36 +97,40 @@ def available(software=True,
|
|||||||
skip_mandatory=False,
|
skip_mandatory=False,
|
||||||
skip_reboot=False,
|
skip_reboot=False,
|
||||||
categories=None,
|
categories=None,
|
||||||
severities=None,
|
severities=None,):
|
||||||
):
|
|
||||||
'''
|
'''
|
||||||
.. versionadded:: 2017.7.0
|
.. versionadded:: 2017.7.0
|
||||||
|
|
||||||
List updates that match the passed criteria.
|
List updates that match the passed criteria. This allows for more filter
|
||||||
|
options than :func:`list`. Good for finding a specific GUID or KB.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
||||||
software (bool): Include software updates in the results (default is
|
software (bool):
|
||||||
True)
|
Include software updates in the results (default is True)
|
||||||
|
|
||||||
drivers (bool): Include driver updates in the results (default is False)
|
drivers (bool):
|
||||||
|
Include driver updates in the results (default is False)
|
||||||
|
|
||||||
summary (bool):
|
summary (bool):
|
||||||
- True: Return a summary of updates available for each category.
|
- True: Return a summary of updates available for each category.
|
||||||
- False (default): Return a detailed list of available updates.
|
- False (default): Return a detailed list of available updates.
|
||||||
|
|
||||||
skip_installed (bool): Skip updates that are already installed. Default
|
skip_installed (bool):
|
||||||
is False.
|
Skip updates that are already installed. Default is False.
|
||||||
|
|
||||||
skip_hidden (bool): Skip updates that have been hidden. Default is True.
|
skip_hidden (bool):
|
||||||
|
Skip updates that have been hidden. Default is True.
|
||||||
|
|
||||||
skip_mandatory (bool): Skip mandatory updates. Default is False.
|
skip_mandatory (bool):
|
||||||
|
Skip mandatory updates. Default is False.
|
||||||
|
|
||||||
skip_reboot (bool): Skip updates that require a reboot. Default is
|
skip_reboot (bool):
|
||||||
False.
|
Skip updates that require a reboot. Default is False.
|
||||||
|
|
||||||
categories (list): Specify the categories to list. Must be passed as a
|
categories (list):
|
||||||
list. All categories returned by default.
|
Specify the categories to list. Must be passed as a list. All
|
||||||
|
categories returned by default.
|
||||||
|
|
||||||
Categories include the following:
|
Categories include the following:
|
||||||
|
|
||||||
@ -101,8 +148,9 @@ def available(software=True,
|
|||||||
* Windows 8.1 and later drivers
|
* Windows 8.1 and later drivers
|
||||||
* Windows Defender
|
* Windows Defender
|
||||||
|
|
||||||
severities (list): Specify the severities to include. Must be passed as
|
severities (list):
|
||||||
a list. All severities returned by default.
|
Specify the severities to include. Must be passed as a list. All
|
||||||
|
severities returned by default.
|
||||||
|
|
||||||
Severities include the following:
|
Severities include the following:
|
||||||
|
|
||||||
@ -152,28 +200,30 @@ def available(software=True,
|
|||||||
salt '*' win_wua.available
|
salt '*' win_wua.available
|
||||||
|
|
||||||
# List all updates with categories of Critical Updates and Drivers
|
# List all updates with categories of Critical Updates and Drivers
|
||||||
salt '*' win_wua.available categories=['Critical Updates','Drivers']
|
salt '*' win_wua.available categories=["Critical Updates","Drivers"]
|
||||||
|
|
||||||
# List all Critical Security Updates
|
# List all Critical Security Updates
|
||||||
salt '*' win_wua.available categories=['Security Updates'] severities=['Critical']
|
salt '*' win_wua.available categories=["Security Updates"] severities=["Critical"]
|
||||||
|
|
||||||
# List all updates with a severity of Critical
|
# List all updates with a severity of Critical
|
||||||
salt '*' win_wua.available severities=['Critical']
|
salt '*' win_wua.available severities=["Critical"]
|
||||||
|
|
||||||
# A summary of all available updates
|
# A summary of all available updates
|
||||||
salt '*' win_wua.available summary=True
|
salt '*' win_wua.available summary=True
|
||||||
|
|
||||||
# A summary of all Feature Packs and Windows 8.1 Updates
|
# A summary of all Feature Packs and Windows 8.1 Updates
|
||||||
salt '*' win_wua.available categories=['Feature Packs','Windows 8.1'] summary=True
|
salt '*' win_wua.available categories=["Feature Packs","Windows 8.1"] summary=True
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Create a Windows Update Agent instance
|
# Create a Windows Update Agent instance
|
||||||
wua = salt.utils.win_update.WindowsUpdateAgent()
|
wua = salt.utils.win_update.WindowsUpdateAgent()
|
||||||
|
|
||||||
# Look for available
|
# Look for available
|
||||||
updates = wua.available(skip_hidden, skip_installed, skip_mandatory,
|
updates = wua.available(
|
||||||
skip_reboot, software, drivers, categories,
|
skip_hidden=skip_hidden, skip_installed=skip_installed,
|
||||||
severities)
|
skip_mandatory=skip_mandatory, skip_reboot=skip_reboot,
|
||||||
|
software=software, drivers=drivers, categories=categories,
|
||||||
|
severities=severities)
|
||||||
|
|
||||||
# Return results as Summary or Details
|
# Return results as Summary or Details
|
||||||
return updates.summary() if summary else updates.list()
|
return updates.summary() if summary else updates.list()
|
||||||
@ -183,23 +233,29 @@ def list_update(name, download=False, install=False):
|
|||||||
'''
|
'''
|
||||||
.. deprecated:: 2017.7.0
|
.. deprecated:: 2017.7.0
|
||||||
Use :func:`get` instead
|
Use :func:`get` instead
|
||||||
|
|
||||||
Returns details for all updates that match the search criteria
|
Returns details for all updates that match the search criteria
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name (str): The name of the update you're searching for. This can be the
|
|
||||||
GUID, a KB number, or any part of the name of the update. GUIDs and
|
|
||||||
KBs are preferred. Run ``list_updates`` to get the GUID for the update
|
|
||||||
you're looking for.
|
|
||||||
|
|
||||||
download (bool): Download the update returned by this function. Run this
|
name (str):
|
||||||
function first to see if the update exists, then set ``download=True``
|
The name of the update you're searching for. This can be the GUID, a
|
||||||
to download the update.
|
KB number, or any part of the name of the update. GUIDs and KBs are
|
||||||
|
preferred. Run ``list_updates`` to get the GUID for the update
|
||||||
|
you're looking for.
|
||||||
|
|
||||||
install (bool): Install the update returned by this function. Run this
|
download (bool):
|
||||||
function first to see if the update exists, then set ``install=True`` to
|
Download the update returned by this function. Run this function
|
||||||
install the update.
|
first to see if the update exists, then set ``download=True`` to
|
||||||
|
download the update.
|
||||||
|
|
||||||
|
install (bool):
|
||||||
|
Install the update returned by this function. Run this function
|
||||||
|
first to see if the update exists, then set ``install=True`` to
|
||||||
|
install the update.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
dict: Returns a dict containing a list of updates that match the name if
|
dict: Returns a dict containing a list of updates that match the name if
|
||||||
download and install are both set to False. Should usually be a single
|
download and install are both set to False. Should usually be a single
|
||||||
update, but can return multiple if a partial name is given.
|
update, but can return multiple if a partial name is given.
|
||||||
@ -258,23 +314,28 @@ def get(name, download=False, install=False):
|
|||||||
'''
|
'''
|
||||||
.. versionadded:: 2017.7.0
|
.. versionadded:: 2017.7.0
|
||||||
|
|
||||||
Returns details for all updates that match the search criteria
|
Returns details for the named update
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name (str): The name of the update you're searching for. This can be the
|
|
||||||
GUID, a KB number, or any part of the name of the update. GUIDs and
|
|
||||||
KBs are preferred. Run ``list`` to get the GUID for the update
|
|
||||||
you're looking for.
|
|
||||||
|
|
||||||
download (bool): Download the update returned by this function. Run this
|
name (str):
|
||||||
function first to see if the update exists, then set ``download=True``
|
The name of the update you're searching for. This can be the GUID, a
|
||||||
to download the update.
|
KB number, or any part of the name of the update. GUIDs and KBs are
|
||||||
|
preferred. Run ``list`` to get the GUID for the update you're
|
||||||
|
looking for.
|
||||||
|
|
||||||
install (bool): Install the update returned by this function. Run this
|
download (bool):
|
||||||
function first to see if the update exists, then set ``install=True`` to
|
Download the update returned by this function. Run this function
|
||||||
install the update.
|
first to see if the update exists, then set ``download=True`` to
|
||||||
|
download the update.
|
||||||
|
|
||||||
|
install (bool):
|
||||||
|
Install the update returned by this function. Run this function
|
||||||
|
first to see if the update exists, then set ``install=True`` to
|
||||||
|
install the update.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
dict: Returns a dict containing a list of updates that match the name if
|
dict: Returns a dict containing a list of updates that match the name if
|
||||||
download and install are both set to False. Should usually be a single
|
download and install are both set to False. Should usually be a single
|
||||||
update, but can return multiple if a partial name is given.
|
update, but can return multiple if a partial name is given.
|
||||||
@ -357,30 +418,35 @@ def list_updates(software=True,
|
|||||||
install is True the same list will be downloaded and/or installed.
|
install is True the same list will be downloaded and/or installed.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
software (bool): Include software updates in the results (default is
|
|
||||||
True)
|
|
||||||
|
|
||||||
drivers (bool): Include driver updates in the results (default is False)
|
software (bool):
|
||||||
|
Include software updates in the results (default is True)
|
||||||
|
|
||||||
|
drivers (bool):
|
||||||
|
Include driver updates in the results (default is False)
|
||||||
|
|
||||||
summary (bool):
|
summary (bool):
|
||||||
- True: Return a summary of updates available for each category.
|
- True: Return a summary of updates available for each category.
|
||||||
- False (default): Return a detailed list of available updates.
|
- False (default): Return a detailed list of available updates.
|
||||||
|
|
||||||
skip_installed (bool): Skip installed updates in the results (default is
|
skip_installed (bool):
|
||||||
False)
|
Skip installed updates in the results (default is False)
|
||||||
|
|
||||||
download (bool): (Overrides reporting functionality) Download the list
|
download (bool):
|
||||||
of updates returned by this function. Run this function first with
|
(Overrides reporting functionality) Download the list of updates
|
||||||
``download=False`` to see what will be downloaded, then set
|
returned by this function. Run this function first with
|
||||||
``download=True`` to download the updates.
|
``download=False`` to see what will be downloaded, then set
|
||||||
|
``download=True`` to download the updates.
|
||||||
|
|
||||||
install (bool): (Overrides reporting functionality) Install the list of
|
install (bool):
|
||||||
updates returned by this function. Run this function first with
|
(Overrides reporting functionality) Install the list of updates
|
||||||
``install=False`` to see what will be installed, then set
|
returned by this function. Run this function first with
|
||||||
``install=True`` to install the updates.
|
``install=False`` to see what will be installed, then set
|
||||||
|
``install=True`` to install the updates.
|
||||||
|
|
||||||
categories (list): Specify the categories to list. Must be passed as a
|
categories (list):
|
||||||
list. All categories returned by default.
|
Specify the categories to list. Must be passed as a list. All
|
||||||
|
categories returned by default.
|
||||||
|
|
||||||
Categories include the following:
|
Categories include the following:
|
||||||
|
|
||||||
@ -398,8 +464,9 @@ def list_updates(software=True,
|
|||||||
* Windows 8.1 and later drivers
|
* Windows 8.1 and later drivers
|
||||||
* Windows Defender
|
* Windows Defender
|
||||||
|
|
||||||
severities (list): Specify the severities to include. Must be passed as
|
severities (list):
|
||||||
a list. All severities returned by default.
|
Specify the severities to include. Must be passed as a list. All
|
||||||
|
severities returned by default.
|
||||||
|
|
||||||
Severities include the following:
|
Severities include the following:
|
||||||
|
|
||||||
@ -486,30 +553,35 @@ def list(software=True,
|
|||||||
install is True the same list will be downloaded and/or installed.
|
install is True the same list will be downloaded and/or installed.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
software (bool): Include software updates in the results (default is
|
|
||||||
True)
|
|
||||||
|
|
||||||
drivers (bool): Include driver updates in the results (default is False)
|
software (bool):
|
||||||
|
Include software updates in the results (default is True)
|
||||||
|
|
||||||
|
drivers (bool):
|
||||||
|
Include driver updates in the results (default is False)
|
||||||
|
|
||||||
summary (bool):
|
summary (bool):
|
||||||
- True: Return a summary of updates available for each category.
|
- True: Return a summary of updates available for each category.
|
||||||
- False (default): Return a detailed list of available updates.
|
- False (default): Return a detailed list of available updates.
|
||||||
|
|
||||||
skip_installed (bool): Skip installed updates in the results (default is
|
skip_installed (bool):
|
||||||
False)
|
Skip installed updates in the results (default is False)
|
||||||
|
|
||||||
download (bool): (Overrides reporting functionality) Download the list
|
download (bool):
|
||||||
of updates returned by this function. Run this function first with
|
(Overrides reporting functionality) Download the list of updates
|
||||||
``download=False`` to see what will be downloaded, then set
|
returned by this function. Run this function first with
|
||||||
``download=True`` to download the updates.
|
``download=False`` to see what will be downloaded, then set
|
||||||
|
``download=True`` to download the updates.
|
||||||
|
|
||||||
install (bool): (Overrides reporting functionality) Install the list of
|
install (bool):
|
||||||
updates returned by this function. Run this function first with
|
(Overrides reporting functionality) Install the list of updates
|
||||||
``install=False`` to see what will be installed, then set
|
returned by this function. Run this function first with
|
||||||
``install=True`` to install the updates.
|
``install=False`` to see what will be installed, then set
|
||||||
|
``install=True`` to install the updates.
|
||||||
|
|
||||||
categories (list): Specify the categories to list. Must be passed as a
|
categories (list):
|
||||||
list. All categories returned by default.
|
Specify the categories to list. Must be passed as a list. All
|
||||||
|
categories returned by default.
|
||||||
|
|
||||||
Categories include the following:
|
Categories include the following:
|
||||||
|
|
||||||
@ -527,8 +599,9 @@ def list(software=True,
|
|||||||
* Windows 8.1 and later drivers
|
* Windows 8.1 and later drivers
|
||||||
* Windows Defender
|
* Windows Defender
|
||||||
|
|
||||||
severities (list): Specify the severities to include. Must be passed as
|
severities (list):
|
||||||
a list. All severities returned by default.
|
Specify the severities to include. Must be passed as a list. All
|
||||||
|
severities returned by default.
|
||||||
|
|
||||||
Severities include the following:
|
Severities include the following:
|
||||||
|
|
||||||
@ -575,22 +648,22 @@ def list(software=True,
|
|||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
# Normal Usage (list all software updates)
|
# Normal Usage (list all software updates)
|
||||||
salt '*' win_wua.list_updates
|
salt '*' win_wua.list
|
||||||
|
|
||||||
# List all updates with categories of Critical Updates and Drivers
|
# List all updates with categories of Critical Updates and Drivers
|
||||||
salt '*' win_wua.list_updates categories=['Critical Updates','Drivers']
|
salt '*' win_wua.list categories=['Critical Updates','Drivers']
|
||||||
|
|
||||||
# List all Critical Security Updates
|
# List all Critical Security Updates
|
||||||
salt '*' win_wua.list_updates categories=['Security Updates'] severities=['Critical']
|
salt '*' win_wua.list categories=['Security Updates'] severities=['Critical']
|
||||||
|
|
||||||
# List all updates with a severity of Critical
|
# List all updates with a severity of Critical
|
||||||
salt '*' win_wua.list_updates severities=['Critical']
|
salt '*' win_wua.list severities=['Critical']
|
||||||
|
|
||||||
# A summary of all available updates
|
# A summary of all available updates
|
||||||
salt '*' win_wua.list_updates summary=True
|
salt '*' win_wua.list summary=True
|
||||||
|
|
||||||
# A summary of all Feature Packs and Windows 8.1 Updates
|
# A summary of all Feature Packs and Windows 8.1 Updates
|
||||||
salt '*' win_wua.list_updates categories=['Feature Packs','Windows 8.1'] summary=True
|
salt '*' win_wua.list categories=['Feature Packs','Windows 8.1'] summary=True
|
||||||
'''
|
'''
|
||||||
# Create a Windows Update Agent instance
|
# Create a Windows Update Agent instance
|
||||||
wua = salt.utils.win_update.WindowsUpdateAgent()
|
wua = salt.utils.win_update.WindowsUpdateAgent()
|
||||||
@ -604,11 +677,11 @@ def list(software=True,
|
|||||||
|
|
||||||
# Download
|
# Download
|
||||||
if download or install:
|
if download or install:
|
||||||
ret['Download'] = wua.download(updates.updates)
|
ret['Download'] = wua.download(updates)
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
if install:
|
if install:
|
||||||
ret['Install'] = wua.install(updates.updates)
|
ret['Install'] = wua.install(updates)
|
||||||
|
|
||||||
if not ret:
|
if not ret:
|
||||||
return updates.summary() if summary else updates.list()
|
return updates.summary() if summary else updates.list()
|
||||||
@ -625,13 +698,16 @@ def download_update(name):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
||||||
name (str): The name of the update to download. This can be a GUID, a KB
|
name (str):
|
||||||
number, or any part of the name. To ensure a single item is matched the
|
The name of the update to download. This can be a GUID, a KB number,
|
||||||
GUID is preferred.
|
or any part of the name. To ensure a single item is matched the GUID
|
||||||
|
is preferred.
|
||||||
|
|
||||||
.. note:: If more than one result is returned an error will be raised.
|
.. note::
|
||||||
|
If more than one result is returned an error will be raised.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
dict: A dictionary containing the results of the download
|
dict: A dictionary containing the results of the download
|
||||||
|
|
||||||
CLI Examples:
|
CLI Examples:
|
||||||
@ -641,7 +717,6 @@ def download_update(name):
|
|||||||
salt '*' win_wua.download_update 12345678-abcd-1234-abcd-1234567890ab
|
salt '*' win_wua.download_update 12345678-abcd-1234-abcd-1234567890ab
|
||||||
|
|
||||||
salt '*' win_wua.download_update KB12312321
|
salt '*' win_wua.download_update KB12312321
|
||||||
|
|
||||||
'''
|
'''
|
||||||
salt.utils.warn_until(
|
salt.utils.warn_until(
|
||||||
'Fluorine',
|
'Fluorine',
|
||||||
@ -660,8 +735,9 @@ def download_updates(names):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
||||||
names (list): A list of updates to download. This can be any combination
|
names (list):
|
||||||
of GUIDs, KB numbers, or names. GUIDs or KBs are preferred.
|
A list of updates to download. This can be any combination of GUIDs,
|
||||||
|
KB numbers, or names. GUIDs or KBs are preferred.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
@ -672,7 +748,7 @@ def download_updates(names):
|
|||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
# Normal Usage
|
# Normal Usage
|
||||||
salt '*' win_wua.download guid=['12345678-abcd-1234-abcd-1234567890ab', 'KB2131233']
|
salt '*' win_wua.download_updates guid=['12345678-abcd-1234-abcd-1234567890ab', 'KB2131233']
|
||||||
'''
|
'''
|
||||||
salt.utils.warn_until(
|
salt.utils.warn_until(
|
||||||
'Fluorine',
|
'Fluorine',
|
||||||
@ -690,9 +766,14 @@ def download(names):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
||||||
names (str, list): A single update or a list of updates to download.
|
names (str, list):
|
||||||
This can be any combination of GUIDs, KB numbers, or names. GUIDs or KBs
|
A single update or a list of updates to download. This can be any
|
||||||
are preferred.
|
combination of GUIDs, KB numbers, or names. GUIDs or KBs are
|
||||||
|
preferred.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
An error will be raised if there are more results than there are items
|
||||||
|
in the names parameter
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
@ -703,7 +784,7 @@ def download(names):
|
|||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
# Normal Usage
|
# Normal Usage
|
||||||
salt '*' win_wua.download guid=['12345678-abcd-1234-abcd-1234567890ab', 'KB2131233']
|
salt '*' win_wua.download names=['12345678-abcd-1234-abcd-1234567890ab', 'KB2131233']
|
||||||
'''
|
'''
|
||||||
# Create a Windows Update Agent instance
|
# Create a Windows Update Agent instance
|
||||||
wua = salt.utils.win_update.WindowsUpdateAgent()
|
wua = salt.utils.win_update.WindowsUpdateAgent()
|
||||||
@ -714,6 +795,13 @@ def download(names):
|
|||||||
if updates.count() == 0:
|
if updates.count() == 0:
|
||||||
raise CommandExecutionError('No updates found')
|
raise CommandExecutionError('No updates found')
|
||||||
|
|
||||||
|
# Make sure it's a list so count comparison is correct
|
||||||
|
if isinstance(names, six.string_types):
|
||||||
|
names = [names]
|
||||||
|
|
||||||
|
if isinstance(names, six.integer_types):
|
||||||
|
names = [str(names)]
|
||||||
|
|
||||||
if updates.count() > len(names):
|
if updates.count() > len(names):
|
||||||
raise CommandExecutionError('Multiple updates found, names need to be '
|
raise CommandExecutionError('Multiple updates found, names need to be '
|
||||||
'more specific')
|
'more specific')
|
||||||
@ -734,10 +822,12 @@ def install_update(name):
|
|||||||
number, or any part of the name. To ensure a single item is matched the
|
number, or any part of the name. To ensure a single item is matched the
|
||||||
GUID is preferred.
|
GUID is preferred.
|
||||||
|
|
||||||
.. note:: If no results or more than one result is returned an error
|
.. note::
|
||||||
will be raised.
|
If no results or more than one result is returned an error will be
|
||||||
|
raised.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
dict: A dictionary containing the results of the install
|
dict: A dictionary containing the results of the install
|
||||||
|
|
||||||
CLI Examples:
|
CLI Examples:
|
||||||
@ -795,9 +885,14 @@ def install(names):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
||||||
names (str, list): A single update or a list of updates to install.
|
names (str, list):
|
||||||
This can be any combination of GUIDs, KB numbers, or names. GUIDs or KBs
|
A single update or a list of updates to install. This can be any
|
||||||
are preferred.
|
combination of GUIDs, KB numbers, or names. GUIDs or KBs are
|
||||||
|
preferred.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
An error will be raised if there are more results than there are items
|
||||||
|
in the names parameter
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
@ -808,7 +903,7 @@ def install(names):
|
|||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
# Normal Usage
|
# Normal Usage
|
||||||
salt '*' win_wua.install_updates guid=['12345678-abcd-1234-abcd-1234567890ab', 'KB12323211']
|
salt '*' win_wua.install KB12323211
|
||||||
'''
|
'''
|
||||||
# Create a Windows Update Agent instance
|
# Create a Windows Update Agent instance
|
||||||
wua = salt.utils.win_update.WindowsUpdateAgent()
|
wua = salt.utils.win_update.WindowsUpdateAgent()
|
||||||
@ -819,6 +914,13 @@ def install(names):
|
|||||||
if updates.count() == 0:
|
if updates.count() == 0:
|
||||||
raise CommandExecutionError('No updates found')
|
raise CommandExecutionError('No updates found')
|
||||||
|
|
||||||
|
# Make sure it's a list so count comparison is correct
|
||||||
|
if isinstance(names, six.string_types):
|
||||||
|
names = [names]
|
||||||
|
|
||||||
|
if isinstance(names, six.integer_types):
|
||||||
|
names = [str(names)]
|
||||||
|
|
||||||
if updates.count() > len(names):
|
if updates.count() > len(names):
|
||||||
raise CommandExecutionError('Multiple updates found, names need to be '
|
raise CommandExecutionError('Multiple updates found, names need to be '
|
||||||
'more specific')
|
'more specific')
|
||||||
@ -834,9 +936,10 @@ def uninstall(names):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
||||||
names (str, list): A single update or a list of updates to uninstall.
|
names (str, list):
|
||||||
This can be any combination of GUIDs, KB numbers, or names. GUIDs or KBs
|
A single update or a list of updates to uninstall. This can be any
|
||||||
are preferred.
|
combination of GUIDs, KB numbers, or names. GUIDs or KBs are
|
||||||
|
preferred.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
@ -875,33 +978,50 @@ def set_wu_settings(level=None,
|
|||||||
Change Windows Update settings. If no parameters are passed, the current
|
Change Windows Update settings. If no parameters are passed, the current
|
||||||
value will be returned.
|
value will be returned.
|
||||||
|
|
||||||
:param int level:
|
Supported:
|
||||||
Number from 1 to 4 indicating the update level:
|
- Windows Vista / Server 2008
|
||||||
|
- Windows 7 / Server 2008R2
|
||||||
|
- Windows 8 / Server 2012
|
||||||
|
- Windows 8.1 / Server 2012R2
|
||||||
|
|
||||||
|
.. note:
|
||||||
|
Microsoft began using the Unified Update Platform (UUP) starting with
|
||||||
|
Windows 10 / Server 2016. The Windows Update settings have changed and
|
||||||
|
the ability to 'Save' Windows Update settings has been removed. Windows
|
||||||
|
Update settings are read-only. See MSDN documentation:
|
||||||
|
https://msdn.microsoft.com/en-us/library/aa385829(v=vs.85).aspx
|
||||||
|
|
||||||
|
Args:
|
||||||
|
|
||||||
|
level (int):
|
||||||
|
Number from 1 to 4 indicating the update level:
|
||||||
|
|
||||||
1. Never check for updates
|
1. Never check for updates
|
||||||
2. Check for updates but let me choose whether to download and install them
|
2. Check for updates but let me choose whether to download and install them
|
||||||
3. Download updates but let me choose whether to install them
|
3. Download updates but let me choose whether to install them
|
||||||
4. Install updates automatically
|
4. Install updates automatically
|
||||||
:param bool recommended:
|
|
||||||
Boolean value that indicates whether to include optional or recommended
|
|
||||||
updates when a search for updates and installation of updates is
|
|
||||||
performed.
|
|
||||||
|
|
||||||
:param bool featured:
|
recommended (bool):
|
||||||
Boolean value that indicates whether to display notifications for
|
Boolean value that indicates whether to include optional or
|
||||||
featured updates.
|
recommended updates when a search for updates and installation of
|
||||||
|
updates is performed.
|
||||||
|
|
||||||
:param bool elevated:
|
featured (bool):
|
||||||
Boolean value that indicates whether non-administrators can perform some
|
Boolean value that indicates whether to display notifications for
|
||||||
update-related actions without administrator approval.
|
featured updates.
|
||||||
|
|
||||||
:param bool msupdate:
|
elevated (bool):
|
||||||
Boolean value that indicates whether to turn on Microsoft Update for
|
Boolean value that indicates whether non-administrators can perform
|
||||||
other Microsoft products
|
some update-related actions without administrator approval.
|
||||||
|
|
||||||
|
msupdate (bool):
|
||||||
|
Boolean value that indicates whether to turn on Microsoft Update for
|
||||||
|
other Microsoft products
|
||||||
|
|
||||||
|
day (str):
|
||||||
|
Days of the week on which Automatic Updates installs or uninstalls
|
||||||
|
updates. Accepted values:
|
||||||
|
|
||||||
:param str day:
|
|
||||||
Days of the week on which Automatic Updates installs or uninstalls
|
|
||||||
updates.
|
|
||||||
Accepted values:
|
|
||||||
- Everyday
|
- Everyday
|
||||||
- Monday
|
- Monday
|
||||||
- Tuesday
|
- Tuesday
|
||||||
@ -910,21 +1030,43 @@ def set_wu_settings(level=None,
|
|||||||
- Friday
|
- Friday
|
||||||
- Saturday
|
- Saturday
|
||||||
|
|
||||||
:param str time:
|
time (str):
|
||||||
Time at which Automatic Updates installs or uninstalls updates. Must be
|
Time at which Automatic Updates installs or uninstalls updates. Must
|
||||||
in the ##:## 24hr format, eg. 3:00 PM would be 15:00
|
be in the ##:## 24hr format, eg. 3:00 PM would be 15:00. Must be in
|
||||||
|
1 hour increments.
|
||||||
|
|
||||||
:return: Returns a dictionary containing the results.
|
Returns:
|
||||||
|
|
||||||
|
dict: Returns a dictionary containing the results.
|
||||||
|
|
||||||
CLI Examples:
|
CLI Examples:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt '*' win_wua.set_wu_settings level=4 recommended=True featured=False
|
salt '*' win_wua.set_wu_settings level=4 recommended=True featured=False
|
||||||
|
|
||||||
'''
|
'''
|
||||||
ret = {}
|
# The AutomaticUpdateSettings.Save() method used in this function does not
|
||||||
ret['Success'] = True
|
# work on Windows 10 / Server 2016. It is called in throughout this function
|
||||||
|
# like this:
|
||||||
|
#
|
||||||
|
# obj_au = win32com.client.Dispatch('Microsoft.Update.AutoUpdate')
|
||||||
|
# obj_au_settings = obj_au.Settings
|
||||||
|
# obj_au_settings.Save()
|
||||||
|
#
|
||||||
|
# The `Save()` method reports success but doesn't actually change anything.
|
||||||
|
# Windows Update settings are read-only in Windows 10 / Server 2016. There's
|
||||||
|
# a little blurb on MSDN that mentions this, but gives no alternative for
|
||||||
|
# changing these settings in Windows 10 / Server 2016.
|
||||||
|
#
|
||||||
|
# https://msdn.microsoft.com/en-us/library/aa385829(v=vs.85).aspx
|
||||||
|
#
|
||||||
|
# Apparently the Windows Update framework in Windows Vista - Windows 8.1 has
|
||||||
|
# been changed quite a bit in Windows 10 / Server 2016. It is now called the
|
||||||
|
# Unified Update Platform (UUP). I haven't found an API or a Powershell
|
||||||
|
# commandlet for working with the the UUP. Perhaps there will be something
|
||||||
|
# forthcoming. The `win_lgpo` module might be an option for changing the
|
||||||
|
# Windows Update settings using local group policy.
|
||||||
|
ret = {'Success': True}
|
||||||
|
|
||||||
# Initialize the PyCom system
|
# Initialize the PyCom system
|
||||||
pythoncom.CoInitialize()
|
pythoncom.CoInitialize()
|
||||||
@ -1076,30 +1218,31 @@ def get_wu_settings():
|
|||||||
Boolean value that indicates whether to display notifications for
|
Boolean value that indicates whether to display notifications for
|
||||||
featured updates.
|
featured updates.
|
||||||
Group Policy Required (Read-only):
|
Group Policy Required (Read-only):
|
||||||
Boolean value that indicates whether Group Policy requires the Automatic
|
Boolean value that indicates whether Group Policy requires the
|
||||||
Updates service.
|
Automatic Updates service.
|
||||||
Microsoft Update:
|
Microsoft Update:
|
||||||
Boolean value that indicates whether to turn on Microsoft Update for
|
Boolean value that indicates whether to turn on Microsoft Update for
|
||||||
other Microsoft Products
|
other Microsoft Products
|
||||||
Needs Reboot:
|
Needs Reboot:
|
||||||
Boolean value that indicates whether the machine is in a reboot pending
|
Boolean value that indicates whether the machine is in a reboot
|
||||||
state.
|
pending state.
|
||||||
Non Admins Elevated:
|
Non Admins Elevated:
|
||||||
Boolean value that indicates whether non-administrators can perform some
|
Boolean value that indicates whether non-administrators can perform
|
||||||
update-related actions without administrator approval.
|
some update-related actions without administrator approval.
|
||||||
Notification Level:
|
Notification Level:
|
||||||
Number 1 to 4 indicating the update level:
|
Number 1 to 4 indicating the update level:
|
||||||
1. Never check for updates
|
1. Never check for updates
|
||||||
2. Check for updates but let me choose whether to download and install them
|
2. Check for updates but let me choose whether to download and
|
||||||
|
install them
|
||||||
3. Download updates but let me choose whether to install them
|
3. Download updates but let me choose whether to install them
|
||||||
4. Install updates automatically
|
4. Install updates automatically
|
||||||
Read Only (Read-only):
|
Read Only (Read-only):
|
||||||
Boolean value that indicates whether the Automatic Update
|
Boolean value that indicates whether the Automatic Update
|
||||||
settings are read-only.
|
settings are read-only.
|
||||||
Recommended Updates:
|
Recommended Updates:
|
||||||
Boolean value that indicates whether to include optional or recommended
|
Boolean value that indicates whether to include optional or
|
||||||
updates when a search for updates and installation of updates is
|
recommended updates when a search for updates and installation of
|
||||||
performed.
|
updates is performed.
|
||||||
Scheduled Day:
|
Scheduled Day:
|
||||||
Days of the week on which Automatic Updates installs or uninstalls
|
Days of the week on which Automatic Updates installs or uninstalls
|
||||||
updates.
|
updates.
|
||||||
@ -1182,13 +1325,12 @@ def get_needs_reboot():
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
bool: True if the system requires a reboot, False if not
|
bool: True if the system requires a reboot, otherwise False
|
||||||
|
|
||||||
CLI Examples:
|
CLI Examples:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt '*' win_wua.get_needs_reboot
|
salt '*' win_wua.get_needs_reboot
|
||||||
|
|
||||||
'''
|
'''
|
||||||
return salt.utils.win_update.needs_reboot()
|
return salt.utils.win_update.needs_reboot()
|
||||||
|
@ -1373,10 +1373,19 @@ def create_certificate(
|
|||||||
['listen_in', 'preqrequired', '__prerequired__']:
|
['listen_in', 'preqrequired', '__prerequired__']:
|
||||||
kwargs.pop(ignore, None)
|
kwargs.pop(ignore, None)
|
||||||
|
|
||||||
cert_txt = __salt__['publish.publish'](
|
certs = __salt__['publish.publish'](
|
||||||
tgt=ca_server,
|
tgt=ca_server,
|
||||||
fun='x509.sign_remote_certificate',
|
fun='x509.sign_remote_certificate',
|
||||||
arg=str(kwargs))[ca_server]
|
arg=str(kwargs))
|
||||||
|
|
||||||
|
if not any(certs):
|
||||||
|
raise salt.exceptions.SaltInvocationError(
|
||||||
|
'ca_server did not respond'
|
||||||
|
' salt master must permit peers to'
|
||||||
|
' call the sign_remote_certificate function.')
|
||||||
|
|
||||||
|
cert_txt = certs[ca_server]
|
||||||
|
|
||||||
if path:
|
if path:
|
||||||
return write_pem(
|
return write_pem(
|
||||||
text=cert_txt,
|
text=cert_txt,
|
||||||
|
@ -181,7 +181,16 @@ def _check_versionlock():
|
|||||||
Ensure that the appropriate versionlock plugin is present
|
Ensure that the appropriate versionlock plugin is present
|
||||||
'''
|
'''
|
||||||
if _yum() == 'dnf':
|
if _yum() == 'dnf':
|
||||||
vl_plugin = 'python-dnf-plugins-extras-versionlock'
|
if int(__grains__.get('osmajorrelease')) >= 26:
|
||||||
|
if six.PY3:
|
||||||
|
vl_plugin = 'python3-dnf-plugin-versionlock'
|
||||||
|
else:
|
||||||
|
vl_plugin = 'python2-dnf-plugin-versionlock'
|
||||||
|
else:
|
||||||
|
if six.PY3:
|
||||||
|
vl_plugin = 'python3-dnf-plugins-extras-versionlock'
|
||||||
|
else:
|
||||||
|
vl_plugin = 'python-dnf-plugins-extras-versionlock'
|
||||||
else:
|
else:
|
||||||
vl_plugin = 'yum-versionlock' \
|
vl_plugin = 'yum-versionlock' \
|
||||||
if __grains__.get('osmajorrelease') == '5' \
|
if __grains__.get('osmajorrelease') == '5' \
|
||||||
@ -1034,6 +1043,11 @@ def refresh_db(**kwargs):
|
|||||||
|
|
||||||
clean_cmd = [_yum(), '--quiet', 'clean', 'expire-cache']
|
clean_cmd = [_yum(), '--quiet', 'clean', 'expire-cache']
|
||||||
update_cmd = [_yum(), '--quiet', 'check-update']
|
update_cmd = [_yum(), '--quiet', 'check-update']
|
||||||
|
|
||||||
|
if __grains__.get('os_family') == 'RedHat' and __grains__.get('osmajorrelease') == '7':
|
||||||
|
# This feature is disable because it is not used by Salt and lasts a lot with using large repo like EPEL
|
||||||
|
update_cmd.append('--setopt=autocheck_running_kernel=false')
|
||||||
|
|
||||||
for args in (repo_arg, exclude_arg, branch_arg):
|
for args in (repo_arg, exclude_arg, branch_arg):
|
||||||
if args:
|
if args:
|
||||||
clean_cmd.extend(args)
|
clean_cmd.extend(args)
|
||||||
|
@ -483,13 +483,22 @@ import signal
|
|||||||
import tarfile
|
import tarfile
|
||||||
from multiprocessing import Process, Pipe
|
from multiprocessing import Process, Pipe
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Import third-party libs
|
# Import third-party libs
|
||||||
# pylint: disable=import-error
|
# pylint: disable=import-error, 3rd-party-module-not-gated
|
||||||
import cherrypy # pylint: disable=3rd-party-module-not-gated
|
import cherrypy
|
||||||
|
try:
|
||||||
|
from cherrypy.lib import cpstats
|
||||||
|
except ImportError:
|
||||||
|
cpstats = None
|
||||||
|
logger.warn('Import of cherrypy.cpstats failed. '
|
||||||
|
'Possible upstream bug: '
|
||||||
|
'https://github.com/cherrypy/cherrypy/issues/1444')
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
import salt.ext.six as six
|
import salt.ext.six as six
|
||||||
# pylint: enable=import-error
|
# pylint: enable=import-error, 3rd-party-module-not-gated
|
||||||
|
|
||||||
|
|
||||||
# Import Salt libs
|
# Import Salt libs
|
||||||
import salt
|
import salt
|
||||||
@ -500,8 +509,6 @@ import salt.utils.event
|
|||||||
# Import salt-api libs
|
# Import salt-api libs
|
||||||
import salt.netapi
|
import salt.netapi
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# Imports related to websocket
|
# Imports related to websocket
|
||||||
try:
|
try:
|
||||||
from .tools import websockets
|
from .tools import websockets
|
||||||
@ -2616,13 +2623,6 @@ class Stats(object):
|
|||||||
:status 406: |406|
|
:status 406: |406|
|
||||||
'''
|
'''
|
||||||
if hasattr(logging, 'statistics'):
|
if hasattr(logging, 'statistics'):
|
||||||
# Late import
|
|
||||||
try:
|
|
||||||
from cherrypy.lib import cpstats
|
|
||||||
except ImportError:
|
|
||||||
logger.error('Import of cherrypy.cpstats failed. Possible '
|
|
||||||
'upstream bug here: https://github.com/cherrypy/cherrypy/issues/1444')
|
|
||||||
return {}
|
|
||||||
return cpstats.extrapolate_statistics(logging.statistics)
|
return cpstats.extrapolate_statistics(logging.statistics)
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
@ -2742,13 +2742,14 @@ class API(object):
|
|||||||
'tools.trailing_slash.on': True,
|
'tools.trailing_slash.on': True,
|
||||||
'tools.gzip.on': True,
|
'tools.gzip.on': True,
|
||||||
|
|
||||||
'tools.cpstats.on': self.apiopts.get('collect_stats', False),
|
|
||||||
|
|
||||||
'tools.html_override.on': True,
|
'tools.html_override.on': True,
|
||||||
'tools.cors_tool.on': True,
|
'tools.cors_tool.on': True,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cpstats and self.apiopts.get('collect_stats', False):
|
||||||
|
conf['/']['tools.cpstats.on'] = True
|
||||||
|
|
||||||
if 'favicon' in self.apiopts:
|
if 'favicon' in self.apiopts:
|
||||||
conf['/favicon.ico'] = {
|
conf['/favicon.ico'] = {
|
||||||
'tools.staticfile.on': True,
|
'tools.staticfile.on': True,
|
||||||
|
@ -523,8 +523,7 @@ class BaseSaltAPIHandler(tornado.web.RequestHandler, SaltClientsMixIn): # pylin
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# Use cgi.parse_header to correctly separate parameters from value
|
# Use cgi.parse_header to correctly separate parameters from value
|
||||||
header = cgi.parse_header(self.request.headers['Content-Type'])
|
value, parameters = cgi.parse_header(self.request.headers['Content-Type'])
|
||||||
value, parameters = header
|
|
||||||
return ct_in_map[value](tornado.escape.native_str(data))
|
return ct_in_map[value](tornado.escape.native_str(data))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.send_error(406)
|
self.send_error(406)
|
||||||
@ -538,7 +537,7 @@ class BaseSaltAPIHandler(tornado.web.RequestHandler, SaltClientsMixIn): # pylin
|
|||||||
if not self.request.body:
|
if not self.request.body:
|
||||||
return
|
return
|
||||||
data = self.deserialize(self.request.body)
|
data = self.deserialize(self.request.body)
|
||||||
self.raw_data = copy(data)
|
self.request_payload = copy(data)
|
||||||
|
|
||||||
if data and 'arg' in data and not isinstance(data['arg'], list):
|
if data and 'arg' in data and not isinstance(data['arg'], list):
|
||||||
data['arg'] = [data['arg']]
|
data['arg'] = [data['arg']]
|
||||||
@ -696,15 +695,13 @@ class SaltAuthHandler(BaseSaltAPIHandler): # pylint: disable=W0223
|
|||||||
}}
|
}}
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
request_payload = self.deserialize(self.request.body)
|
if not isinstance(self.request_payload, dict):
|
||||||
|
|
||||||
if not isinstance(request_payload, dict):
|
|
||||||
self.send_error(400)
|
self.send_error(400)
|
||||||
return
|
return
|
||||||
|
|
||||||
creds = {'username': request_payload['username'],
|
creds = {'username': self.request_payload['username'],
|
||||||
'password': request_payload['password'],
|
'password': self.request_payload['password'],
|
||||||
'eauth': request_payload['eauth'],
|
'eauth': self.request_payload['eauth'],
|
||||||
}
|
}
|
||||||
# if any of the args are missing, its a bad request
|
# if any of the args are missing, its a bad request
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -1641,7 +1638,7 @@ class WebhookSaltAPIHandler(SaltAPIHandler): # pylint: disable=W0223
|
|||||||
value = value[0]
|
value = value[0]
|
||||||
arguments[argname] = value
|
arguments[argname] = value
|
||||||
ret = self.event.fire_event({
|
ret = self.event.fire_event({
|
||||||
'post': self.raw_data,
|
'post': self.request_payload,
|
||||||
'get': arguments,
|
'get': arguments,
|
||||||
# In Tornado >= v4.0.3, the headers come
|
# In Tornado >= v4.0.3, the headers come
|
||||||
# back as an HTTPHeaders instance, which
|
# back as an HTTPHeaders instance, which
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user