mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 09:23:56 +00:00
Merge remote-tracking branch 'upstream/develop' into sam_dev1
This commit is contained in:
commit
4b82b72702
5
doc/_templates/saltstack.html
vendored
5
doc/_templates/saltstack.html
vendored
@ -8,7 +8,10 @@ Call for speakers now open. Early-bird and group discounts.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4>SaltStack training</h4>
|
<h4>SaltStack training</h4>
|
||||||
|
<p>
|
||||||
<a href="http://www.saltstack.com/training/">
|
<a href="http://www.saltstack.com/training/">
|
||||||
<img src="{{ pathto('_static/images/salt-training.png', 1) }}" alt="" style="padding-bottom: 1em;">
|
Now offering remote attendee training!
|
||||||
|
{# <img src="{{ pathto('_static/images/salt-training.png', 1) }}" alt="" style="padding-bottom: 1em;"> #}
|
||||||
</a>
|
</a>
|
||||||
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
4
doc/_templates/version.html
vendored
4
doc/_templates/version.html
vendored
@ -10,5 +10,5 @@
|
|||||||
<p>Latest Salt release: <a href="{{ pathto('topics/releases/{0}'.format(release)) }}">{{ release }}</a></p>
|
<p>Latest Salt release: <a href="{{ pathto('topics/releases/{0}'.format(release)) }}">{{ release }}</a></p>
|
||||||
|
|
||||||
<p>Try the shiny new release candidate of Salt,
|
<p>Try the shiny new release candidate of Salt,
|
||||||
<a href="{{ pathto('topics/releases/2014.7.0') }}">v2014.7.0rc3</a>! More info
|
<a href="{{ pathto('topics/releases/2014.7.0') }}">v2014.7.0rc6</a>! More info
|
||||||
<a href="{{ pathto('topics/releases/releasecandidate') }}">here.</a></p>
|
<a href="{{ pathto('topics/releases/releasecandidate') }}">here</a>.</p>
|
||||||
|
@ -28,8 +28,9 @@ How to Use it
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Since this option changes the basic behavior of the state runtime states
|
Since this option changes the basic behavior of the state runtime, after
|
||||||
should be executed in
|
it is enabled states should be executed using `test=True` to ensure that
|
||||||
|
the desired behavior is preserved.
|
||||||
|
|
||||||
Since this behavior can dramatically change the flow of configuration
|
Since this behavior can dramatically change the flow of configuration
|
||||||
management inside of Salt it is disabled by default. But enabling it is easy.
|
management inside of Salt it is disabled by default. But enabling it is easy.
|
||||||
|
@ -210,10 +210,10 @@ examples of "changes" dictionaries.)
|
|||||||
|
|
||||||
If the "changes" key contains a populated dictionary, it means that the
|
If the "changes" key contains a populated dictionary, it means that the
|
||||||
pre-required state expects changes to occur when the state is actually
|
pre-required state expects changes to occur when the state is actually
|
||||||
executed, as opposed to the test-run. The pre-required state will now
|
executed, as opposed to the test-run. The pre-requiring state will now
|
||||||
actually run. If the pre-required state executes successfully, the
|
actually run. If the pre-requiring state executes successfully, the
|
||||||
pre-requiring state will then execute. If the pre-required state fails, the
|
pre-required state will then execute. If the pre-requiring state fails, the
|
||||||
pre-requiring state will not execute.
|
pre-required state will not execute.
|
||||||
|
|
||||||
If the "changes" key contains an empty dictionary, this means that changes are
|
If the "changes" key contains an empty dictionary, this means that changes are
|
||||||
not expected by the pre-required state. Neither the pre-required state nor the
|
not expected by the pre-required state. Neither the pre-required state nor the
|
||||||
|
@ -15,3 +15,4 @@ Full list of builtin wheel modules
|
|||||||
file_roots
|
file_roots
|
||||||
key
|
key
|
||||||
pillar_roots
|
pillar_roots
|
||||||
|
minions
|
||||||
|
7
doc/ref/wheel/all/salt.wheel.minions.rst
Normal file
7
doc/ref/wheel/all/salt.wheel.minions.rst
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
==================
|
||||||
|
salt.wheel.minions
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. automodule:: salt.wheel.minions
|
||||||
|
:members:
|
||||||
|
|
@ -5,24 +5,19 @@ OS X
|
|||||||
Dependency Installation
|
Dependency Installation
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
When installing via Homebrew, dependency resolution is handled for you.
|
When using Homebrew, install this way:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
brew install saltstack
|
sudo brew install saltstack
|
||||||
|
|
||||||
When using macports, zmq, swig, and pip may need to be installed this way:
|
When using MacPorts, install this way:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
sudo port install py-zmq
|
sudo port install salt
|
||||||
sudo port install py27-m2crypto
|
|
||||||
sudo port install py27-crypto
|
|
||||||
sudo port install py27-msgpack
|
|
||||||
sudo port install swig-python
|
|
||||||
sudo port install py-pip
|
|
||||||
|
|
||||||
For installs using the OS X system python, pip install needs to use 'sudo':
|
When only using the OS X system's pip, install this way:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
@ -47,7 +42,7 @@ Now the salt-master should run without errors:
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
sudo /usr/local/share/python/salt-master --log-level=all
|
sudo salt-master --log-level=all
|
||||||
|
|
||||||
Post-installation tasks
|
Post-installation tasks
|
||||||
=======================
|
=======================
|
||||||
|
@ -108,6 +108,18 @@ If this repo is added *before* Salt is installed, then installing either
|
|||||||
additional states to upgrade ZeroMQ and pyzmq are unnecessary.
|
additional states to upgrade ZeroMQ and pyzmq are unnecessary.
|
||||||
|
|
||||||
|
|
||||||
|
Package Management
|
||||||
|
==================
|
||||||
|
|
||||||
|
Salt's interface to :mod:`yum <salt.modules.yumpkg>` makes heavy use of the
|
||||||
|
**repoquery** utility, from the yum-utils_ package. This package will be
|
||||||
|
installed as a dependency if salt is installed via EPEL. However, if salt has
|
||||||
|
been installed using pip, or a host is being managed using salt-ssh, then as of
|
||||||
|
version 2014.7.0 yum-utils_ will be installed automatically to satisfy this
|
||||||
|
dependency.
|
||||||
|
|
||||||
|
.. _yum-utils: http://yum.baseurl.org/wiki/YumUtils
|
||||||
|
|
||||||
Post-installation tasks
|
Post-installation tasks
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@ Mapping Events to Reactor SLS Files
|
|||||||
Reactor SLS files and event tags are associated in the master config file.
|
Reactor SLS files and event tags are associated in the master config file.
|
||||||
By default this is /etc/salt/master, or /etc/salt/master.d/reactor.conf.
|
By default this is /etc/salt/master, or /etc/salt/master.d/reactor.conf.
|
||||||
|
|
||||||
|
.. versionadded:: 2014.7.0
|
||||||
|
Added Reactor support for ``salt://`` file paths.
|
||||||
|
|
||||||
In the master config section 'reactor:' is a list of event tags to be matched
|
In the master config section 'reactor:' is a list of event tags to be matched
|
||||||
and each event tag has a list of reactor SLS files to be run.
|
and each event tag has a list of reactor SLS files to be run.
|
||||||
|
|
||||||
@ -172,14 +175,28 @@ Understanding the Structure of Reactor Formulas
|
|||||||
===============================================
|
===============================================
|
||||||
|
|
||||||
While the reactor system uses the same data structure as the state system, this
|
While the reactor system uses the same data structure as the state system, this
|
||||||
data does not translate the same way to operations. In state files formula
|
data does not translate the same way to function calls.
|
||||||
information is mapped to the state functions, but in the reactor system
|
|
||||||
information is mapped to a number of available subsystems on the master. These
|
.. versionchanged:: 2014.7.0
|
||||||
systems are the :strong:`LocalClient` and the :strong:`Runners`. The
|
The ``cmd`` prefix was renamed to ``local`` for consistency with other
|
||||||
:strong:`state declaration` field takes a reference to the function to call in
|
parts of Salt. A backward-compatible alias was added for ``cmd``.
|
||||||
each interface. So to trigger a salt-run call the :strong:`state declaration`
|
|
||||||
field will start with :strong:`runner`, followed by the runner function to
|
In state files the minion generates the data structure locally and uses that to
|
||||||
call. This means that a call to what would be on the command line
|
call local state functions. In the reactor system the master generates a data
|
||||||
|
structure that is used to call methods on one of Salt's client interfaces
|
||||||
|
described in :ref:`the Python API documentation <client-apis>`.
|
||||||
|
|
||||||
|
* :py:class:`~salt.client.LocalClient` is used to call Execution modules
|
||||||
|
remotely on minions. (The :command:`salt` CLI program uses this also.)
|
||||||
|
* :py:class:`~salt.runner.RunnerClient` calls Runner modules locally on the
|
||||||
|
master.
|
||||||
|
* :py:class:`~salt.wheel.WheelClient` calls Wheel modules locally on the
|
||||||
|
master.
|
||||||
|
|
||||||
|
The :strong:`state declaration` field takes a reference to the function to call
|
||||||
|
in each interface. So to trigger a salt-run call the :strong:`state
|
||||||
|
declaration` field will start with :strong:`runner`, followed by the runner
|
||||||
|
function to call. This means that a call to what would be on the command line
|
||||||
:strong:`salt-run manage.up` will be :strong:`runner.manage.up`. An example of
|
:strong:`salt-run manage.up` will be :strong:`runner.manage.up`. An example of
|
||||||
this in a reactor formula would look like this:
|
this in a reactor formula would look like this:
|
||||||
|
|
||||||
|
@ -6,6 +6,20 @@ This release is the largest Salt release ever, with more features and commits
|
|||||||
then any previous release of Salt. Everything from the new RAET transport to
|
then any previous release of Salt. Everything from the new RAET transport to
|
||||||
major updates in Salt Cloud and the merging of Salt API into the main project.
|
major updates in Salt Cloud and the merging of Salt API into the main project.
|
||||||
|
|
||||||
|
.. important::
|
||||||
|
|
||||||
|
The Fedora/RHEL/CentOS **salt-master** package has been modified for this
|
||||||
|
release. The following components of Salt have been broken out and placed
|
||||||
|
into their own packages:
|
||||||
|
|
||||||
|
* salt-syndic
|
||||||
|
* salt-cloud
|
||||||
|
* salt-ssh
|
||||||
|
|
||||||
|
When the **salt-master** package is upgraded, these components will be
|
||||||
|
removed, and they will need to be manually installed.
|
||||||
|
|
||||||
|
|
||||||
New Transport!
|
New Transport!
|
||||||
==============
|
==============
|
||||||
|
|
||||||
@ -29,12 +43,12 @@ Simply stated, users running Salt with RAET should expect some hiccups as we
|
|||||||
hammer out the update. This is a BETA release of Salt RAET.
|
hammer out the update. This is a BETA release of Salt RAET.
|
||||||
|
|
||||||
For information about how to use Salt with RAET please see the
|
For information about how to use Salt with RAET please see the
|
||||||
:doc:`tutorial </topics/transports/raet/programming_intro>`.
|
:doc:`tutorial </topics/transports/raet/index>`.
|
||||||
|
|
||||||
Salt SSH Enhancements
|
Salt SSH Enhancements
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Salt SSH has just entered a new league, which substantial updates and
|
Salt SSH has just entered a new league, with substantial updates and
|
||||||
improvements to make salt-ssh more reliable and easier then ever! From new
|
improvements to make salt-ssh more reliable and easier then ever! From new
|
||||||
features like the ansible roster and fileserver backends to the new pypi
|
features like the ansible roster and fileserver backends to the new pypi
|
||||||
salt-ssh installer to lowered deps and a swath of bugfixes, salt-ssh is
|
salt-ssh installer to lowered deps and a swath of bugfixes, salt-ssh is
|
||||||
@ -58,7 +72,7 @@ which may be seen can be safely ignored.
|
|||||||
Fileserver Backends
|
Fileserver Backends
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Salt-ssh can now use the salt fileserver backend system, this allows for
|
Salt-ssh can now use the salt fileserver backend system. This allows for
|
||||||
the gitfs, hgfs, s3, and many more ways to centrally store states to be easily
|
the gitfs, hgfs, s3, and many more ways to centrally store states to be easily
|
||||||
used with salt-ssh. This also allows for a distributed team to easily use
|
used with salt-ssh. This also allows for a distributed team to easily use
|
||||||
a centralized source.
|
a centralized source.
|
||||||
@ -78,8 +92,8 @@ to use salt-ssh with teams.
|
|||||||
No More sshpass
|
No More sshpass
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Thanks to the enhancements in the salt vt system salt-ssh no longer requires
|
Thanks to the enhancements in the salt vt system, salt-ssh no longer requires
|
||||||
sshpass to send passwords to ssh, this also makes the manipulation of ssh
|
sshpass to send passwords to ssh. This also makes the manipulation of ssh
|
||||||
calls substantially more flexible, allowing for intercepting ssh calls in
|
calls substantially more flexible, allowing for intercepting ssh calls in
|
||||||
a much more fluid way.
|
a much more fluid way.
|
||||||
|
|
||||||
@ -109,11 +123,11 @@ More Thin Directory Options
|
|||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
Salt ssh functions by copying a subset of the salt code, or `salt thin` down
|
Salt ssh functions by copying a subset of the salt code, or `salt thin` down
|
||||||
to the target system. In the past this was always transfered to /tmp/.salt
|
to the target system. In the past this was always transferred to /tmp/.salt
|
||||||
and cached there for subsequent commands.
|
and cached there for subsequent commands.
|
||||||
|
|
||||||
Now, salt thin can be sent to a random directory and removed when the call
|
Now, salt thin can be sent to a random directory and removed when the call
|
||||||
is complete with the `-W` option. The new `-w` option still uses a static
|
is complete with the `-W` option. The new `-W` option still uses a static
|
||||||
location but will clean up that location when finished.
|
location but will clean up that location when finished.
|
||||||
|
|
||||||
The default `salt thin` location is now user defined, allowing multiple users
|
The default `salt thin` location is now user defined, allowing multiple users
|
||||||
@ -125,9 +139,9 @@ State System Enhancements
|
|||||||
New Imperative State Keyword "Listen"
|
New Imperative State Keyword "Listen"
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
The new ``listen`` keyword allows for completely imperative states by calling
|
The new ``listen`` and ``listen_in`` keywords allow for completely imperative
|
||||||
the ``mod_watch()`` routine after all states have run instead of re-ordering
|
states by calling the ``mod_watch()`` routine after all states have run instead
|
||||||
the states.
|
of re-ordering the states.
|
||||||
|
|
||||||
Mod Aggregate Runtime Manipulator
|
Mod Aggregate Runtime Manipulator
|
||||||
---------------------------------
|
---------------------------------
|
||||||
@ -137,7 +151,7 @@ state data during execution. This allows for state definitions to be aggregated
|
|||||||
dynamically at runtime.
|
dynamically at runtime.
|
||||||
|
|
||||||
The best example is found in the :mod:`pkg <salt.states.pkg>` state. If
|
The best example is found in the :mod:`pkg <salt.states.pkg>` state. If
|
||||||
``mod_aggregate`` is turned on, then when the first pkg state is reached the
|
``mod_aggregate`` is turned on, then when the first pkg state is reached, the
|
||||||
state system will scan all of the other running states for pkg states and take
|
state system will scan all of the other running states for pkg states and take
|
||||||
all other packages set for install and install them all at once in the first
|
all other packages set for install and install them all at once in the first
|
||||||
pkg state.
|
pkg state.
|
||||||
@ -152,7 +166,15 @@ For more documentation on ``mod_aggregate``, see :doc:`the documentation
|
|||||||
New Requisites: onchanges and onfail
|
New Requisites: onchanges and onfail
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
New requisites!
|
The new ``onchanges`` and ``onchanges_in`` requisites make a state apply only if
|
||||||
|
there are changes in the required state. This is useful to execute post hooks
|
||||||
|
after changes occur on a system.
|
||||||
|
|
||||||
|
The other new requisites, ``onfail`` and ``onfail_in``, allow for a state to run
|
||||||
|
in reaction to the failure of another state.
|
||||||
|
|
||||||
|
For more information about these new requisites, see the
|
||||||
|
:doc:`requisites documentation </ref/states/requisites>`.
|
||||||
|
|
||||||
|
|
||||||
Global onlyif and unless
|
Global onlyif and unless
|
||||||
@ -200,7 +222,7 @@ Fileserver Backends in salt-call
|
|||||||
|
|
||||||
Fileserver backends like gitfs can now be used without a salt master! Just add
|
Fileserver backends like gitfs can now be used without a salt master! Just add
|
||||||
the fileserver backend configuration to the minion config and execute
|
the fileserver backend configuration to the minion config and execute
|
||||||
salt-call. This has been a much-requested feature and we are heppy to finally
|
salt-call. This has been a much-requested feature and we are happy to finally
|
||||||
bring it to our users.
|
bring it to our users.
|
||||||
|
|
||||||
Amazon Execution Modules
|
Amazon Execution Modules
|
||||||
|
@ -8,7 +8,7 @@ Salt SSH
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
On many systems, ``salt-ssh`` will be in its own package, usually named
|
On many systems, the ``salt-ssh`` executable will be in its own package, usually named
|
||||||
``salt-ssh``.
|
``salt-ssh``.
|
||||||
|
|
||||||
In version 0.17.0 of Salt a new transport system was introduced, the ability
|
In version 0.17.0 of Salt a new transport system was introduced, the ability
|
||||||
|
@ -6,8 +6,10 @@ The RAET Transport
|
|||||||
|
|
||||||
The RAET transport is in very early development, it is functional but no
|
The RAET transport is in very early development, it is functional but no
|
||||||
promises are yet made as to its reliability or security.
|
promises are yet made as to its reliability or security.
|
||||||
|
As for reliability and security, the encryption used has been audited and
|
||||||
This document is also not yet complete
|
our tests show that raet is reliable. With this said we are still conducting
|
||||||
|
more security audits and pushing the reliability.
|
||||||
|
This document outlines the encryption used in RAET
|
||||||
|
|
||||||
.. versionadded:: 2014.7.0
|
.. versionadded:: 2014.7.0
|
||||||
|
|
||||||
@ -23,57 +25,12 @@ processes on multiple machines. Messages can also be restricted, allowing
|
|||||||
processes to be sent messages of specific types from specific sources
|
processes to be sent messages of specific types from specific sources
|
||||||
allowing for trust to be established.
|
allowing for trust to be established.
|
||||||
|
|
||||||
Why?
|
|
||||||
====
|
|
||||||
|
|
||||||
Customer and User Request
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
Why make an alternative transport for Salt? There are many reasons, but the
|
|
||||||
primary motivation came from customer requests, many large companies came with
|
|
||||||
requests to run Salt over an alternative transport, the reasoning was varied,
|
|
||||||
from performance and scaling improvements to licensing concerns. These
|
|
||||||
customers have partnered with SaltStack to make RAET a reality.
|
|
||||||
|
|
||||||
RAET Reliability
|
|
||||||
================
|
|
||||||
|
|
||||||
RAET is reliable, hence the name (Reliable Asynchronous Event Transport).
|
|
||||||
|
|
||||||
The concern posed by some over RAET reliability is based on the fact that
|
|
||||||
RAET used UDP instead of TCP and UDP does not have built in reliability.
|
|
||||||
|
|
||||||
RAET itself implements the needed reliability layers that are not natively
|
|
||||||
present in UDP, this allows RAET to dynamically optimize packet delivery
|
|
||||||
in a way that keeps it both reliable and asynchronous.
|
|
||||||
|
|
||||||
RAET and ZeroMQ
|
|
||||||
===============
|
|
||||||
|
|
||||||
When using RAET, ZeroMQ is not required. RAET is a complete networking
|
|
||||||
replacement. It is noteworthy that RAET is not a ZeroMQ replacement in a
|
|
||||||
general sense, the ZeroMQ constructs are not reproduced in RAET, but they are
|
|
||||||
instead implemented in such a way that is specific to Salt's needs.
|
|
||||||
|
|
||||||
RAET is primarily an async communication layer over truly async connections,
|
|
||||||
defaulting to UDP. ZeroMQ is over TCP and abstracts async constructs within the
|
|
||||||
socket layer.
|
|
||||||
|
|
||||||
Salt is not dropping ZeroMQ support and has no immediate plans to do so.
|
|
||||||
|
|
||||||
Encryption
|
|
||||||
==========
|
|
||||||
|
|
||||||
RAET uses Dan Bernstein's NACL encryption libraries and CurveCP handshake.
|
|
||||||
The libnacl python binding binds to both libsodium and tweetnacl to execute
|
|
||||||
the underlying cryptography.
|
|
||||||
|
|
||||||
Using RAET in Salt
|
Using RAET in Salt
|
||||||
==================
|
==================
|
||||||
|
|
||||||
Using RAET in Salt is easy, the main difference is that the core dependencies
|
Using RAET in Salt is easy, the main difference is that the core dependencies
|
||||||
change, instead of needing pycrypto, M2Crypto, ZeroMQ and PYZMQ, the packages
|
change, instead of needing pycrypto, M2Crypto, ZeroMQ and PYZMQ, the packages
|
||||||
libsodium, libnacl and ioflo are required. Encryption is handled very cleanly
|
libsodium, libnacl, ioflo and raet are required. Encryption is handled very cleanly
|
||||||
by libnacl, while the queueing and flow control is handled by
|
by libnacl, while the queueing and flow control is handled by
|
||||||
ioflo. Distribution packages are forthcoming, but libsodium can be easily
|
ioflo. Distribution packages are forthcoming, but libsodium can be easily
|
||||||
installed from source, or many distributions do ship packages for it.
|
installed from source, or many distributions do ship packages for it.
|
||||||
@ -104,3 +61,77 @@ Now start salt as it would normally be started, the minion will connect to the
|
|||||||
master and share long term keys, which can then in turn be managed via
|
master and share long term keys, which can then in turn be managed via
|
||||||
salt-key. Remote execution and salt states will function in the same way as
|
salt-key. Remote execution and salt states will function in the same way as
|
||||||
with Salt over ZeroMQ.
|
with Salt over ZeroMQ.
|
||||||
|
|
||||||
|
Limitations
|
||||||
|
===========
|
||||||
|
|
||||||
|
The 2014.7 release of RAET is not complete! The Syndic and Multi Master have
|
||||||
|
not been completed yet and these are slated for completetion in the Lithium
|
||||||
|
release.
|
||||||
|
|
||||||
|
Also, Salt-Raet allows for more control over the client but these hooks have
|
||||||
|
not been implimented yet, thereforre the client still uses the same system
|
||||||
|
as the ZeroMQ client. This means that the extra reliability that RAET exposes
|
||||||
|
has not yet been implimented in the CLI client.
|
||||||
|
|
||||||
|
Why?
|
||||||
|
====
|
||||||
|
|
||||||
|
Customer and User Request
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Why make an alternative transport for Salt? There are many reasons, but the
|
||||||
|
primary motivation came from customer requests, many large companies came with
|
||||||
|
requests to run Salt over an alternative transport, the reasoning was varied,
|
||||||
|
from performance and scaling improvements to licensing concerns. These
|
||||||
|
customers have partnered with SaltStack to make RAET a reality.
|
||||||
|
|
||||||
|
More Capabilities
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
RAET has been designed to allow salt to have greater communication
|
||||||
|
capabilities. It has been designed to allow for development into features
|
||||||
|
which out ZeroMQ topologies can't match.
|
||||||
|
|
||||||
|
Many of the proposed features are still under development and will be
|
||||||
|
announced as they enter proff of concept phases, but these features include
|
||||||
|
`salt-fuse` - a filesystem over salt, `salt-vt` - a paralell api driven shell
|
||||||
|
over the salt transport and many others.
|
||||||
|
|
||||||
|
RAET Reliability
|
||||||
|
================
|
||||||
|
|
||||||
|
RAET is reliable, hence the name (Reliable Asynchronous Event Transport).
|
||||||
|
|
||||||
|
The concern posed by some over RAET reliability is based on the fact that
|
||||||
|
RAET uses UDP instead of TCP and UDP does not have built in reliability.
|
||||||
|
|
||||||
|
RAET itself implements the needed reliability layers that are not natively
|
||||||
|
present in UDP, this allows RAET to dynamically optimize packet delivery
|
||||||
|
in a way that keeps it both reliable and asynchronous.
|
||||||
|
|
||||||
|
RAET and ZeroMQ
|
||||||
|
===============
|
||||||
|
|
||||||
|
When using RAET, ZeroMQ is not required. RAET is a complete networking
|
||||||
|
replacement. It is noteworthy that RAET is not a ZeroMQ replacement in a
|
||||||
|
general sense, the ZeroMQ constructs are not reproduced in RAET, but they are
|
||||||
|
instead implemented in such a way that is specific to Salt's needs.
|
||||||
|
|
||||||
|
RAET is primarily an async communication layer over truly async connections,
|
||||||
|
defaulting to UDP. ZeroMQ is over TCP and abstracts async constructs within the
|
||||||
|
socket layer.
|
||||||
|
|
||||||
|
Salt is not dropping ZeroMQ support and has no immediate plans to do so.
|
||||||
|
|
||||||
|
Encryption
|
||||||
|
==========
|
||||||
|
|
||||||
|
RAET uses Dan Bernstein's NACL encryption libraries and CurveCP handshake.
|
||||||
|
The libnacl python binding binds to both libsodium and tweetnacl to execute
|
||||||
|
the underlying cryptography. This allows us to completely rely on an
|
||||||
|
externally developed cryptography system.
|
||||||
|
|
||||||
|
For more information on libsodium and CurveCP please see:
|
||||||
|
http://doc.libsodium.org/
|
||||||
|
http://curvecp.org/
|
||||||
|
@ -103,7 +103,7 @@ to them asking that they fetch their pillars from the master:
|
|||||||
|
|
||||||
salt '*' saltutil.refresh_pillar
|
salt '*' saltutil.refresh_pillar
|
||||||
|
|
||||||
Now that the minions have the new pillar, it can be retreived:
|
Now that the minions have the new pillar, it can be retrieved:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Oct 16 19:26:57 UTC 2014 - aboe76@gmail.com
|
||||||
|
|
||||||
|
- Updated to 2014.1.13 a bugfix release on 2014.1.12
|
||||||
|
+ fix module run exit code (issue 16420)
|
||||||
|
+ salt cloud Check the exit status code of scp before assuming it has failed. (issue 16599)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Oct 10 18:47:07 UTC 2014 - aboe76@gmail.com
|
||||||
|
ff
|
||||||
|
- Updated to 2014.1.12 a bugfix release on 2014.1.11
|
||||||
|
+ Fix scp_file always failing (which broke salt-cloud) (issue 16437)
|
||||||
|
+ Fix regression in pillar in masterless (issue 16210, issue 16416, issue 16428)
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Sep 10 18:10:50 UTC 2014 - aboe76@gmail.com
|
Wed Sep 10 18:10:50 UTC 2014 - aboe76@gmail.com
|
||||||
|
|
||||||
|
@ -15,9 +15,8 @@
|
|||||||
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
Name: salt
|
Name: salt
|
||||||
Version: 2014.1.11
|
Version: 2014.1.13
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: A parallel remote execution system
|
Summary: A parallel remote execution system
|
||||||
License: Apache-2.0
|
License: Apache-2.0
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Index: salt-2014.1.8/pkg/salt-master.service
|
Index: salt-2014.1.8/pkg/salt-master.service
|
||||||
===================================================================
|
===================================================================
|
||||||
--- salt-2014.1.11.orig/pkg/salt-master.service
|
--- salt-2014.1.13.orig/pkg/salt-master.service
|
||||||
+++ salt-2014.1.11/pkg/salt-master.service
|
+++ salt-2014.1.13/pkg/salt-master.service
|
||||||
@@ -3,8 +3,10 @@ Description=The Salt Master Server
|
@@ -3,8 +3,10 @@ Description=The Salt Master Server
|
||||||
After=syslog.target network.target
|
After=syslog.target network.target
|
||||||
|
|
||||||
|
@ -540,7 +540,7 @@ class Single(object):
|
|||||||
'root_dir': os.path.join(self.thin_dir, 'running_data'),
|
'root_dir': os.path.join(self.thin_dir, 'running_data'),
|
||||||
'id': self.id,
|
'id': self.id,
|
||||||
'sock_dir': '/',
|
'sock_dir': '/',
|
||||||
}).strip()
|
}, width=1000).strip()
|
||||||
self.target = kwargs
|
self.target = kwargs
|
||||||
self.target.update(args)
|
self.target.update(args)
|
||||||
self.serial = salt.payload.Serial(opts)
|
self.serial = salt.payload.Serial(opts)
|
||||||
|
@ -93,6 +93,7 @@ def unpack_ext(ext_path):
|
|||||||
'var',
|
'var',
|
||||||
'cache',
|
'cache',
|
||||||
'salt',
|
'salt',
|
||||||
|
'minion',
|
||||||
'extmods')
|
'extmods')
|
||||||
tfile = tarfile.TarFile.gzopen(ext_path)
|
tfile = tarfile.TarFile.gzopen(ext_path)
|
||||||
tfile.extractall(path=modcache)
|
tfile.extractall(path=modcache)
|
||||||
|
@ -101,9 +101,9 @@ def avail_images(call=None):
|
|||||||
items = query(method='images')
|
items = query(method='images')
|
||||||
ret = {}
|
ret = {}
|
||||||
for image in items['images']:
|
for image in items['images']:
|
||||||
ret[image['name']] = {}
|
ret[image['id']] = {}
|
||||||
for item in image.keys():
|
for item in image.keys():
|
||||||
ret[image['name']][item] = str(image[item])
|
ret[image['id']][item] = str(image[item])
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -106,12 +106,12 @@ def avail_images(call=None):
|
|||||||
items = query(method='images', command='?page=' + str(page))
|
items = query(method='images', command='?page=' + str(page))
|
||||||
|
|
||||||
for image in items['images']:
|
for image in items['images']:
|
||||||
ret[image['name']] = {}
|
ret[image['id']] = {}
|
||||||
for item in image.keys():
|
for item in image.keys():
|
||||||
ret[image['name']][item] = str(image[item])
|
ret[image['id']][item] = str(image[item])
|
||||||
|
|
||||||
page += 1
|
page += 1
|
||||||
fetch = next in items['links']['pages']
|
fetch = 'next' in items['links']['pages']
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ Setting up Service Account Authentication:
|
|||||||
- Consider using a more secure location for your private key.
|
- Consider using a more secure location for your private key.
|
||||||
|
|
||||||
Supported commands:
|
Supported commands:
|
||||||
|
|
||||||
# Create a few instances fro profile_name in /etc/salt/cloud.profiles
|
# Create a few instances fro profile_name in /etc/salt/cloud.profiles
|
||||||
- salt-cloud -p profile_name inst1 inst2 inst3
|
- salt-cloud -p profile_name inst1 inst2 inst3
|
||||||
# Delete an instance
|
# Delete an instance
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
# CREATED: 10/15/2012 09:49:37 PM WEST
|
# CREATED: 10/15/2012 09:49:37 PM WEST
|
||||||
#======================================================================================================================
|
#======================================================================================================================
|
||||||
set -o nounset # Treat unset variables as an error
|
set -o nounset # Treat unset variables as an error
|
||||||
__ScriptVersion="2014.10.14"
|
__ScriptVersion="2014.10.28"
|
||||||
__ScriptName="bootstrap-salt.sh"
|
__ScriptName="bootstrap-salt.sh"
|
||||||
|
|
||||||
#======================================================================================================================
|
#======================================================================================================================
|
||||||
@ -202,6 +202,7 @@ _INSECURE_DL=${BS_INSECURE_DL:-$BS_FALSE}
|
|||||||
_WGET_ARGS=${BS_WGET_ARGS:-}
|
_WGET_ARGS=${BS_WGET_ARGS:-}
|
||||||
_CURL_ARGS=${BS_CURL_ARGS:-}
|
_CURL_ARGS=${BS_CURL_ARGS:-}
|
||||||
_FETCH_ARGS=${BS_FETCH_ARGS:-}
|
_FETCH_ARGS=${BS_FETCH_ARGS:-}
|
||||||
|
_ENABLE_EXTERNAL_ZMQ_REPOS=${BS_ENABLE_EXTERNAL_ZMQ_REPOS:-$BS_FALSE}
|
||||||
_SALT_MASTER_ADDRESS=${BS_SALT_MASTER_ADDRESS:-null}
|
_SALT_MASTER_ADDRESS=${BS_SALT_MASTER_ADDRESS:-null}
|
||||||
_SALT_MINION_ID="null"
|
_SALT_MINION_ID="null"
|
||||||
# __SIMPLIFY_VERSION is mostly used in Solaris based distributions
|
# __SIMPLIFY_VERSION is mostly used in Solaris based distributions
|
||||||
@ -242,6 +243,7 @@ usage() {
|
|||||||
-D Show debug output.
|
-D Show debug output.
|
||||||
-c Temporary configuration directory
|
-c Temporary configuration directory
|
||||||
-g Salt repository URL. (default: git://github.com/saltstack/salt.git)
|
-g Salt repository URL. (default: git://github.com/saltstack/salt.git)
|
||||||
|
-G Insteady of cloning from git://github.com/saltstack/salt.git, clone from https://github.com/saltstack/salt.git (Usually necessary on systems which have the regular git protocol port blocked, where https usualy is not)
|
||||||
-k Temporary directory holding the minion keys which will pre-seed
|
-k Temporary directory holding the minion keys which will pre-seed
|
||||||
the master.
|
the master.
|
||||||
-s Sleep time used when waiting for daemons to start, restart and when checking
|
-s Sleep time used when waiting for daemons to start, restart and when checking
|
||||||
@ -271,12 +273,13 @@ usage() {
|
|||||||
-p Extra-package to install while installing salt dependencies. One package
|
-p Extra-package to install while installing salt dependencies. One package
|
||||||
per -p flag. You're responsible for providing the proper package name.
|
per -p flag. You're responsible for providing the proper package name.
|
||||||
-H Use the specified http proxy for the installation
|
-H Use the specified http proxy for the installation
|
||||||
|
-Z Enable external software source for newer ZeroMQ(Only available for RHEL/CentOS/Fedora based distributions)
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
} # ---------- end of function usage ----------
|
} # ---------- end of function usage ----------
|
||||||
|
|
||||||
|
|
||||||
while getopts ":hvnDc:g:k:MSNXCPFUKIA:i:Lp:H:" opt
|
while getopts ":hvnDc:Gg:k:MSNXCPFUKIA:i:Lp:H:Z" opt
|
||||||
do
|
do
|
||||||
case "${opt}" in
|
case "${opt}" in
|
||||||
|
|
||||||
@ -297,6 +300,13 @@ do
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
g ) _SALT_REPO_URL=$OPTARG ;;
|
g ) _SALT_REPO_URL=$OPTARG ;;
|
||||||
|
G ) if [ "${_SALT_REPO_URL}" = "${_SALTSTACK_REPO_URL}" ]; then
|
||||||
|
_SALTSTACK_REPO_URL="https://github.com/saltstack/salt.git"
|
||||||
|
_SALT_REPO_URL=${_SALTSTACK_REPO_URL}
|
||||||
|
else
|
||||||
|
_SALTSTACK_REPO_URL="https://github.com/saltstack/salt.git"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
k ) _TEMP_KEYS_DIR="$OPTARG"
|
k ) _TEMP_KEYS_DIR="$OPTARG"
|
||||||
# If the configuration directory does not exist, error out
|
# If the configuration directory does not exist, error out
|
||||||
if [ ! -d "$_TEMP_KEYS_DIR" ]; then
|
if [ ! -d "$_TEMP_KEYS_DIR" ]; then
|
||||||
@ -319,6 +329,7 @@ do
|
|||||||
L ) _INSTALL_CLOUD=$BS_TRUE ;;
|
L ) _INSTALL_CLOUD=$BS_TRUE ;;
|
||||||
p ) _EXTRA_PACKAGES="$_EXTRA_PACKAGES $OPTARG" ;;
|
p ) _EXTRA_PACKAGES="$_EXTRA_PACKAGES $OPTARG" ;;
|
||||||
H ) _HTTP_PROXY="$OPTARG" ;;
|
H ) _HTTP_PROXY="$OPTARG" ;;
|
||||||
|
Z) _ENABLE_EXTERNAL_ZMQ_REPOS=$BS_TRUE ;;
|
||||||
|
|
||||||
|
|
||||||
\?) echo
|
\?) echo
|
||||||
@ -1124,7 +1135,10 @@ __git_clone_and_checkout() {
|
|||||||
|
|
||||||
echodebug "Installed git version: $(git --version | awk '{ print $3 }')"
|
echodebug "Installed git version: $(git --version | awk '{ print $3 }')"
|
||||||
|
|
||||||
__SALT_GIT_CHECKOUT_PARENT_DIR=$(dirname "${__SALT_GIT_CHECKOUT_DIR}")
|
local __SALT_GIT_CHECKOUT_PARENT_DIR=$(dirname "${__SALT_GIT_CHECKOUT_DIR}" 2>/dev/null)
|
||||||
|
__SALT_GIT_CHECKOUT_PARENT_DIR="${__SALT_GIT_CHECKOUT_PARENT_DIR:-/tmp/git}"
|
||||||
|
local __SALT_CHECKOUT_REPONAME="$(basename "${__SALT_GIT_CHECKOUT_DIR}" 2>/dev/null)"
|
||||||
|
__SALT_CHECKOUT_REPONAME="${__SALT_CHECKOUT_REPONAME:-salt}"
|
||||||
[ -d "${__SALT_GIT_CHECKOUT_PARENT_DIR}" ] || mkdir "${__SALT_GIT_CHECKOUT_PARENT_DIR}"
|
[ -d "${__SALT_GIT_CHECKOUT_PARENT_DIR}" ] || mkdir "${__SALT_GIT_CHECKOUT_PARENT_DIR}"
|
||||||
cd "${__SALT_GIT_CHECKOUT_PARENT_DIR}"
|
cd "${__SALT_GIT_CHECKOUT_PARENT_DIR}"
|
||||||
if [ -d "${__SALT_GIT_CHECKOUT_DIR}" ]; then
|
if [ -d "${__SALT_GIT_CHECKOUT_DIR}" ]; then
|
||||||
@ -1170,7 +1184,7 @@ __git_clone_and_checkout() {
|
|||||||
if [ "$(git clone --help | grep 'single-branch')" != "" ]; then
|
if [ "$(git clone --help | grep 'single-branch')" != "" ]; then
|
||||||
# The "--single-branch" option is supported, attempt shallow cloning
|
# The "--single-branch" option is supported, attempt shallow cloning
|
||||||
echoinfo "Attempting to shallow clone $GIT_REV from Salt's repository ${_SALT_REPO_URL}"
|
echoinfo "Attempting to shallow clone $GIT_REV from Salt's repository ${_SALT_REPO_URL}"
|
||||||
git clone --depth 1 --branch "$GIT_REV" "$_SALT_REPO_URL"
|
git clone --depth 1 --branch "$GIT_REV" "$_SALT_REPO_URL" "$__SALT_CHECKOUT_REPONAME"
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
cd "${__SALT_GIT_CHECKOUT_DIR}"
|
cd "${__SALT_GIT_CHECKOUT_DIR}"
|
||||||
__SHALLOW_CLONE="${BS_TRUE}"
|
__SHALLOW_CLONE="${BS_TRUE}"
|
||||||
@ -1178,17 +1192,17 @@ __git_clone_and_checkout() {
|
|||||||
# Shallow clone above failed(missing upstream tags???), let's resume the old behaviour.
|
# Shallow clone above failed(missing upstream tags???), let's resume the old behaviour.
|
||||||
echowarn "Failed to shallow clone."
|
echowarn "Failed to shallow clone."
|
||||||
echoinfo "Resuming regular git clone and remote SaltStack repository addition procedure"
|
echoinfo "Resuming regular git clone and remote SaltStack repository addition procedure"
|
||||||
git clone "$_SALT_REPO_URL" || return 1
|
git clone "$_SALT_REPO_URL" "$__SALT_CHECKOUT_REPONAME" || return 1
|
||||||
cd "${__SALT_GIT_CHECKOUT_DIR}"
|
cd "${__SALT_GIT_CHECKOUT_DIR}"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echodebug "Shallow cloning not possible. Required git version not met."
|
echodebug "Shallow cloning not possible. Required git version not met."
|
||||||
git clone "$_SALT_REPO_URL" || return 1
|
git clone "$_SALT_REPO_URL" "$__SALT_CHECKOUT_REPONAME" || return 1
|
||||||
cd "${__SALT_GIT_CHECKOUT_DIR}"
|
cd "${__SALT_GIT_CHECKOUT_DIR}"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echowarn "The git revision being installed does not match a Salt version tag. Shallow cloning disabled"
|
echowarn "The git revision being installed does not match a Salt version tag. Shallow cloning disabled"
|
||||||
git clone "$_SALT_REPO_URL" || return 1
|
git clone "$_SALT_REPO_URL" "$__SALT_CHECKOUT_REPONAME" || return 1
|
||||||
cd "${__SALT_GIT_CHECKOUT_DIR}"
|
cd "${__SALT_GIT_CHECKOUT_DIR}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -1540,7 +1554,7 @@ __check_services_debian() {
|
|||||||
servicename=$1
|
servicename=$1
|
||||||
echodebug "Checking if service ${servicename} is enabled"
|
echodebug "Checking if service ${servicename} is enabled"
|
||||||
|
|
||||||
# shellcheck disable=SC2086,SC2046
|
# shellcheck disable=SC2086,SC2046,SC2144
|
||||||
if [ -f /etc/rc$(runlevel | awk '{ print $2 }').d/S*${servicename} ]; then
|
if [ -f /etc/rc$(runlevel | awk '{ print $2 }').d/S*${servicename} ]; then
|
||||||
echodebug "Service ${servicename} is enabled"
|
echodebug "Service ${servicename} is enabled"
|
||||||
return 0
|
return 0
|
||||||
@ -1695,6 +1709,10 @@ install_ubuntu_deps() {
|
|||||||
__apt_get_install_noinput python-apt
|
__apt_get_install_noinput python-apt
|
||||||
|
|
||||||
if [ "$DISTRO_MAJOR_VERSION" -gt 12 ] || ([ "$DISTRO_MAJOR_VERSION" -eq 12 ] && [ "$DISTRO_MINOR_VERSION" -gt 03 ]); then
|
if [ "$DISTRO_MAJOR_VERSION" -gt 12 ] || ([ "$DISTRO_MAJOR_VERSION" -eq 12 ] && [ "$DISTRO_MINOR_VERSION" -gt 03 ]); then
|
||||||
|
if [ "$_ENABLE_EXTERNAL_ZMQ_REPOS" -eq $BS_TRUE ]; then
|
||||||
|
echoinfo "Installing ZMQ>=4/PyZMQ>=14 from Chris Lea's PPA repository"
|
||||||
|
add-apt-repository -y ppa:chris-lea/zeromq || return 1
|
||||||
|
fi
|
||||||
__apt_get_install_noinput python-requests
|
__apt_get_install_noinput python-requests
|
||||||
__PIP_PACKAGES=""
|
__PIP_PACKAGES=""
|
||||||
else
|
else
|
||||||
@ -2360,6 +2378,10 @@ install_debian_check_services() {
|
|||||||
# Fedora Install Functions
|
# Fedora Install Functions
|
||||||
#
|
#
|
||||||
install_fedora_deps() {
|
install_fedora_deps() {
|
||||||
|
if [ "$_ENABLE_EXTERNAL_ZMQ_REPOS" -eq $BS_TRUE ]; then
|
||||||
|
__install_saltstack_copr_zeromq_repository || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
__PACKAGES="yum-utils PyYAML libyaml m2crypto python-crypto python-jinja2 python-msgpack python-zmq python-requests"
|
__PACKAGES="yum-utils PyYAML libyaml m2crypto python-crypto python-jinja2 python-msgpack python-zmq python-requests"
|
||||||
|
|
||||||
if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then
|
if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then
|
||||||
@ -2415,7 +2437,7 @@ install_fedora_stable_post() {
|
|||||||
install_fedora_git_deps() {
|
install_fedora_git_deps() {
|
||||||
install_fedora_deps || return 1
|
install_fedora_deps || return 1
|
||||||
|
|
||||||
yum install -y git || return 1
|
yum install -y git systemd-python || return 1
|
||||||
|
|
||||||
__git_clone_and_checkout || return 1
|
__git_clone_and_checkout || return 1
|
||||||
|
|
||||||
@ -2531,9 +2553,28 @@ __install_epel_repository() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__install_saltstack_copr_zeromq_repository() {
|
||||||
|
echoinfo "Installing Zeromq >=4 and PyZMQ>=14 from SaltStack's COPR repository"
|
||||||
|
if [ ! -f /etc/yum.repos.d/saltstack-zeromq4.repo ]; then
|
||||||
|
if [ "${DISTRO_NAME_L}" = "fedora" ]; then
|
||||||
|
__REPOTYPE="${DISTRO_NAME_L}"
|
||||||
|
else
|
||||||
|
__REPOTYPE="epel"
|
||||||
|
fi
|
||||||
|
wget -O /etc/yum.repos.d/saltstack-zeromq4.repo \
|
||||||
|
"https://copr.fedoraproject.org/coprs/saltstack/zeromq4/repo/${__REPOTYPE}-${DISTRO_MAJOR_VERSION}/saltstack-zeromq4-${__REPOTYPE}-${DISTRO_MAJOR_VERSION}.repo" || return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
install_centos_stable_deps() {
|
install_centos_stable_deps() {
|
||||||
__install_epel_repository || return 1
|
__install_epel_repository || return 1
|
||||||
|
|
||||||
|
if [ "$_ENABLE_EXTERNAL_ZMQ_REPOS" -eq $BS_TRUE ]; then
|
||||||
|
__install_saltstack_copr_zeromq_repository || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then
|
if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then
|
||||||
yum -y update || return 1
|
yum -y update || return 1
|
||||||
fi
|
fi
|
||||||
@ -2674,7 +2715,7 @@ install_centos_git() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_centos_git_post() {
|
install_centos_git_post() {
|
||||||
for fname in minion master minion api; do
|
for fname in minion master syndic api; do
|
||||||
|
|
||||||
# Skip if not meant to be installed
|
# Skip if not meant to be installed
|
||||||
[ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue
|
[ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue
|
||||||
@ -3344,7 +3385,7 @@ install_arch_linux_git_deps() {
|
|||||||
pacman -R --noconfirm --needed python2-distribute
|
pacman -R --noconfirm --needed python2-distribute
|
||||||
pacman -Sy --noconfirm --needed git python2-crypto python2-setuptools python2-jinja \
|
pacman -Sy --noconfirm --needed git python2-crypto python2-setuptools python2-jinja \
|
||||||
python2-m2crypto python2-markupsafe python2-msgpack python2-psutil python2-yaml \
|
python2-m2crypto python2-markupsafe python2-msgpack python2-psutil python2-yaml \
|
||||||
python2-pyzmq zeromq python2-requests || return 1
|
python2-pyzmq zeromq python2-requests python2-systemd || return 1
|
||||||
|
|
||||||
__git_clone_and_checkout || return 1
|
__git_clone_and_checkout || return 1
|
||||||
|
|
||||||
@ -3656,9 +3697,9 @@ install_freebsd_git() {
|
|||||||
# Install from git
|
# Install from git
|
||||||
if [ ! -f salt/syspaths.py ]; then
|
if [ ! -f salt/syspaths.py ]; then
|
||||||
# We still can't provide the system paths, salt 0.16.x
|
# We still can't provide the system paths, salt 0.16.x
|
||||||
/usr/local/bin/python setup.py install || return 1
|
/usr/local/bin/python2 setup.py install || return 1
|
||||||
else
|
else
|
||||||
/usr/local/bin/python setup.py install \
|
/usr/local/bin/python2 setup.py install \
|
||||||
--salt-root-dir=/usr/local \
|
--salt-root-dir=/usr/local \
|
||||||
--salt-config-dir="${_SALT_ETC_DIR}" \
|
--salt-config-dir="${_SALT_ETC_DIR}" \
|
||||||
--salt-cache-dir=/var/cache/salt \
|
--salt-cache-dir=/var/cache/salt \
|
||||||
|
@ -294,7 +294,7 @@ DEFAULT_MINION_OPTS = {
|
|||||||
'failhard': False,
|
'failhard': False,
|
||||||
'autoload_dynamic_modules': True,
|
'autoload_dynamic_modules': True,
|
||||||
'environment': None,
|
'environment': None,
|
||||||
'extension_modules': os.path.join(salt.syspaths.CACHE_DIR, 'extmods'),
|
'extension_modules': '',
|
||||||
'state_top': 'top.sls',
|
'state_top': 'top.sls',
|
||||||
'startup_states': '',
|
'startup_states': '',
|
||||||
'sls_list': [],
|
'sls_list': [],
|
||||||
|
@ -21,6 +21,7 @@ import salt.crypt
|
|||||||
import salt.loader
|
import salt.loader
|
||||||
import salt.payload
|
import salt.payload
|
||||||
import salt.transport
|
import salt.transport
|
||||||
|
import salt.fileserver
|
||||||
import salt.utils
|
import salt.utils
|
||||||
import salt.utils.templates
|
import salt.utils.templates
|
||||||
import salt.utils.gzip_util
|
import salt.utils.gzip_util
|
||||||
|
@ -1489,7 +1489,8 @@ class ClearFuncs(object):
|
|||||||
pass
|
pass
|
||||||
elif os.path.isfile(pubfn_rejected):
|
elif os.path.isfile(pubfn_rejected):
|
||||||
# The key has been rejected, don't place it in pending
|
# The key has been rejected, don't place it in pending
|
||||||
log.info('Public key rejected for {id}'.format(**load))
|
log.info('Public key rejected for {0}. Key is present in '
|
||||||
|
'rejection key dir.'.format(load['id']))
|
||||||
eload = {'result': False,
|
eload = {'result': False,
|
||||||
'id': load['id'],
|
'id': load['id'],
|
||||||
'pub': load['pub']}
|
'pub': load['pub']}
|
||||||
@ -2254,14 +2255,17 @@ class ClearFuncs(object):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
# Retrieve the jid
|
# Retrieve the jid
|
||||||
if not clear_load['jid']:
|
|
||||||
fstr = '{0}.prep_jid'.format(self.opts['master_job_cache'])
|
fstr = '{0}.prep_jid'.format(self.opts['master_job_cache'])
|
||||||
try:
|
try:
|
||||||
clear_load['jid'] = self.mminion.returners[fstr](nocache=extra.get('nocache', False))
|
clear_load['jid'] = self.mminion.returners[fstr](nocache=extra.get('nocache', False),
|
||||||
|
# the jid in clear_load can be None, '', or something else.
|
||||||
|
# this is an attempt to clean up the value before passing to plugins
|
||||||
|
passed_jid=clear_load['jid'] if clear_load.get('jid') else None)
|
||||||
except TypeError: # The returner is not present
|
except TypeError: # The returner is not present
|
||||||
log.error('The requested returner {0} could not be loaded. Publication not sent.'.format(fstr.split('.')[0]))
|
log.error('The requested returner {0} could not be loaded. Publication not sent.'.format(fstr.split('.')[0]))
|
||||||
return {}
|
return {}
|
||||||
# TODO Error reporting over the master event bus
|
# TODO Error reporting over the master event bus
|
||||||
|
|
||||||
self.event.fire_event({'minions': minions}, clear_load['jid'])
|
self.event.fire_event({'minions': minions}, clear_load['jid'])
|
||||||
|
|
||||||
new_job_load = {
|
new_job_load = {
|
||||||
|
@ -105,10 +105,10 @@ def resolve_dns(opts):
|
|||||||
if opts['retry_dns']:
|
if opts['retry_dns']:
|
||||||
while True:
|
while True:
|
||||||
import salt.log
|
import salt.log
|
||||||
msg = ('Master hostname: {0} not found. Retrying in {1} '
|
msg = ('Master hostname: \'{0}\' not found. Retrying in {1} '
|
||||||
'seconds').format(opts['master'], opts['retry_dns'])
|
'seconds').format(opts['master'], opts['retry_dns'])
|
||||||
if salt.log.is_console_configured():
|
if salt.log.is_console_configured():
|
||||||
log.warn(msg)
|
log.error(msg)
|
||||||
else:
|
else:
|
||||||
print('WARNING: {0}'.format(msg))
|
print('WARNING: {0}'.format(msg))
|
||||||
time.sleep(opts['retry_dns'])
|
time.sleep(opts['retry_dns'])
|
||||||
@ -711,6 +711,8 @@ class Minion(MinionBase):
|
|||||||
' {0}'.format(opts['master']))
|
' {0}'.format(opts['master']))
|
||||||
if opts['master_shuffle']:
|
if opts['master_shuffle']:
|
||||||
shuffle(opts['master'])
|
shuffle(opts['master'])
|
||||||
|
elif opts['__role'] == 'syndic':
|
||||||
|
log.info('Syndic setting master_syndic to \'{0}\''.format(opts['master']))
|
||||||
|
|
||||||
# if failed=True, the minion was previously connected
|
# if failed=True, the minion was previously connected
|
||||||
# we're probably called from the minions main-event-loop
|
# we're probably called from the minions main-event-loop
|
||||||
@ -1971,16 +1973,18 @@ class Syndic(Minion):
|
|||||||
'''
|
'''
|
||||||
Lock onto the publisher. This is the main event loop for the syndic
|
Lock onto the publisher. This is the main event loop for the syndic
|
||||||
'''
|
'''
|
||||||
# Instantiate the local client
|
|
||||||
self.local = salt.client.get_local_client(self.opts['_minion_conf_file'])
|
|
||||||
self.local.event.subscribe('')
|
|
||||||
self.local.opts['interface'] = self._syndic_interface
|
|
||||||
|
|
||||||
signal.signal(signal.SIGTERM, self.clean_die)
|
signal.signal(signal.SIGTERM, self.clean_die)
|
||||||
log.debug('Syndic {0!r} trying to tune in'.format(self.opts['id']))
|
log.debug('Syndic {0!r} trying to tune in'.format(self.opts['id']))
|
||||||
|
|
||||||
self._init_context_and_poller()
|
self._init_context_and_poller()
|
||||||
|
|
||||||
|
# Instantiate the local client
|
||||||
|
self.local = salt.client.get_local_client(self.opts['_minion_conf_file'])
|
||||||
|
self.local.event.subscribe('')
|
||||||
|
self.local.opts['interface'] = self._syndic_interface
|
||||||
|
# register the event sub to the poller
|
||||||
|
self.poller.register(self.local.event.sub)
|
||||||
|
|
||||||
# Start with the publish socket
|
# Start with the publish socket
|
||||||
# Share the poller with the event object
|
# Share the poller with the event object
|
||||||
self.socket = self.context.socket(zmq.SUB)
|
self.socket = self.context.socket(zmq.SUB)
|
||||||
|
469
salt/modules/drac.py
Normal file
469
salt/modules/drac.py
Normal file
@ -0,0 +1,469 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Manage Dell DRAC
|
||||||
|
'''
|
||||||
|
|
||||||
|
import salt.utils
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def __virtual__():
|
||||||
|
'''
|
||||||
|
|
||||||
|
'''
|
||||||
|
if salt.utils.which('racadm'):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def __parse_drac(output):
|
||||||
|
'''
|
||||||
|
Parse Dell DRAC output
|
||||||
|
'''
|
||||||
|
drac = {}
|
||||||
|
section = ''
|
||||||
|
|
||||||
|
for i in output.splitlines():
|
||||||
|
if len(i.rstrip()) > 0 and '=' in i:
|
||||||
|
if section in drac:
|
||||||
|
drac[section].update(dict(
|
||||||
|
[[prop.strip() for prop in i.split('=')]]
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
section = i.strip()[:-1]
|
||||||
|
if section not in drac and section:
|
||||||
|
drac[section] = {}
|
||||||
|
|
||||||
|
return drac
|
||||||
|
|
||||||
|
|
||||||
|
def __execute_cmd(command):
|
||||||
|
'''
|
||||||
|
Execute rac commands
|
||||||
|
'''
|
||||||
|
cmd = __salt__['cmd.run_all']('racadm {0}'.format(command))
|
||||||
|
|
||||||
|
if cmd['retcode'] != 0:
|
||||||
|
log.warn('racadm return an exit code \'{0}\'.'.format(cmd['retcode']))
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def system_info():
|
||||||
|
'''
|
||||||
|
Return System information
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.getsysinfo
|
||||||
|
'''
|
||||||
|
drac = {}
|
||||||
|
section = ''
|
||||||
|
|
||||||
|
cmd = __salt__['cmd.run_all']('racadm getsysinfo')
|
||||||
|
|
||||||
|
if cmd['retcode'] != 0:
|
||||||
|
log.warn('racadm return an exit code \'{0}\'.'.format(cmd['retcode']))
|
||||||
|
|
||||||
|
return __parse_drac(cmd['stdout'])
|
||||||
|
|
||||||
|
|
||||||
|
def network_info():
|
||||||
|
'''
|
||||||
|
Return Network Configuration
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.getniccfg
|
||||||
|
'''
|
||||||
|
|
||||||
|
cmd = __salt__['cmd.run_all']('racadm getniccfg')
|
||||||
|
|
||||||
|
if cmd['retcode'] != 0:
|
||||||
|
log.warn('racadm return an exit code \'{0}\'.'.format(cmd['retcode']))
|
||||||
|
|
||||||
|
return __parse_drac(cmd['stdout'])
|
||||||
|
|
||||||
|
|
||||||
|
def nameservers(*ns):
|
||||||
|
'''
|
||||||
|
Configure the nameservers on the DRAC
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.nameservers [NAMESERVERS]
|
||||||
|
salt dell drac.nameservers ns1.example.com ns2.example.com
|
||||||
|
'''
|
||||||
|
if len(ns) > 2:
|
||||||
|
log.warn('racadm only supports two nameservers')
|
||||||
|
return False
|
||||||
|
|
||||||
|
for i in range(1, len(ns) + 1):
|
||||||
|
if not __execute_cmd('config -g cfgLanNetworking -o \
|
||||||
|
cfgDNSServer{0} {1}'.format(i, ns[i - 1])):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def syslog(server, enable=True):
|
||||||
|
'''
|
||||||
|
Configure syslog remote logging, by default syslog will automatically be
|
||||||
|
enabled if a server is specified. However, if you want to disable syslog
|
||||||
|
you will need to specify a server followed by False
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.syslog [SYSLOG IP] [ENABLE/DISABLE]
|
||||||
|
salt dell drac.syslog 0.0.0.0 False
|
||||||
|
'''
|
||||||
|
if enable:
|
||||||
|
if __execute_cmd('config -g cfgRemoteHosts -o \
|
||||||
|
cfgRhostsSyslogEnable 1'):
|
||||||
|
return __execute_cmd('config -g cfgRemoteHosts -o \
|
||||||
|
cfgRhostsSyslogServer1 {0}'.format(server))
|
||||||
|
|
||||||
|
return __execute_cmd('config -g cfgRemoteHosts -o cfgRhostsSyslogEnable 0')
|
||||||
|
|
||||||
|
|
||||||
|
def email_alerts(action):
|
||||||
|
'''
|
||||||
|
Enable/Disable email alerts
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.email_alerts True
|
||||||
|
salt dell drac.email_alerts False
|
||||||
|
'''
|
||||||
|
|
||||||
|
if action:
|
||||||
|
return __execute_cmd('config -g cfgEmailAlert -o \
|
||||||
|
cfgEmailAlertEnable -i 1 1')
|
||||||
|
else:
|
||||||
|
return __execute_cmd('config -g cfgEmailAlert -o \
|
||||||
|
cfgEmailAlertEnable -i 1 0')
|
||||||
|
|
||||||
|
|
||||||
|
def list_users():
|
||||||
|
'''
|
||||||
|
List all DRAC users
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.list_users
|
||||||
|
'''
|
||||||
|
users = {}
|
||||||
|
_username = ''
|
||||||
|
|
||||||
|
for i in range(1, 12):
|
||||||
|
cmd = __salt__['cmd.run_all']('racadm getconfig -g \
|
||||||
|
cfgUserAdmin -i {0}'.format(i))
|
||||||
|
|
||||||
|
if cmd['retcode'] != 0:
|
||||||
|
log.warn('racadm return an exit \
|
||||||
|
code \'{0}\'.'.format(cmd['retcode']))
|
||||||
|
|
||||||
|
for user in cmd['stdout'].splitlines():
|
||||||
|
if 'cfgUserAdminIndex' in user or user.startswith('#'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
(k, v) = user.split('=')
|
||||||
|
|
||||||
|
if k.startswith('cfgUserAdminUserName'):
|
||||||
|
_username = v.strip()
|
||||||
|
|
||||||
|
if v:
|
||||||
|
users[_username] = {'index': i}
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
users[_username].update({k: v})
|
||||||
|
|
||||||
|
return users
|
||||||
|
|
||||||
|
|
||||||
|
def delete_user(username, uid=None):
|
||||||
|
'''
|
||||||
|
Delete a user
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.delete_user [USERNAME] [UID - optional]
|
||||||
|
salt dell drac.delete_user diana 4
|
||||||
|
'''
|
||||||
|
if uid is None:
|
||||||
|
user = list_users()
|
||||||
|
uid = user[username]['index']
|
||||||
|
|
||||||
|
if uid:
|
||||||
|
return __execute_cmd('config -g cfgUserAdmin -o \
|
||||||
|
cfgUserAdminUserName -i {0} ""'.format(uid))
|
||||||
|
|
||||||
|
else:
|
||||||
|
log.warn('\'{0}\' does not exist'.format(username))
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def change_password(username, password, uid=None):
|
||||||
|
'''
|
||||||
|
Change users password
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.change_password [USERNAME] [PASSWORD] [UID - optional]
|
||||||
|
salt dell drac.change_password diana secret
|
||||||
|
'''
|
||||||
|
if uid is None:
|
||||||
|
user = list_users()
|
||||||
|
uid = user[username]['index']
|
||||||
|
|
||||||
|
if uid:
|
||||||
|
return __execute_cmd('config -g cfgUserAdmin -o \
|
||||||
|
cfgUserAdminPassword -i {0} {1}'.format(uid, password))
|
||||||
|
else:
|
||||||
|
log.warn('\'{0}\' does not exist'.format(username))
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def create_user(username, password, permissions):
|
||||||
|
'''
|
||||||
|
Create user accounts
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.create_user [USERNAME] [PASSWORD] [PRIVELEGES]
|
||||||
|
salt dell drac.create_user diana secret login,test_alerts,clear_logs
|
||||||
|
|
||||||
|
DRAC Priveleges
|
||||||
|
* login : Login to iDRAC
|
||||||
|
* drac : Configure iDRAC
|
||||||
|
* user_management : Configure Users
|
||||||
|
* clear_logs : Clear Logs
|
||||||
|
* server_control_commands : Execute Server Control Commands
|
||||||
|
* console_redirection : Access Console Redirection
|
||||||
|
* virtual_media : Access Virtual Media
|
||||||
|
* test_alerts : Test Alerts
|
||||||
|
* debug_commands : Execute Debug Commands
|
||||||
|
'''
|
||||||
|
_uids = set()
|
||||||
|
|
||||||
|
user = list_users()
|
||||||
|
|
||||||
|
if username in user:
|
||||||
|
log.warn('\'{0}\' already exists'.format(username))
|
||||||
|
return False
|
||||||
|
|
||||||
|
for i in user.keys():
|
||||||
|
_uids.add(user[i]['index'])
|
||||||
|
|
||||||
|
uid = sorted(list(set(xrange(2, 12)) - _uids), reverse=True).pop()
|
||||||
|
|
||||||
|
# Create user accountvfirst
|
||||||
|
if not __execute_cmd('config -g cfgUserAdmin -o \
|
||||||
|
cfgUserAdminUserName -i {0} {1}'.format(uid, username)):
|
||||||
|
delete_user(username, uid)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Configure users permissions
|
||||||
|
if not set_permissions(username, permissions, uid):
|
||||||
|
log.warn('unable to set user permissions')
|
||||||
|
delete_user(username, uid)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Configure users password
|
||||||
|
if not change_password(username, password, uid):
|
||||||
|
log.warn('unable to set user password')
|
||||||
|
delete_user(username, uid)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Enable users admin
|
||||||
|
if not __execute_cmd('config -g cfgUserAdmin -o \
|
||||||
|
cfgUserAdminEnable -i {0} 1'.format(uid)):
|
||||||
|
delete_user(username, uid)
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def set_permissions(username, permissions, uid=None):
|
||||||
|
'''
|
||||||
|
Configure users permissions
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.set_permissions [USERNAME] [PRIVELEGES] [USER INDEX - optional]
|
||||||
|
salt dell drac.set_permissions diana login,test_alerts,clear_logs 4
|
||||||
|
|
||||||
|
DRAC Priveleges
|
||||||
|
* login : Login to iDRAC
|
||||||
|
* drac : Configure iDRAC
|
||||||
|
* user_management : Configure Users
|
||||||
|
* clear_logs : Clear Logs
|
||||||
|
* server_control_commands : Execute Server Control Commands
|
||||||
|
* console_redirection : Access Console Redirection
|
||||||
|
* virtual_media : Access Virtual Media
|
||||||
|
* test_alerts : Test Alerts
|
||||||
|
* debug_commands : Execute Debug Commands
|
||||||
|
'''
|
||||||
|
privileges = {'login': '0x0000001',
|
||||||
|
'drac': '0x0000002',
|
||||||
|
'user_management': '0x0000004',
|
||||||
|
'clear_logs': '0x0000008',
|
||||||
|
'server_control_commands': '0x0000010',
|
||||||
|
'console_redirection': '0x0000020',
|
||||||
|
'virtual_media': '0x0000040',
|
||||||
|
'test_alerts': '0x0000080',
|
||||||
|
'debug_commands': '0x0000100'}
|
||||||
|
|
||||||
|
permission = 0
|
||||||
|
|
||||||
|
# When users don't provide a user ID we need to search for this
|
||||||
|
if uid is None:
|
||||||
|
user = list_users()
|
||||||
|
uid = user[username]['index']
|
||||||
|
|
||||||
|
# Generate privilege bit mask
|
||||||
|
for i in permissions.split(','):
|
||||||
|
perm = i.strip()
|
||||||
|
|
||||||
|
if perm in privileges:
|
||||||
|
permission += int(privileges[perm], 16)
|
||||||
|
|
||||||
|
return __execute_cmd('config -g cfgUserAdmin -o \
|
||||||
|
cfgUserAdminPrivilege -i {0} 0x{1:08X}'.format(uid, permission))
|
||||||
|
|
||||||
|
|
||||||
|
def set_snmp(community):
|
||||||
|
'''
|
||||||
|
Configure SNMP community string
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.set_snmp [COMMUNITY]
|
||||||
|
salt dell drac.set_snmp public
|
||||||
|
'''
|
||||||
|
return __execute_cmd('config -g cfgOobSnmp -o \
|
||||||
|
cfgOobSnmpAgentCommunity {0}'.format(community))
|
||||||
|
|
||||||
|
|
||||||
|
def set_network(ip, netmask, gateway):
|
||||||
|
'''
|
||||||
|
Configure Network
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.set_network [DRAC IP] [NETMASK] [GATEWAY]
|
||||||
|
salt dell drac.set_network 192.168.0.2 255.255.255.0 192.168.0.1
|
||||||
|
'''
|
||||||
|
return __execute_cmd('setniccfg -s {0} {1} {2}'.format(
|
||||||
|
ip, netmask, gateway
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def server_reboot():
|
||||||
|
'''
|
||||||
|
Issues a power-cycle operation on the managed server. This action is
|
||||||
|
similar to pressing the power button on the system's front panel to
|
||||||
|
power down and then power up the system.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.server_reboot
|
||||||
|
'''
|
||||||
|
return __execute_cmd('serveraction powercycle')
|
||||||
|
|
||||||
|
|
||||||
|
def server_poweroff():
|
||||||
|
'''
|
||||||
|
Powers down the managed server.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.server_poweroff
|
||||||
|
'''
|
||||||
|
return __execute_cmd('serveraction powerdown')
|
||||||
|
|
||||||
|
|
||||||
|
def server_poweron():
|
||||||
|
'''
|
||||||
|
Powers up the managed server.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.server_poweron
|
||||||
|
'''
|
||||||
|
return __execute_cmd('serveraction powerup')
|
||||||
|
|
||||||
|
|
||||||
|
def server_hardreset():
|
||||||
|
'''
|
||||||
|
Performs a reset (reboot) operation on the managed server.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.server_hardreset
|
||||||
|
'''
|
||||||
|
return __execute_cmd('serveraction hardreset')
|
||||||
|
|
||||||
|
|
||||||
|
def server_pxe():
|
||||||
|
'''
|
||||||
|
Configure server to PXE perform a one off PXE boot
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt dell drac.server_pxe
|
||||||
|
'''
|
||||||
|
if __execute_cmd('config -g cfgServerInfo -o \
|
||||||
|
cfgServerFirstBootDevice PXE'):
|
||||||
|
if __execute_cmd('config -g cfgServerInfo -o cfgServerBootOnce 1'):
|
||||||
|
return server_reboot
|
||||||
|
else:
|
||||||
|
log.warn('failed to set boot order')
|
||||||
|
return False
|
||||||
|
|
||||||
|
log.warn('failed to to configure PXE boot')
|
||||||
|
return False
|
@ -98,8 +98,9 @@ def list_pkgs(versions_as_list=False, **kwargs):
|
|||||||
salt '*' pkg.list_pkgs
|
salt '*' pkg.list_pkgs
|
||||||
'''
|
'''
|
||||||
versions_as_list = salt.utils.is_true(versions_as_list)
|
versions_as_list = salt.utils.is_true(versions_as_list)
|
||||||
# 'removed' not yet implemented or not applicable
|
# 'removed', 'purge_desired' not yet implemented or not applicable
|
||||||
if salt.utils.is_true(kwargs.get('removed')):
|
if any([salt.utils.is_true(kwargs.get(x))
|
||||||
|
for x in ('removed', 'purge_desired')]):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
if 'pkg.list_pkgs' in __context__:
|
if 'pkg.list_pkgs' in __context__:
|
||||||
|
@ -197,6 +197,7 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
|
|||||||
process_dependency_links=False,
|
process_dependency_links=False,
|
||||||
__env__=None,
|
__env__=None,
|
||||||
saltenv='base',
|
saltenv='base',
|
||||||
|
env_vars=None,
|
||||||
use_vt=False):
|
use_vt=False):
|
||||||
'''
|
'''
|
||||||
Install packages with pip
|
Install packages with pip
|
||||||
@ -311,6 +312,11 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
|
|||||||
Enable the processing of dependency links
|
Enable the processing of dependency links
|
||||||
use_vt
|
use_vt
|
||||||
Use VT terminal emulation (see ouptut while installing)
|
Use VT terminal emulation (see ouptut while installing)
|
||||||
|
env_vars
|
||||||
|
Set environment variables that some builds will depend on. For example,
|
||||||
|
a Python C-module may have a Makefile that needs INCLUDE_PATH set to
|
||||||
|
pick up a header file while compiling.
|
||||||
|
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
@ -576,6 +582,9 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
|
|||||||
if process_dependency_links:
|
if process_dependency_links:
|
||||||
cmd.append('--process-dependency-links')
|
cmd.append('--process-dependency-links')
|
||||||
|
|
||||||
|
if env_vars:
|
||||||
|
os.environ.update(env_vars)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cmd_kwargs = dict(runas=user, cwd=cwd, saltenv=saltenv, use_vt=use_vt)
|
cmd_kwargs = dict(runas=user, cwd=cwd, saltenv=saltenv, use_vt=use_vt)
|
||||||
if bin_env and os.path.isdir(bin_env):
|
if bin_env and os.path.isdir(bin_env):
|
||||||
|
@ -29,7 +29,7 @@ def __virtual__():
|
|||||||
|
|
||||||
enabled = ('amazon', 'xcp', 'xenserver')
|
enabled = ('amazon', 'xcp', 'xenserver')
|
||||||
|
|
||||||
if os_family == 'redhat' or os_grain in enabled:
|
if os_family in ['redhat', 'suse'] or os_grain in enabled:
|
||||||
return __virtualname__
|
return __virtualname__
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -183,3 +183,34 @@ def file_dict(*packages):
|
|||||||
files.append(line)
|
files.append(line)
|
||||||
ret[pkg] = files
|
ret[pkg] = files
|
||||||
return {'errors': errors, 'packages': ret}
|
return {'errors': errors, 'packages': ret}
|
||||||
|
|
||||||
|
|
||||||
|
def owner(*paths):
|
||||||
|
'''
|
||||||
|
Return the name of the package that owns the file. Multiple file paths can
|
||||||
|
be passed. If a single path is passed, a string will be returned,
|
||||||
|
and if multiple paths are passed, a dictionary of file/package name pairs
|
||||||
|
will be returned.
|
||||||
|
|
||||||
|
If the file is not owned by a package, or is not present on the minion,
|
||||||
|
then an empty string will be returned for that path.
|
||||||
|
|
||||||
|
CLI Examples:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' lowpkg.owner /usr/bin/apachectl
|
||||||
|
salt '*' lowpkg.owner /usr/bin/apachectl /etc/httpd/conf/httpd.conf
|
||||||
|
'''
|
||||||
|
if not paths:
|
||||||
|
return ''
|
||||||
|
ret = {}
|
||||||
|
cmd = 'rpm -qf --queryformat "%{{NAME}}" {0!r}'
|
||||||
|
for path in paths:
|
||||||
|
ret[path] = __salt__['cmd.run_stdout'](cmd.format(path),
|
||||||
|
output_loglevel='trace')
|
||||||
|
if 'not owned' in ret[path].lower():
|
||||||
|
ret[path] = ''
|
||||||
|
if len(ret) == 1:
|
||||||
|
return ret.values()[0]
|
||||||
|
return ret
|
||||||
|
@ -1,77 +1,265 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
'''
|
||||||
Module for notifications via Slack.
|
Module for sending messages to Slack
|
||||||
See https://slack.com for more info.
|
|
||||||
|
|
||||||
.. versionadded:: Lithium
|
.. versionadded:: Lithium
|
||||||
|
|
||||||
:depends: - pyslack python module
|
:configuration: This module can be used by either passing an api key and version
|
||||||
:configuration: Configure this module by specifying the name of a configuration
|
directly or by specifying both in a configuration profile in the salt
|
||||||
profile in the minion config, minion pillar, or master config.
|
master/minion config.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
slack.api_token: <api token>
|
slack:
|
||||||
slack.username: salt-bot
|
api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||||
'''
|
'''
|
||||||
|
import requests
|
||||||
import logging
|
import logging
|
||||||
from salt.exceptions import CommandExecutionError
|
from urlparse import urljoin as _urljoin
|
||||||
|
from requests.exceptions import ConnectionError
|
||||||
HAS_LIBS = False
|
|
||||||
try:
|
|
||||||
import slack
|
|
||||||
import slack.chat
|
|
||||||
from slack.exception import ChannelNotFoundError
|
|
||||||
from slack.exception import NotAuthedError
|
|
||||||
HAS_LIBS = True
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
__virtualname__ = 'slack'
|
__virtualname__ = 'slack'
|
||||||
|
|
||||||
|
|
||||||
def __virtual__():
|
def __virtual__():
|
||||||
'''
|
'''
|
||||||
Only load this module if slack is installed on this minion.
|
Return virtual name of the module.
|
||||||
|
|
||||||
|
:return: The virtual name of the module.
|
||||||
'''
|
'''
|
||||||
if HAS_LIBS:
|
|
||||||
return __virtualname__
|
return __virtualname__
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _setup():
|
def _query(function, api_key=None, method='GET', data=None):
|
||||||
'''
|
'''
|
||||||
Return the slack connection
|
Slack object method function to construct and execute on the API URL.
|
||||||
|
|
||||||
|
:param api_key: The Slack api key.
|
||||||
|
:param function: The Slack api function to perform.
|
||||||
|
:param method: The HTTP method, e.g. GET or POST.
|
||||||
|
:param data: The data to be sent for POST method.
|
||||||
|
:return: The json response from the API call or False.
|
||||||
'''
|
'''
|
||||||
creds = {}
|
headers = {}
|
||||||
creds['api_token'] = __salt__['config.option']('slack.api_token')
|
query_params = {}
|
||||||
creds['username'] = __salt__['config.option']('slack.username')
|
|
||||||
slack.api_token = creds.get('api_token')
|
if data is None:
|
||||||
return creds
|
data = {}
|
||||||
|
|
||||||
|
ret = {'message': '',
|
||||||
|
'res': True}
|
||||||
|
|
||||||
|
slack_functions = {
|
||||||
|
'rooms': {
|
||||||
|
'request': 'channels.list',
|
||||||
|
'response': 'channels',
|
||||||
|
},
|
||||||
|
'users': {
|
||||||
|
'request': 'users.list',
|
||||||
|
'response': 'members',
|
||||||
|
},
|
||||||
|
'message': {
|
||||||
|
'request': 'chat.postMessage',
|
||||||
|
'response': 'channel',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if not api_key:
|
||||||
|
try:
|
||||||
|
options = __salt__['config.option']('slack')
|
||||||
|
if not api_key:
|
||||||
|
api_key = options.get('api_key')
|
||||||
|
except (NameError, KeyError, AttributeError):
|
||||||
|
log.error('No Slack api key found.')
|
||||||
|
ret['message'] = 'No Slack api key found.'
|
||||||
|
ret['res'] = False
|
||||||
|
return ret
|
||||||
|
|
||||||
|
api_url = 'https://slack.com'
|
||||||
|
base_url = _urljoin(api_url, '/api/')
|
||||||
|
path = slack_functions.get(function).get('request')
|
||||||
|
url = _urljoin(base_url, path, False)
|
||||||
|
query_params['token'] = api_key
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = requests.request(
|
||||||
|
method=method,
|
||||||
|
url=url,
|
||||||
|
headers=headers,
|
||||||
|
params=query_params,
|
||||||
|
data=data,
|
||||||
|
verify=True,
|
||||||
|
)
|
||||||
|
except ConnectionError as e:
|
||||||
|
ret['message'] = e
|
||||||
|
ret['res'] = False
|
||||||
|
return ret
|
||||||
|
|
||||||
|
if result.status_code == 200:
|
||||||
|
result = result.json()
|
||||||
|
response = slack_functions.get(function).get('response')
|
||||||
|
if 'error' in result:
|
||||||
|
ret['message'] = result['error']
|
||||||
|
ret['res'] = False
|
||||||
|
return ret
|
||||||
|
ret['message'] = result.get(response)
|
||||||
|
return ret
|
||||||
|
elif result.status_code == 204:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
log.debug(url)
|
||||||
|
log.debug(query_params)
|
||||||
|
log.debug(data)
|
||||||
|
log.debug(result)
|
||||||
|
if 'error' in result:
|
||||||
|
ret['message'] = result['error']
|
||||||
|
ret['res'] = False
|
||||||
|
return ret
|
||||||
|
ret['message'] = result
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def post_message(message, channel='#general', username=None):
|
def list_rooms(api_key=None):
|
||||||
'''
|
'''
|
||||||
Post a message to a channel
|
List all Slack rooms.
|
||||||
|
|
||||||
|
:param api_key: The Slack admin api key.
|
||||||
|
:return: The room list.
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: bash
|
||||||
|
|
||||||
salt '*' slack.post_message 'Test message'
|
salt '*' slack.list_rooms
|
||||||
|
|
||||||
|
salt '*' slack.list_rooms api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||||
'''
|
'''
|
||||||
ret = {}
|
return _query(function='rooms', api_key=api_key)
|
||||||
creds = _setup()
|
|
||||||
if username is None:
|
|
||||||
username = creds['username']
|
def list_users(api_key=None):
|
||||||
try:
|
'''
|
||||||
ret = slack.chat.post_message(channel, message, username=username)
|
List all Slack users.
|
||||||
except ChannelNotFoundError as exc:
|
:param api_key: The Slack admin api key.
|
||||||
raise CommandExecutionError('Channel "{0}" does not exist. {1}'.format(channel, exc))
|
:return: The user list.
|
||||||
except NotAuthedError as exc:
|
|
||||||
raise CommandExecutionError('Authentication Failed. {0}'.format(exc))
|
CLI Example:
|
||||||
return ret
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' slack.list_users
|
||||||
|
|
||||||
|
salt '*' slack.list_users api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||||
|
'''
|
||||||
|
return _query(function='users', api_key=api_key)
|
||||||
|
|
||||||
|
|
||||||
|
def find_room(name, api_key=None):
|
||||||
|
'''
|
||||||
|
Find a room by name and return it.
|
||||||
|
:param name: The room name.
|
||||||
|
:param api_key: The Slack admin api key.
|
||||||
|
:return: The room object.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' slack.find_room name="random"
|
||||||
|
|
||||||
|
salt '*' slack.find_room name="random" api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||||
|
'''
|
||||||
|
|
||||||
|
# search results don't include the name of the
|
||||||
|
# channel with a hash, if the passed channel name
|
||||||
|
# has a hash we remove it.
|
||||||
|
if name.startswith('#'):
|
||||||
|
name = name[1:]
|
||||||
|
ret = list_rooms(api_key)
|
||||||
|
if ret['res']:
|
||||||
|
rooms = ret['message']
|
||||||
|
if rooms:
|
||||||
|
for room in range(0, len(rooms)):
|
||||||
|
if rooms[room]['name'] == name:
|
||||||
|
return rooms[room]
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def find_user(name, api_key=None):
|
||||||
|
'''
|
||||||
|
Find a user by name and return it.
|
||||||
|
:param name: The user name.
|
||||||
|
:param api_key: The Slack admin api key.
|
||||||
|
:return: The user object.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' slack.find_user name="ThomasHatch"
|
||||||
|
|
||||||
|
salt '*' slack.find_user name="ThomasHatch" api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||||
|
'''
|
||||||
|
ret = list_users(api_key)
|
||||||
|
if ret['res']:
|
||||||
|
users = ret['message']
|
||||||
|
if users:
|
||||||
|
for user in range(0, len(users)):
|
||||||
|
if users[user]['name'] == name:
|
||||||
|
return users[user]
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def post_message(channel,
|
||||||
|
message,
|
||||||
|
from_name,
|
||||||
|
api_key=None):
|
||||||
|
'''
|
||||||
|
Send a message to a Slack channel.
|
||||||
|
:param channel: The channel name, either will work.
|
||||||
|
:param message: The message to send to the HipChat room.
|
||||||
|
:param from_name: Specify who the message is from.
|
||||||
|
:param api_key: The Slack api key, if not specified in the configuration.
|
||||||
|
:return: Boolean if message was sent successfully.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' slack.send_message channel="Development Room" message="Build is done" from_name="Build Server"
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
if not channel:
|
||||||
|
log.error('channel is a required option.')
|
||||||
|
|
||||||
|
# channel must start with a hash
|
||||||
|
if not channel.startswith('#'):
|
||||||
|
channel = '#{0}'.format(channel)
|
||||||
|
|
||||||
|
if not from_name:
|
||||||
|
log.error('from_name is a required option.')
|
||||||
|
|
||||||
|
if not message:
|
||||||
|
log.error('message is a required option.')
|
||||||
|
|
||||||
|
if not from_name:
|
||||||
|
log.error('from_name is a required option.')
|
||||||
|
|
||||||
|
parameters = dict()
|
||||||
|
parameters['channel'] = channel
|
||||||
|
parameters['username'] = from_name
|
||||||
|
parameters['text'] = message
|
||||||
|
|
||||||
|
result = _query(function='message',
|
||||||
|
api_key=api_key,
|
||||||
|
method='POST',
|
||||||
|
data=parameters)
|
||||||
|
|
||||||
|
if result['res']:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return result
|
||||||
|
@ -619,7 +619,7 @@ def fullversion():
|
|||||||
continue
|
continue
|
||||||
if ': ' in line:
|
if ': ' in line:
|
||||||
comps = line.split(': ')
|
comps = line.split(': ')
|
||||||
ret[comps[0]] = comps[1]
|
ret[comps[0]] = comps[1].lstrip()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,8 +98,6 @@ def __get_conn():
|
|||||||
- http://libvirt.org/uri.html#URI_config
|
- http://libvirt.org/uri.html#URI_config
|
||||||
'''
|
'''
|
||||||
connection = __salt__['config.get']('libvirt:connection', 'esx')
|
connection = __salt__['config.get']('libvirt:connection', 'esx')
|
||||||
if connection.startswith('esx://'):
|
|
||||||
return connection
|
|
||||||
return connection
|
return connection
|
||||||
|
|
||||||
def __esxi_auth():
|
def __esxi_auth():
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
'''
|
||||||
Support for YUM
|
Support for YUM
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
This module makes heavy use of the **repoquery** utility, from the
|
||||||
|
yum-utils_ package. This package will be installed as a dependency if salt
|
||||||
|
is installed via EPEL. However, if salt has been installed using pip, or a
|
||||||
|
host is being managed using salt-ssh, then as of version 2014.7.0
|
||||||
|
yum-utils_ will be installed automatically to satisfy this dependency.
|
||||||
|
|
||||||
|
.. _yum-utils: http://yum.baseurl.org/wiki/YumUtils
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Import python libs
|
# Import python libs
|
||||||
@ -102,10 +112,27 @@ def _repoquery_pkginfo(repoquery_args):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def _check_repoquery():
|
||||||
|
'''
|
||||||
|
Check for existence of repoquery and install yum-utils if it is not
|
||||||
|
present.
|
||||||
|
'''
|
||||||
|
if not salt.utils.which('repoquery'):
|
||||||
|
__salt__['cmd.run'](
|
||||||
|
['yum', '-y', 'install', 'yum-utils'],
|
||||||
|
python_shell=False,
|
||||||
|
output_loglevel='trace'
|
||||||
|
)
|
||||||
|
# Check again now that we've installed yum-utils
|
||||||
|
if not salt.utils.which('repoquery'):
|
||||||
|
raise CommandExecutionError('Unable to install yum-utils')
|
||||||
|
|
||||||
|
|
||||||
def _repoquery(repoquery_args, query_format=__QUERYFORMAT):
|
def _repoquery(repoquery_args, query_format=__QUERYFORMAT):
|
||||||
'''
|
'''
|
||||||
Runs a repoquery command and returns a list of namedtuples
|
Runs a repoquery command and returns a list of namedtuples
|
||||||
'''
|
'''
|
||||||
|
_check_repoquery()
|
||||||
cmd = 'repoquery --plugins --queryformat="{0}" {1}'.format(
|
cmd = 'repoquery --plugins --queryformat="{0}" {1}'.format(
|
||||||
query_format, repoquery_args
|
query_format, repoquery_args
|
||||||
)
|
)
|
||||||
|
@ -5,6 +5,7 @@ Module for running ZFS zpool command
|
|||||||
|
|
||||||
# Import Python libs
|
# Import Python libs
|
||||||
import os
|
import os
|
||||||
|
import stat
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
# Import Salt libs
|
# Import Salt libs
|
||||||
@ -150,15 +151,18 @@ def scrub(pool_name=None):
|
|||||||
ret['Error'] = 'Storage pool {0} does not exist'.format(pool_name)
|
ret['Error'] = 'Storage pool {0} does not exist'.format(pool_name)
|
||||||
|
|
||||||
|
|
||||||
def create(pool_name, *vdevs):
|
def create(pool_name, *vdevs, **kwargs):
|
||||||
'''
|
'''
|
||||||
Create a new storage pool
|
Create a simple zpool, a mirrored zpool, a zpool having nested VDEVs and a hybrid zpool with cache and log drives
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt '*' zpool.create myzpool /path/to/vdev1 [/path/to/vdev2] [...]
|
salt '*' zpool.create myzpool /path/to/vdev1 [...] [force=True|False]
|
||||||
|
salt '*' zpool.create myzpool mirror /path/to/vdev1 /path/to/vdev2 [...] [force=True|False]
|
||||||
|
salt '*' zpool.create myzpool mirror /path/to/vdev1 [...] mirror /path/to/vdev2 /path/to/vdev3 [...] [force=True|False]
|
||||||
|
salt '*' zpool.create myhybridzpool mirror /tmp/file1 [...] log mirror /path/to/vdev1 [...] cache /path/to/vdev2 [...] [force=True|False]
|
||||||
'''
|
'''
|
||||||
ret = {}
|
ret = {}
|
||||||
dlist = []
|
dlist = []
|
||||||
@ -170,26 +174,37 @@ def create(pool_name, *vdevs):
|
|||||||
|
|
||||||
# make sure files are present on filesystem
|
# make sure files are present on filesystem
|
||||||
for vdev in vdevs:
|
for vdev in vdevs:
|
||||||
if not os.path.isfile(vdev):
|
if vdev not in ['mirror', 'log', 'cache']:
|
||||||
# File is not there error and return
|
if not os.path.exists(vdev):
|
||||||
|
# Path doesn't exist so error and return
|
||||||
ret[vdev] = '{0} not present on filesystem'.format(vdev)
|
ret[vdev] = '{0} not present on filesystem'.format(vdev)
|
||||||
return ret
|
return ret
|
||||||
else:
|
mode = os.stat(vdev).st_mode
|
||||||
|
if not stat.S_ISBLK(mode) and not stat.S_ISREG(mode):
|
||||||
|
# Not a block device or file vdev so error and return
|
||||||
|
ret[vdev] = '{0} is not a block device or a file vdev'.format(vdev)
|
||||||
|
return ret
|
||||||
dlist.append(vdev)
|
dlist.append(vdev)
|
||||||
|
|
||||||
devs = ' '.join(dlist)
|
devs = ' '.join(dlist)
|
||||||
zpool = _check_zpool()
|
zpool = _check_zpool()
|
||||||
|
force = kwargs.get('force', False)
|
||||||
|
if force is True:
|
||||||
|
cmd = '{0} create -f {1} {2}'.format(zpool, pool_name, devs)
|
||||||
|
else:
|
||||||
cmd = '{0} create {1} {2}'.format(zpool, pool_name, devs)
|
cmd = '{0} create {1} {2}'.format(zpool, pool_name, devs)
|
||||||
|
|
||||||
# Create storage pool
|
# Create storage pool
|
||||||
__salt__['cmd.run'](cmd)
|
res = __salt__['cmd.run'](cmd)
|
||||||
|
|
||||||
# Check and see if the pools is available
|
# Check and see if the pools is available
|
||||||
if exists(pool_name):
|
if exists(pool_name):
|
||||||
ret[pool_name] = 'created'
|
ret[pool_name] = 'created'
|
||||||
return ret
|
return ret
|
||||||
else:
|
else:
|
||||||
ret['Error'] = 'Unable to create storage pool {0}'.format(pool_name)
|
ret['Error'] = {}
|
||||||
|
ret['Error']['Messsage'] = 'Unable to create storage pool {0}'.format(pool_name)
|
||||||
|
ret['Error']['Reason'] = res
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ Package support for openSUSE via the zypper package manager
|
|||||||
import copy
|
import copy
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
|
from xml.dom import minidom as dom
|
||||||
from contextlib import contextmanager as _contextmanager
|
from contextlib import contextmanager as _contextmanager
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
@ -18,6 +20,7 @@ from salt.exceptions import (
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
HAS_ZYPP = False
|
HAS_ZYPP = False
|
||||||
|
LOCKS = "/etc/zypp/locks"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import zypp
|
import zypp
|
||||||
@ -847,3 +850,238 @@ def purge(name=None, pkgs=None, **kwargs):
|
|||||||
salt '*' pkg.purge pkgs='["foo", "bar"]'
|
salt '*' pkg.purge pkgs='["foo", "bar"]'
|
||||||
'''
|
'''
|
||||||
return _uninstall(action='purge', name=name, pkgs=pkgs)
|
return _uninstall(action='purge', name=name, pkgs=pkgs)
|
||||||
|
|
||||||
|
|
||||||
|
def list_locks():
|
||||||
|
'''
|
||||||
|
List current package locks.
|
||||||
|
|
||||||
|
Return a dict containing the locked package with attributes::
|
||||||
|
|
||||||
|
{'<package>': {'case_sensitive': '<case_sensitive>',
|
||||||
|
'match_type': '<match_type>'
|
||||||
|
'type': '<type>'}}
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.list_locks
|
||||||
|
'''
|
||||||
|
if not os.path.exists(LOCKS):
|
||||||
|
return False
|
||||||
|
|
||||||
|
locks = {}
|
||||||
|
for meta in map(lambda item: item.split("\n"),
|
||||||
|
open(LOCKS).read().split("\n\n")):
|
||||||
|
lock = {}
|
||||||
|
for element in [el for el in meta if el]:
|
||||||
|
if ":" in element:
|
||||||
|
lock.update(dict([tuple(map(lambda i: i.strip(),
|
||||||
|
element.split(":", 1))), ]))
|
||||||
|
if lock.get('solvable_name'):
|
||||||
|
locks[lock.pop('solvable_name')] = lock
|
||||||
|
|
||||||
|
return locks
|
||||||
|
|
||||||
|
|
||||||
|
def clean_locks():
|
||||||
|
'''
|
||||||
|
Remove unused locks that do not currently (with regard to repositories used) lock any package.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.clean_locks
|
||||||
|
'''
|
||||||
|
if not os.path.exists(LOCKS):
|
||||||
|
return False
|
||||||
|
|
||||||
|
cmd = ('zypper --non-interactive cl')
|
||||||
|
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def remove_lock(name=None, pkgs=None, **kwargs):
|
||||||
|
'''
|
||||||
|
Remove specified package lock.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.remove_lock <package name>
|
||||||
|
salt '*' pkg.remove_lock <package1>,<package2>,<package3>
|
||||||
|
salt '*' pkg.remove_lock pkgs='["foo", "bar"]'
|
||||||
|
'''
|
||||||
|
|
||||||
|
locks = list_locks()
|
||||||
|
packages = []
|
||||||
|
try:
|
||||||
|
packages = __salt__['pkg_resource.parse_targets'](name, pkgs)[0].keys()
|
||||||
|
except MinionError as exc:
|
||||||
|
raise CommandExecutionError(exc)
|
||||||
|
|
||||||
|
removed = []
|
||||||
|
missing = []
|
||||||
|
for pkg in packages:
|
||||||
|
if locks.get(pkg):
|
||||||
|
removed.append(pkg)
|
||||||
|
else:
|
||||||
|
missing.append(pkg)
|
||||||
|
|
||||||
|
if removed:
|
||||||
|
__salt__['cmd.run'](('zypper --non-interactive rl {0}'.format(' '.join(removed))),
|
||||||
|
output_loglevel='trace')
|
||||||
|
|
||||||
|
return {'removed': len(removed), 'not_found': missing}
|
||||||
|
|
||||||
|
|
||||||
|
def add_lock(name=None, pkgs=None, **kwargs):
|
||||||
|
'''
|
||||||
|
Add a package lock. Specify packages to lock by exact name.
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.add_lock <package name>
|
||||||
|
salt '*' pkg.add_lock <package1>,<package2>,<package3>
|
||||||
|
salt '*' pkg.add_lock pkgs='["foo", "bar"]'
|
||||||
|
'''
|
||||||
|
locks = list_locks()
|
||||||
|
packages = []
|
||||||
|
added = []
|
||||||
|
try:
|
||||||
|
packages = __salt__['pkg_resource.parse_targets'](name, pkgs)[0].keys()
|
||||||
|
except MinionError as exc:
|
||||||
|
raise CommandExecutionError(exc)
|
||||||
|
|
||||||
|
for pkg in packages:
|
||||||
|
if not locks.get(pkg):
|
||||||
|
added.append(pkg)
|
||||||
|
|
||||||
|
if added:
|
||||||
|
__salt__['cmd.run'](('zypper --non-interactive al {0}'.format(' '.join(added))),
|
||||||
|
output_loglevel='trace')
|
||||||
|
|
||||||
|
return {'added': len(added), 'packages': added}
|
||||||
|
|
||||||
|
|
||||||
|
def verify(*names, **kwargs):
|
||||||
|
'''
|
||||||
|
Runs an rpm -Va on a system, and returns the results in a dict
|
||||||
|
|
||||||
|
Files with an attribute of config, doc, ghost, license or readme in the
|
||||||
|
package header can be ignored using the ``ignore_types`` keyword argument
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.verify
|
||||||
|
salt '*' pkg.verify httpd
|
||||||
|
salt '*' pkg.verify 'httpd postfix'
|
||||||
|
salt '*' pkg.verify 'httpd postfix' ignore_types=['config','doc']
|
||||||
|
'''
|
||||||
|
return __salt__['lowpkg.verify'](*names, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def file_list(*packages):
|
||||||
|
'''
|
||||||
|
List the files that belong to a package. Not specifying any packages will
|
||||||
|
return a list of *every* file on the system's rpm database (not generally
|
||||||
|
recommended).
|
||||||
|
|
||||||
|
CLI Examples:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.file_list httpd
|
||||||
|
salt '*' pkg.file_list httpd postfix
|
||||||
|
salt '*' pkg.file_list
|
||||||
|
'''
|
||||||
|
return __salt__['lowpkg.file_list'](*packages)
|
||||||
|
|
||||||
|
|
||||||
|
def file_dict(*packages):
|
||||||
|
'''
|
||||||
|
List the files that belong to a package, grouped by package. Not
|
||||||
|
specifying any packages will return a list of *every* file on the system's
|
||||||
|
rpm database (not generally recommended).
|
||||||
|
|
||||||
|
CLI Examples:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.file_list httpd
|
||||||
|
salt '*' pkg.file_list httpd postfix
|
||||||
|
salt '*' pkg.file_list
|
||||||
|
'''
|
||||||
|
return __salt__['lowpkg.file_dict'](*packages)
|
||||||
|
|
||||||
|
|
||||||
|
def owner(*paths):
|
||||||
|
'''
|
||||||
|
Return the name of the package that owns the file. Multiple file paths can
|
||||||
|
be passed. If a single path is passed, a string will be returned,
|
||||||
|
and if multiple paths are passed, a dictionary of file/package name
|
||||||
|
pairs will be returned.
|
||||||
|
|
||||||
|
If the file is not owned by a package, or is not present on the minion,
|
||||||
|
then an empty string will be returned for that path.
|
||||||
|
|
||||||
|
CLI Examples:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.owner /usr/bin/apachectl
|
||||||
|
salt '*' pkg.owner /usr/bin/apachectl /etc/httpd/conf/httpd.conf
|
||||||
|
'''
|
||||||
|
return __salt__['lowpkg.owner'](*paths)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_patterns(installed_only=None):
|
||||||
|
'''
|
||||||
|
List all known patterns in repos.
|
||||||
|
'''
|
||||||
|
patterns = {}
|
||||||
|
doc = dom.parseString(__salt__['cmd.run'](('zypper --xmlout se -t pattern'),
|
||||||
|
output_loglevel='trace'))
|
||||||
|
for element in doc.getElementsByTagName("solvable"):
|
||||||
|
installed = element.getAttribute("status") == "installed"
|
||||||
|
if (installed_only and installed) or not installed_only:
|
||||||
|
patterns[element.getAttribute("name")] = {
|
||||||
|
'installed': installed,
|
||||||
|
'summary': element.getAttribute("summary"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return patterns
|
||||||
|
|
||||||
|
|
||||||
|
def list_patterns():
|
||||||
|
'''
|
||||||
|
List all known patterns from available repos.
|
||||||
|
|
||||||
|
CLI Examples:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.list_patterns
|
||||||
|
'''
|
||||||
|
return _get_patterns()
|
||||||
|
|
||||||
|
|
||||||
|
def list_installed_patterns():
|
||||||
|
'''
|
||||||
|
List installed patterns on the system.
|
||||||
|
|
||||||
|
CLI Examples:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.list_installed_patterns
|
||||||
|
'''
|
||||||
|
return _get_patterns(installed_only=True)
|
||||||
|
@ -232,8 +232,8 @@ def returner(ret):
|
|||||||
total_sent_bytes += sent_bytes
|
total_sent_bytes += sent_bytes
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any work necessary to prepare a JID, including sending a custom id
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -74,9 +74,8 @@ def returner(ret):
|
|||||||
ccf.insert(ret['jid'], columns)
|
ccf.insert(ret['jid'], columns)
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any work necessary to prepare the jid for storage,
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
including returning a custom jid
|
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -119,21 +119,27 @@ def _get_ttl():
|
|||||||
|
|
||||||
|
|
||||||
#TODO: add to returner docs-- this is a new one
|
#TODO: add to returner docs-- this is a new one
|
||||||
def prep_jid(nocache=False):
|
def prep_jid(nocache=False, passed_jid=None):
|
||||||
'''
|
'''
|
||||||
Return a job id and prepare the job id directory
|
Return a job id and prepare the job id directory
|
||||||
This is the function responsible for making sure jids don't collide (unless its passed a jid)
|
This is the function responsible for making sure jids don't collide (unless its passed a jid)
|
||||||
So do what you have to do to make sure that stays the case
|
So do what you have to do to make sure that stays the case
|
||||||
'''
|
'''
|
||||||
|
if passed_jid is None:
|
||||||
|
jid = salt.utils.gen_jid()
|
||||||
|
else:
|
||||||
|
jid = passed_jid
|
||||||
|
|
||||||
cb_ = _get_connection()
|
cb_ = _get_connection()
|
||||||
|
|
||||||
jid = salt.utils.gen_jid()
|
|
||||||
try:
|
try:
|
||||||
cb_.add(str(jid),
|
cb_.add(str(jid),
|
||||||
{'nocache': nocache},
|
{'nocache': nocache},
|
||||||
ttl=_get_ttl(),
|
ttl=_get_ttl(),
|
||||||
)
|
)
|
||||||
except couchbase.exceptions.KeyExistsError:
|
except couchbase.exceptions.KeyExistsError:
|
||||||
|
# TODO: some sort of sleep or something? Spinning is generally bad practice
|
||||||
|
if passed_jid is None:
|
||||||
return prep_jid(nocache=nocache)
|
return prep_jid(nocache=nocache)
|
||||||
|
|
||||||
return jid
|
return jid
|
||||||
|
@ -349,8 +349,8 @@ def set_salt_view():
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any necessary pre-processing and return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -148,9 +148,8 @@ def returner(ret):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Prepare the jid, including doing any pre-processing and
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
returning the jid to use
|
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -168,8 +168,8 @@ def get_minions():
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Pre-process the JID and return the JID to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -97,13 +97,16 @@ def _format_jid_instance(jid, job):
|
|||||||
|
|
||||||
|
|
||||||
#TODO: add to returner docs-- this is a new one
|
#TODO: add to returner docs-- this is a new one
|
||||||
def prep_jid(nocache=False):
|
def prep_jid(nocache=False, passed_jid=None):
|
||||||
'''
|
'''
|
||||||
Return a job id and prepare the job id directory
|
Return a job id and prepare the job id directory
|
||||||
This is the function responsible for making sure jids don't collide (unless its passed a jid)
|
This is the function responsible for making sure jids don't collide (unless its passed a jid)
|
||||||
So do what you have to do to make sure that stays the case
|
So do what you have to do to make sure that stays the case
|
||||||
'''
|
'''
|
||||||
|
if passed_jid is None: # this can be a None of an empty string
|
||||||
jid = salt.utils.gen_jid()
|
jid = salt.utils.gen_jid()
|
||||||
|
else:
|
||||||
|
jid = passed_jid
|
||||||
|
|
||||||
jid_dir_ = _jid_dir(jid)
|
jid_dir_ = _jid_dir(jid)
|
||||||
|
|
||||||
@ -113,6 +116,7 @@ def prep_jid(nocache=False):
|
|||||||
os.makedirs(jid_dir_)
|
os.makedirs(jid_dir_)
|
||||||
except OSError:
|
except OSError:
|
||||||
# TODO: some sort of sleep or something? Spinning is generally bad practice
|
# TODO: some sort of sleep or something? Spinning is generally bad practice
|
||||||
|
if passed_jid is None:
|
||||||
return prep_jid(nocache=nocache)
|
return prep_jid(nocache=nocache)
|
||||||
|
|
||||||
with salt.utils.fopen(os.path.join(jid_dir_, 'jid'), 'w+') as fn_:
|
with salt.utils.fopen(os.path.join(jid_dir_, 'jid'), 'w+') as fn_:
|
||||||
|
@ -93,11 +93,11 @@ def _get_serv(ret):
|
|||||||
# an integer weight value.
|
# an integer weight value.
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Pre-process the jid and return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
|
||||||
|
|
||||||
def returner(ret):
|
def returner(ret):
|
||||||
|
@ -209,8 +209,8 @@ def get_jids():
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Pre-process the jid and return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -157,8 +157,8 @@ def get_fun(fun):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Pre-process the jid and return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -30,7 +30,7 @@ def _mminion():
|
|||||||
return MMINION
|
return MMINION
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache=False):
|
def prep_jid(nocache=False, passed_jid=None):
|
||||||
'''
|
'''
|
||||||
Call both with prep_jid on all returners in multi_returner
|
Call both with prep_jid on all returners in multi_returner
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ def prep_jid(nocache=False):
|
|||||||
returners is non-trivial
|
returners is non-trivial
|
||||||
'''
|
'''
|
||||||
|
|
||||||
jid = None
|
jid = passed_jid
|
||||||
for returner in __opts__[CONFIG_KEY]:
|
for returner in __opts__[CONFIG_KEY]:
|
||||||
if jid is None:
|
if jid is None:
|
||||||
jid = _mminion().returners['{0}.prep_jid'.format(returner)](nocache=nocache)
|
jid = _mminion().returners['{0}.prep_jid'.format(returner)](nocache=nocache)
|
||||||
|
@ -85,6 +85,7 @@ import logging
|
|||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.returners
|
import salt.returners
|
||||||
|
import salt.utils
|
||||||
|
|
||||||
# Import third party libs
|
# Import third party libs
|
||||||
try:
|
try:
|
||||||
@ -148,7 +149,7 @@ def _get_serv(ret=None, commit=False):
|
|||||||
try:
|
try:
|
||||||
yield cursor
|
yield cursor
|
||||||
except MySQLdb.DatabaseError as err:
|
except MySQLdb.DatabaseError as err:
|
||||||
error, = err.args
|
error = err.args
|
||||||
sys.stderr.write(str(error))
|
sys.stderr.write(str(error))
|
||||||
cursor.execute("ROLLBACK")
|
cursor.execute("ROLLBACK")
|
||||||
raise err
|
raise err
|
||||||
@ -196,13 +197,11 @@ def get_load(jid):
|
|||||||
'''
|
'''
|
||||||
with _get_serv(ret=None, commit=True) as cur:
|
with _get_serv(ret=None, commit=True) as cur:
|
||||||
|
|
||||||
sql = '''SELECT load FROM `jids`
|
sql = '''SELECT `load` FROM `jids` WHERE `jid` = %s;'''
|
||||||
WHERE `jid` = '%s';'''
|
|
||||||
|
|
||||||
cur.execute(sql, (jid,))
|
cur.execute(sql, (jid,))
|
||||||
data = cur.fetchone()
|
data = cur.fetchone()
|
||||||
if data:
|
if data:
|
||||||
return json.loads(data)
|
return json.loads(data[0])
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
@ -280,3 +279,10 @@ def get_minions():
|
|||||||
for minion in data:
|
for minion in data:
|
||||||
ret.append(minion[0])
|
ret.append(minion[0])
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
|
'''
|
||||||
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
|
'''
|
||||||
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -300,8 +300,8 @@ def get_minions():
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any jid pre-processing and return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -272,8 +272,8 @@ def get_minions():
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any pre-processing necessary and return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -162,8 +162,8 @@ def get_minions():
|
|||||||
return list(serv.smembers('minions'))
|
return list(serv.smembers('minions'))
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any pre-processing necessary and return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -111,8 +111,8 @@ def returner(ret):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any necessary pre-processing and then return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
269
salt/returners/slack_returner.py
Normal file
269
salt/returners/slack_returner.py
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Return salt data via slack
|
||||||
|
|
||||||
|
.. versionadded:: Lithium
|
||||||
|
|
||||||
|
The following fields can be set in the minion conf file::
|
||||||
|
|
||||||
|
slack.channel (required)
|
||||||
|
slack.api_key (required)
|
||||||
|
slack.from_name (required)
|
||||||
|
slack.profile (optional)
|
||||||
|
|
||||||
|
Alternative configuration values can be used by prefacing the configuration.
|
||||||
|
Any values not found in the alternative configuration will be pulled from
|
||||||
|
the default location::
|
||||||
|
|
||||||
|
slack.channel
|
||||||
|
slack.api_key
|
||||||
|
slack.from_name
|
||||||
|
|
||||||
|
Hipchat settings may also be configured as::
|
||||||
|
|
||||||
|
slack:
|
||||||
|
channel: RoomName
|
||||||
|
api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
from_name: user@email.com
|
||||||
|
|
||||||
|
alternative.slack:
|
||||||
|
room_id: RoomName
|
||||||
|
api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
from_name: user@email.com
|
||||||
|
|
||||||
|
slack_profile:
|
||||||
|
api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
from_name: user@email.com
|
||||||
|
|
||||||
|
slack:
|
||||||
|
profile: slack_profile
|
||||||
|
channel: RoomName
|
||||||
|
|
||||||
|
alternative.slack:
|
||||||
|
profile: slack_profile
|
||||||
|
channel: RoomName
|
||||||
|
|
||||||
|
To use the HipChat returner, append '--return slack' to the salt command. ex:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' test.ping --return slack
|
||||||
|
|
||||||
|
To use the alternative configuration, append '--return_config alternative' to the salt command. ex:
|
||||||
|
|
||||||
|
salt '*' test.ping --return slack --return_config alternative
|
||||||
|
'''
|
||||||
|
|
||||||
|
import salt.returners
|
||||||
|
|
||||||
|
import pprint
|
||||||
|
import requests
|
||||||
|
import logging
|
||||||
|
from urlparse import urljoin as _urljoin
|
||||||
|
from requests.exceptions import ConnectionError
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
__virtualname__ = 'slack'
|
||||||
|
|
||||||
|
|
||||||
|
def _get_options(ret=None):
|
||||||
|
'''
|
||||||
|
Get the slack options from salt.
|
||||||
|
'''
|
||||||
|
|
||||||
|
defaults = {'channel': '#general'}
|
||||||
|
|
||||||
|
attrs = {'slack_profile': 'profile',
|
||||||
|
'channel': 'channel',
|
||||||
|
'from_name': 'from_name',
|
||||||
|
'api_key': 'api_key',
|
||||||
|
}
|
||||||
|
|
||||||
|
profile_attr = 'slack_profile'
|
||||||
|
|
||||||
|
profile_attrs = {'from_jid': 'from_jid',
|
||||||
|
'api_key': 'api_key',
|
||||||
|
'api_version': 'api_key'
|
||||||
|
}
|
||||||
|
|
||||||
|
_options = salt.returners.get_returner_options(__virtualname__,
|
||||||
|
ret,
|
||||||
|
attrs,
|
||||||
|
profile_attr=profile_attr,
|
||||||
|
profile_attrs=profile_attrs,
|
||||||
|
__salt__=__salt__,
|
||||||
|
__opts__=__opts__,
|
||||||
|
defaults=defaults)
|
||||||
|
return _options
|
||||||
|
|
||||||
|
|
||||||
|
def __virtual__():
|
||||||
|
'''
|
||||||
|
Return virtual name of the module.
|
||||||
|
|
||||||
|
:return: The virtual name of the module.
|
||||||
|
'''
|
||||||
|
return __virtualname__
|
||||||
|
|
||||||
|
|
||||||
|
def _query(function, api_key=None, method='GET', data=None):
|
||||||
|
'''
|
||||||
|
Slack object method function to construct and execute on the API URL.
|
||||||
|
|
||||||
|
:param api_key: The Slack api key.
|
||||||
|
:param function: The Slack api function to perform.
|
||||||
|
:param method: The HTTP method, e.g. GET or POST.
|
||||||
|
:param data: The data to be sent for POST method.
|
||||||
|
:return: The json response from the API call or False.
|
||||||
|
'''
|
||||||
|
headers = {}
|
||||||
|
query_params = {}
|
||||||
|
|
||||||
|
if data is None:
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
ret = {'message': '',
|
||||||
|
'res': True}
|
||||||
|
|
||||||
|
slack_functions = {
|
||||||
|
'rooms': {
|
||||||
|
'request': 'channels.list',
|
||||||
|
'response': 'channels',
|
||||||
|
},
|
||||||
|
'users': {
|
||||||
|
'request': 'users.list',
|
||||||
|
'response': 'members',
|
||||||
|
},
|
||||||
|
'message': {
|
||||||
|
'request': 'chat.postMessage',
|
||||||
|
'response': 'channel',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if not api_key:
|
||||||
|
try:
|
||||||
|
options = __salt__['config.option']('slack')
|
||||||
|
if not api_key:
|
||||||
|
api_key = options.get('api_key')
|
||||||
|
except (NameError, KeyError, AttributeError):
|
||||||
|
log.error('No Slack api key found.')
|
||||||
|
ret['message'] = 'No Slack api key found.'
|
||||||
|
ret['res'] = False
|
||||||
|
return ret
|
||||||
|
|
||||||
|
api_url = 'https://slack.com'
|
||||||
|
base_url = _urljoin(api_url, '/api/')
|
||||||
|
path = slack_functions.get(function).get('request')
|
||||||
|
url = _urljoin(base_url, path, False)
|
||||||
|
query_params['token'] = api_key
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = requests.request(
|
||||||
|
method=method,
|
||||||
|
url=url,
|
||||||
|
headers=headers,
|
||||||
|
params=query_params,
|
||||||
|
data=data,
|
||||||
|
verify=True,
|
||||||
|
)
|
||||||
|
except ConnectionError as e:
|
||||||
|
ret['message'] = e
|
||||||
|
ret['res'] = False
|
||||||
|
return ret
|
||||||
|
|
||||||
|
if result.status_code == 200:
|
||||||
|
result = result.json()
|
||||||
|
response = slack_functions.get(function).get('response')
|
||||||
|
if 'error' in result:
|
||||||
|
ret['message'] = result['error']
|
||||||
|
ret['res'] = False
|
||||||
|
return ret
|
||||||
|
ret['message'] = result.get(response)
|
||||||
|
return ret
|
||||||
|
elif result.status_code == 204:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
log.debug(url)
|
||||||
|
log.debug(query_params)
|
||||||
|
log.debug(data)
|
||||||
|
log.debug(result)
|
||||||
|
if 'error' in result:
|
||||||
|
ret['message'] = result['error']
|
||||||
|
ret['res'] = False
|
||||||
|
return ret
|
||||||
|
ret['message'] = result
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def _post_message(channel,
|
||||||
|
message,
|
||||||
|
from_name,
|
||||||
|
api_key=None):
|
||||||
|
'''
|
||||||
|
Send a message to a HipChat room.
|
||||||
|
:param room_id: The room id or room name, either will work.
|
||||||
|
:param message: The message to send to the HipChat room.
|
||||||
|
:param from_name: Specify who the message is from.
|
||||||
|
:param api_key: The HipChat api key, if not specified in the configuration.
|
||||||
|
:param api_version: The HipChat api version, if not specified in the configuration.
|
||||||
|
:param color: The color for the message, default: yellow.
|
||||||
|
:param notify: Whether to notify the room, default: False.
|
||||||
|
:return: Boolean if message was sent successfully.
|
||||||
|
'''
|
||||||
|
|
||||||
|
parameters = dict()
|
||||||
|
parameters['channel'] = channel
|
||||||
|
parameters['from'] = from_name
|
||||||
|
parameters['text'] = message
|
||||||
|
|
||||||
|
result = _query(function='message',
|
||||||
|
api_key=api_key,
|
||||||
|
method='POST',
|
||||||
|
data=parameters)
|
||||||
|
|
||||||
|
log.debug('result {0}'.format(result))
|
||||||
|
if result:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def returner(ret):
|
||||||
|
'''
|
||||||
|
Send an slack message with the data
|
||||||
|
'''
|
||||||
|
|
||||||
|
_options = _get_options(ret)
|
||||||
|
|
||||||
|
channel = _options.get('channel')
|
||||||
|
from_name = _options.get('from_name')
|
||||||
|
api_key = _options.get('api_key')
|
||||||
|
|
||||||
|
if not channel:
|
||||||
|
log.error('slack.channel not defined in salt config')
|
||||||
|
return
|
||||||
|
|
||||||
|
if not from_name:
|
||||||
|
log.error('slack.from_name not defined in salt config')
|
||||||
|
return
|
||||||
|
|
||||||
|
if not api_key:
|
||||||
|
log.error('slack.api_key not defined in salt config')
|
||||||
|
return
|
||||||
|
|
||||||
|
message = ('id: {0}\r\n'
|
||||||
|
'function: {1}\r\n'
|
||||||
|
'function args: {2}\r\n'
|
||||||
|
'jid: {3}\r\n'
|
||||||
|
'return: {4}\r\n').format(
|
||||||
|
ret.get('id'),
|
||||||
|
ret.get('fun'),
|
||||||
|
ret.get('fun_args'),
|
||||||
|
ret.get('jid'),
|
||||||
|
pprint.pformat(ret.get('return')))
|
||||||
|
|
||||||
|
slack = _post_message(channel,
|
||||||
|
message,
|
||||||
|
channel,
|
||||||
|
api_key)
|
||||||
|
return slack
|
@ -183,8 +183,8 @@ def returner(ret):
|
|||||||
server.quit()
|
server.quit()
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any necessary pre-processing and return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -271,8 +271,8 @@ def get_minions():
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any necessary pre-processing and then return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -41,8 +41,8 @@ def returner(ret):
|
|||||||
syslog.syslog(syslog.LOG_INFO, 'salt-minion: {0}'.format(json.dumps(ret)))
|
syslog.syslog(syslog.LOG_INFO, 'salt-minion: {0}'.format(json.dumps(ret)))
|
||||||
|
|
||||||
|
|
||||||
def prep_jid(nocache): # pylint: disable=unused-argument
|
def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Do any necessary pre-preocessing and then return the jid to use
|
Do any work necessary to prepare a JID, including sending a custom id
|
||||||
'''
|
'''
|
||||||
return salt.utils.gen_jid()
|
return passed_jid if passed_jid is not None else salt.utils.gen_jid()
|
||||||
|
@ -74,7 +74,7 @@ def lookup_jid(jid, ext_source=None, missing=False, outputter=None):
|
|||||||
try:
|
try:
|
||||||
data = mminion.returners['{0}.get_jid'.format(returner)](jid)
|
data = mminion.returners['{0}.get_jid'.format(returner)](jid)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
print 'Requested returner could not be loaded. No JIDs could be retreived.'
|
print 'Requested returner could not be loaded. No JIDs could be retrieved.'
|
||||||
return
|
return
|
||||||
for minion in data:
|
for minion in data:
|
||||||
if u'return' in data[minion]:
|
if u'return' in data[minion]:
|
||||||
@ -132,7 +132,7 @@ def list_jobs(ext_source=None,
|
|||||||
try:
|
try:
|
||||||
ret = mminion.returners['{0}.get_jids'.format(returner)]()
|
ret = mminion.returners['{0}.get_jids'.format(returner)]()
|
||||||
except TypeError:
|
except TypeError:
|
||||||
print 'Error: Requested returner could not be loaded. No jobs could be retreived.'
|
print 'Error: Requested returner could not be loaded. No jobs could be retrieved.'
|
||||||
return
|
return
|
||||||
|
|
||||||
if search_metadata:
|
if search_metadata:
|
||||||
@ -200,8 +200,8 @@ def print_job(jid, ext_source=None, outputter=None):
|
|||||||
job = mminion.returners['{0}.get_load'.format(returner)](jid)
|
job = mminion.returners['{0}.get_load'.format(returner)](jid)
|
||||||
ret[jid] = _format_jid_instance(jid, job)
|
ret[jid] = _format_jid_instance(jid, job)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
ret[jid]['Result'] = 'Requested returner {0} is not available. Jobs cannot be retreived. '
|
ret[jid]['Result'] = ('Requested returner {0} is not available. Jobs cannot be retrieved. '
|
||||||
'Check master log for details.'.format(returner)
|
'Check master log for details.'.format(returner))
|
||||||
return ret
|
return ret
|
||||||
ret[jid]['Result'] = mminion.returners['{0}.get_jid'.format(returner)](jid)
|
ret[jid]['Result'] = mminion.returners['{0}.get_jid'.format(returner)](jid)
|
||||||
salt.output.display_output(ret, outputter, opts=__opts__)
|
salt.output.display_output(ret, outputter, opts=__opts__)
|
||||||
|
@ -20,7 +20,7 @@ def __virtual__():
|
|||||||
return 'at.at' in __salt__
|
return 'at.at' in __salt__
|
||||||
|
|
||||||
|
|
||||||
def present(name, timespec, tag=None, runas=None, user=None, job=None):
|
def present(name, timespec, tag=None, user=None, job=None):
|
||||||
'''
|
'''
|
||||||
Add a job to queue.
|
Add a job to queue.
|
||||||
|
|
||||||
@ -33,11 +33,6 @@ def present(name, timespec, tag=None, runas=None, user=None, job=None):
|
|||||||
tag
|
tag
|
||||||
Make a tag for the job.
|
Make a tag for the job.
|
||||||
|
|
||||||
runas
|
|
||||||
Users run the job.
|
|
||||||
|
|
||||||
.. deprecated:: 2014.1.4
|
|
||||||
|
|
||||||
user
|
user
|
||||||
The user to run the at job
|
The user to run the at job
|
||||||
|
|
||||||
@ -48,7 +43,7 @@ def present(name, timespec, tag=None, runas=None, user=None, job=None):
|
|||||||
rose:
|
rose:
|
||||||
at.present:
|
at.present:
|
||||||
- job: 'echo "I love saltstack" > love'
|
- job: 'echo "I love saltstack" > love'
|
||||||
- timespec: '9:9 11/09/13'
|
- timespec: '9:09 11/09/13'
|
||||||
- tag: love
|
- tag: love
|
||||||
- user: jam
|
- user: jam
|
||||||
|
|
||||||
@ -61,30 +56,6 @@ def present(name, timespec, tag=None, runas=None, user=None, job=None):
|
|||||||
'comment': 'job {0} is add and will run on {1}'.format(name,
|
'comment': 'job {0} is add and will run on {1}'.format(name,
|
||||||
timespec)}
|
timespec)}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 2014.1.4. Support will be removed in {version}.',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
binary = salt.utils.which('at')
|
binary = salt.utils.which('at')
|
||||||
|
|
||||||
if __opts__['test']:
|
if __opts__['test']:
|
||||||
|
@ -202,49 +202,3 @@ def change(name, context=None, changes=None, lens=None, **kwargs):
|
|||||||
ret['changes'] = changes
|
ret['changes'] = changes
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def setvalue(name, prefix=None, changes=None, **kwargs):
|
|
||||||
'''
|
|
||||||
.. deprecated:: 2014.7.0
|
|
||||||
Use :py:func:`~salt.states.augeas.change` instead.
|
|
||||||
|
|
||||||
Set a value for a specific augeas path
|
|
||||||
'''
|
|
||||||
ret = {'name': name, 'result': False, 'comment': '', 'changes': {}}
|
|
||||||
|
|
||||||
args = []
|
|
||||||
if not changes:
|
|
||||||
ret['comment'] = '\'changes\' must be specified'
|
|
||||||
return ret
|
|
||||||
else:
|
|
||||||
if not isinstance(changes, list):
|
|
||||||
ret['comment'] = '\'changes\' must be formatted as a list'
|
|
||||||
return ret
|
|
||||||
for change_ in changes:
|
|
||||||
if not isinstance(change_, dict) or len(change_) > 1:
|
|
||||||
ret['comment'] = 'Invalidly-formatted change'
|
|
||||||
return ret
|
|
||||||
key = next(iter(change_))
|
|
||||||
args.extend([key, change_[key]])
|
|
||||||
|
|
||||||
if prefix is not None:
|
|
||||||
args.insert(0, 'prefix={0}'.format(prefix))
|
|
||||||
|
|
||||||
if __opts__['test']:
|
|
||||||
ret['result'] = None
|
|
||||||
ret['comment'] = 'Calling setvalue with {0}'.format(args)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
call = __salt__['augeas.setvalue'](*args)
|
|
||||||
|
|
||||||
ret['result'] = call['retval']
|
|
||||||
|
|
||||||
if ret['result'] is False:
|
|
||||||
ret['comment'] = 'Error: {0}'.format(call['error'])
|
|
||||||
return ret
|
|
||||||
|
|
||||||
ret['comment'] = 'Success'
|
|
||||||
for change_ in changes:
|
|
||||||
ret['changes'].update(change_)
|
|
||||||
return ret
|
|
||||||
|
@ -39,7 +39,6 @@ the location of composer in the state.
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils
|
|
||||||
from salt.exceptions import CommandExecutionError, CommandNotFoundError
|
from salt.exceptions import CommandExecutionError, CommandNotFoundError
|
||||||
|
|
||||||
|
|
||||||
@ -53,7 +52,6 @@ def __virtual__():
|
|||||||
def installed(name,
|
def installed(name,
|
||||||
composer=None,
|
composer=None,
|
||||||
php=None,
|
php=None,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
prefer_source=None,
|
prefer_source=None,
|
||||||
prefer_dist=None,
|
prefer_dist=None,
|
||||||
@ -78,11 +76,6 @@ def installed(name,
|
|||||||
Location of the php executable to use with composer.
|
Location of the php executable to use with composer.
|
||||||
(i.e. /usr/bin/php)
|
(i.e. /usr/bin/php)
|
||||||
|
|
||||||
runas
|
|
||||||
Which system user to run composer as.
|
|
||||||
|
|
||||||
.. deprecated:: 2014.1.4
|
|
||||||
|
|
||||||
user
|
user
|
||||||
Which system user to run composer as.
|
Which system user to run composer as.
|
||||||
|
|
||||||
@ -114,30 +107,6 @@ def installed(name,
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 2014.1.4.',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
call = __salt__['composer.install'](
|
call = __salt__['composer.install'](
|
||||||
name,
|
name,
|
||||||
|
@ -2288,7 +2288,8 @@ def replace(name,
|
|||||||
|
|
||||||
.. versionadded:: 0.17.0
|
.. versionadded:: 0.17.0
|
||||||
|
|
||||||
Params are identical to :py:func:`~salt.modules.file.replace`.
|
Params are identical to the remote execution function :mod:`file.replace
|
||||||
|
<salt.modules.file.replace>`.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
name = os.path.expanduser(name)
|
name = os.path.expanduser(name)
|
||||||
@ -2484,138 +2485,6 @@ def blockreplace(
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def sed(name,
|
|
||||||
before,
|
|
||||||
after,
|
|
||||||
limit='',
|
|
||||||
backup='.bak',
|
|
||||||
options='-r -e',
|
|
||||||
flags='g',
|
|
||||||
negate_match=False):
|
|
||||||
'''
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
Use :py:func:`~salt.states.file.replace` instead.
|
|
||||||
|
|
||||||
Maintain a simple edit to a file
|
|
||||||
|
|
||||||
The file will be searched for the ``before`` pattern before making the
|
|
||||||
edit. In general the ``limit`` pattern should be as specific as possible
|
|
||||||
and ``before`` and ``after`` should contain the minimal text to be changed.
|
|
||||||
|
|
||||||
before
|
|
||||||
A pattern that should exist in the file before the edit.
|
|
||||||
after
|
|
||||||
A pattern that should exist in the file after the edit.
|
|
||||||
limit
|
|
||||||
An optional second pattern that can limit the scope of the before
|
|
||||||
pattern.
|
|
||||||
backup : '.bak'
|
|
||||||
The extension for the backed-up version of the file before the edit. If
|
|
||||||
no backups is desired, pass in the empty string: ''
|
|
||||||
options : ``-r -e``
|
|
||||||
Any options to pass to the ``sed`` command. ``-r`` uses extended
|
|
||||||
regular expression syntax and ``-e`` denotes that what follows is an
|
|
||||||
expression that sed will execute.
|
|
||||||
flags : ``g``
|
|
||||||
Any flags to append to the sed expression. ``g`` specifies the edit
|
|
||||||
should be made globally (and not stop after the first replacement).
|
|
||||||
negate_match : False
|
|
||||||
Negate the search command (``!``)
|
|
||||||
|
|
||||||
.. versionadded:: 0.17.0
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
# Disable the epel repo by default
|
|
||||||
/etc/yum.repos.d/epel.repo:
|
|
||||||
file.sed:
|
|
||||||
- before: 1
|
|
||||||
- after: 0
|
|
||||||
- limit: ^enabled=
|
|
||||||
|
|
||||||
# Remove ldap from nsswitch
|
|
||||||
/etc/nsswitch.conf:
|
|
||||||
file.sed:
|
|
||||||
- before: 'ldap'
|
|
||||||
- after: ''
|
|
||||||
- limit: '^passwd:'
|
|
||||||
|
|
||||||
.. versionadded:: 0.9.5
|
|
||||||
'''
|
|
||||||
name = os.path.expanduser(name)
|
|
||||||
|
|
||||||
ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
|
|
||||||
|
|
||||||
check_res, check_msg = _check_file(name)
|
|
||||||
if not check_res:
|
|
||||||
return _error(ret, check_msg)
|
|
||||||
|
|
||||||
# Mandate that before and after are strings
|
|
||||||
before = str(before)
|
|
||||||
after = str(after)
|
|
||||||
|
|
||||||
# Look for the pattern before attempting the edit
|
|
||||||
if not __salt__['file.sed_contains'](name,
|
|
||||||
before,
|
|
||||||
limit=limit,
|
|
||||||
flags=flags):
|
|
||||||
# Pattern not found; don't try to guess why, just tell the user there
|
|
||||||
# were no changes made, as the changes should only be made once anyway.
|
|
||||||
# This makes it so users can use backreferences without the state
|
|
||||||
# coming back as failed all the time.
|
|
||||||
ret['comment'] = '"before" pattern not found, no changes made'
|
|
||||||
ret['result'] = True
|
|
||||||
return ret
|
|
||||||
|
|
||||||
if __opts__['test']:
|
|
||||||
ret['comment'] = 'File {0} is set to be updated'.format(name)
|
|
||||||
ret['result'] = None
|
|
||||||
return ret
|
|
||||||
|
|
||||||
with salt.utils.fopen(name, 'rb') as fp_:
|
|
||||||
slines = fp_.readlines()
|
|
||||||
|
|
||||||
# should be ok now; perform the edit
|
|
||||||
retcode = __salt__['file.sed'](path=name,
|
|
||||||
before=before,
|
|
||||||
after=after,
|
|
||||||
limit=limit,
|
|
||||||
backup=backup,
|
|
||||||
options=options,
|
|
||||||
flags=flags,
|
|
||||||
negate_match=negate_match)['retcode']
|
|
||||||
|
|
||||||
if retcode != 0:
|
|
||||||
ret['result'] = False
|
|
||||||
ret['comment'] = ('There was an error running sed. '
|
|
||||||
'Return code {0}').format(retcode)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
with salt.utils.fopen(name, 'rb') as fp_:
|
|
||||||
nlines = fp_.readlines()
|
|
||||||
|
|
||||||
if slines != nlines:
|
|
||||||
if not salt.utils.istextfile(name):
|
|
||||||
ret['changes']['diff'] = 'Replace binary file'
|
|
||||||
else:
|
|
||||||
# Changes happened, add them
|
|
||||||
ret['changes']['diff'] = ''.join(difflib.unified_diff(slines,
|
|
||||||
nlines))
|
|
||||||
|
|
||||||
# Don't check the result -- sed is not designed to be able to check
|
|
||||||
# the result, because of backreferences and so forth. Just report
|
|
||||||
# that sed was run, and assume it was successful (no error!)
|
|
||||||
ret['result'] = True
|
|
||||||
ret['comment'] = 'sed ran without error'
|
|
||||||
else:
|
|
||||||
ret['result'] = True
|
|
||||||
ret['comment'] = 'sed ran without error, but no changes were made'
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def comment(name, regex, char='#', backup='.bak'):
|
def comment(name, regex, char='#', backup='.bak'):
|
||||||
'''
|
'''
|
||||||
Comment out specified lines in a file.
|
Comment out specified lines in a file.
|
||||||
|
@ -15,9 +15,6 @@ you can specify what ruby version and gemset to target.
|
|||||||
- ruby: jruby@jgemset
|
- ruby: jruby@jgemset
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Import salt libs
|
|
||||||
import salt.utils
|
|
||||||
|
|
||||||
|
|
||||||
def __virtual__():
|
def __virtual__():
|
||||||
'''
|
'''
|
||||||
@ -28,7 +25,6 @@ def __virtual__():
|
|||||||
|
|
||||||
def installed(name, # pylint: disable=C0103
|
def installed(name, # pylint: disable=C0103
|
||||||
ruby=None,
|
ruby=None,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
version=None,
|
version=None,
|
||||||
rdoc=False,
|
rdoc=False,
|
||||||
@ -44,11 +40,6 @@ def installed(name, # pylint: disable=C0103
|
|||||||
ruby: None
|
ruby: None
|
||||||
For RVM or rbenv installations: the ruby version and gemset to target.
|
For RVM or rbenv installations: the ruby version and gemset to target.
|
||||||
|
|
||||||
runas: None
|
|
||||||
The user under which to run the ``gem`` command
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user: None
|
user: None
|
||||||
The user under which to run the ``gem`` command
|
The user under which to run the ``gem`` command
|
||||||
|
|
||||||
@ -72,31 +63,6 @@ def installed(name, # pylint: disable=C0103
|
|||||||
Format: http://hostname[:port]
|
Format: http://hostname[:port]
|
||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
gems = __salt__['gem.list'](name, ruby, runas=user)
|
gems = __salt__['gem.list'](name, ruby, runas=user)
|
||||||
if name in gems and version is not None and version in gems[name]:
|
if name in gems and version is not None and version in gems[name]:
|
||||||
ret['result'] = True
|
ret['result'] = True
|
||||||
@ -128,7 +94,7 @@ def installed(name, # pylint: disable=C0103
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def removed(name, ruby=None, runas=None, user=None):
|
def removed(name, ruby=None, user=None):
|
||||||
'''
|
'''
|
||||||
Make sure that a gem is not installed.
|
Make sure that a gem is not installed.
|
||||||
|
|
||||||
@ -138,11 +104,6 @@ def removed(name, ruby=None, runas=None, user=None):
|
|||||||
ruby: None
|
ruby: None
|
||||||
For RVM or rbenv installations: the ruby version and gemset to target.
|
For RVM or rbenv installations: the ruby version and gemset to target.
|
||||||
|
|
||||||
runas: None
|
|
||||||
The user under which to run the ``gem`` command
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user: None
|
user: None
|
||||||
The user under which to run the ``gem`` command
|
The user under which to run the ``gem`` command
|
||||||
|
|
||||||
@ -150,30 +111,6 @@ def removed(name, ruby=None, runas=None, user=None):
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if name not in __salt__['gem.list'](name, ruby, runas=user):
|
if name not in __salt__['gem.list'](name, ruby, runas=user):
|
||||||
ret['result'] = True
|
ret['result'] = True
|
||||||
ret['comment'] = 'Gem is not installed.'
|
ret['comment'] = 'Gem is not installed.'
|
||||||
|
@ -22,7 +22,6 @@ import os.path
|
|||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils
|
|
||||||
from salt.exceptions import CommandExecutionError
|
from salt.exceptions import CommandExecutionError
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -38,7 +37,6 @@ def __virtual__():
|
|||||||
def latest(name,
|
def latest(name,
|
||||||
rev=None,
|
rev=None,
|
||||||
target=None,
|
target=None,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
force=None,
|
force=None,
|
||||||
force_checkout=False,
|
force_checkout=False,
|
||||||
@ -64,11 +62,6 @@ def latest(name,
|
|||||||
target
|
target
|
||||||
Name of the target directory where repository is about to be cloned
|
Name of the target directory where repository is about to be cloned
|
||||||
|
|
||||||
runas
|
|
||||||
Name of the user performing repository management operations
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
Name of the user performing repository management operations
|
Name of the user performing repository management operations
|
||||||
|
|
||||||
@ -162,30 +155,6 @@ def latest(name,
|
|||||||
return _fail(ret, '"target" option is required')
|
return _fail(ret, '"target" option is required')
|
||||||
target = os.path.expanduser(target)
|
target = os.path.expanduser(target)
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
run_check_cmd_kwargs = {'runas': user}
|
run_check_cmd_kwargs = {'runas': user}
|
||||||
if 'shell' in __grains__:
|
if 'shell' in __grains__:
|
||||||
run_check_cmd_kwargs['shell'] = __grains__['shell']
|
run_check_cmd_kwargs['shell'] = __grains__['shell']
|
||||||
@ -405,7 +374,7 @@ def latest(name,
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def present(name, bare=True, runas=None, user=None, force=False):
|
def present(name, bare=True, user=None, force=False):
|
||||||
'''
|
'''
|
||||||
Make sure the repository is present in the given directory
|
Make sure the repository is present in the given directory
|
||||||
|
|
||||||
@ -415,11 +384,6 @@ def present(name, bare=True, runas=None, user=None, force=False):
|
|||||||
bare
|
bare
|
||||||
Create a bare repository (Default: True)
|
Create a bare repository (Default: True)
|
||||||
|
|
||||||
runas
|
|
||||||
Name of the user performing repository management operations
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
Name of the user performing repository management operations
|
Name of the user performing repository management operations
|
||||||
|
|
||||||
@ -432,30 +396,6 @@ def present(name, bare=True, runas=None, user=None, force=False):
|
|||||||
name = os.path.expanduser(name)
|
name = os.path.expanduser(name)
|
||||||
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
# If the named directory is a git repo return True
|
# If the named directory is a git repo return True
|
||||||
if os.path.isdir(name):
|
if os.path.isdir(name):
|
||||||
if bare and os.path.isfile(os.path.join(name, 'HEAD')):
|
if bare and os.path.isfile(os.path.join(name, 'HEAD')):
|
||||||
|
@ -42,7 +42,6 @@ def latest(name,
|
|||||||
rev=None,
|
rev=None,
|
||||||
target=None,
|
target=None,
|
||||||
clean=False,
|
clean=False,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
force=False,
|
force=False,
|
||||||
opts=False):
|
opts=False):
|
||||||
@ -61,11 +60,6 @@ def latest(name,
|
|||||||
clean
|
clean
|
||||||
Force a clean update with -C (Default: False)
|
Force a clean update with -C (Default: False)
|
||||||
|
|
||||||
runas
|
|
||||||
Name of the user performing repository management operations
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
Name of the user performing repository management operations
|
Name of the user performing repository management operations
|
||||||
|
|
||||||
@ -79,30 +73,6 @@ def latest(name,
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if not target:
|
if not target:
|
||||||
return _fail(ret, '"target option is required')
|
return _fail(ret, '"target option is required')
|
||||||
|
|
||||||
|
@ -338,6 +338,14 @@ def append(name, family='ipv4', **kwargs):
|
|||||||
name,
|
name,
|
||||||
command.strip(),
|
command.strip(),
|
||||||
family)
|
family)
|
||||||
|
if kwargs['save']:
|
||||||
|
if kwargs['save'] is not True:
|
||||||
|
filename = kwargs['save']
|
||||||
|
else:
|
||||||
|
filename = None
|
||||||
|
__salt__['iptables.save'](filename, family=family)
|
||||||
|
ret['comment'] += ('\nSaved iptables rule for {0} to: '
|
||||||
|
'{1} for {2}'.format(name, command.strip(), family))
|
||||||
return ret
|
return ret
|
||||||
if __opts__['test']:
|
if __opts__['test']:
|
||||||
ret['comment'] = 'iptables rule for {0} needs to be set ({1}) for {2}'.format(
|
ret['comment'] = 'iptables rule for {0} needs to be set ({1}) for {2}'.format(
|
||||||
@ -409,6 +417,11 @@ def insert(name, family='ipv4', **kwargs):
|
|||||||
name,
|
name,
|
||||||
family,
|
family,
|
||||||
command.strip())
|
command.strip())
|
||||||
|
if 'save' in kwargs:
|
||||||
|
if kwargs['save']:
|
||||||
|
__salt__['iptables.save'](filename=None, family=family)
|
||||||
|
ret['comment'] += ('\nSaved iptables rule for {0} to: '
|
||||||
|
'{1} for {2}').format(name, command.strip(), family)
|
||||||
return ret
|
return ret
|
||||||
if __opts__['test']:
|
if __opts__['test']:
|
||||||
ret['comment'] = 'iptables rule for {0} needs to be set for {1} ({2})'.format(
|
ret['comment'] = 'iptables rule for {0} needs to be set for {1} ({2})'.format(
|
||||||
|
@ -129,7 +129,6 @@ def run(name, **kwargs):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
aspec = salt.utils.get_function_argspec(__salt__[name])
|
aspec = salt.utils.get_function_argspec(__salt__[name])
|
||||||
|
|
||||||
args = []
|
args = []
|
||||||
defaults = {}
|
defaults = {}
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ for the package which provides npm (simply ``npm`` in most cases). Example:
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils
|
|
||||||
from salt.exceptions import CommandExecutionError, CommandNotFoundError
|
from salt.exceptions import CommandExecutionError, CommandNotFoundError
|
||||||
|
|
||||||
|
|
||||||
@ -34,7 +33,6 @@ def __virtual__():
|
|||||||
def installed(name,
|
def installed(name,
|
||||||
pkgs=None,
|
pkgs=None,
|
||||||
dir=None,
|
dir=None,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
force_reinstall=False,
|
force_reinstall=False,
|
||||||
registry=None,
|
registry=None,
|
||||||
@ -67,11 +65,6 @@ def installed(name,
|
|||||||
The target directory in which to install the package, or None for
|
The target directory in which to install the package, or None for
|
||||||
global installation
|
global installation
|
||||||
|
|
||||||
runas
|
|
||||||
The user to run NPM with
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
The user to run NPM with
|
The user to run NPM with
|
||||||
|
|
||||||
@ -94,37 +87,13 @@ def installed(name,
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if pkgs is not None:
|
if pkgs is not None:
|
||||||
pkg_list = pkgs
|
pkg_list = pkgs
|
||||||
else:
|
else:
|
||||||
pkg_list = [name]
|
pkg_list = [name]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
installed_pkgs = __salt__['npm.list'](dir=dir, runas=runas, env=env)
|
installed_pkgs = __salt__['npm.list'](dir=dir, runas=user, env=env)
|
||||||
except (CommandNotFoundError, CommandExecutionError) as err:
|
except (CommandNotFoundError, CommandExecutionError) as err:
|
||||||
ret['result'] = False
|
ret['result'] = False
|
||||||
ret['comment'] = 'Error looking up {0!r}: {1}'.format(name, err)
|
ret['comment'] = 'Error looking up {0!r}: {1}'.format(name, err)
|
||||||
@ -221,7 +190,6 @@ def installed(name,
|
|||||||
|
|
||||||
def removed(name,
|
def removed(name,
|
||||||
dir=None,
|
dir=None,
|
||||||
runas=None,
|
|
||||||
user=None):
|
user=None):
|
||||||
'''
|
'''
|
||||||
Verify that the given package is not installed.
|
Verify that the given package is not installed.
|
||||||
@ -230,11 +198,6 @@ def removed(name,
|
|||||||
The target directory in which to install the package, or None for
|
The target directory in which to install the package, or None for
|
||||||
global installation
|
global installation
|
||||||
|
|
||||||
runas
|
|
||||||
The user to run NPM with
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
The user to run NPM with
|
The user to run NPM with
|
||||||
|
|
||||||
@ -242,30 +205,6 @@ def removed(name,
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
installed_pkgs = __salt__['npm.list'](dir=dir)
|
installed_pkgs = __salt__['npm.list'](dir=dir)
|
||||||
except (CommandExecutionError, CommandNotFoundError) as err:
|
except (CommandExecutionError, CommandNotFoundError) as err:
|
||||||
@ -295,50 +234,18 @@ def removed(name,
|
|||||||
|
|
||||||
|
|
||||||
def bootstrap(name,
|
def bootstrap(name,
|
||||||
runas=None,
|
|
||||||
user=None):
|
user=None):
|
||||||
'''
|
'''
|
||||||
Bootstraps a node.js application.
|
Bootstraps a node.js application.
|
||||||
|
|
||||||
will execute npm install --json on the specified directory
|
Will execute 'npm install --json' on the specified directory.
|
||||||
|
|
||||||
|
|
||||||
runas
|
|
||||||
The user to run NPM with
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
The user to run NPM with
|
The user to run NPM with
|
||||||
|
|
||||||
.. versionadded:: 0.17.0
|
.. versionadded:: 0.17.0
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
call = __salt__['npm.install'](dir=name, runas=user, pkg=None)
|
call = __salt__['npm.install'](dir=name, runas=user, pkg=None)
|
||||||
|
@ -130,6 +130,7 @@ def installed(name,
|
|||||||
allow_external=None,
|
allow_external=None,
|
||||||
allow_unverified=None,
|
allow_unverified=None,
|
||||||
process_dependency_links=False,
|
process_dependency_links=False,
|
||||||
|
env_vars=None,
|
||||||
use_vt=False):
|
use_vt=False):
|
||||||
'''
|
'''
|
||||||
Make sure the package is installed
|
Make sure the package is installed
|
||||||
@ -267,6 +268,11 @@ def installed(name,
|
|||||||
a pip executable. The example below assumes a virtual environment
|
a pip executable. The example below assumes a virtual environment
|
||||||
has been created at ``/foo/.virtualenvs/bar``.
|
has been created at ``/foo/.virtualenvs/bar``.
|
||||||
|
|
||||||
|
env_vars
|
||||||
|
Add or modify environment variables. Useful for tweaking build steps,
|
||||||
|
such as specifying INCLUDE or LIBRARY paths in Makefiles, build scripts or
|
||||||
|
compiler calls.
|
||||||
|
|
||||||
use_vt
|
use_vt
|
||||||
Use VT terminal emulation (see ouptut while installing)
|
Use VT terminal emulation (see ouptut while installing)
|
||||||
|
|
||||||
@ -554,6 +560,7 @@ def installed(name,
|
|||||||
allow_unverified=allow_unverified,
|
allow_unverified=allow_unverified,
|
||||||
process_dependency_links=process_dependency_links,
|
process_dependency_links=process_dependency_links,
|
||||||
saltenv=__env__,
|
saltenv=__env__,
|
||||||
|
env_vars=env_vars,
|
||||||
use_vt=use_vt
|
use_vt=use_vt
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ def present(name,
|
|||||||
lc_ctype=None,
|
lc_ctype=None,
|
||||||
owner=None,
|
owner=None,
|
||||||
template=None,
|
template=None,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
maintenance_db=None,
|
maintenance_db=None,
|
||||||
db_password=None,
|
db_password=None,
|
||||||
@ -62,11 +61,6 @@ def present(name,
|
|||||||
template
|
template
|
||||||
The template database from which to build this database
|
The template database from which to build this database
|
||||||
|
|
||||||
runas
|
|
||||||
System user all operations should be performed on behalf of
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
System user all operations should be performed on behalf of
|
System user all operations should be performed on behalf of
|
||||||
|
|
||||||
@ -95,23 +89,6 @@ def present(name,
|
|||||||
'added in 0.17.0',
|
'added in 0.17.0',
|
||||||
_dont_call_warnings=True
|
_dont_call_warnings=True
|
||||||
)
|
)
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
db_args = {
|
db_args = {
|
||||||
'maintenance_db': maintenance_db,
|
'maintenance_db': maintenance_db,
|
||||||
@ -188,7 +165,6 @@ def present(name,
|
|||||||
|
|
||||||
|
|
||||||
def absent(name,
|
def absent(name,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
maintenance_db=None,
|
maintenance_db=None,
|
||||||
db_password=None,
|
db_password=None,
|
||||||
@ -213,11 +189,6 @@ def absent(name,
|
|||||||
db_port
|
db_port
|
||||||
Database port if different from config or default
|
Database port if different from config or default
|
||||||
|
|
||||||
runas
|
|
||||||
System user all operations should be performed on behalf of
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
System user all operations should be performed on behalf of
|
System user all operations should be performed on behalf of
|
||||||
|
|
||||||
@ -227,29 +198,6 @@ def absent(name,
|
|||||||
'changes': {},
|
'changes': {},
|
||||||
'result': True,
|
'result': True,
|
||||||
'comment': ''}
|
'comment': ''}
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
db_args = {
|
db_args = {
|
||||||
'maintenance_db': maintenance_db,
|
'maintenance_db': maintenance_db,
|
||||||
|
@ -14,7 +14,6 @@ The postgres_group module is used to create and manage Postgres groups.
|
|||||||
# Import Python libs
|
# Import Python libs
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
# Salt imports
|
# Salt imports
|
||||||
@ -43,7 +42,6 @@ def present(name,
|
|||||||
password=None,
|
password=None,
|
||||||
refresh_password=None,
|
refresh_password=None,
|
||||||
groups=None,
|
groups=None,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
maintenance_db=None,
|
maintenance_db=None,
|
||||||
db_password=None,
|
db_password=None,
|
||||||
@ -109,11 +107,6 @@ def present(name,
|
|||||||
groups
|
groups
|
||||||
A string of comma separated groups the group should be in
|
A string of comma separated groups the group should be in
|
||||||
|
|
||||||
runas
|
|
||||||
System user all operations should be performed on behalf of
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
System user all operations should be performed on behalf of
|
System user all operations should be performed on behalf of
|
||||||
|
|
||||||
@ -136,12 +129,6 @@ def present(name,
|
|||||||
'result': True,
|
'result': True,
|
||||||
'comment': 'Group {0} is already present'.format(name)}
|
'comment': 'Group {0} is already present'.format(name)}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if createuser:
|
if createuser:
|
||||||
createroles = True
|
createroles = True
|
||||||
# default to encrypted passwords
|
# default to encrypted passwords
|
||||||
@ -151,24 +138,6 @@ def present(name,
|
|||||||
password = postgres._maybe_encrypt_password(name,
|
password = postgres._maybe_encrypt_password(name,
|
||||||
password,
|
password,
|
||||||
encrypted=encrypted)
|
encrypted=encrypted)
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
db_args = {
|
db_args = {
|
||||||
'maintenance_db': maintenance_db,
|
'maintenance_db': maintenance_db,
|
||||||
'runas': user,
|
'runas': user,
|
||||||
@ -250,7 +219,6 @@ def present(name,
|
|||||||
|
|
||||||
|
|
||||||
def absent(name,
|
def absent(name,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
maintenance_db=None,
|
maintenance_db=None,
|
||||||
db_password=None,
|
db_password=None,
|
||||||
@ -263,11 +231,6 @@ def absent(name,
|
|||||||
name
|
name
|
||||||
The groupname of the group to remove
|
The groupname of the group to remove
|
||||||
|
|
||||||
runas
|
|
||||||
System user all operations should be performed on behalf of
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
System user all operations should be performed on behalf of
|
System user all operations should be performed on behalf of
|
||||||
|
|
||||||
@ -290,30 +253,6 @@ def absent(name,
|
|||||||
'result': True,
|
'result': True,
|
||||||
'comment': ''}
|
'comment': ''}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
db_args = {
|
db_args = {
|
||||||
'maintenance_db': maintenance_db,
|
'maintenance_db': maintenance_db,
|
||||||
'runas': user,
|
'runas': user,
|
||||||
|
@ -14,7 +14,6 @@ The postgres_users module is used to create and manage Postgres users.
|
|||||||
# Import Python libs
|
# Import Python libs
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
# Salt imports
|
# Salt imports
|
||||||
@ -43,7 +42,6 @@ def present(name,
|
|||||||
password=None,
|
password=None,
|
||||||
refresh_password=None,
|
refresh_password=None,
|
||||||
groups=None,
|
groups=None,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
maintenance_db=None,
|
maintenance_db=None,
|
||||||
db_password=None,
|
db_password=None,
|
||||||
@ -108,11 +106,6 @@ def present(name,
|
|||||||
groups
|
groups
|
||||||
A string of comma separated groups the user should be in
|
A string of comma separated groups the user should be in
|
||||||
|
|
||||||
runas
|
|
||||||
System user all operations should be performed on behalf of
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
System user all operations should be performed on behalf of
|
System user all operations should be performed on behalf of
|
||||||
|
|
||||||
@ -135,12 +128,6 @@ def present(name,
|
|||||||
'result': True,
|
'result': True,
|
||||||
'comment': 'User {0} is already present'.format(name)}
|
'comment': 'User {0} is already present'.format(name)}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if createuser:
|
if createuser:
|
||||||
createroles = True
|
createroles = True
|
||||||
# default to encrypted passwords
|
# default to encrypted passwords
|
||||||
@ -151,24 +138,6 @@ def present(name,
|
|||||||
password,
|
password,
|
||||||
encrypted=encrypted)
|
encrypted=encrypted)
|
||||||
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
db_args = {
|
db_args = {
|
||||||
'maintenance_db': maintenance_db,
|
'maintenance_db': maintenance_db,
|
||||||
'runas': user,
|
'runas': user,
|
||||||
@ -254,7 +223,6 @@ def present(name,
|
|||||||
|
|
||||||
|
|
||||||
def absent(name,
|
def absent(name,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
maintenance_db=None,
|
maintenance_db=None,
|
||||||
db_password=None,
|
db_password=None,
|
||||||
@ -267,11 +235,6 @@ def absent(name,
|
|||||||
name
|
name
|
||||||
The username of the user to remove
|
The username of the user to remove
|
||||||
|
|
||||||
runas
|
|
||||||
System user all operations should be performed on behalf of
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
System user all operations should be performed on behalf of
|
System user all operations should be performed on behalf of
|
||||||
|
|
||||||
@ -294,30 +257,6 @@ def absent(name,
|
|||||||
'result': True,
|
'result': True,
|
||||||
'comment': ''}
|
'comment': ''}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
db_args = {
|
db_args = {
|
||||||
'maintenance_db': maintenance_db,
|
'maintenance_db': maintenance_db,
|
||||||
'runas': user,
|
'runas': user,
|
||||||
|
@ -48,9 +48,6 @@ This is how a state configuration could look like:
|
|||||||
# Import python libs
|
# Import python libs
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# Import salt libs
|
|
||||||
import salt.utils
|
|
||||||
|
|
||||||
|
|
||||||
def _check_pyenv(ret, user=None):
|
def _check_pyenv(ret, user=None):
|
||||||
'''
|
'''
|
||||||
@ -99,7 +96,7 @@ def _check_and_install_python(ret, python, default=False, user=None):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def installed(name, default=False, runas=None, user=None):
|
def installed(name, default=False, user=None):
|
||||||
'''
|
'''
|
||||||
Verify that the specified python is installed with pyenv. pyenv is
|
Verify that the specified python is installed with pyenv. pyenv is
|
||||||
installed if necessary.
|
installed if necessary.
|
||||||
@ -110,11 +107,6 @@ def installed(name, default=False, runas=None, user=None):
|
|||||||
default : False
|
default : False
|
||||||
Whether to make this python the default.
|
Whether to make this python the default.
|
||||||
|
|
||||||
runas: None
|
|
||||||
The user to run pyenv as.
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user: None
|
user: None
|
||||||
The user to run pyenv as.
|
The user to run pyenv as.
|
||||||
|
|
||||||
@ -124,18 +116,6 @@ def installed(name, default=False, runas=None, user=None):
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if name.startswith('python-'):
|
if name.startswith('python-'):
|
||||||
name = re.sub(r'^python-', '', name)
|
name = re.sub(r'^python-', '', name)
|
||||||
|
|
||||||
@ -179,7 +159,7 @@ def _check_and_uninstall_python(ret, python, user=None):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def absent(name, runas=None, user=None):
|
def absent(name, user=None):
|
||||||
'''
|
'''
|
||||||
Verify that the specified python is not installed with pyenv. pyenv
|
Verify that the specified python is not installed with pyenv. pyenv
|
||||||
is installed if necessary.
|
is installed if necessary.
|
||||||
@ -187,11 +167,6 @@ def absent(name, runas=None, user=None):
|
|||||||
name
|
name
|
||||||
The version of python to uninstall
|
The version of python to uninstall
|
||||||
|
|
||||||
runas: None
|
|
||||||
The user to run pyenv as.
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user: None
|
user: None
|
||||||
The user to run pyenv as.
|
The user to run pyenv as.
|
||||||
|
|
||||||
@ -201,30 +176,6 @@ def absent(name, runas=None, user=None):
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Hydrogen',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if name.startswith('python-'):
|
if name.startswith('python-'):
|
||||||
name = re.sub(r'^python-', '', name)
|
name = re.sub(r'^python-', '', name)
|
||||||
|
|
||||||
|
@ -45,9 +45,6 @@ This is how a state configuration could look like:
|
|||||||
import re
|
import re
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
# Import salt libs
|
|
||||||
import salt.utils
|
|
||||||
|
|
||||||
|
|
||||||
def _check_rbenv(ret, user=None):
|
def _check_rbenv(ret, user=None):
|
||||||
'''
|
'''
|
||||||
@ -96,7 +93,7 @@ def _check_and_install_ruby(ret, ruby, default=False, user=None):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def installed(name, default=False, runas=None, user=None):
|
def installed(name, default=False, user=None):
|
||||||
'''
|
'''
|
||||||
Verify that the specified ruby is installed with rbenv. Rbenv is
|
Verify that the specified ruby is installed with rbenv. Rbenv is
|
||||||
installed if necessary.
|
installed if necessary.
|
||||||
@ -107,11 +104,6 @@ def installed(name, default=False, runas=None, user=None):
|
|||||||
default : False
|
default : False
|
||||||
Whether to make this ruby the default.
|
Whether to make this ruby the default.
|
||||||
|
|
||||||
runas: None
|
|
||||||
The user to run rbenv as.
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user: None
|
user: None
|
||||||
The user to run rbenv as.
|
The user to run rbenv as.
|
||||||
|
|
||||||
@ -122,30 +114,6 @@ def installed(name, default=False, runas=None, user=None):
|
|||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
rbenv_installed_ret = copy.deepcopy(ret)
|
rbenv_installed_ret = copy.deepcopy(ret)
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if name.startswith('ruby-'):
|
if name.startswith('ruby-'):
|
||||||
name = re.sub(r'^ruby-', '', name)
|
name = re.sub(r'^ruby-', '', name)
|
||||||
|
|
||||||
@ -187,7 +155,7 @@ def _check_and_uninstall_ruby(ret, ruby, user=None):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def absent(name, runas=None, user=None):
|
def absent(name, user=None):
|
||||||
'''
|
'''
|
||||||
Verify that the specified ruby is not installed with rbenv. Rbenv
|
Verify that the specified ruby is not installed with rbenv. Rbenv
|
||||||
is installed if necessary.
|
is installed if necessary.
|
||||||
@ -195,11 +163,6 @@ def absent(name, runas=None, user=None):
|
|||||||
name
|
name
|
||||||
The version of ruby to uninstall
|
The version of ruby to uninstall
|
||||||
|
|
||||||
runas: None
|
|
||||||
The user to run rbenv as.
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user: None
|
user: None
|
||||||
The user to run rbenv as.
|
The user to run rbenv as.
|
||||||
|
|
||||||
@ -209,30 +172,6 @@ def absent(name, runas=None, user=None):
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if name.startswith('ruby-'):
|
if name.startswith('ruby-'):
|
||||||
name = re.sub(r'^ruby-', '', name)
|
name = re.sub(r'^ruby-', '', name)
|
||||||
|
|
||||||
|
@ -105,9 +105,6 @@ configuration could look like:
|
|||||||
# Import python libs
|
# Import python libs
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# Import salt libs
|
|
||||||
import salt.utils
|
|
||||||
|
|
||||||
|
|
||||||
def _check_rvm(ret, user=None):
|
def _check_rvm(ret, user=None):
|
||||||
'''
|
'''
|
||||||
@ -169,7 +166,7 @@ def _check_ruby(ret, ruby, user=None):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def installed(name, default=False, runas=None, user=None):
|
def installed(name, default=False, user=None):
|
||||||
'''
|
'''
|
||||||
Verify that the specified ruby is installed with RVM. RVM is
|
Verify that the specified ruby is installed with RVM. RVM is
|
||||||
installed when necessary.
|
installed when necessary.
|
||||||
@ -180,11 +177,6 @@ def installed(name, default=False, runas=None, user=None):
|
|||||||
default : False
|
default : False
|
||||||
Whether to make this ruby the default.
|
Whether to make this ruby the default.
|
||||||
|
|
||||||
runas: None
|
|
||||||
The user to run rvm as.
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user: None
|
user: None
|
||||||
The user to run rvm as.
|
The user to run rvm as.
|
||||||
|
|
||||||
@ -192,30 +184,6 @@ def installed(name, default=False, runas=None, user=None):
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if __opts__['test']:
|
if __opts__['test']:
|
||||||
ret['comment'] = 'Ruby {0} is set to be installed'.format(name)
|
ret['comment'] = 'Ruby {0} is set to be installed'.format(name)
|
||||||
return ret
|
return ret
|
||||||
@ -231,7 +199,7 @@ def installed(name, default=False, runas=None, user=None):
|
|||||||
return _check_and_install_ruby(ret, name, default, user=user)
|
return _check_and_install_ruby(ret, name, default, user=user)
|
||||||
|
|
||||||
|
|
||||||
def gemset_present(name, ruby='default', runas=None, user=None):
|
def gemset_present(name, ruby='default', user=None):
|
||||||
'''
|
'''
|
||||||
Verify that the gemset is present.
|
Verify that the gemset is present.
|
||||||
|
|
||||||
@ -241,11 +209,6 @@ def gemset_present(name, ruby='default', runas=None, user=None):
|
|||||||
ruby: default
|
ruby: default
|
||||||
The ruby version this gemset belongs to.
|
The ruby version this gemset belongs to.
|
||||||
|
|
||||||
runas: None
|
|
||||||
The user to run rvm as.
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user: None
|
user: None
|
||||||
The user to run rvm as.
|
The user to run rvm as.
|
||||||
|
|
||||||
@ -253,30 +216,6 @@ def gemset_present(name, ruby='default', runas=None, user=None):
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
ret = _check_rvm(ret, user)
|
ret = _check_rvm(ret, user)
|
||||||
if ret['result'] is False:
|
if ret['result'] is False:
|
||||||
return ret
|
return ret
|
||||||
|
108
salt/states/slack.py
Normal file
108
salt/states/slack.py
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Send a message to Slack
|
||||||
|
=========================
|
||||||
|
|
||||||
|
This state is useful for sending messages to Slack during state runs.
|
||||||
|
|
||||||
|
.. versionadded:: Lithium
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
slack-message:
|
||||||
|
slack.send_message:
|
||||||
|
- channel: '#general'
|
||||||
|
- from_name: SuperAdmin
|
||||||
|
- message: 'This state was executed successfully.'
|
||||||
|
- api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||||
|
|
||||||
|
The api key can be specified in the master or minion configuration like below:
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
slack:
|
||||||
|
api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
def __virtual__():
|
||||||
|
'''
|
||||||
|
Only load if the slack module is available in __salt__
|
||||||
|
'''
|
||||||
|
return 'slack' if 'slack.post_message' in __salt__ else False
|
||||||
|
|
||||||
|
|
||||||
|
def post_message(name,
|
||||||
|
channel,
|
||||||
|
from_name,
|
||||||
|
message,
|
||||||
|
api_key=None):
|
||||||
|
'''
|
||||||
|
Send a message to a Slack room.
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
slack-message:
|
||||||
|
slack.send_message:
|
||||||
|
- channel: '#general'
|
||||||
|
- from_name: SuperAdmin
|
||||||
|
- message: 'This state was executed successfully.'
|
||||||
|
- api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||||
|
|
||||||
|
The following parameters are required:
|
||||||
|
|
||||||
|
name
|
||||||
|
The unique name for this event.
|
||||||
|
|
||||||
|
channel
|
||||||
|
The room to send the message to. Can either be the ID or the name.
|
||||||
|
|
||||||
|
from_name
|
||||||
|
The name of that is to be shown in the "from" field.
|
||||||
|
If not specified, defaults to.
|
||||||
|
|
||||||
|
message
|
||||||
|
The message that is to be sent to the Hipchat room.
|
||||||
|
|
||||||
|
The following parameters are optional:
|
||||||
|
api_key
|
||||||
|
The api key for Slack to use for authentication,
|
||||||
|
if not specified in the configuration options of master or minion.
|
||||||
|
|
||||||
|
'''
|
||||||
|
ret = {'name': name,
|
||||||
|
'changes': {},
|
||||||
|
'result': False,
|
||||||
|
'comment': ''}
|
||||||
|
|
||||||
|
if __opts__['test']:
|
||||||
|
ret['comment'] = 'The following message is to be sent to Slack: {0}'.format(message)
|
||||||
|
ret['result'] = None
|
||||||
|
return ret
|
||||||
|
|
||||||
|
if not channel:
|
||||||
|
ret['comment'] = 'Slack channel is missing: {0}'.format(channel)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
if not from_name:
|
||||||
|
ret['comment'] = 'Slack from name is missing: {0}'.format(from_name)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
if not message:
|
||||||
|
ret['comment'] = 'Slack message is missing: {0}'.format(message)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
result = __salt__['slack.post_message'](
|
||||||
|
channel=channel,
|
||||||
|
message=message,
|
||||||
|
from_name=from_name,
|
||||||
|
api_key=api_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
ret['result'] = True
|
||||||
|
ret['comment'] = 'Sent message: {0}'.format(name)
|
||||||
|
else:
|
||||||
|
ret['comment'] = 'Failed to send message: {0}'.format(name)
|
||||||
|
|
||||||
|
return ret
|
@ -17,8 +17,6 @@ Interaction with the Supervisor daemon
|
|||||||
# Import python libs
|
# Import python libs
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
# Import salt libs
|
|
||||||
import salt.utils
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -48,7 +46,6 @@ def running(name,
|
|||||||
restart=False,
|
restart=False,
|
||||||
update=False,
|
update=False,
|
||||||
user=None,
|
user=None,
|
||||||
runas=None,
|
|
||||||
conf_file=None,
|
conf_file=None,
|
||||||
bin_env=None):
|
bin_env=None):
|
||||||
'''
|
'''
|
||||||
@ -63,11 +60,6 @@ def running(name,
|
|||||||
update
|
update
|
||||||
Whether to update the supervisor configuration.
|
Whether to update the supervisor configuration.
|
||||||
|
|
||||||
runas
|
|
||||||
Name of the user to run the supervisorctl command
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
Name of the user to run the supervisorctl command
|
Name of the user to run the supervisorctl command
|
||||||
|
|
||||||
@ -83,30 +75,6 @@ def running(name,
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if 'supervisord.status' not in __salt__:
|
if 'supervisord.status' not in __salt__:
|
||||||
ret['result'] = False
|
ret['result'] = False
|
||||||
ret['comment'] = 'Supervisord module not activated. Do you need to install supervisord?'
|
ret['comment'] = 'Supervisord module not activated. Do you need to install supervisord?'
|
||||||
@ -270,7 +238,7 @@ def running(name,
|
|||||||
log.debug(comment)
|
log.debug(comment)
|
||||||
result = __salt__['supervisord.start'](
|
result = __salt__['supervisord.start'](
|
||||||
name,
|
name,
|
||||||
user=runas,
|
user=user,
|
||||||
conf_file=conf_file,
|
conf_file=conf_file,
|
||||||
bin_env=bin_env
|
bin_env=bin_env
|
||||||
)
|
)
|
||||||
@ -285,7 +253,6 @@ def running(name,
|
|||||||
|
|
||||||
def dead(name,
|
def dead(name,
|
||||||
user=None,
|
user=None,
|
||||||
runas=None,
|
|
||||||
conf_file=None,
|
conf_file=None,
|
||||||
bin_env=None):
|
bin_env=None):
|
||||||
'''
|
'''
|
||||||
@ -294,11 +261,6 @@ def dead(name,
|
|||||||
name
|
name
|
||||||
Service name as defined in the supervisor configuration file
|
Service name as defined in the supervisor configuration file
|
||||||
|
|
||||||
runas
|
|
||||||
Name of the user to run the supervisorctl command
|
|
||||||
|
|
||||||
.. deprecated:: 0.17.0
|
|
||||||
|
|
||||||
user
|
user
|
||||||
Name of the user to run the supervisorctl command
|
Name of the user to run the supervisorctl command
|
||||||
|
|
||||||
@ -314,30 +276,6 @@ def dead(name,
|
|||||||
'''
|
'''
|
||||||
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 0.17.0',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if __opts__['test']:
|
if __opts__['test']:
|
||||||
ret['result'] = None
|
ret['result'] = None
|
||||||
ret['comment'] = (
|
ret['comment'] = (
|
||||||
@ -347,7 +285,7 @@ def dead(name,
|
|||||||
log.debug(comment)
|
log.debug(comment)
|
||||||
|
|
||||||
all_processes = __salt__['supervisord.status'](
|
all_processes = __salt__['supervisord.status'](
|
||||||
user=runas,
|
user=user,
|
||||||
conf_file=conf_file,
|
conf_file=conf_file,
|
||||||
bin_env=bin_env
|
bin_env=bin_env
|
||||||
)
|
)
|
||||||
@ -397,7 +335,6 @@ def mod_watch(name,
|
|||||||
restart=True,
|
restart=True,
|
||||||
update=False,
|
update=False,
|
||||||
user=None,
|
user=None,
|
||||||
runas=None,
|
|
||||||
conf_file=None,
|
conf_file=None,
|
||||||
bin_env=None):
|
bin_env=None):
|
||||||
# Always restart on watch
|
# Always restart on watch
|
||||||
@ -406,7 +343,6 @@ def mod_watch(name,
|
|||||||
restart=restart,
|
restart=restart,
|
||||||
update=update,
|
update=update,
|
||||||
user=user,
|
user=user,
|
||||||
runas=runas,
|
|
||||||
conf_file=conf_file,
|
conf_file=conf_file,
|
||||||
bin_env=bin_env
|
bin_env=bin_env
|
||||||
)
|
)
|
||||||
|
@ -35,7 +35,6 @@ def managed(name,
|
|||||||
never_download=None,
|
never_download=None,
|
||||||
prompt=None,
|
prompt=None,
|
||||||
user=None,
|
user=None,
|
||||||
runas=None,
|
|
||||||
no_chown=False,
|
no_chown=False,
|
||||||
cwd=None,
|
cwd=None,
|
||||||
index_url=None,
|
index_url=None,
|
||||||
@ -83,29 +82,6 @@ def managed(name,
|
|||||||
ret['comment'] = 'Virtualenv was not detected on this system'
|
ret['comment'] = 'Virtualenv was not detected on this system'
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'The support for \'runas\' is being deprecated in favor of '
|
|
||||||
'\'user\' and will be removed in Salt Beryllium. Please update '
|
|
||||||
'your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. \'runas\' is '
|
|
||||||
'being ignored in favor of \'user\' as the support for \'runas\' '
|
|
||||||
'is being deprecated in favor of \'user\' and will be removed in '
|
|
||||||
'Salt Beryllium. Please update your state files.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
if salt.utils.is_windows():
|
if salt.utils.is_windows():
|
||||||
venv_py = os.path.join(name, 'Scripts', 'python.exe')
|
venv_py = os.path.join(name, 'Scripts', 'python.exe')
|
||||||
else:
|
else:
|
||||||
|
@ -40,7 +40,6 @@ Available Functions
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils
|
|
||||||
from salt._compat import string_types
|
from salt._compat import string_types
|
||||||
|
|
||||||
# Define the module's virtual name
|
# Define the module's virtual name
|
||||||
@ -120,7 +119,6 @@ def installed(name,
|
|||||||
config='buildout.cfg',
|
config='buildout.cfg',
|
||||||
quiet=False,
|
quiet=False,
|
||||||
parts=None,
|
parts=None,
|
||||||
runas=None,
|
|
||||||
user=None,
|
user=None,
|
||||||
env=(),
|
env=(),
|
||||||
buildout_ver=None,
|
buildout_ver=None,
|
||||||
@ -154,11 +152,6 @@ def installed(name,
|
|||||||
parts
|
parts
|
||||||
specific buildout parts to run
|
specific buildout parts to run
|
||||||
|
|
||||||
runas
|
|
||||||
user used to run buildout as
|
|
||||||
|
|
||||||
.. deprecated:: 2014.1.4
|
|
||||||
|
|
||||||
user
|
user
|
||||||
user used to run buildout as
|
user used to run buildout as
|
||||||
|
|
||||||
@ -209,30 +202,6 @@ def installed(name,
|
|||||||
'''
|
'''
|
||||||
ret = {}
|
ret = {}
|
||||||
|
|
||||||
salt.utils.warn_until(
|
|
||||||
'Lithium',
|
|
||||||
'Please remove \'runas\' support at this stage. \'user\' support was '
|
|
||||||
'added in 2014.1.4.',
|
|
||||||
_dont_call_warnings=True
|
|
||||||
)
|
|
||||||
if runas:
|
|
||||||
# Warn users about the deprecation
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'The \'runas\' argument is being deprecated in favor of \'user\', '
|
|
||||||
'please update your state files.'
|
|
||||||
)
|
|
||||||
if user is not None and runas is not None:
|
|
||||||
# user wins over runas but let warn about the deprecation.
|
|
||||||
ret.setdefault('warnings', []).append(
|
|
||||||
'Passed both the \'runas\' and \'user\' arguments. Please don\'t. '
|
|
||||||
'\'runas\' is being ignored in favor of \'user\'.'
|
|
||||||
)
|
|
||||||
runas = None
|
|
||||||
elif runas is not None:
|
|
||||||
# Support old runas usage
|
|
||||||
user = runas
|
|
||||||
runas = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
test_release = int(test_release)
|
test_release = int(test_release)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -526,15 +526,13 @@ def dns_check(addr, safe=False, ipv6=False):
|
|||||||
if not addr:
|
if not addr:
|
||||||
error = True
|
error = True
|
||||||
except TypeError:
|
except TypeError:
|
||||||
err = ('Attempt to resolve address failed. Invalid or unresolveable address')
|
err = ('Attempt to resolve address \'{0}\' failed. Invalid or unresolveable address').format(addr)
|
||||||
raise SaltSystemExit(code=42, msg=err)
|
raise SaltSystemExit(code=42, msg=err)
|
||||||
except socket.error:
|
except socket.error:
|
||||||
error = True
|
error = True
|
||||||
|
|
||||||
if error:
|
if error:
|
||||||
err = ('This master address: \'{0}\' was previously resolvable '
|
err = ('DNS lookup of \'{0}\' failed.').format(addr)
|
||||||
'but now fails to resolve! The previously resolved ip addr '
|
|
||||||
'will continue to be used').format(addr)
|
|
||||||
if safe:
|
if safe:
|
||||||
if salt.log.is_console_configured():
|
if salt.log.is_console_configured():
|
||||||
# If logging is not configured it also means that either
|
# If logging is not configured it also means that either
|
||||||
@ -842,13 +840,6 @@ def build_whitespace_split_regex(text):
|
|||||||
return r'(?m)^{0}$'.format(regex)
|
return r'(?m)^{0}$'.format(regex)
|
||||||
|
|
||||||
|
|
||||||
def build_whitepace_splited_regex(text):
|
|
||||||
warnings.warn('The build_whitepace_splited_regex function is deprecated,'
|
|
||||||
' please use build_whitespace_split_regex instead.',
|
|
||||||
DeprecationWarning)
|
|
||||||
build_whitespace_split_regex(text)
|
|
||||||
|
|
||||||
|
|
||||||
def format_call(fun,
|
def format_call(fun,
|
||||||
data,
|
data,
|
||||||
initial_ret=None,
|
initial_ret=None,
|
||||||
|
@ -367,6 +367,9 @@ def bootstrap(vm_, opts):
|
|||||||
'known_hosts_file': salt.config.get_cloud_config_value(
|
'known_hosts_file': salt.config.get_cloud_config_value(
|
||||||
'known_hosts_file', vm_, opts, default='/dev/null'
|
'known_hosts_file', vm_, opts, default='/dev/null'
|
||||||
),
|
),
|
||||||
|
'file_map': salt.config.get_cloud_config_value(
|
||||||
|
'file_map', vm_, opts, default=None
|
||||||
|
),
|
||||||
}
|
}
|
||||||
# forward any info about possible ssh gateway to deploy script
|
# forward any info about possible ssh gateway to deploy script
|
||||||
# as some providers need also a 'gateway' configuration
|
# as some providers need also a 'gateway' configuration
|
||||||
@ -428,8 +431,10 @@ def bootstrap(vm_, opts):
|
|||||||
else:
|
else:
|
||||||
deployed = deploy_script(**deploy_kwargs)
|
deployed = deploy_script(**deploy_kwargs)
|
||||||
|
|
||||||
if deployed:
|
if deployed is not False:
|
||||||
ret['deployed'] = deployed
|
ret['deployed'] = True
|
||||||
|
if deployed is not True:
|
||||||
|
ret.update(deployed)
|
||||||
log.info('Salt installed on {0}'.format(vm_['name']))
|
log.info('Salt installed on {0}'.format(vm_['name']))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -938,6 +943,7 @@ def deploy_script(host,
|
|||||||
deploy_command='/tmp/.saltcloud/deploy.sh',
|
deploy_command='/tmp/.saltcloud/deploy.sh',
|
||||||
opts=None,
|
opts=None,
|
||||||
tmp_dir='/tmp/.saltcloud',
|
tmp_dir='/tmp/.saltcloud',
|
||||||
|
file_map=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
'''
|
'''
|
||||||
Copy a deploy script to a remote server, execute it, and remove it
|
Copy a deploy script to a remote server, execute it, and remove it
|
||||||
@ -1021,6 +1027,34 @@ def deploy_script(host,
|
|||||||
'Cant set {0} ownership on {1}'.format(
|
'Cant set {0} ownership on {1}'.format(
|
||||||
username, tmp_dir))
|
username, tmp_dir))
|
||||||
|
|
||||||
|
if not isinstance(file_map, dict):
|
||||||
|
file_map = {}
|
||||||
|
|
||||||
|
# Copy an arbitrary group of files to the target system
|
||||||
|
remote_dirs = []
|
||||||
|
file_map_success = []
|
||||||
|
file_map_fail = []
|
||||||
|
for map_item in file_map:
|
||||||
|
local_file = map_item
|
||||||
|
remote_file = file_map[map_item]
|
||||||
|
if not os.path.exists(map_item):
|
||||||
|
log.error(
|
||||||
|
'The local file "{0}" does not exist, and will not be '
|
||||||
|
'copied to "{1}" on the target system'.format(
|
||||||
|
local_file, remote_file
|
||||||
|
)
|
||||||
|
)
|
||||||
|
file_map_fail.append({local_file: remote_file})
|
||||||
|
continue
|
||||||
|
remote_dir = os.path.dirname(remote_file)
|
||||||
|
if remote_dir not in remote_dirs:
|
||||||
|
root_cmd('mkdir -p {0}'.format(remote_dir), tty, sudo, **ssh_kwargs)
|
||||||
|
remote_dirs.append(remote_dir)
|
||||||
|
sftp_file(
|
||||||
|
remote_file, kwargs=ssh_kwargs, local_file=local_file
|
||||||
|
)
|
||||||
|
file_map_success.append({local_file: remote_file})
|
||||||
|
|
||||||
# Minion configuration
|
# Minion configuration
|
||||||
if minion_pem:
|
if minion_pem:
|
||||||
sftp_file('{0}/minion.pem'.format(tmp_dir), minion_pem, ssh_kwargs)
|
sftp_file('{0}/minion.pem'.format(tmp_dir), minion_pem, ssh_kwargs)
|
||||||
@ -1316,6 +1350,11 @@ def deploy_script(host,
|
|||||||
},
|
},
|
||||||
transport=opts.get('transport', 'zeromq')
|
transport=opts.get('transport', 'zeromq')
|
||||||
)
|
)
|
||||||
|
if file_map_fail or file_map_success:
|
||||||
|
return {
|
||||||
|
'File Upload Success': file_map_success,
|
||||||
|
'File Upload Failure': file_map_fail,
|
||||||
|
}
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -1500,14 +1539,18 @@ def smb_file(dest_path, contents, kwargs):
|
|||||||
win_cmd(cmd)
|
win_cmd(cmd)
|
||||||
|
|
||||||
|
|
||||||
def sftp_file(dest_path, contents, kwargs):
|
def sftp_file(dest_path, contents=None, kwargs=None, local_file=None):
|
||||||
'''
|
'''
|
||||||
Use sftp to upload a file to a server
|
Use sftp to upload a file to a server
|
||||||
'''
|
'''
|
||||||
|
if contents is not None:
|
||||||
tmpfh, tmppath = tempfile.mkstemp()
|
tmpfh, tmppath = tempfile.mkstemp()
|
||||||
with salt.utils.fopen(tmppath, 'w') as tmpfile:
|
with salt.utils.fopen(tmppath, 'w') as tmpfile:
|
||||||
tmpfile.write(contents)
|
tmpfile.write(contents)
|
||||||
|
|
||||||
|
if local_file is not None:
|
||||||
|
tmppath = local_file
|
||||||
|
|
||||||
log.debug('Uploading {0} to {1} (sfcp)'.format(dest_path, kwargs['hostname']))
|
log.debug('Uploading {0} to {1} (sfcp)'.format(dest_path, kwargs['hostname']))
|
||||||
|
|
||||||
ssh_args = [
|
ssh_args = [
|
||||||
|
@ -183,15 +183,12 @@ class CkMinions(object):
|
|||||||
if not greedy and id_ in minions:
|
if not greedy and id_ in minions:
|
||||||
minions.remove(id_)
|
minions.remove(id_)
|
||||||
continue
|
continue
|
||||||
try:
|
search_results = self.serial.load(
|
||||||
with salt.utils.fopen(datap, 'rb') as fp_:
|
salt.utils.fopen(datap, 'rb')
|
||||||
search_results = self.serial.load(fp_).get(search_type)
|
).get(search_type)
|
||||||
except (IOError, OSError):
|
|
||||||
continue
|
|
||||||
if not salt.utils.subdict_match(search_results,
|
if not salt.utils.subdict_match(search_results,
|
||||||
expr,
|
expr,
|
||||||
delimiter,
|
regex_match=regex_match) and id_ in minions:
|
||||||
regex_match=regex_match):
|
|
||||||
minions.remove(id_)
|
minions.remove(id_)
|
||||||
return list(minions)
|
return list(minions)
|
||||||
|
|
||||||
@ -205,36 +202,11 @@ class CkMinions(object):
|
|||||||
'''
|
'''
|
||||||
Return the minions found by looking via grains with PCRE
|
Return the minions found by looking via grains with PCRE
|
||||||
'''
|
'''
|
||||||
cache_enabled = self.opts.get('minion_data_cache', False)
|
return self._check_cache_minions(expr,
|
||||||
|
delimiter,
|
||||||
if greedy:
|
greedy,
|
||||||
minions = set(
|
'grains',
|
||||||
os.listdir(os.path.join(self.opts['pki_dir'], self.acc))
|
regex_match=True)
|
||||||
)
|
|
||||||
elif cache_enabled:
|
|
||||||
minions = os.listdir(os.path.join(self.opts['cachedir'], 'minions'))
|
|
||||||
else:
|
|
||||||
return list()
|
|
||||||
|
|
||||||
if cache_enabled:
|
|
||||||
cdir = os.path.join(self.opts['cachedir'], 'minions')
|
|
||||||
if not os.path.isdir(cdir):
|
|
||||||
return list(minions)
|
|
||||||
for id_ in os.listdir(cdir):
|
|
||||||
if not greedy and id_ not in minions:
|
|
||||||
continue
|
|
||||||
datap = os.path.join(cdir, id_, 'data.p')
|
|
||||||
if not os.path.isfile(datap):
|
|
||||||
if not greedy and id_ in minions:
|
|
||||||
minions.remove(id_)
|
|
||||||
continue
|
|
||||||
grains = self.serial.load(
|
|
||||||
salt.utils.fopen(datap, 'rb')
|
|
||||||
).get('grains')
|
|
||||||
if not salt.utils.subdict_match(grains, expr,
|
|
||||||
delimiter=':', regex_match=True) and id_ in minions:
|
|
||||||
minions.remove(id_)
|
|
||||||
return list(minions)
|
|
||||||
|
|
||||||
def _check_pillar_minions(self, expr, delimiter, greedy):
|
def _check_pillar_minions(self, expr, delimiter, greedy):
|
||||||
'''
|
'''
|
||||||
|
23
salt/wheel/minions.py
Normal file
23
salt/wheel/minions.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Wheel system wrapper for connected minions
|
||||||
|
'''
|
||||||
|
|
||||||
|
from salt.utils.cache import CacheCli
|
||||||
|
import salt.config
|
||||||
|
import salt.utils.minion
|
||||||
|
|
||||||
|
|
||||||
|
def connected():
|
||||||
|
'''
|
||||||
|
List all connected minions on a salt-master
|
||||||
|
'''
|
||||||
|
opts = salt.config.master_config(__opts__['conf_file'])
|
||||||
|
minions = []
|
||||||
|
|
||||||
|
if opts.get('con_cache'):
|
||||||
|
cache_cli = CacheCli(opts)
|
||||||
|
minions = cache_cli.get_cached()
|
||||||
|
else:
|
||||||
|
minions = list(salt.utils.minions.CkMinions(opts).connected_ids())
|
||||||
|
return minions
|
1
setup.py
1
setup.py
@ -651,6 +651,7 @@ SETUP_KWARGS = {'name': NAME,
|
|||||||
'salt.utils',
|
'salt.utils',
|
||||||
'salt.utils.decorators',
|
'salt.utils.decorators',
|
||||||
'salt.utils.openstack',
|
'salt.utils.openstack',
|
||||||
|
'salt.utils.openstack.pyrax',
|
||||||
'salt.utils.validate',
|
'salt.utils.validate',
|
||||||
'salt.utils.serializers',
|
'salt.utils.serializers',
|
||||||
'salt.wheel',
|
'salt.wheel',
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
digitalocean-test:
|
digitalocean-test:
|
||||||
provider: digitalocean-config
|
provider: digitalocean-config
|
||||||
image: Ubuntu 14.04 x64
|
image: 14.04 x64
|
||||||
size: 2GB
|
size: 2GB
|
||||||
|
@ -518,40 +518,6 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
|
|||||||
finally:
|
finally:
|
||||||
os.remove(name)
|
os.remove(name)
|
||||||
|
|
||||||
def test_sed(self):
|
|
||||||
'''
|
|
||||||
file.sed
|
|
||||||
'''
|
|
||||||
name = os.path.join(integration.TMP, 'sed_test')
|
|
||||||
with salt.utils.fopen(name, 'w+') as fp_:
|
|
||||||
fp_.write('change_me')
|
|
||||||
ret = self.run_state(
|
|
||||||
'file.sed', name=name, before='change', after='salt'
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
with salt.utils.fopen(name, 'r') as fp_:
|
|
||||||
self.assertIn('salt', fp_.read())
|
|
||||||
self.assertSaltTrueReturn(ret)
|
|
||||||
finally:
|
|
||||||
os.remove(name)
|
|
||||||
|
|
||||||
def test_test_sed(self):
|
|
||||||
'''
|
|
||||||
file.sed test integration
|
|
||||||
'''
|
|
||||||
name = os.path.join(integration.TMP, 'sed_test_test')
|
|
||||||
with salt.utils.fopen(name, 'w+') as fp_:
|
|
||||||
fp_.write('change_me')
|
|
||||||
ret = self.run_state(
|
|
||||||
'file.sed', test=True, name=name, before='change', after='salt'
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
with salt.utils.fopen(name, 'r') as fp_:
|
|
||||||
self.assertIn('change', fp_.read())
|
|
||||||
self.assertSaltNoneReturn(ret)
|
|
||||||
finally:
|
|
||||||
os.remove(name)
|
|
||||||
|
|
||||||
def test_comment(self):
|
def test_comment(self):
|
||||||
'''
|
'''
|
||||||
file.comment
|
file.comment
|
||||||
|
74
tests/unit/states/module_test.py
Normal file
74
tests/unit/states/module_test.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
:codeauthor: :email:`Nicole Thomas (nicole@saltstack.com)`
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Import Pyhton Libs
|
||||||
|
from inspect import ArgSpec
|
||||||
|
|
||||||
|
# Import Salt Libs
|
||||||
|
from salt.states import module
|
||||||
|
|
||||||
|
# Import Salt Testing Libs
|
||||||
|
from salttesting import skipIf, TestCase
|
||||||
|
from salttesting.helpers import ensure_in_syspath
|
||||||
|
from salttesting.mock import (
|
||||||
|
NO_MOCK,
|
||||||
|
NO_MOCK_REASON,
|
||||||
|
MagicMock,
|
||||||
|
patch
|
||||||
|
)
|
||||||
|
|
||||||
|
ensure_in_syspath('../../')
|
||||||
|
|
||||||
|
CMD = 'foo.bar'
|
||||||
|
MOCK = MagicMock()
|
||||||
|
module.__salt__ = {CMD: MOCK}
|
||||||
|
module.__opts__ = {'test': False}
|
||||||
|
|
||||||
|
|
||||||
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||||
|
class ModuleStateTest(TestCase):
|
||||||
|
'''
|
||||||
|
Tests module state (salt/states/module.py)
|
||||||
|
'''
|
||||||
|
|
||||||
|
aspec = ArgSpec(args=['hello', 'world'],
|
||||||
|
varargs=None,
|
||||||
|
keywords=None,
|
||||||
|
defaults=False)
|
||||||
|
|
||||||
|
def test_module_run_module_not_available(self):
|
||||||
|
'''
|
||||||
|
Tests the return of module.run state when the module function
|
||||||
|
name isn't available
|
||||||
|
'''
|
||||||
|
with patch.dict(module.__salt__, {}):
|
||||||
|
cmd = 'hello.world'
|
||||||
|
ret = module.run(cmd)
|
||||||
|
comment = 'Module function {0} is not available'.format(cmd)
|
||||||
|
self.assertEqual(ret['comment'], comment)
|
||||||
|
self.assertFalse(ret['result'])
|
||||||
|
|
||||||
|
def test_module_run_test_true(self):
|
||||||
|
'''
|
||||||
|
Tests the return of module.run state when test=True is passed in
|
||||||
|
'''
|
||||||
|
with patch.dict(module.__opts__, {'test': True}):
|
||||||
|
ret = module.run(CMD)
|
||||||
|
comment = 'Module function {0} is set to execute'.format(CMD)
|
||||||
|
self.assertEqual(ret['comment'], comment)
|
||||||
|
|
||||||
|
@patch('salt.utils.get_function_argspec', MagicMock(return_value=aspec))
|
||||||
|
def test_module_run_missing_arg(self):
|
||||||
|
'''
|
||||||
|
Tests the return of module.run state when arguments are missing
|
||||||
|
'''
|
||||||
|
ret = module.run(CMD)
|
||||||
|
comment = 'The following arguments are missing: world hello'
|
||||||
|
self.assertEqual(ret['comment'], comment)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
from integration import run_tests
|
||||||
|
run_tests(ModuleStateTest, needs_daemon=False)
|
@ -108,13 +108,6 @@ class UtilsTestCase(TestCase):
|
|||||||
ret = utils.build_whitespace_split_regex(' '.join(LORUM_IPSUM.split()[:5]))
|
ret = utils.build_whitespace_split_regex(' '.join(LORUM_IPSUM.split()[:5]))
|
||||||
self.assertEqual(ret, expected_regex)
|
self.assertEqual(ret, expected_regex)
|
||||||
|
|
||||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
||||||
@patch('warnings.warn')
|
|
||||||
def test_build_whitepace_splited_regex(self, warnings_mock):
|
|
||||||
# noinspection PyDeprecation
|
|
||||||
utils.build_whitepace_splited_regex('foo')
|
|
||||||
self.assertTrue(warnings_mock.called)
|
|
||||||
|
|
||||||
def test_get_function_argspec(self):
|
def test_get_function_argspec(self):
|
||||||
def dummy_func(first, second, third, fourth='fifth'):
|
def dummy_func(first, second, third, fourth='fifth'):
|
||||||
pass
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user