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.
|
||||
#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
|
||||
# pki_dir/minion_autosign/keyid is automatically accepted. Expired autosign keys
|
||||
# are removed when the master checks the minion_autosign directory.
|
||||
@ -959,6 +962,21 @@
|
||||
#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 #####
|
||||
##########################################
|
||||
# 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!
|
||||
#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
|
||||
# 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
|
||||
@ -661,6 +664,21 @@
|
||||
# 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 #####
|
||||
###########################################
|
||||
# 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'
|
||||
|
||||
version = salt.version.__version__
|
||||
latest_release = '2016.11.6' # latest release
|
||||
previous_release = '2016.3.6' # latest release from previous branch
|
||||
previous_release_dir = '2016.3' # path on web server for previous branch
|
||||
latest_release = '2017.7.1' # latest release
|
||||
previous_release = '2016.11.7' # latest release from previous branch
|
||||
previous_release_dir = '2016.11' # path on web server for previous branch
|
||||
next_release = '' # next release
|
||||
next_release_dir = '' # path on web server for next release branch
|
||||
|
||||
@ -258,8 +258,8 @@ if on_saltstack:
|
||||
copyright = time.strftime("%Y")
|
||||
|
||||
# < --- START do not merge these settings to other branches START ---> #
|
||||
build_type = 'develop' # latest, previous, develop, next
|
||||
release = version # version, latest_release, previous_release
|
||||
build_type = 'latest' # latest, previous, develop, next
|
||||
release = latest_release # version, latest_release, previous_release
|
||||
# < --- END do not merge these settings to other branches END ---> #
|
||||
|
||||
# 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.
|
||||
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
|
||||
|
||||
@ -337,8 +357,8 @@ The following example works on both UNIX-like and Windows operating systems:
|
||||
- pkg: Upgrade Salt Minion
|
||||
|
||||
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
|
||||
supported:
|
||||
Salt (before ``2016.3.0``) on UNIX-like operating systems, where executing
|
||||
commands in the background is not supported:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
|
@ -33,6 +33,10 @@ Output Options
|
||||
|
||||
Write the output to the specified file.
|
||||
|
||||
.. option:: --out-file-append, --output-file-append
|
||||
|
||||
Append the output to the specified file.
|
||||
|
||||
.. option:: --no-color
|
||||
|
||||
Disable all colored output
|
||||
@ -46,3 +50,14 @@ Output Options
|
||||
|
||||
``green`` denotes success, ``red`` denotes failure, ``blue`` denotes
|
||||
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
|
||||
|
||||
.. 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
|
||||
|
||||
``ret_port``
|
||||
@ -946,6 +888,74 @@ to socket concurrently.
|
||||
|
||||
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:
|
||||
|
||||
@ -1192,6 +1202,19 @@ public keys from minions.
|
||||
|
||||
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
|
||||
|
||||
``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
|
||||
: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
|
||||
|
||||
``publisher_acl``
|
||||
@ -1278,6 +1319,20 @@ This is completely disabled by default.
|
||||
- cmd.*
|
||||
- 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
|
||||
|
||||
``external_auth``
|
||||
@ -1462,6 +1517,19 @@ Do not disable this unless it is absolutely clear what this does.
|
||||
|
||||
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
|
||||
|
||||
``ssl``
|
||||
@ -1492,6 +1560,24 @@ constant names without ssl module prefix: ``CERT_REQUIRED`` or ``PROTOCOL_SSLv23
|
||||
``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``
|
||||
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
@ -3179,6 +3386,26 @@ configuration.
|
||||
|
||||
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:
|
||||
|
||||
.. conf_master:: ext_pillar
|
||||
@ -3849,6 +4076,62 @@ can be utilized:
|
||||
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
|
||||
@ -4315,6 +4598,63 @@ option then the master will log a warning message.
|
||||
- /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:
|
||||
|
||||
Windows Software Repo Settings
|
||||
@ -4453,7 +4793,7 @@ URL of the repository:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
winrepo_remotes:
|
||||
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
|
||||
|
@ -750,6 +750,20 @@ seconds each iteration.
|
||||
|
||||
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
|
||||
|
||||
``random_reauth_delay``
|
||||
@ -1180,7 +1194,7 @@ If certain returners should be disabled, this is the place
|
||||
.. conf_minion:: enable_whitelist_modules
|
||||
|
||||
``whitelist_modules``
|
||||
----------------------------
|
||||
---------------------
|
||||
|
||||
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
|
||||
@ -1272,6 +1286,20 @@ A list of extra directories to search for Salt renderers
|
||||
render_dirs:
|
||||
- /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
|
||||
|
||||
``cython_enable``
|
||||
@ -1320,6 +1348,20 @@ below.
|
||||
providers:
|
||||
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_blacklist
|
||||
|
||||
@ -1345,8 +1387,8 @@ whitelist an empty list.
|
||||
modules:
|
||||
- specific_module
|
||||
|
||||
|
||||
Valid options:
|
||||
|
||||
- beacons
|
||||
- clouds
|
||||
- sdb
|
||||
@ -1492,6 +1534,52 @@ environment lacks one.
|
||||
|
||||
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
|
||||
=========================
|
||||
|
||||
@ -1508,7 +1596,7 @@ The default renderer used for local state executions
|
||||
|
||||
renderer: yaml_jinja
|
||||
|
||||
.. conf_master:: test
|
||||
.. conf_minion:: 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'
|
||||
|
||||
.. 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
|
||||
|
||||
``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'
|
||||
|
||||
|
||||
.. conf_master:: ssl
|
||||
.. conf_minion:: ssl
|
||||
|
||||
``ssl``
|
||||
-------
|
||||
@ -2159,6 +2276,62 @@ constant names without ssl module prefix: ``CERT_REQUIRED`` or ``PROTOCOL_SSLv23
|
||||
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
|
||||
===============
|
||||
|
||||
@ -2429,6 +2602,62 @@ option then the minion will log a warning message.
|
||||
- /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
|
||||
============================
|
||||
@ -2530,6 +2759,36 @@ out.
|
||||
|
||||
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:: 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
|
||||
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.
|
||||
|
||||
.. 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
|
||||
keystone
|
||||
kmod
|
||||
kubernetes
|
||||
launchctl
|
||||
layman
|
||||
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 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
|
||||
=============
|
||||
|
@ -135,6 +135,7 @@ state modules
|
||||
keyboard
|
||||
keystone
|
||||
kmod
|
||||
kubernetes
|
||||
layman
|
||||
ldap
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@ -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.
|
||||
|
||||
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-watch-in:
|
||||
.. _requisites-onchanges-in:
|
||||
|
@ -78,6 +78,7 @@ parameters are discussed in more detail below.
|
||||
# RHEL -> ec2-user
|
||||
# CentOS -> ec2-user
|
||||
# Ubuntu -> ubuntu
|
||||
# Debian -> admin
|
||||
#
|
||||
ssh_username: ec2-user
|
||||
|
||||
|
@ -371,7 +371,6 @@ both.
|
||||
compute_name: cloudServersOpenStack
|
||||
protocol: ipv4
|
||||
compute_region: DFW
|
||||
protocol: ipv4
|
||||
user: myuser
|
||||
tenant: 5555555
|
||||
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
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
|
||||
|
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
|
||||
debian
|
||||
eos
|
||||
fedora
|
||||
freebsd
|
||||
gentoo
|
||||
|
@ -335,7 +335,7 @@ Returns:
|
||||
|
||||
.. versionadded:: 2017.7.0
|
||||
|
||||
Wraps a text around quoutes.
|
||||
This text will be wrapped in quotes.
|
||||
|
||||
|
||||
.. jinja_ref:: regex_search
|
||||
@ -750,19 +750,43 @@ Returns:
|
||||
|
||||
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
|
||||
|
||||
{{ 5 | check_whitelist_blacklist(whitelist=[5, 6, 7]) }}
|
||||
{{ 5 | check_whitelist_blacklist(blacklist=[5, 6, 7]) }}
|
||||
{{ 5 | check_whitelist_blacklist(whitelist=[5, 6, 7]) }}
|
||||
|
||||
Returns:
|
||||
|
||||
.. 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
|
||||
|
||||
@ -825,6 +849,13 @@ Example:
|
||||
|
||||
{{ '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
|
||||
|
||||
@ -876,16 +907,22 @@ Returns:
|
||||
------------
|
||||
|
||||
.. 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:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set passwd_length = 17 %}
|
||||
{{ passwd_length | rand_str }}
|
||||
{{ passwd_length | rand_str('sha512') }}
|
||||
{% set num_range = 99999999 %}
|
||||
{{ num_range | rand_str }}
|
||||
{{ num_range | rand_str('sha512') }}
|
||||
|
||||
Returns:
|
||||
|
||||
@ -1186,7 +1223,7 @@ Example:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ ['192.168.0.1', 'foo', 'bar', 'fe80::'] | ipv4 }}
|
||||
{{ ['192.168.0.1', 'foo', 'bar', 'fe80::'] | ipv6 }}
|
||||
|
||||
Returns:
|
||||
|
||||
@ -1202,7 +1239,12 @@ Returns:
|
||||
|
||||
.. 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:
|
||||
|
||||
@ -1224,7 +1266,7 @@ Returns:
|
||||
|
||||
.. 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:
|
||||
|
||||
@ -1284,6 +1326,13 @@ Example:
|
||||
|
||||
{{ '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
|
||||
|
||||
|
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
|
||||
|
||||
- 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.
|
||||
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
|
||||
run_something:
|
||||
module.run:
|
||||
mymodule.something:
|
||||
- mymodule.something:
|
||||
- name: some name
|
||||
- first_arg: one
|
||||
- second_arg: two
|
||||
- do_stuff: True
|
||||
|
||||
|
||||
Since a lot of users are already using :py:func:`module.run
|
||||
<salt.states.module.run>` states, this new behavior must currently be
|
||||
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
|
||||
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>`,
|
||||
add the following to the minion config file:
|
||||
|
||||
@ -145,6 +172,7 @@ State Module Changes
|
||||
|
||||
use_superseded:
|
||||
- module.run
|
||||
|
||||
- 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
|
||||
``md5`` to ``sha256``.
|
||||
@ -678,6 +706,7 @@ Execution modules
|
||||
- :mod:`salt.modules.grafana4 <salt.modules.grafana4>`
|
||||
- :mod:`salt.modules.heat <salt.modules.heat>`
|
||||
- :mod:`salt.modules.icinga2 <salt.modules.icinga2>`
|
||||
- :mod:`salt.modules.kubernetes <salt.modules.kubernetes>`
|
||||
- :mod:`salt.modules.logmod <salt.modules.logmod>`
|
||||
- :mod:`salt.modules.mattermost <salt.modules.mattermost>`
|
||||
- :mod:`salt.modules.namecheap_dns <salt.modules.namecheap_dns>`
|
||||
@ -756,6 +785,7 @@ States
|
||||
- :mod:`salt.states.icinga2 <salt.states.icinga2>`
|
||||
- :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.kubernetes <salt.states.kubernetes>`
|
||||
- :mod:`salt.states.logadm <salt.states.logadm>`
|
||||
- :mod:`salt.states.logrotate <salt.states.logrotate>`
|
||||
- :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 ``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
|
||||
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/>`_.
|
||||
|
||||
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:
|
||||
|
||||
- Amazon Linux
|
||||
- Debian 8
|
||||
- macOS
|
||||
- RHEL 7
|
||||
- SmartOS (see below)
|
||||
- Ubuntu 16.04
|
||||
- Ubuntu16
|
||||
- Redhat7
|
||||
- Windows
|
||||
|
||||
.. 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
|
||||
==========================
|
||||
|
||||
@ -67,14 +47,14 @@ You can install a release candidate of Salt using `Salt Bootstrap
|
||||
.. code-block:: bash
|
||||
|
||||
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:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
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
|
||||
the ``-M`` and ``-N`` flags:
|
||||
@ -82,13 +62,13 @@ the ``-M`` and ``-N`` flags:
|
||||
.. code-block:: bash
|
||||
|
||||
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 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.
|
||||
|
||||
.. note::
|
||||
@ -126,4 +106,4 @@ Then install salt using the following command:
|
||||
|
||||
.. 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
|
||||
/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.
|
||||
|
||||
|
@ -28,6 +28,7 @@ hit `Enter`. Also, you can convert tabs to 2 spaces by these commands in Vim:
|
||||
|
||||
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
|
||||
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``,
|
||||
``on``, and ``off``). This can be especially problematic when constructing
|
||||
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,
|
||||
so you'll need to wrap your values in multiple quotes, for example '"false"'.
|
||||
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, 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
|
||||
============
|
||||
@ -248,8 +265,10 @@ Alternatively, they can be defined the "old way", or with multiple
|
||||
- require:
|
||||
- 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.
|
||||
|
||||
|
@ -166,13 +166,15 @@ Ubuntu 14.04 LTS and Debian Wheezy (7.x) also have a compatible version packaged
|
||||
|
||||
# apt-get install python-git
|
||||
|
||||
If your master is running an older version (such as Ubuntu 12.04 LTS or Debian
|
||||
Squeeze), then you will need to install GitPython using either pip_ or
|
||||
easy_install (it is recommended to use pip). Version 0.3.2.RC1 is now marked as
|
||||
the stable release in PyPI, so it should be a simple matter of running ``pip
|
||||
install GitPython`` (or ``easy_install GitPython``) as root.
|
||||
GitPython_ requires the ``git`` CLI utility to work. If installed from a system
|
||||
package, then git should already be installed, but if installed via pip_ then
|
||||
it may still be necessary to install git separately. For MacOS users,
|
||||
GitPython_ comes bundled in with the Salt installer, but git must still be
|
||||
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::
|
||||
|
||||
|
@ -110,7 +110,7 @@ To pass through a file that contains jinja + yaml templating (the default):
|
||||
method='POST',
|
||||
data_file='/srv/salt/somefile.jinja',
|
||||
data_render=True,
|
||||
template_data={'key1': 'value1', 'key2': 'value2'}
|
||||
template_dict={'key1': 'value1', 'key2': 'value2'}
|
||||
)
|
||||
|
||||
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_render=True,
|
||||
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
|
||||
@ -140,7 +140,7 @@ However, this can be changed to ``master`` if necessary.
|
||||
method='POST',
|
||||
data_file='/srv/salt/somefile.jinja',
|
||||
data_render=True,
|
||||
template_data={'key1': 'value1', 'key2': 'value2'},
|
||||
template_dict={'key1': 'value1', 'key2': 'value2'},
|
||||
opts=__opts__
|
||||
)
|
||||
|
||||
@ -149,7 +149,7 @@ However, this can be changed to ``master`` if necessary.
|
||||
method='POST',
|
||||
data_file='/srv/salt/somefile.jinja',
|
||||
data_render=True,
|
||||
template_data={'key1': 'value1', 'key2': 'value2'},
|
||||
template_dict={'key1': 'value1', 'key2': 'value2'},
|
||||
node='master'
|
||||
)
|
||||
|
||||
@ -170,11 +170,11 @@ a Python dict.
|
||||
header_file='/srv/salt/headers.jinja',
|
||||
header_render=True,
|
||||
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
|
||||
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.
|
||||
|
||||
Authentication
|
||||
|
@ -75,7 +75,7 @@ The default location for the pillar is in /srv/pillar.
|
||||
|
||||
.. 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
|
||||
tree or file_roots. If the pillar is under file_roots, any pillar targeting
|
||||
can be bypassed by minions.
|
||||
@ -242,7 +242,7 @@ set in the minion's pillar, then the default of ``httpd`` will be used.
|
||||
.. note::
|
||||
|
||||
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
|
||||
======================================
|
||||
@ -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.
|
||||
|
||||
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
|
||||
=======================================
|
||||
|
||||
|
@ -54,7 +54,7 @@ types like so:
|
||||
|
||||
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
|
||||
:ref:`__virtual__ function <modules-virtual-name>` to conditionally load them,
|
||||
@ -81,11 +81,56 @@ the ``foo`` utility module with a ``__virtual__`` function.
|
||||
def bar():
|
||||
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
|
||||
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
|
||||
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
|
||||
<all-salt.output>`/returner, as well as an execution module.
|
||||
|
||||
|
@ -86,9 +86,9 @@ sudo $PKGRESOURCES/build_env.sh $PYVER
|
||||
# Install Salt
|
||||
############################################################################
|
||||
echo -n -e "\033]0;Build: Install Salt\007"
|
||||
sudo rm -rm $SRCDIR/build
|
||||
sudo rm -rm $SRCDIR/dist
|
||||
sudo $PYTHON $SRCDIR/setup.py install
|
||||
sudo rm -rf $SRCDIR/build
|
||||
sudo rm -rf $SRCDIR/dist
|
||||
sudo $PYTHON $SRCDIR/setup.py build -e "$PYTHON -E -s" install
|
||||
|
||||
############################################################################
|
||||
# Build Package
|
||||
|
@ -7,7 +7,7 @@ CherryPy==11.0.0
|
||||
click==6.7
|
||||
enum34==1.1.6
|
||||
gitdb==0.6.4
|
||||
GitPython==2.1.5
|
||||
GitPython==2.1.1
|
||||
idna==2.5
|
||||
ipaddress==1.0.18
|
||||
Jinja2==2.9.6
|
||||
|
@ -110,6 +110,13 @@ if not %errorLevel%==0 (
|
||||
)
|
||||
@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
|
||||
@echo %0 :: Install Current Version of salt...
|
||||
@echo ---------------------------------------------------------------------
|
||||
|
@ -108,9 +108,9 @@ xcopy /E /Q "%PyDir%" "%BinDir%\"
|
||||
@echo Copying configs to buildenv\conf...
|
||||
@echo ----------------------------------------------------------------------
|
||||
@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%\"
|
||||
xcopy /Q "%SrcDir%\conf\minion" "%CnfDir%\"
|
||||
xcopy /Q /Y "%SrcDir%\conf\minion" "%CnfDir%\"
|
||||
@echo.
|
||||
|
||||
@echo Copying VCRedist to Prerequisites
|
||||
@ -582,6 +582,10 @@ If Exist "%BinDir%\Scripts\salt-run*"^
|
||||
If Exist "%BldDir%\salt-run.bat"^
|
||||
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
|
||||
makensis.exe /DSaltVersion=%Version% /DPythonVersion=%Python% "%InsDir%\Salt-Minion-Setup.nsi"
|
||||
@echo.
|
||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-call
|
||||
|
||||
:: 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
|
||||
|
||||
:: 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
|
||||
|
||||
:: 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
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -12,5 +12,4 @@ Set Script=%SaltDir%\bin\Scripts\salt-minion
|
||||
net stop salt-minion
|
||||
|
||||
:: 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
|
||||
|
||||
:: 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
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -379,13 +379,12 @@ Section -Post
|
||||
WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "Path" "$INSTDIR\bin\"
|
||||
|
||||
; 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 set salt-minion AppEnvironmentExtra PYTHONHOME="
|
||||
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 Description Salt Minion from saltstack.com"
|
||||
nsExec::Exec "nssm.exe set salt-minion Start SERVICE_AUTO_START"
|
||||
nsExec::Exec "nssm.exe set salt-minion AppNoConsole 1"
|
||||
|
||||
RMDir /R "$INSTDIR\var\cache\salt" ; removing cache from old version
|
||||
nsExec::Exec "nssm.exe set salt-minion AppStopMethodConsole 24000"
|
||||
nsExec::Exec "nssm.exe set salt-minion AppStopMethodWindow 2000"
|
||||
|
||||
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'
|
||||
__func_alias__ = {
|
||||
'list_': 'list'
|
||||
'ls': 'list'
|
||||
}
|
||||
|
||||
log = logging.getLogger(__file__)
|
||||
@ -145,6 +145,9 @@ def __virtual__():
|
||||
# helper functions -- will not be exported
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def init_kwargs(kwargs):
|
||||
return {}
|
||||
|
||||
|
||||
def _get_redis_cache_opts():
|
||||
'''
|
||||
@ -415,7 +418,7 @@ def flush(bank, key=None):
|
||||
return True
|
||||
|
||||
|
||||
def list_(bank):
|
||||
def ls(bank):
|
||||
'''
|
||||
Lists entries stored in the specified bank.
|
||||
'''
|
||||
|
@ -544,6 +544,7 @@ class LocalClient(object):
|
||||
{'stewart': {...}}
|
||||
'''
|
||||
if 'expr_form' in kwargs:
|
||||
import salt
|
||||
salt.utils.warn_until(
|
||||
'Fluorine',
|
||||
'The target type should be passed using the \'tgt_type\' '
|
||||
@ -738,7 +739,7 @@ class LocalClient(object):
|
||||
ret[mid] = (data if full_return
|
||||
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
|
||||
return ret
|
||||
finally:
|
||||
|
@ -405,8 +405,6 @@ class SyncClientMixin(object):
|
||||
)
|
||||
data['success'] = False
|
||||
|
||||
namespaced_event.fire_event(data, 'ret')
|
||||
|
||||
if self.store_job:
|
||||
try:
|
||||
salt.utils.job.store_job(
|
||||
@ -424,6 +422,9 @@ class SyncClientMixin(object):
|
||||
log.error('Could not store job cache info. '
|
||||
'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.
|
||||
# This will ensure that we call destroy, which will do the 0MQ linger
|
||||
log.info('Runner completed: {0}'.format(data['jid']))
|
||||
|
@ -467,6 +467,8 @@ class SSH(object):
|
||||
for default in self.defaults:
|
||||
if default not in self.targets[host]:
|
||||
self.targets[host][default] = self.defaults[default]
|
||||
if 'host' not in self.targets[host]:
|
||||
self.targets[host]['host'] = host
|
||||
args = (
|
||||
que,
|
||||
self.opts,
|
||||
|
@ -407,13 +407,14 @@ def list_nodes_full(conn=None, call=None): # pylint: disable=unused-argument
|
||||
for group in list_resource_groups():
|
||||
nodes = compconn.virtual_machines.list(group)
|
||||
for node in nodes:
|
||||
private_ips, public_ips = __get_ips_from_node(group, node)
|
||||
ret[node.name] = object_to_dict(node)
|
||||
ret[node.name]['id'] = node.id
|
||||
ret[node.name]['name'] = node.name
|
||||
ret[node.name]['size'] = node.hardware_profile.vm_size
|
||||
ret[node.name]['state'] = node.provisioning_state
|
||||
ret[node.name]['private_ips'] = node.network_profile.network_interfaces
|
||||
ret[node.name]['public_ips'] = node.network_profile.network_interfaces
|
||||
ret[node.name]['private_ips'] = private_ips
|
||||
ret[node.name]['public_ips'] = public_ips
|
||||
ret[node.name]['storage_profile']['data_disks'] = []
|
||||
ret[node.name]['resource_group'] = group
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
'''
|
||||
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)
|
||||
or 'private_ips'.
|
||||
'''
|
||||
return config.get_cloud_config_value(
|
||||
ret = config.get_cloud_config_value(
|
||||
'ssh_interface', vm_, __opts__, default='public_ips',
|
||||
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_):
|
||||
|
@ -1071,10 +1071,10 @@ def query(action=None,
|
||||
timenow = datetime.datetime.utcnow()
|
||||
timestamp = timenow.strftime('%a, %d %b %Y %H:%M:%S %Z').strip()
|
||||
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)
|
||||
hash_ = SHA256.new()
|
||||
hash_.update(timestamp)
|
||||
hash_.update(timestamp.encode(__salt_system_encoding__))
|
||||
signed = base64.b64encode(rsa_.sign(hash_))
|
||||
keyid = '/{0}/keys/{1}'.format(user.split('/')[0], ssh_keyname)
|
||||
|
||||
@ -1085,7 +1085,7 @@ def query(action=None,
|
||||
'Date': timestamp,
|
||||
'Authorization': 'Signature keyId="{0}",algorithm="rsa-sha256" {1}'.format(
|
||||
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
|
||||
|
||||
|
||||
.. 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
|
||||
@ -855,40 +863,43 @@ def _assign_floating_ips(vm_, conn, kwargs):
|
||||
pool = OpenStack_1_1_FloatingIpPool(
|
||||
net['floating'], conn.connection
|
||||
)
|
||||
for idx in pool.list_floating_ips():
|
||||
if idx.node_id is None:
|
||||
floating.append(idx)
|
||||
try:
|
||||
floating.append(pool.create_floating_ip())
|
||||
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:
|
||||
try:
|
||||
floating.append(pool.create_floating_ip())
|
||||
except Exception as e:
|
||||
raise SaltCloudSystemExit(
|
||||
'Floating pool \'{0}\' does not have any more '
|
||||
'please create some more or use a different '
|
||||
'pool.'.format(net['floating'])
|
||||
)
|
||||
raise SaltCloudSystemExit(
|
||||
'There are no more floating IP addresses '
|
||||
'available, please create some more'
|
||||
)
|
||||
# otherwise, attempt to obtain list without specifying pool
|
||||
# this is the same as 'nova floating-ip-list'
|
||||
elif ssh_interface(vm_) != 'private_ips':
|
||||
try:
|
||||
# This try/except is here because it appears some
|
||||
# *cough* Rackspace *cough*
|
||||
# OpenStack providers return a 404 Not Found for the
|
||||
# floating ip pool URL if there are no pools setup
|
||||
pool = OpenStack_1_1_FloatingIpPool(
|
||||
'', conn.connection
|
||||
)
|
||||
for idx in pool.list_floating_ips():
|
||||
if idx.node_id is None:
|
||||
floating.append(idx)
|
||||
try:
|
||||
floating.append(pool.create_floating_ip())
|
||||
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:
|
||||
try:
|
||||
floating.append(pool.create_floating_ip())
|
||||
except Exception as e:
|
||||
raise SaltCloudSystemExit(
|
||||
'There are no more floating IP addresses '
|
||||
'available, please create some more'
|
||||
)
|
||||
log.warning(
|
||||
'There are no more floating IP addresses '
|
||||
'available, please create some more if necessary'
|
||||
)
|
||||
except Exception as e:
|
||||
if str(e).startswith('404'):
|
||||
pass
|
||||
|
@ -150,7 +150,7 @@ def avail_locations(conn=None, call=None):
|
||||
|
||||
ret[img_name] = {}
|
||||
for attr in dir(img):
|
||||
if attr.startswith('_'):
|
||||
if attr.startswith('_') or attr == 'driver':
|
||||
continue
|
||||
|
||||
attr_value = getattr(img, attr)
|
||||
@ -187,7 +187,7 @@ def avail_images(conn=None, call=None):
|
||||
|
||||
ret[img_name] = {}
|
||||
for attr in dir(img):
|
||||
if attr.startswith('_'):
|
||||
if attr.startswith('_') or attr in ('driver', 'get_uuid'):
|
||||
continue
|
||||
attr_value = getattr(img, attr)
|
||||
if isinstance(attr_value, string_types) and not six.PY3:
|
||||
@ -222,7 +222,7 @@ def avail_sizes(conn=None, call=None):
|
||||
|
||||
ret[size_name] = {}
|
||||
for attr in dir(size):
|
||||
if attr.startswith('_'):
|
||||
if attr.startswith('_') or attr in ('driver', 'get_uuid'):
|
||||
continue
|
||||
|
||||
try:
|
||||
|
@ -352,7 +352,7 @@ VALID_OPTS = {
|
||||
# The TCP port on which minion events should be pulled if ipc_mode is TCP
|
||||
'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,
|
||||
|
||||
# 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'),
|
||||
'add_proxymodule_to_opts': False,
|
||||
'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',
|
||||
|
||||
# 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',
|
||||
'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 urlparse(opts.get(config_key, '')).scheme == '':
|
||||
prepend_root_dirs.append(config_key)
|
||||
|
@ -373,17 +373,18 @@ class AsyncAuth(object):
|
||||
loop_instance_map = AsyncAuth.instance_map[io_loop]
|
||||
|
||||
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))
|
||||
# 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
|
||||
# references it-- this forces a reference while we return to the caller
|
||||
new_auth = object.__new__(cls)
|
||||
new_auth.__singleton_init__(opts, io_loop=io_loop)
|
||||
loop_instance_map[key] = new_auth
|
||||
auth = object.__new__(cls)
|
||||
auth.__singleton_init__(opts, io_loop=io_loop)
|
||||
loop_instance_map[key] = auth
|
||||
else:
|
||||
log.debug('Re-using AsyncAuth for {0}'.format(key))
|
||||
return loop_instance_map[key]
|
||||
return auth
|
||||
|
||||
@classmethod
|
||||
def __key(cls, opts, io_loop=None):
|
||||
@ -1009,14 +1010,15 @@ class SAuth(AsyncAuth):
|
||||
Only create one instance of SAuth per __key()
|
||||
'''
|
||||
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))
|
||||
new_auth = object.__new__(cls)
|
||||
new_auth.__singleton_init__(opts)
|
||||
SAuth.instances[key] = new_auth
|
||||
auth = object.__new__(cls)
|
||||
auth.__singleton_init__(opts)
|
||||
SAuth.instances[key] = auth
|
||||
else:
|
||||
log.debug('Re-using SAuth for {0}'.format(key))
|
||||
return SAuth.instances[key]
|
||||
return auth
|
||||
|
||||
@classmethod
|
||||
def __key(cls, opts, io_loop=None):
|
||||
|
@ -50,8 +50,8 @@ def start(docker_url='unix://var/run/docker.sock',
|
||||
.. code-block:: yaml
|
||||
|
||||
engines:
|
||||
docker_events:
|
||||
docker_url: unix://var/run/docker.sock
|
||||
- docker_events:
|
||||
docker_url: unix://var/run/docker.sock
|
||||
|
||||
The config above sets up engines to listen
|
||||
for events from the Docker daemon and publish
|
||||
|
@ -14,25 +14,25 @@ keys make the engine interactive.
|
||||
.. code-block:: yaml
|
||||
|
||||
engines:
|
||||
- hipchat:
|
||||
api_url: http://api.hipchat.myteam.com
|
||||
token: 'XXXXXX'
|
||||
room: 'salt'
|
||||
control: True
|
||||
valid_users:
|
||||
- SomeUser
|
||||
valid_commands:
|
||||
- test.ping
|
||||
- cmd.run
|
||||
- list_jobs
|
||||
- list_commands
|
||||
aliases:
|
||||
list_jobs:
|
||||
cmd: jobs.list_jobs
|
||||
list_commands:
|
||||
cmd: pillar.get salt:engines:hipchat:valid_commands target=saltmaster tgt_type=list
|
||||
max_rooms: 0
|
||||
wait_time: 1
|
||||
- hipchat:
|
||||
api_url: http://api.hipchat.myteam.com
|
||||
token: 'XXXXXX'
|
||||
room: 'salt'
|
||||
control: True
|
||||
valid_users:
|
||||
- SomeUser
|
||||
valid_commands:
|
||||
- test.ping
|
||||
- cmd.run
|
||||
- list_jobs
|
||||
- list_commands
|
||||
aliases:
|
||||
list_jobs:
|
||||
cmd: jobs.list_jobs
|
||||
list_commands:
|
||||
cmd: pillar.get salt:engines:hipchat:valid_commands target=saltmaster
|
||||
max_rooms: 0
|
||||
wait_time: 1
|
||||
'''
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
@ -12,13 +12,13 @@ them onto a logstash endpoint via HTTP requests.
|
||||
|
||||
engines:
|
||||
- http_logstash:
|
||||
url: http://blabla.com/salt-stuff
|
||||
tags:
|
||||
- salt/job/*/new
|
||||
- salt/job/*/ret/*
|
||||
funs:
|
||||
- probes.results
|
||||
- bgp.config
|
||||
url: http://blabla.com/salt-stuff
|
||||
tags:
|
||||
- salt/job/*/new
|
||||
- salt/job/*/ret/*
|
||||
funs:
|
||||
- probes.results
|
||||
- bgp.config
|
||||
'''
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
@ -24,6 +24,9 @@ master config.
|
||||
:configuration:
|
||||
|
||||
Example configuration
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
engines:
|
||||
- logentries:
|
||||
endpoint: data.logentries.com
|
||||
|
@ -8,6 +8,9 @@ them onto a logstash endpoint.
|
||||
:configuration:
|
||||
|
||||
Example configuration
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
engines:
|
||||
- logstash:
|
||||
host: log.my_network.com
|
||||
|
@ -7,10 +7,10 @@ Example Config in Master or Minion config
|
||||
.. code-block:: yaml
|
||||
|
||||
engines:
|
||||
reactor:
|
||||
refresh_interval: 60
|
||||
worker_threads: 10
|
||||
worker_hwm: 10000
|
||||
- reactor:
|
||||
refresh_interval: 60
|
||||
worker_threads: 10
|
||||
worker_hwm: 10000
|
||||
|
||||
reactor:
|
||||
- 'salt/cloud/*/destroyed':
|
||||
|
@ -8,6 +8,9 @@ events based on the channels they are subscribed to.
|
||||
:configuration:
|
||||
|
||||
Example configuration
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
engines:
|
||||
- redis_sentinel:
|
||||
hosts:
|
||||
|
@ -12,44 +12,43 @@ prefaced with a ``!``.
|
||||
.. code-block:: yaml
|
||||
|
||||
engines:
|
||||
slack:
|
||||
token: 'xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
control: True
|
||||
valid_users:
|
||||
- garethgreenaway
|
||||
valid_commands:
|
||||
- test.ping
|
||||
- cmd.run
|
||||
- list_jobs
|
||||
- list_commands
|
||||
aliases:
|
||||
list_jobs:
|
||||
cmd: jobs.list_jobs
|
||||
list_commands:
|
||||
cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster tgt_type=list
|
||||
- slack:
|
||||
token: 'xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
control: True
|
||||
valid_users:
|
||||
- garethgreenaway
|
||||
valid_commands:
|
||||
- test.ping
|
||||
- cmd.run
|
||||
- list_jobs
|
||||
- list_commands
|
||||
aliases:
|
||||
list_jobs:
|
||||
cmd: jobs.list_jobs
|
||||
list_commands:
|
||||
cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster tgt_type=list
|
||||
|
||||
:configuration: Example configuration using groups
|
||||
.. versionadded: 2017.7.0
|
||||
|
||||
engines:
|
||||
slack:
|
||||
token: 'xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
control: True
|
||||
groups:
|
||||
gods:
|
||||
users:
|
||||
- garethgreenaway
|
||||
commands:
|
||||
- test.ping
|
||||
- cmd.run
|
||||
- list_jobs
|
||||
- list_commands
|
||||
aliases:
|
||||
- slack:
|
||||
token: 'xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
control: True
|
||||
groups:
|
||||
gods:
|
||||
users:
|
||||
- garethgreenaway
|
||||
commands:
|
||||
- test.ping
|
||||
- cmd.run
|
||||
- list_jobs
|
||||
- list_commands
|
||||
aliases:
|
||||
list_jobs:
|
||||
cmd: jobs.list_jobs
|
||||
cmd: jobs.list_jobs
|
||||
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
|
||||
'''
|
||||
@ -62,6 +61,7 @@ import logging
|
||||
import time
|
||||
import re
|
||||
import yaml
|
||||
import ast
|
||||
|
||||
try:
|
||||
import slackclient
|
||||
@ -246,6 +246,10 @@ def start(token,
|
||||
tgt_type = 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 = {}
|
||||
|
||||
if cmd in runner_functions:
|
||||
@ -255,7 +259,7 @@ def start(token,
|
||||
# Default to trying to run as a client module.
|
||||
else:
|
||||
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:
|
||||
return_text = json.dumps(ret, sort_keys=True, indent=1)
|
||||
|
@ -73,7 +73,7 @@ class SudoExecutor(ModuleExecutorBase):
|
||||
'-c', salt.syspaths.CONFIG_DIR,
|
||||
'--',
|
||||
data.get('fun')]
|
||||
if data['fun'] == 'state.sls':
|
||||
if data['fun'] in ('state.sls', 'state.highstate', 'state.apply'):
|
||||
kwargs['concurrent'] = True
|
||||
for arg in args:
|
||||
self.cmd.append(_cmd_quote(str(arg)))
|
||||
|
@ -28,9 +28,6 @@ bytes = bytearray
|
||||
# Python 2 does not support exception chaining.
|
||||
# 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.
|
||||
_builtin_isinstance = isinstance
|
||||
|
||||
@ -2259,7 +2256,7 @@ class IPv6Network(_BaseV6, _BaseNetwork):
|
||||
"""
|
||||
network = int(self.network_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)
|
||||
|
||||
@property
|
||||
|
@ -9,6 +9,7 @@ from __future__ import absolute_import
|
||||
import socket
|
||||
import ctypes
|
||||
import os
|
||||
import ipaddress
|
||||
|
||||
|
||||
class sockaddr(ctypes.Structure):
|
||||
@ -31,6 +32,24 @@ else:
|
||||
|
||||
|
||||
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.sa_family = address_family
|
||||
addr_size = ctypes.c_int(ctypes.sizeof(addr))
|
||||
|
@ -1257,7 +1257,7 @@ class RemoteClient(Client):
|
||||
if not os.path.isfile(path):
|
||||
msg = 'specified file {0} is not present to generate hash: {1}'
|
||||
log.warning(msg.format(path, err))
|
||||
return {}
|
||||
return {}, None
|
||||
else:
|
||||
ret = {}
|
||||
hash_type = self.opts.get('hash_type', 'md5')
|
||||
|
@ -2,7 +2,7 @@
|
||||
'''
|
||||
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
|
||||
backend, add ``svn`` to the :conf_master:`fileserver_backend` option in the
|
||||
Master config file.
|
||||
@ -697,7 +697,7 @@ def file_hash(load, fnd):
|
||||
|
||||
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:
|
||||
salt.utils.warn_until(
|
||||
|
@ -984,28 +984,20 @@ def _windows_platform_data():
|
||||
|
||||
os_release = platform.release()
|
||||
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
|
||||
# started reporting the Desktop version instead of the Server version on
|
||||
# Server versions of Windows, so we need to look those up
|
||||
# Check for Python >=2.7.12 or >=3.5.2
|
||||
ver = pythonversion()['pythonversion']
|
||||
if ((six.PY2 and
|
||||
salt.utils.compare_versions(ver, '>=', [2, 7, 12, 'final', 0]))
|
||||
or
|
||||
(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`')
|
||||
# So, if you find a Server Platform that's a key in the server
|
||||
# dictionary, then lookup the actual Server Release.
|
||||
# (Product Type 1 is Desktop, Everything else is Server)
|
||||
if info['ProductType'] > 1 and os_release in server:
|
||||
os_release = server[os_release]
|
||||
|
||||
service_pack = None
|
||||
if info['ServicePackMajor'] > 0:
|
||||
@ -2359,6 +2351,10 @@ def _zpool_data(grains):
|
||||
if salt.utils.is_windows() or 'proxyminion' in __opts__:
|
||||
return {}
|
||||
|
||||
# quickly return if NetBSD (ZFS still under development)
|
||||
if salt.utils.is_netbsd():
|
||||
return {}
|
||||
|
||||
# quickly return if no zpool and zfs command
|
||||
if not salt.utils.which('zpool'):
|
||||
return {}
|
||||
|
@ -194,7 +194,7 @@ def minion_mods(
|
||||
generated modules in __context__
|
||||
|
||||
: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
|
||||
configuration.
|
||||
|
||||
@ -1094,7 +1094,8 @@ class LazyLoader(salt.utils.lazy.LazyDict):
|
||||
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()
|
||||
|
||||
|
@ -1251,7 +1251,7 @@ class Minion(MinionBase):
|
||||
ret = yield channel.send(load, timeout=timeout)
|
||||
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.
|
||||
'''
|
||||
@ -1270,10 +1270,6 @@ class Minion(MinionBase):
|
||||
else:
|
||||
return
|
||||
|
||||
def timeout_handler(*_):
|
||||
log.info('fire_master failed: master could not be contacted. Request timed out.')
|
||||
return True
|
||||
|
||||
if sync:
|
||||
try:
|
||||
self._send_req_sync(load, timeout)
|
||||
@ -1284,6 +1280,12 @@ class Minion(MinionBase):
|
||||
log.info('fire_master failed: {0}'.format(traceback.format_exc()))
|
||||
return False
|
||||
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):
|
||||
self._send_req_async(load, timeout, callback=lambda f: None) # pylint: disable=unexpected-keyword-arg
|
||||
return True
|
||||
@ -1985,8 +1987,9 @@ class Minion(MinionBase):
|
||||
elif tag.startswith('_minion_mine'):
|
||||
self._mine_send(tag, data)
|
||||
elif tag.startswith('fire_master'):
|
||||
log.debug('Forwarding master event tag={tag}'.format(tag=data['tag']))
|
||||
self._fire_master(data['data'], data['tag'], data['events'], data['pretag'])
|
||||
if self.connected:
|
||||
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')):
|
||||
# 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']:
|
||||
@ -2205,13 +2208,15 @@ class Minion(MinionBase):
|
||||
if ping_interval > 0 and self.connected:
|
||||
def ping_master():
|
||||
try:
|
||||
if not self._fire_master('ping', 'minion_ping'):
|
||||
def ping_timeout_handler(*_):
|
||||
if not self.opts.get('auth_safemode', True):
|
||||
log.error('** Master Ping failed. Attempting to restart minion**')
|
||||
delay = self.opts.get('random_reauth_delay', 5)
|
||||
log.info('delaying random_reauth_delay {0}s'.format(delay))
|
||||
# regular sys.exit raises an exception -- which isn't sufficient in a thread
|
||||
os._exit(salt.defaults.exitcodes.SALT_KEEPALIVE)
|
||||
|
||||
self._fire_master('ping', 'minion_ping', sync=False, timeout_handler=ping_timeout_handler)
|
||||
except Exception:
|
||||
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)
|
||||
@ -2226,7 +2231,7 @@ class Minion(MinionBase):
|
||||
except Exception:
|
||||
log.critical('The beacon errored: ', exc_info=True)
|
||||
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)
|
||||
|
||||
|
@ -199,7 +199,7 @@ def execute(context=None, lens=None, commands=(), load_path=None):
|
||||
method = METHOD_MAP[cmd]
|
||||
nargs = arg_map[method]
|
||||
|
||||
parts = salt.utils.shlex_split(arg)
|
||||
parts = salt.utils.shlex_split(arg, posix=False)
|
||||
|
||||
if len(parts) not in nargs:
|
||||
err = '{0} takes {1} args: {2}'.format(method, nargs, parts)
|
||||
|
@ -158,7 +158,7 @@ def create_file_system(name,
|
||||
import os
|
||||
import base64
|
||||
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)
|
||||
|
||||
@ -223,10 +223,23 @@ def create_mount_target(filesystemid,
|
||||
|
||||
client = _get_conn(key=key, keyid=keyid, profile=profile, region=region)
|
||||
|
||||
return client.create_mount_point(FileSystemId=filesystemid,
|
||||
SubnetId=subnetid,
|
||||
IpAddress=ipaddress,
|
||||
SecurityGroups=securitygroups)
|
||||
if ipaddress is None and securitygroups is None:
|
||||
return client.create_mount_target(FileSystemId=filesystemid,
|
||||
SubnetId=subnetid)
|
||||
|
||||
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,
|
||||
|
@ -2,7 +2,7 @@
|
||||
'''
|
||||
Connection module for Amazon ALB
|
||||
|
||||
.. versionadded:: TBD
|
||||
.. versionadded:: 2017.7.0
|
||||
|
||||
:configuration: This module accepts explicit elb credentials but can also utilize
|
||||
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')
|
||||
except boto.exception.BotoServerError as e:
|
||||
log.debug(e)
|
||||
msg = 'Failed to list {0} policy vesions.'
|
||||
msg = 'Failed to list {0} policy versions.'
|
||||
log.error(msg.format(policy_name))
|
||||
return []
|
||||
|
||||
|
@ -294,6 +294,9 @@ def _run(cmd,
|
||||
if runas is None and '__context__' in globals():
|
||||
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
|
||||
# salt-minion is running as. Defaults to home directory of user under which
|
||||
# the minion is running.
|
||||
|
@ -1978,6 +1978,8 @@ def acl_create(consul_url=None, **kwargs):
|
||||
Create a new ACL token.
|
||||
|
||||
: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 type: Type is either client or management. A management
|
||||
token is comparable to a root user and has the
|
||||
@ -2008,6 +2010,9 @@ def acl_create(consul_url=None, **kwargs):
|
||||
else:
|
||||
raise SaltInvocationError('Required argument "name" is missing.')
|
||||
|
||||
if 'id' in kwargs:
|
||||
data['ID'] = kwargs['id']
|
||||
|
||||
if 'type' in kwargs:
|
||||
data['Type'] = kwargs['type']
|
||||
|
||||
@ -2126,7 +2131,7 @@ def acl_delete(consul_url=None, **kwargs):
|
||||
ret['res'] = False
|
||||
return ret
|
||||
|
||||
function = 'acl/delete/{0}'.format(kwargs['id'])
|
||||
function = 'acl/destroy/{0}'.format(kwargs['id'])
|
||||
res = _query(consul_url=consul_url,
|
||||
data=data,
|
||||
method='PUT',
|
||||
|
@ -1,6 +1,10 @@
|
||||
# -*- 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
|
||||
|
||||
@ -232,7 +236,7 @@ def check_ip(ip_addr):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt ns1 dig.check_ip 127.0.0.1
|
||||
salt ns1 dnsutil.check_ip 127.0.0.1
|
||||
'''
|
||||
if _has_dig():
|
||||
return __salt__['dig.check_ip'](ip_addr)
|
||||
@ -242,7 +246,7 @@ def check_ip(ip_addr):
|
||||
|
||||
def A(host, nameserver=None):
|
||||
'''
|
||||
Return the A record(s) for `host`.
|
||||
Return the A record(s) for ``host``.
|
||||
|
||||
Always returns a list.
|
||||
|
||||
@ -267,7 +271,7 @@ def A(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.
|
||||
|
||||
@ -302,7 +306,7 @@ def NS(domain, resolve=True, nameserver=None):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt ns1 dig.NS google.com
|
||||
salt ns1 dnsutil.NS google.com
|
||||
|
||||
'''
|
||||
if _has_dig():
|
||||
@ -323,7 +327,7 @@ def SPF(domain, record='SPF', nameserver=None):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt ns1 dig.SPF google.com
|
||||
salt ns1 dnsutil.SPF google.com
|
||||
'''
|
||||
if _has_dig():
|
||||
return __salt__['dig.SPF'](domain, record, nameserver)
|
||||
@ -346,7 +350,7 @@ def MX(domain, resolve=False, nameserver=None):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt ns1 dig.MX google.com
|
||||
salt ns1 dnsutil.MX google.com
|
||||
'''
|
||||
if _has_dig():
|
||||
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)]
|
||||
|
||||
|
||||
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):
|
||||
'''
|
||||
Format bytes as human-readable file sizes
|
||||
@ -884,8 +899,15 @@ def compare_container(first, second, ignore=None):
|
||||
continue
|
||||
val1 = result1[conf_dict][item]
|
||||
val2 = result2[conf_dict].get(item)
|
||||
if val1 != val2:
|
||||
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
||||
if item in ('OomKillDisable',):
|
||||
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
|
||||
# and not the first.
|
||||
for item in result2[conf_dict]:
|
||||
@ -895,8 +917,15 @@ def compare_container(first, second, ignore=None):
|
||||
continue
|
||||
val1 = result1[conf_dict].get(item)
|
||||
val2 = result2[conf_dict][item]
|
||||
if val1 != val2:
|
||||
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
||||
if item in ('OomKillDisable',):
|
||||
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
|
||||
|
||||
|
||||
@ -978,6 +1007,10 @@ def login(*registries):
|
||||
cmd = ['docker', 'login', '-u', username, '-p', password]
|
||||
if registry.lower() != 'hub':
|
||||
cmd.append(registry)
|
||||
log.debug(
|
||||
'Attempting to login to docker registry \'%s\' as user \'%s\'',
|
||||
registry, username
|
||||
)
|
||||
login_cmd = __salt__['cmd.run_all'](
|
||||
cmd,
|
||||
python_shell=False,
|
||||
@ -1803,7 +1836,7 @@ def create(image,
|
||||
generate one for you (it will be included in the return data).
|
||||
|
||||
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
|
||||
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
|
||||
@ -2071,9 +2104,9 @@ def create(image,
|
||||
- ``dns_search="[foo1.domain.tld, foo2.domain.tld]"``
|
||||
|
||||
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 for the container. Either a string (e.g. ``"mycmd --arg1
|
||||
|
@ -710,18 +710,21 @@ def check_hash(path, file_hash):
|
||||
|
||||
hash
|
||||
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``),
|
||||
but for earlier releases it is necessary to also specify the hash type
|
||||
in the format ``<hash_type>:<hash_value>`` (e.g.
|
||||
``md5:e138491e9d5b97023cea823fe17bac22``).
|
||||
in the format ``<hash_type>=<hash_value>`` (e.g.
|
||||
``md5=e138491e9d5b97023cea823fe17bac22``).
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
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)
|
||||
|
||||
@ -1898,6 +1901,7 @@ def replace(path,
|
||||
show_changes=True,
|
||||
ignore_if_missing=False,
|
||||
preserve_inode=True,
|
||||
backslash_literal=False,
|
||||
):
|
||||
'''
|
||||
.. versionadded:: 0.17.0
|
||||
@ -1998,6 +2002,14 @@ def replace(path,
|
||||
filename. Hard links will then share an inode with the backup, instead
|
||||
(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
|
||||
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
|
||||
@ -2094,7 +2106,10 @@ def replace(path,
|
||||
if re.search(cpattern, r_data):
|
||||
return True # `with` block handles file closure
|
||||
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)
|
||||
if nrepl > 0:
|
||||
@ -2148,8 +2163,10 @@ def replace(path,
|
||||
r_data = mmap.mmap(r_file.fileno(),
|
||||
0,
|
||||
access=mmap.ACCESS_READ)
|
||||
result, nrepl = re.subn(cpattern, repl,
|
||||
r_data, count)
|
||||
result, nrepl = re.subn(cpattern,
|
||||
repl.replace('\\', '\\\\') if backslash_literal else repl,
|
||||
r_data,
|
||||
count)
|
||||
try:
|
||||
w_file.write(salt.utils.to_str(result))
|
||||
except (OSError, IOError) as exc:
|
||||
|
@ -185,15 +185,24 @@ def _git_run(command, cwd=None, user=None, password=None, identity=None,
|
||||
identity = [identity]
|
||||
|
||||
# try each of the identities, independently
|
||||
tmp_identity_file = None
|
||||
for id_file in identity:
|
||||
if 'salt://' in id_file:
|
||||
_id_file = id_file
|
||||
id_file = __salt__['cp.cache_file'](id_file, saltenv)
|
||||
with salt.utils.files.set_umask(0o077):
|
||||
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:
|
||||
log.error('identity {0} does not exist.'.format(_id_file))
|
||||
__salt__['file.remove'](tmp_identity_file)
|
||||
continue
|
||||
else:
|
||||
__salt__['file.set_mode'](id_file, '0600')
|
||||
if user:
|
||||
os.chown(id_file,
|
||||
__salt__['file.user_to_uid'](user),
|
||||
-1)
|
||||
else:
|
||||
if not __salt__['file.file_exists'](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:
|
||||
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 result['retcode'] == 0:
|
||||
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
|
||||
file does not exist, it will be created.
|
||||
|
||||
.. deprecated:: 2016.3.0
|
||||
|
||||
pwfile
|
||||
Path to htpasswd file
|
||||
|
||||
|
@ -262,7 +262,7 @@ def create_keytab(name, keytab, enctypes=None):
|
||||
|
||||
.. 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 = {}
|
||||
|
||||
|
@ -16,6 +16,7 @@ or `api_password` parameters when calling a function:
|
||||
.. code-block:: bash
|
||||
salt '*' kubernetes.nodes api_url=http://k8s-api-server:port api_user=myuser api_password=pass
|
||||
|
||||
.. versionadded: 2017.7.0
|
||||
'''
|
||||
|
||||
# Import Python Futures
|
||||
@ -39,6 +40,14 @@ try:
|
||||
except ImportError:
|
||||
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__)
|
||||
|
||||
@ -761,7 +770,7 @@ def create_deployment(
|
||||
'''
|
||||
body = __create_object_body(
|
||||
kind='Deployment',
|
||||
obj_class=kubernetes.client.V1beta1Deployment,
|
||||
obj_class=AppsV1beta1Deployment,
|
||||
spec_creator=__dict_to_deployment_spec,
|
||||
name=name,
|
||||
namespace=namespace,
|
||||
@ -1012,7 +1021,7 @@ def replace_deployment(name,
|
||||
'''
|
||||
body = __create_object_body(
|
||||
kind='Deployment',
|
||||
obj_class=kubernetes.client.V1beta1Deployment,
|
||||
obj_class=AppsV1beta1Deployment,
|
||||
spec_creator=__dict_to_deployment_spec,
|
||||
name=name,
|
||||
namespace=namespace,
|
||||
@ -1275,9 +1284,9 @@ def __dict_to_object_meta(name, namespace, metadata):
|
||||
|
||||
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):
|
||||
if hasattr(spec_obj, key):
|
||||
setattr(spec_obj, key, value)
|
||||
|
@ -216,7 +216,7 @@ def align_check(device, part_type, partition):
|
||||
'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
|
||||
)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
|
@ -257,8 +257,8 @@ def items(*args, **kwargs):
|
||||
__opts__,
|
||||
__grains__,
|
||||
__opts__['id'],
|
||||
pillar_override=kwargs.get('pillar'),
|
||||
pillarenv=kwargs.get('pillarenv') or __opts__['pillarenv'])
|
||||
pillar_override=pillar_override,
|
||||
pillarenv=pillarenv)
|
||||
|
||||
return pillar.compile_pillar()
|
||||
|
||||
|
@ -345,9 +345,10 @@ def summary():
|
||||
|
||||
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:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' puppet.plugin_sync
|
||||
|
@ -135,6 +135,7 @@ def _safe_output(line):
|
||||
'''
|
||||
return not any([
|
||||
line.startswith('Listing') and line.endswith('...'),
|
||||
line.startswith('Listing') and '\t' not in line,
|
||||
'...done' in line,
|
||||
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():
|
||||
runas = salt.utils.get_user()
|
||||
|
||||
if tags and isinstance(tags, (list, tuple)):
|
||||
tags = ' '.join(tags)
|
||||
if not isinstance(tags, (list, tuple)):
|
||||
tags = [tags]
|
||||
|
||||
res = __salt__['cmd.run_all'](
|
||||
[RABBITMQCTL, 'set_user_tags', name, tags],
|
||||
[RABBITMQCTL, 'set_user_tags', name] + list(tags),
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
msg = "Tag(s) set"
|
||||
|
@ -150,7 +150,9 @@ class Registry(object): # pylint: disable=R0903
|
||||
_winreg.REG_DWORD: 'REG_DWORD',
|
||||
_winreg.REG_EXPAND_SZ: 'REG_EXPAND_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 = {
|
||||
_winreg.REG_OPTION_NON_VOLATILE: 'REG_OPTION_NON_VOLATILE',
|
||||
|
@ -218,7 +218,7 @@ def uptime():
|
||||
with salt.utils.fopen(ut_path) as rfh:
|
||||
seconds = int(float(rfh.read().split()[0]))
|
||||
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
|
||||
res = __salt__['cmd.run_all']('kstat -p unix:0:system_misc:boot_time')
|
||||
if res['retcode'] > 0:
|
||||
|
@ -1687,9 +1687,6 @@ def check_perms(path,
|
||||
perms = changes[user]['perms']
|
||||
|
||||
try:
|
||||
log.debug('*' * 68)
|
||||
log.debug(perms)
|
||||
log.debug('*' * 68)
|
||||
salt.utils.win_dacl.set_permissions(
|
||||
path, user, perms, 'deny', applies_to)
|
||||
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)
|
||||
|
||||
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))
|
||||
return False
|
||||
|
||||
|
@ -3982,78 +3982,77 @@ def _write_regpol_data(data_to_write,
|
||||
gpt_extension_guid: admx registry extension guid for the class
|
||||
'''
|
||||
try:
|
||||
if data_to_write:
|
||||
reg_pol_header = u'\u5250\u6765\x01\x00'
|
||||
if not os.path.exists(policy_file_path):
|
||||
ret = __salt__['file.makedirs'](policy_file_path)
|
||||
with salt.utils.fopen(policy_file_path, 'wb') as pol_file:
|
||||
if not data_to_write.startswith(reg_pol_header):
|
||||
pol_file.write(reg_pol_header.encode('utf-16-le'))
|
||||
pol_file.write(data_to_write.encode('utf-16-le'))
|
||||
try:
|
||||
gpt_ini_data = ''
|
||||
if os.path.exists(gpt_ini_path):
|
||||
with salt.utils.fopen(gpt_ini_path, 'rb') as gpt_file:
|
||||
gpt_ini_data = gpt_file.read()
|
||||
if not _regexSearchRegPolData(r'\[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):
|
||||
# ensure the line contains the ADM guid
|
||||
gpt_ext_loc = re.search(r'^{0}=.*\r\n'.format(re.escape(gpt_extension)),
|
||||
gpt_ini_data,
|
||||
re.IGNORECASE | re.MULTILINE)
|
||||
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)),
|
||||
gpt_ext_str):
|
||||
gpt_ext_str = gpt_ext_str.split('=')
|
||||
gpt_ext_str[1] = gpt_extension_guid + gpt_ext_str[1]
|
||||
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():]
|
||||
else:
|
||||
general_location = re.search(r'^\[General\]\r\n',
|
||||
gpt_ini_data,
|
||||
re.IGNORECASE | re.MULTILINE)
|
||||
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
||||
gpt_ini_data[general_location.start():general_location.end()],
|
||||
gpt_extension, gpt_extension_guid,
|
||||
gpt_ini_data[general_location.end():])
|
||||
# https://technet.microsoft.com/en-us/library/cc978247.aspx
|
||||
if _regexSearchRegPolData(r'Version=', gpt_ini_data):
|
||||
version_loc = re.search(r'^Version=.*\r\n',
|
||||
gpt_ini_data,
|
||||
re.IGNORECASE | re.MULTILINE)
|
||||
version_str = gpt_ini_data[version_loc.start():version_loc.end()]
|
||||
version_str = version_str.split('=')
|
||||
version_nums = struct.unpack('>2H', struct.pack('>I', int(version_str[1])))
|
||||
if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower():
|
||||
version_nums = (version_nums[0], version_nums[1] + 1)
|
||||
elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower():
|
||||
version_nums = (version_nums[0] + 1, version_nums[1])
|
||||
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:version_loc.start()],
|
||||
'Version', version_num,
|
||||
gpt_ini_data[version_loc.end():])
|
||||
else:
|
||||
general_location = re.search(r'^\[General\]\r\n',
|
||||
gpt_ini_data,
|
||||
re.IGNORECASE | re.MULTILINE)
|
||||
if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower():
|
||||
version_nums = (0, 1)
|
||||
elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower():
|
||||
version_nums = (1, 0)
|
||||
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
||||
gpt_ini_data[general_location.start():general_location.end()],
|
||||
'Version',
|
||||
int("{0}{1}".format(str(version_nums[0]).zfill(4), str(version_nums[1]).zfill(4)), 16),
|
||||
gpt_ini_data[general_location.end():])
|
||||
if gpt_ini_data:
|
||||
with salt.utils.fopen(gpt_ini_path, 'wb') as gpt_file:
|
||||
gpt_file.write(gpt_ini_data)
|
||||
except Exception as e:
|
||||
msg = 'An error occurred attempting to write to {0}, the exception was {1}'.format(
|
||||
gpt_ini_path, e)
|
||||
raise CommandExecutionError(msg)
|
||||
reg_pol_header = u'\u5250\u6765\x01\x00'
|
||||
if not os.path.exists(policy_file_path):
|
||||
ret = __salt__['file.makedirs'](policy_file_path)
|
||||
with salt.utils.files.fopen(policy_file_path, 'wb') as pol_file:
|
||||
if not data_to_write.startswith(reg_pol_header):
|
||||
pol_file.write(reg_pol_header.encode('utf-16-le'))
|
||||
pol_file.write(data_to_write.encode('utf-16-le'))
|
||||
try:
|
||||
gpt_ini_data = ''
|
||||
if os.path.exists(gpt_ini_path):
|
||||
with salt.utils.files.fopen(gpt_ini_path, 'rb') as gpt_file:
|
||||
gpt_ini_data = gpt_file.read()
|
||||
if not _regexSearchRegPolData(r'\[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):
|
||||
# ensure the line contains the ADM guid
|
||||
gpt_ext_loc = re.search(r'^{0}=.*\r\n'.format(re.escape(gpt_extension)),
|
||||
gpt_ini_data,
|
||||
re.IGNORECASE | re.MULTILINE)
|
||||
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)),
|
||||
gpt_ext_str):
|
||||
gpt_ext_str = gpt_ext_str.split('=')
|
||||
gpt_ext_str[1] = gpt_extension_guid + gpt_ext_str[1]
|
||||
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():]
|
||||
else:
|
||||
general_location = re.search(r'^\[General\]\r\n',
|
||||
gpt_ini_data,
|
||||
re.IGNORECASE | re.MULTILINE)
|
||||
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
||||
gpt_ini_data[general_location.start():general_location.end()],
|
||||
gpt_extension, gpt_extension_guid,
|
||||
gpt_ini_data[general_location.end():])
|
||||
# https://technet.microsoft.com/en-us/library/cc978247.aspx
|
||||
if _regexSearchRegPolData(r'Version=', gpt_ini_data):
|
||||
version_loc = re.search(r'^Version=.*\r\n',
|
||||
gpt_ini_data,
|
||||
re.IGNORECASE | re.MULTILINE)
|
||||
version_str = gpt_ini_data[version_loc.start():version_loc.end()]
|
||||
version_str = version_str.split('=')
|
||||
version_nums = struct.unpack('>2H', struct.pack('>I', int(version_str[1])))
|
||||
if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower():
|
||||
version_nums = (version_nums[0], version_nums[1] + 1)
|
||||
elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower():
|
||||
version_nums = (version_nums[0] + 1, version_nums[1])
|
||||
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:version_loc.start()],
|
||||
'Version', version_num,
|
||||
gpt_ini_data[version_loc.end():])
|
||||
else:
|
||||
general_location = re.search(r'^\[General\]\r\n',
|
||||
gpt_ini_data,
|
||||
re.IGNORECASE | re.MULTILINE)
|
||||
if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower():
|
||||
version_nums = (0, 1)
|
||||
elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower():
|
||||
version_nums = (1, 0)
|
||||
gpt_ini_data = "{0}{1}={2}\r\n{3}".format(
|
||||
gpt_ini_data[general_location.start():general_location.end()],
|
||||
'Version',
|
||||
int("{0}{1}".format(str(version_nums[0]).zfill(4), str(version_nums[1]).zfill(4)), 16),
|
||||
gpt_ini_data[general_location.end():])
|
||||
if gpt_ini_data:
|
||||
with salt.utils.files.fopen(gpt_ini_path, 'wb') as gpt_file:
|
||||
gpt_file.write(gpt_ini_data)
|
||||
except Exception as e:
|
||||
msg = 'An error occurred attempting to write to {0}, the exception was {1}'.format(
|
||||
gpt_ini_path, e)
|
||||
raise CommandExecutionError(msg)
|
||||
except Exception as e:
|
||||
msg = 'An error occurred attempting to write to {0}, the exception was {1}'.format(policy_file_path, e)
|
||||
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
|
||||
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:
|
||||
|
||||
version (str):
|
||||
The specific version to install. If omitted, the latest version
|
||||
will be installed. If passed with multiple install, the version
|
||||
will apply to all packages. Recommended for single installation
|
||||
only.
|
||||
The specific version to install. If omitted, the latest version will
|
||||
be installed. Recommend for use when installing a single package.
|
||||
|
||||
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):
|
||||
A single file to copy down for use with the installer. Copied to
|
||||
the same location as the installer. Use this over ``cache_dir`` if
|
||||
there are many files in the directory and you only need a specific
|
||||
file and don't want to cache additional files that may reside in
|
||||
the installer directory. Only applies to files on ``salt://``
|
||||
A single file to copy down for use with the installer. Copied to the
|
||||
same location as the installer. Use this over ``cache_dir`` if there
|
||||
are many files in the directory and you only need a specific file
|
||||
and don't want to cache additional files that may reside in the
|
||||
installer directory. Only applies to files on ``salt://``
|
||||
|
||||
cache_dir (bool):
|
||||
True will copy the contents of the installer directory. This is
|
||||
useful for installations that are not a single file. Only applies
|
||||
to directories on ``salt://``
|
||||
useful for installations that are not a single file. Only applies to
|
||||
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):
|
||||
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
|
||||
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:
|
||||
log.error('No package definition found')
|
||||
return {}
|
||||
|
||||
if not pkgs and len(pkg_params) == 1:
|
||||
# Only use the 'version' param if 'name' was not specified as a
|
||||
# comma-separated list
|
||||
# Only use the 'version' param if a single item was passed to the 'name'
|
||||
# parameter
|
||||
pkg_params = {
|
||||
name: {
|
||||
'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)
|
||||
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 = ''
|
||||
if options:
|
||||
if options.get('version') is not None:
|
||||
version_num = str(options.get('version'))
|
||||
version_num = 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:
|
||||
version_num = _get_latest_pkg_version(pkginfo)
|
||||
@ -1423,6 +1472,11 @@ def remove(name=None, pkgs=None, version=None, **kwargs):
|
||||
continue
|
||||
|
||||
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:
|
||||
version_num = 'latest'
|
||||
elif 'latest' in pkginfo:
|
||||
|
@ -1,9 +1,18 @@
|
||||
# -*- 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
|
||||
|
||||
:depends:
|
||||
- PowerShell 4
|
||||
- PKI Client Module (Windows 8+ / Windows Server 2012+)
|
||||
|
||||
.. versionadded:: 2016.11.0
|
||||
'''
|
||||
# Import python libs
|
||||
@ -29,11 +38,17 @@ __virtualname__ = 'win_pki'
|
||||
|
||||
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():
|
||||
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']:
|
||||
return False, 'Powershell not available'
|
||||
|
||||
|
@ -303,6 +303,11 @@ def get_community_names():
|
||||
# Windows SNMP service GUI.
|
||||
if isinstance(current_values, list):
|
||||
for current_value in current_values:
|
||||
|
||||
# Ignore error values
|
||||
if not isinstance(current_value, dict):
|
||||
continue
|
||||
|
||||
permissions = str()
|
||||
for permission_name in _PERMISSION_TYPES:
|
||||
if current_value['vdata'] == _PERMISSION_TYPES[permission_name]:
|
||||
|
@ -37,6 +37,7 @@ except ImportError:
|
||||
import salt.utils
|
||||
import salt.utils.locales
|
||||
import salt.ext.six as six
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
# Set up logging
|
||||
log = logging.getLogger(__name__)
|
||||
@ -622,7 +623,11 @@ def join_domain(domain,
|
||||
.. versionadded:: 2015.8.2/2015.5.7
|
||||
|
||||
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:
|
||||
|
||||
@ -655,6 +660,56 @@ def join_domain(domain,
|
||||
account_ou = account_ou.split('\\')
|
||||
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_ACCOUNT_CREATE = 0x2 # pylint: disable=invalid-name
|
||||
NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x20 # pylint: disable=invalid-name
|
||||
@ -670,23 +725,13 @@ def join_domain(domain,
|
||||
pythoncom.CoInitialize()
|
||||
conn = wmi.WMI()
|
||||
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
|
||||
# formatted value that looks like (0,)
|
||||
if not err[0]:
|
||||
ret = {'Domain': domain,
|
||||
'Restart': False}
|
||||
if restart:
|
||||
ret['Restart'] = reboot()
|
||||
return ret
|
||||
|
||||
log.error(win32api.FormatMessage(err[0]).rstrip())
|
||||
return False
|
||||
# Return the results of the command as an error
|
||||
# JoinDomainOrWorkgroup returns a strangely formatted value that looks like
|
||||
# (0,) so return the first item
|
||||
return comp.JoinDomainOrWorkgroup(
|
||||
Name=domain, Password=password, UserName=username, AccountOU=account_ou,
|
||||
FJoinOptions=join_options)[0]
|
||||
|
||||
|
||||
def unjoin_domain(username=None,
|
||||
@ -919,7 +964,11 @@ def set_system_date_time(years=None,
|
||||
seconds (int): Seconds digit: 0 - 59
|
||||
|
||||
Returns:
|
||||
bool: True if successful, otherwise False.
|
||||
bool: True if successful
|
||||
|
||||
Raises:
|
||||
CommandExecutionError: Raises an error if ``SetLocalTime`` function
|
||||
fails
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -972,12 +1021,15 @@ def set_system_date_time(years=None,
|
||||
system_time.wSecond = int(seconds)
|
||||
system_time_ptr = ctypes.pointer(system_time)
|
||||
succeeded = ctypes.windll.kernel32.SetLocalTime(system_time_ptr)
|
||||
return succeeded is not 0
|
||||
except OSError:
|
||||
if succeeded is not 0:
|
||||
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')
|
||||
return False
|
||||
|
||||
return True
|
||||
raise CommandExecutionError(err)
|
||||
|
||||
|
||||
def get_system_date():
|
||||
|
@ -2,6 +2,49 @@
|
||||
'''
|
||||
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
|
||||
|
||||
:depends:
|
||||
@ -54,36 +97,40 @@ def available(software=True,
|
||||
skip_mandatory=False,
|
||||
skip_reboot=False,
|
||||
categories=None,
|
||||
severities=None,
|
||||
):
|
||||
severities=None,):
|
||||
'''
|
||||
.. 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:
|
||||
|
||||
software (bool): Include software updates in the results (default is
|
||||
True)
|
||||
software (bool):
|
||||
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):
|
||||
- True: Return a summary of updates available for each category.
|
||||
- False (default): Return a detailed list of available updates.
|
||||
- True: Return a summary of updates available for each category.
|
||||
- False (default): Return a detailed list of available updates.
|
||||
|
||||
skip_installed (bool): Skip updates that are already installed. Default
|
||||
is False.
|
||||
skip_installed (bool):
|
||||
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
|
||||
False.
|
||||
skip_reboot (bool):
|
||||
Skip updates that require a reboot. Default is False.
|
||||
|
||||
categories (list): Specify the categories to list. Must be passed as a
|
||||
list. All categories returned by default.
|
||||
categories (list):
|
||||
Specify the categories to list. Must be passed as a list. All
|
||||
categories returned by default.
|
||||
|
||||
Categories include the following:
|
||||
|
||||
@ -101,8 +148,9 @@ def available(software=True,
|
||||
* Windows 8.1 and later drivers
|
||||
* Windows Defender
|
||||
|
||||
severities (list): Specify the severities to include. Must be passed as
|
||||
a list. All severities returned by default.
|
||||
severities (list):
|
||||
Specify the severities to include. Must be passed as a list. All
|
||||
severities returned by default.
|
||||
|
||||
Severities include the following:
|
||||
|
||||
@ -152,28 +200,30 @@ def available(software=True,
|
||||
salt '*' win_wua.available
|
||||
|
||||
# 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
|
||||
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
|
||||
salt '*' win_wua.available severities=['Critical']
|
||||
salt '*' win_wua.available severities=["Critical"]
|
||||
|
||||
# A summary of all available updates
|
||||
salt '*' win_wua.available summary=True
|
||||
|
||||
# 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
|
||||
wua = salt.utils.win_update.WindowsUpdateAgent()
|
||||
|
||||
# Look for available
|
||||
updates = wua.available(skip_hidden, skip_installed, skip_mandatory,
|
||||
skip_reboot, software, drivers, categories,
|
||||
severities)
|
||||
updates = wua.available(
|
||||
skip_hidden=skip_hidden, skip_installed=skip_installed,
|
||||
skip_mandatory=skip_mandatory, skip_reboot=skip_reboot,
|
||||
software=software, drivers=drivers, categories=categories,
|
||||
severities=severities)
|
||||
|
||||
# Return results as Summary or Details
|
||||
return updates.summary() if summary else updates.list()
|
||||
@ -183,23 +233,29 @@ def list_update(name, download=False, install=False):
|
||||
'''
|
||||
.. deprecated:: 2017.7.0
|
||||
Use :func:`get` instead
|
||||
|
||||
Returns details for all updates that match the search criteria
|
||||
|
||||
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
|
||||
function first to see if the update exists, then set ``download=True``
|
||||
to download the update.
|
||||
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.
|
||||
|
||||
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.
|
||||
download (bool):
|
||||
Download the update returned by this function. Run this function
|
||||
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:
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Returns details for all updates that match the search criteria
|
||||
Returns details for the named update
|
||||
|
||||
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
|
||||
function first to see if the update exists, then set ``download=True``
|
||||
to download the update.
|
||||
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.
|
||||
|
||||
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.
|
||||
download (bool):
|
||||
Download the update returned by this function. Run this function
|
||||
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:
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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):
|
||||
- True: Return a summary of updates available for each category.
|
||||
- False (default): Return a detailed list of available updates.
|
||||
- True: Return a summary of updates available for each category.
|
||||
- False (default): Return a detailed list of available updates.
|
||||
|
||||
skip_installed (bool): Skip installed updates in the results (default is
|
||||
False)
|
||||
skip_installed (bool):
|
||||
Skip installed updates in the results (default is False)
|
||||
|
||||
download (bool): (Overrides reporting functionality) Download the list
|
||||
of updates returned by this function. Run this function first with
|
||||
``download=False`` to see what will be downloaded, then set
|
||||
``download=True`` to download the updates.
|
||||
download (bool):
|
||||
(Overrides reporting functionality) Download the list of updates
|
||||
returned by this function. Run this function first with
|
||||
``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
|
||||
updates returned by this function. Run this function first with
|
||||
``install=False`` to see what will be installed, then set
|
||||
``install=True`` to install the updates.
|
||||
install (bool):
|
||||
(Overrides reporting functionality) Install the list of updates
|
||||
returned by this function. Run this function first with
|
||||
``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
|
||||
list. All categories returned by default.
|
||||
categories (list):
|
||||
Specify the categories to list. Must be passed as a list. All
|
||||
categories returned by default.
|
||||
|
||||
Categories include the following:
|
||||
|
||||
@ -398,8 +464,9 @@ def list_updates(software=True,
|
||||
* Windows 8.1 and later drivers
|
||||
* Windows Defender
|
||||
|
||||
severities (list): Specify the severities to include. Must be passed as
|
||||
a list. All severities returned by default.
|
||||
severities (list):
|
||||
Specify the severities to include. Must be passed as a list. All
|
||||
severities returned by default.
|
||||
|
||||
Severities include the following:
|
||||
|
||||
@ -486,30 +553,35 @@ def list(software=True,
|
||||
install is True the same list will be downloaded and/or installed.
|
||||
|
||||
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):
|
||||
- True: Return a summary of updates available for each category.
|
||||
- False (default): Return a detailed list of available updates.
|
||||
- True: Return a summary of updates available for each category.
|
||||
- False (default): Return a detailed list of available updates.
|
||||
|
||||
skip_installed (bool): Skip installed updates in the results (default is
|
||||
False)
|
||||
skip_installed (bool):
|
||||
Skip installed updates in the results (default is False)
|
||||
|
||||
download (bool): (Overrides reporting functionality) Download the list
|
||||
of updates returned by this function. Run this function first with
|
||||
``download=False`` to see what will be downloaded, then set
|
||||
``download=True`` to download the updates.
|
||||
download (bool):
|
||||
(Overrides reporting functionality) Download the list of updates
|
||||
returned by this function. Run this function first with
|
||||
``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
|
||||
updates returned by this function. Run this function first with
|
||||
``install=False`` to see what will be installed, then set
|
||||
``install=True`` to install the updates.
|
||||
install (bool):
|
||||
(Overrides reporting functionality) Install the list of updates
|
||||
returned by this function. Run this function first with
|
||||
``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
|
||||
list. All categories returned by default.
|
||||
categories (list):
|
||||
Specify the categories to list. Must be passed as a list. All
|
||||
categories returned by default.
|
||||
|
||||
Categories include the following:
|
||||
|
||||
@ -527,8 +599,9 @@ def list(software=True,
|
||||
* Windows 8.1 and later drivers
|
||||
* Windows Defender
|
||||
|
||||
severities (list): Specify the severities to include. Must be passed as
|
||||
a list. All severities returned by default.
|
||||
severities (list):
|
||||
Specify the severities to include. Must be passed as a list. All
|
||||
severities returned by default.
|
||||
|
||||
Severities include the following:
|
||||
|
||||
@ -575,22 +648,22 @@ def list(software=True,
|
||||
.. code-block:: bash
|
||||
|
||||
# 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
|
||||
salt '*' win_wua.list_updates categories=['Critical Updates','Drivers']
|
||||
salt '*' win_wua.list categories=['Critical Updates','Drivers']
|
||||
|
||||
# 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
|
||||
salt '*' win_wua.list_updates severities=['Critical']
|
||||
salt '*' win_wua.list severities=['Critical']
|
||||
|
||||
# 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
|
||||
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
|
||||
wua = salt.utils.win_update.WindowsUpdateAgent()
|
||||
@ -604,11 +677,11 @@ def list(software=True,
|
||||
|
||||
# Download
|
||||
if download or install:
|
||||
ret['Download'] = wua.download(updates.updates)
|
||||
ret['Download'] = wua.download(updates)
|
||||
|
||||
# Install
|
||||
if install:
|
||||
ret['Install'] = wua.install(updates.updates)
|
||||
ret['Install'] = wua.install(updates)
|
||||
|
||||
if not ret:
|
||||
return updates.summary() if summary else updates.list()
|
||||
@ -625,13 +698,16 @@ def download_update(name):
|
||||
|
||||
Args:
|
||||
|
||||
name (str): The name of the update to download. This can be a GUID, a KB
|
||||
number, or any part of the name. To ensure a single item is matched the
|
||||
GUID is preferred.
|
||||
name (str):
|
||||
The name of the update to download. This can be a GUID, a KB number,
|
||||
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:
|
||||
|
||||
dict: A dictionary containing the results of the download
|
||||
|
||||
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 KB12312321
|
||||
|
||||
'''
|
||||
salt.utils.warn_until(
|
||||
'Fluorine',
|
||||
@ -660,8 +735,9 @@ def download_updates(names):
|
||||
|
||||
Args:
|
||||
|
||||
names (list): A list of updates to download. This can be any combination
|
||||
of GUIDs, KB numbers, or names. GUIDs or KBs are preferred.
|
||||
names (list):
|
||||
A list of updates to download. This can be any combination of GUIDs,
|
||||
KB numbers, or names. GUIDs or KBs are preferred.
|
||||
|
||||
Returns:
|
||||
|
||||
@ -672,7 +748,7 @@ def download_updates(names):
|
||||
.. code-block:: bash
|
||||
|
||||
# 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(
|
||||
'Fluorine',
|
||||
@ -690,9 +766,14 @@ def download(names):
|
||||
|
||||
Args:
|
||||
|
||||
names (str, list): A single update or a list of updates to download.
|
||||
This can be any combination of GUIDs, KB numbers, or names. GUIDs or KBs
|
||||
are preferred.
|
||||
names (str, list):
|
||||
A single update or a list of updates to download. This can be any
|
||||
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:
|
||||
|
||||
@ -703,7 +784,7 @@ def download(names):
|
||||
.. code-block:: bash
|
||||
|
||||
# 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
|
||||
wua = salt.utils.win_update.WindowsUpdateAgent()
|
||||
@ -714,6 +795,13 @@ def download(names):
|
||||
if updates.count() == 0:
|
||||
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):
|
||||
raise CommandExecutionError('Multiple updates found, names need to be '
|
||||
'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
|
||||
GUID is preferred.
|
||||
|
||||
.. note:: If no results or more than one result is returned an error
|
||||
will be raised.
|
||||
.. note::
|
||||
If no results or more than one result is returned an error will be
|
||||
raised.
|
||||
|
||||
Returns:
|
||||
|
||||
dict: A dictionary containing the results of the install
|
||||
|
||||
CLI Examples:
|
||||
@ -795,9 +885,14 @@ def install(names):
|
||||
|
||||
Args:
|
||||
|
||||
names (str, list): A single update or a list of updates to install.
|
||||
This can be any combination of GUIDs, KB numbers, or names. GUIDs or KBs
|
||||
are preferred.
|
||||
names (str, list):
|
||||
A single update or a list of updates to install. This can be any
|
||||
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:
|
||||
|
||||
@ -808,7 +903,7 @@ def install(names):
|
||||
.. code-block:: bash
|
||||
|
||||
# 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
|
||||
wua = salt.utils.win_update.WindowsUpdateAgent()
|
||||
@ -819,6 +914,13 @@ def install(names):
|
||||
if updates.count() == 0:
|
||||
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):
|
||||
raise CommandExecutionError('Multiple updates found, names need to be '
|
||||
'more specific')
|
||||
@ -834,9 +936,10 @@ def uninstall(names):
|
||||
|
||||
Args:
|
||||
|
||||
names (str, list): A single update or a list of updates to uninstall.
|
||||
This can be any combination of GUIDs, KB numbers, or names. GUIDs or KBs
|
||||
are preferred.
|
||||
names (str, list):
|
||||
A single update or a list of updates to uninstall. This can be any
|
||||
combination of GUIDs, KB numbers, or names. GUIDs or KBs are
|
||||
preferred.
|
||||
|
||||
Returns:
|
||||
|
||||
@ -875,33 +978,50 @@ def set_wu_settings(level=None,
|
||||
Change Windows Update settings. If no parameters are passed, the current
|
||||
value will be returned.
|
||||
|
||||
:param int level:
|
||||
Number from 1 to 4 indicating the update level:
|
||||
Supported:
|
||||
- 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
|
||||
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
|
||||
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:
|
||||
Boolean value that indicates whether to display notifications for
|
||||
featured updates.
|
||||
recommended (bool):
|
||||
Boolean value that indicates whether to include optional or
|
||||
recommended updates when a search for updates and installation of
|
||||
updates is performed.
|
||||
|
||||
:param bool elevated:
|
||||
Boolean value that indicates whether non-administrators can perform some
|
||||
update-related actions without administrator approval.
|
||||
featured (bool):
|
||||
Boolean value that indicates whether to display notifications for
|
||||
featured updates.
|
||||
|
||||
:param bool msupdate:
|
||||
Boolean value that indicates whether to turn on Microsoft Update for
|
||||
other Microsoft products
|
||||
elevated (bool):
|
||||
Boolean value that indicates whether non-administrators can perform
|
||||
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
|
||||
- Monday
|
||||
- Tuesday
|
||||
@ -910,21 +1030,43 @@ def set_wu_settings(level=None,
|
||||
- Friday
|
||||
- Saturday
|
||||
|
||||
:param str time:
|
||||
Time at which Automatic Updates installs or uninstalls updates. Must be
|
||||
in the ##:## 24hr format, eg. 3:00 PM would be 15:00
|
||||
time (str):
|
||||
Time at which Automatic Updates installs or uninstalls updates. Must
|
||||
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:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' win_wua.set_wu_settings level=4 recommended=True featured=False
|
||||
|
||||
'''
|
||||
ret = {}
|
||||
ret['Success'] = True
|
||||
# The AutomaticUpdateSettings.Save() method used in this function does not
|
||||
# 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
|
||||
pythoncom.CoInitialize()
|
||||
@ -1076,30 +1218,31 @@ def get_wu_settings():
|
||||
Boolean value that indicates whether to display notifications for
|
||||
featured updates.
|
||||
Group Policy Required (Read-only):
|
||||
Boolean value that indicates whether Group Policy requires the Automatic
|
||||
Updates service.
|
||||
Boolean value that indicates whether Group Policy requires the
|
||||
Automatic Updates service.
|
||||
Microsoft Update:
|
||||
Boolean value that indicates whether to turn on Microsoft Update for
|
||||
other Microsoft Products
|
||||
Needs Reboot:
|
||||
Boolean value that indicates whether the machine is in a reboot pending
|
||||
state.
|
||||
Boolean value that indicates whether the machine is in a reboot
|
||||
pending state.
|
||||
Non Admins Elevated:
|
||||
Boolean value that indicates whether non-administrators can perform some
|
||||
update-related actions without administrator approval.
|
||||
Boolean value that indicates whether non-administrators can perform
|
||||
some update-related actions without administrator approval.
|
||||
Notification Level:
|
||||
Number 1 to 4 indicating the update level:
|
||||
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
|
||||
4. Install updates automatically
|
||||
Read Only (Read-only):
|
||||
Boolean value that indicates whether the Automatic Update
|
||||
settings are read-only.
|
||||
Recommended Updates:
|
||||
Boolean value that indicates whether to include optional or recommended
|
||||
updates when a search for updates and installation of updates is
|
||||
performed.
|
||||
Boolean value that indicates whether to include optional or
|
||||
recommended updates when a search for updates and installation of
|
||||
updates is performed.
|
||||
Scheduled Day:
|
||||
Days of the week on which Automatic Updates installs or uninstalls
|
||||
updates.
|
||||
@ -1182,13 +1325,12 @@ def get_needs_reboot():
|
||||
|
||||
Returns:
|
||||
|
||||
bool: True if the system requires a reboot, False if not
|
||||
bool: True if the system requires a reboot, otherwise False
|
||||
|
||||
CLI Examples:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' win_wua.get_needs_reboot
|
||||
|
||||
'''
|
||||
return salt.utils.win_update.needs_reboot()
|
||||
|
@ -1373,10 +1373,19 @@ def create_certificate(
|
||||
['listen_in', 'preqrequired', '__prerequired__']:
|
||||
kwargs.pop(ignore, None)
|
||||
|
||||
cert_txt = __salt__['publish.publish'](
|
||||
certs = __salt__['publish.publish'](
|
||||
tgt=ca_server,
|
||||
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:
|
||||
return write_pem(
|
||||
text=cert_txt,
|
||||
|
@ -181,7 +181,16 @@ def _check_versionlock():
|
||||
Ensure that the appropriate versionlock plugin is present
|
||||
'''
|
||||
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:
|
||||
vl_plugin = 'yum-versionlock' \
|
||||
if __grains__.get('osmajorrelease') == '5' \
|
||||
@ -1034,6 +1043,11 @@ def refresh_db(**kwargs):
|
||||
|
||||
clean_cmd = [_yum(), '--quiet', 'clean', 'expire-cache']
|
||||
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):
|
||||
if args:
|
||||
clean_cmd.extend(args)
|
||||
|
@ -483,13 +483,22 @@ import signal
|
||||
import tarfile
|
||||
from multiprocessing import Process, Pipe
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Import third-party libs
|
||||
# pylint: disable=import-error
|
||||
import cherrypy # pylint: disable=3rd-party-module-not-gated
|
||||
# pylint: disable=import-error, 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 salt.ext.six as six
|
||||
# pylint: enable=import-error
|
||||
|
||||
# pylint: enable=import-error, 3rd-party-module-not-gated
|
||||
|
||||
# Import Salt libs
|
||||
import salt
|
||||
@ -500,8 +509,6 @@ import salt.utils.event
|
||||
# Import salt-api libs
|
||||
import salt.netapi
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Imports related to websocket
|
||||
try:
|
||||
from .tools import websockets
|
||||
@ -2616,13 +2623,6 @@ class Stats(object):
|
||||
:status 406: |406|
|
||||
'''
|
||||
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 {}
|
||||
@ -2742,13 +2742,14 @@ class API(object):
|
||||
'tools.trailing_slash.on': True,
|
||||
'tools.gzip.on': True,
|
||||
|
||||
'tools.cpstats.on': self.apiopts.get('collect_stats', False),
|
||||
|
||||
'tools.html_override.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:
|
||||
conf['/favicon.ico'] = {
|
||||
'tools.staticfile.on': True,
|
||||
|
@ -523,8 +523,7 @@ class BaseSaltAPIHandler(tornado.web.RequestHandler, SaltClientsMixIn): # pylin
|
||||
|
||||
try:
|
||||
# Use cgi.parse_header to correctly separate parameters from value
|
||||
header = cgi.parse_header(self.request.headers['Content-Type'])
|
||||
value, parameters = header
|
||||
value, parameters = cgi.parse_header(self.request.headers['Content-Type'])
|
||||
return ct_in_map[value](tornado.escape.native_str(data))
|
||||
except KeyError:
|
||||
self.send_error(406)
|
||||
@ -538,7 +537,7 @@ class BaseSaltAPIHandler(tornado.web.RequestHandler, SaltClientsMixIn): # pylin
|
||||
if not self.request.body:
|
||||
return
|
||||
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):
|
||||
data['arg'] = [data['arg']]
|
||||
@ -696,15 +695,13 @@ class SaltAuthHandler(BaseSaltAPIHandler): # pylint: disable=W0223
|
||||
}}
|
||||
'''
|
||||
try:
|
||||
request_payload = self.deserialize(self.request.body)
|
||||
|
||||
if not isinstance(request_payload, dict):
|
||||
if not isinstance(self.request_payload, dict):
|
||||
self.send_error(400)
|
||||
return
|
||||
|
||||
creds = {'username': request_payload['username'],
|
||||
'password': request_payload['password'],
|
||||
'eauth': request_payload['eauth'],
|
||||
creds = {'username': self.request_payload['username'],
|
||||
'password': self.request_payload['password'],
|
||||
'eauth': self.request_payload['eauth'],
|
||||
}
|
||||
# if any of the args are missing, its a bad request
|
||||
except KeyError:
|
||||
@ -1641,7 +1638,7 @@ class WebhookSaltAPIHandler(SaltAPIHandler): # pylint: disable=W0223
|
||||
value = value[0]
|
||||
arguments[argname] = value
|
||||
ret = self.event.fire_event({
|
||||
'post': self.raw_data,
|
||||
'post': self.request_payload,
|
||||
'get': arguments,
|
||||
# In Tornado >= v4.0.3, the headers come
|
||||
# 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