mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 01:18:58 +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>
|
||||
|
||||
<h4>SaltStack training</h4>
|
||||
<p>
|
||||
<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>
|
||||
</p>
|
||||
{% 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>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/releasecandidate') }}">here.</a></p>
|
||||
<a href="{{ pathto('topics/releases/2014.7.0') }}">v2014.7.0rc6</a>! More info
|
||||
<a href="{{ pathto('topics/releases/releasecandidate') }}">here</a>.</p>
|
||||
|
@ -28,8 +28,9 @@ How to Use it
|
||||
|
||||
.. note::
|
||||
|
||||
Since this option changes the basic behavior of the state runtime states
|
||||
should be executed in
|
||||
Since this option changes the basic behavior of the state runtime, after
|
||||
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
|
||||
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
|
||||
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
|
||||
actually run. If the pre-required state executes successfully, the
|
||||
pre-requiring state will then execute. If the pre-required state fails, the
|
||||
pre-requiring state will not execute.
|
||||
executed, as opposed to the test-run. The pre-requiring state will now
|
||||
actually run. If the pre-requiring state executes successfully, the
|
||||
pre-required state will then execute. If the pre-requiring state fails, the
|
||||
pre-required state will not execute.
|
||||
|
||||
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
|
||||
|
@ -15,3 +15,4 @@ Full list of builtin wheel modules
|
||||
file_roots
|
||||
key
|
||||
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
|
||||
-----------------------
|
||||
|
||||
When installing via Homebrew, dependency resolution is handled for you.
|
||||
When using Homebrew, install this way:
|
||||
|
||||
.. 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
|
||||
|
||||
sudo port install py-zmq
|
||||
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':
|
||||
sudo port install salt
|
||||
|
||||
When only using the OS X system's pip, install this way:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@ -47,7 +42,7 @@ Now the salt-master should run without errors:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo /usr/local/share/python/salt-master --log-level=all
|
||||
sudo salt-master --log-level=all
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
=======================
|
||||
|
||||
|
@ -38,6 +38,9 @@ Mapping Events to Reactor SLS Files
|
||||
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.
|
||||
|
||||
.. 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
|
||||
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
|
||||
data does not translate the same way to operations. In state files formula
|
||||
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
|
||||
systems are the :strong:`LocalClient` and the :strong:`Runners`. 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
|
||||
data does not translate the same way to function calls.
|
||||
|
||||
.. versionchanged:: 2014.7.0
|
||||
The ``cmd`` prefix was renamed to ``local`` for consistency with other
|
||||
parts of Salt. A backward-compatible alias was added for ``cmd``.
|
||||
|
||||
In state files the minion generates the data structure locally and uses that to
|
||||
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
|
||||
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
|
||||
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!
|
||||
==============
|
||||
|
||||
@ -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.
|
||||
|
||||
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 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
|
||||
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
|
||||
@ -58,7 +72,7 @@ which may be seen can be safely ignored.
|
||||
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
|
||||
used with salt-ssh. This also allows for a distributed team to easily use
|
||||
a centralized source.
|
||||
@ -78,8 +92,8 @@ to use salt-ssh with teams.
|
||||
No More sshpass
|
||||
---------------
|
||||
|
||||
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
|
||||
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
|
||||
calls substantially more flexible, allowing for intercepting ssh calls in
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
The default `salt thin` location is now user defined, allowing multiple users
|
||||
@ -125,9 +139,9 @@ State System Enhancements
|
||||
New Imperative State Keyword "Listen"
|
||||
-------------------------------------
|
||||
|
||||
The new ``listen`` keyword allows for completely imperative states by calling
|
||||
the ``mod_watch()`` routine after all states have run instead of re-ordering
|
||||
the states.
|
||||
The new ``listen`` and ``listen_in`` keywords allow for completely imperative
|
||||
states by calling the ``mod_watch()`` routine after all states have run instead
|
||||
of re-ordering the states.
|
||||
|
||||
Mod Aggregate Runtime Manipulator
|
||||
---------------------------------
|
||||
@ -137,7 +151,7 @@ state data during execution. This allows for state definitions to be aggregated
|
||||
dynamically at runtime.
|
||||
|
||||
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
|
||||
all other packages set for install and install them all at once in the first
|
||||
pkg state.
|
||||
@ -152,7 +166,15 @@ For more documentation on ``mod_aggregate``, see :doc:`the documentation
|
||||
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
|
||||
@ -200,7 +222,7 @@ Fileserver Backends in salt-call
|
||||
|
||||
Fileserver backends like gitfs can now be used without a salt master! Just add
|
||||
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.
|
||||
|
||||
Amazon Execution Modules
|
||||
|
@ -8,7 +8,7 @@ Salt SSH
|
||||
|
||||
.. 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``.
|
||||
|
||||
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
|
||||
promises are yet made as to its reliability or security.
|
||||
|
||||
This document is also not yet complete
|
||||
As for reliability and security, the encryption used has been audited and
|
||||
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
|
||||
|
||||
@ -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
|
||||
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 is easy, the main difference is that the core dependencies
|
||||
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
|
||||
ioflo. Distribution packages are forthcoming, but libsodium can be easily
|
||||
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
|
||||
salt-key. Remote execution and salt states will function in the same way as
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -15,9 +15,8 @@
|
||||
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
||||
#
|
||||
|
||||
|
||||
Name: salt
|
||||
Version: 2014.1.11
|
||||
Version: 2014.1.13
|
||||
Release: 0
|
||||
Summary: A parallel remote execution system
|
||||
License: Apache-2.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
Index: salt-2014.1.8/pkg/salt-master.service
|
||||
===================================================================
|
||||
--- salt-2014.1.11.orig/pkg/salt-master.service
|
||||
+++ salt-2014.1.11/pkg/salt-master.service
|
||||
--- salt-2014.1.13.orig/pkg/salt-master.service
|
||||
+++ salt-2014.1.13/pkg/salt-master.service
|
||||
@@ -3,8 +3,10 @@ Description=The Salt Master Server
|
||||
After=syslog.target network.target
|
||||
|
||||
|
@ -540,7 +540,7 @@ class Single(object):
|
||||
'root_dir': os.path.join(self.thin_dir, 'running_data'),
|
||||
'id': self.id,
|
||||
'sock_dir': '/',
|
||||
}).strip()
|
||||
}, width=1000).strip()
|
||||
self.target = kwargs
|
||||
self.target.update(args)
|
||||
self.serial = salt.payload.Serial(opts)
|
||||
|
@ -93,6 +93,7 @@ def unpack_ext(ext_path):
|
||||
'var',
|
||||
'cache',
|
||||
'salt',
|
||||
'minion',
|
||||
'extmods')
|
||||
tfile = tarfile.TarFile.gzopen(ext_path)
|
||||
tfile.extractall(path=modcache)
|
||||
|
@ -101,9 +101,9 @@ def avail_images(call=None):
|
||||
items = query(method='images')
|
||||
ret = {}
|
||||
for image in items['images']:
|
||||
ret[image['name']] = {}
|
||||
ret[image['id']] = {}
|
||||
for item in image.keys():
|
||||
ret[image['name']][item] = str(image[item])
|
||||
ret[image['id']][item] = str(image[item])
|
||||
|
||||
return ret
|
||||
|
||||
|
@ -106,12 +106,12 @@ def avail_images(call=None):
|
||||
items = query(method='images', command='?page=' + str(page))
|
||||
|
||||
for image in items['images']:
|
||||
ret[image['name']] = {}
|
||||
ret[image['id']] = {}
|
||||
for item in image.keys():
|
||||
ret[image['name']][item] = str(image[item])
|
||||
ret[image['id']][item] = str(image[item])
|
||||
|
||||
page += 1
|
||||
fetch = next in items['links']['pages']
|
||||
fetch = 'next' in items['links']['pages']
|
||||
|
||||
return ret
|
||||
|
||||
|
@ -43,63 +43,64 @@ Setting up Service Account Authentication:
|
||||
- Consider using a more secure location for your private key.
|
||||
|
||||
Supported commands:
|
||||
# Create a few instances fro profile_name in /etc/salt/cloud.profiles
|
||||
- salt-cloud -p profile_name inst1 inst2 inst3
|
||||
# Delete an instance
|
||||
- salt-cloud -d inst1
|
||||
# Look up data on an instance
|
||||
- salt-cloud -a show_instance inst2
|
||||
# List available locations (aka 'zones') for provider 'gce'
|
||||
- salt-cloud --list-locations gce
|
||||
# List available instance sizes (aka 'machine types') for provider 'gce'
|
||||
- salt-cloud --list-sizes gce
|
||||
# List available images for provider 'gce'
|
||||
- salt-cloud --list-images gce
|
||||
# Create a persistent disk
|
||||
- salt-cloud -f create_disk gce disk_name=pd location=us-central1-b ima...
|
||||
# Permanently delete a persistent disk
|
||||
- salt-cloud -f delete_disk gce disk_name=pd
|
||||
# Attach an existing disk to an existing instance
|
||||
- salt-cloud -a attach_disk myinstance disk_name=mydisk mode=READ_ONLY
|
||||
# Detach a disk from an instance
|
||||
- salt-cloud -a detach_disk myinstance disk_name=mydisk
|
||||
# Show information about the named disk
|
||||
- salt-cloud -a show_disk myinstance disk_name=pd
|
||||
- salt-cloud -f show_disk gce disk_name=pd
|
||||
# Create a snapshot of a persistent disk
|
||||
- salt-cloud -f create_snapshot gce name=snap-1 disk_name=pd
|
||||
# Permanently delete a disk snapshot
|
||||
- salt-cloud -f delete_snapshot gce name=snap-1
|
||||
# Show information about the named snapshot
|
||||
- salt-cloud -f show_snapshot gce name=snap-1
|
||||
# Create a network
|
||||
- salt-cloud -f create_network gce name=mynet cidr=10.10.10.0/24
|
||||
# Delete a network
|
||||
- salt-cloud -f delete_network gce name=mynet
|
||||
# Show info for a network
|
||||
- salt-cloud -f show_network gce name=mynet
|
||||
# Create a firewall rule
|
||||
- salt-cloud -f create_fwrule gce name=fw1 network=mynet allow=tcp:80
|
||||
# Delete a firewall rule
|
||||
- salt-cloud -f delete_fwrule gce name=fw1
|
||||
# Show info for a firewall rule
|
||||
-salt-cloud -f show_fwrule gce name=fw1
|
||||
# Create a load-balancer HTTP health check
|
||||
- salt-cloud -f create_hc gce name=hc path=/ port=80
|
||||
# Delete a load-balancer HTTP health check
|
||||
- salt-cloud -f delete_hc gce name=hc
|
||||
# Show info about an HTTP health check
|
||||
- salt-cloud -f show_hc gce name=hc
|
||||
# Create a load-balancer configuration
|
||||
- salt-cloud -f create_lb gce name=lb region=us-central1 ports=80 ...
|
||||
# Delete a load-balancer configuration
|
||||
- salt-cloud -f delete_lb gce name=lb
|
||||
# Show details about load-balancer
|
||||
- salt-cloud -f show_lb gce name=lb
|
||||
# Add member to load-balancer
|
||||
- salt-cloud -f attach_lb gce name=lb member=www1
|
||||
# Remove member from load-balancer
|
||||
- salt-cloud -f detach_lb gce name=lb member=www1
|
||||
|
||||
# Create a few instances fro profile_name in /etc/salt/cloud.profiles
|
||||
- salt-cloud -p profile_name inst1 inst2 inst3
|
||||
# Delete an instance
|
||||
- salt-cloud -d inst1
|
||||
# Look up data on an instance
|
||||
- salt-cloud -a show_instance inst2
|
||||
# List available locations (aka 'zones') for provider 'gce'
|
||||
- salt-cloud --list-locations gce
|
||||
# List available instance sizes (aka 'machine types') for provider 'gce'
|
||||
- salt-cloud --list-sizes gce
|
||||
# List available images for provider 'gce'
|
||||
- salt-cloud --list-images gce
|
||||
# Create a persistent disk
|
||||
- salt-cloud -f create_disk gce disk_name=pd location=us-central1-b ima...
|
||||
# Permanently delete a persistent disk
|
||||
- salt-cloud -f delete_disk gce disk_name=pd
|
||||
# Attach an existing disk to an existing instance
|
||||
- salt-cloud -a attach_disk myinstance disk_name=mydisk mode=READ_ONLY
|
||||
# Detach a disk from an instance
|
||||
- salt-cloud -a detach_disk myinstance disk_name=mydisk
|
||||
# Show information about the named disk
|
||||
- salt-cloud -a show_disk myinstance disk_name=pd
|
||||
- salt-cloud -f show_disk gce disk_name=pd
|
||||
# Create a snapshot of a persistent disk
|
||||
- salt-cloud -f create_snapshot gce name=snap-1 disk_name=pd
|
||||
# Permanently delete a disk snapshot
|
||||
- salt-cloud -f delete_snapshot gce name=snap-1
|
||||
# Show information about the named snapshot
|
||||
- salt-cloud -f show_snapshot gce name=snap-1
|
||||
# Create a network
|
||||
- salt-cloud -f create_network gce name=mynet cidr=10.10.10.0/24
|
||||
# Delete a network
|
||||
- salt-cloud -f delete_network gce name=mynet
|
||||
# Show info for a network
|
||||
- salt-cloud -f show_network gce name=mynet
|
||||
# Create a firewall rule
|
||||
- salt-cloud -f create_fwrule gce name=fw1 network=mynet allow=tcp:80
|
||||
# Delete a firewall rule
|
||||
- salt-cloud -f delete_fwrule gce name=fw1
|
||||
# Show info for a firewall rule
|
||||
-salt-cloud -f show_fwrule gce name=fw1
|
||||
# Create a load-balancer HTTP health check
|
||||
- salt-cloud -f create_hc gce name=hc path=/ port=80
|
||||
# Delete a load-balancer HTTP health check
|
||||
- salt-cloud -f delete_hc gce name=hc
|
||||
# Show info about an HTTP health check
|
||||
- salt-cloud -f show_hc gce name=hc
|
||||
# Create a load-balancer configuration
|
||||
- salt-cloud -f create_lb gce name=lb region=us-central1 ports=80 ...
|
||||
# Delete a load-balancer configuration
|
||||
- salt-cloud -f delete_lb gce name=lb
|
||||
# Show details about load-balancer
|
||||
- salt-cloud -f show_lb gce name=lb
|
||||
# Add member to load-balancer
|
||||
- salt-cloud -f attach_lb gce name=lb member=www1
|
||||
# Remove member from load-balancer
|
||||
- salt-cloud -f detach_lb gce name=lb member=www1
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
# CREATED: 10/15/2012 09:49:37 PM WEST
|
||||
#======================================================================================================================
|
||||
set -o nounset # Treat unset variables as an error
|
||||
__ScriptVersion="2014.10.14"
|
||||
__ScriptVersion="2014.10.28"
|
||||
__ScriptName="bootstrap-salt.sh"
|
||||
|
||||
#======================================================================================================================
|
||||
@ -202,6 +202,7 @@ _INSECURE_DL=${BS_INSECURE_DL:-$BS_FALSE}
|
||||
_WGET_ARGS=${BS_WGET_ARGS:-}
|
||||
_CURL_ARGS=${BS_CURL_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_MINION_ID="null"
|
||||
# __SIMPLIFY_VERSION is mostly used in Solaris based distributions
|
||||
@ -242,6 +243,7 @@ usage() {
|
||||
-D Show debug output.
|
||||
-c Temporary configuration directory
|
||||
-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
|
||||
the master.
|
||||
-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
|
||||
per -p flag. You're responsible for providing the proper package name.
|
||||
-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
|
||||
} # ---------- 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
|
||||
case "${opt}" in
|
||||
|
||||
@ -297,6 +300,13 @@ do
|
||||
fi
|
||||
;;
|
||||
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"
|
||||
# If the configuration directory does not exist, error out
|
||||
if [ ! -d "$_TEMP_KEYS_DIR" ]; then
|
||||
@ -319,6 +329,7 @@ do
|
||||
L ) _INSTALL_CLOUD=$BS_TRUE ;;
|
||||
p ) _EXTRA_PACKAGES="$_EXTRA_PACKAGES $OPTARG" ;;
|
||||
H ) _HTTP_PROXY="$OPTARG" ;;
|
||||
Z) _ENABLE_EXTERNAL_ZMQ_REPOS=$BS_TRUE ;;
|
||||
|
||||
|
||||
\?) echo
|
||||
@ -1124,7 +1135,10 @@ __git_clone_and_checkout() {
|
||||
|
||||
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}"
|
||||
cd "${__SALT_GIT_CHECKOUT_PARENT_DIR}"
|
||||
if [ -d "${__SALT_GIT_CHECKOUT_DIR}" ]; then
|
||||
@ -1170,7 +1184,7 @@ __git_clone_and_checkout() {
|
||||
if [ "$(git clone --help | grep 'single-branch')" != "" ]; then
|
||||
# The "--single-branch" option is supported, attempt shallow cloning
|
||||
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
|
||||
cd "${__SALT_GIT_CHECKOUT_DIR}"
|
||||
__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.
|
||||
echowarn "Failed to shallow clone."
|
||||
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}"
|
||||
fi
|
||||
else
|
||||
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}"
|
||||
fi
|
||||
else
|
||||
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}"
|
||||
fi
|
||||
|
||||
@ -1540,7 +1554,7 @@ __check_services_debian() {
|
||||
servicename=$1
|
||||
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
|
||||
echodebug "Service ${servicename} is enabled"
|
||||
return 0
|
||||
@ -1695,6 +1709,10 @@ install_ubuntu_deps() {
|
||||
__apt_get_install_noinput python-apt
|
||||
|
||||
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
|
||||
__PIP_PACKAGES=""
|
||||
else
|
||||
@ -2360,6 +2378,10 @@ install_debian_check_services() {
|
||||
# Fedora Install Functions
|
||||
#
|
||||
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"
|
||||
|
||||
if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then
|
||||
@ -2415,7 +2437,7 @@ install_fedora_stable_post() {
|
||||
install_fedora_git_deps() {
|
||||
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
|
||||
|
||||
@ -2531,9 +2553,28 @@ __install_epel_repository() {
|
||||
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_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
|
||||
yum -y update || return 1
|
||||
fi
|
||||
@ -2674,7 +2715,7 @@ install_centos_git() {
|
||||
}
|
||||
|
||||
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
|
||||
[ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue
|
||||
@ -3344,7 +3385,7 @@ install_arch_linux_git_deps() {
|
||||
pacman -R --noconfirm --needed python2-distribute
|
||||
pacman -Sy --noconfirm --needed git python2-crypto python2-setuptools python2-jinja \
|
||||
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
|
||||
|
||||
@ -3656,9 +3697,9 @@ install_freebsd_git() {
|
||||
# Install from git
|
||||
if [ ! -f salt/syspaths.py ]; then
|
||||
# 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
|
||||
/usr/local/bin/python setup.py install \
|
||||
/usr/local/bin/python2 setup.py install \
|
||||
--salt-root-dir=/usr/local \
|
||||
--salt-config-dir="${_SALT_ETC_DIR}" \
|
||||
--salt-cache-dir=/var/cache/salt \
|
||||
|
@ -294,7 +294,7 @@ DEFAULT_MINION_OPTS = {
|
||||
'failhard': False,
|
||||
'autoload_dynamic_modules': True,
|
||||
'environment': None,
|
||||
'extension_modules': os.path.join(salt.syspaths.CACHE_DIR, 'extmods'),
|
||||
'extension_modules': '',
|
||||
'state_top': 'top.sls',
|
||||
'startup_states': '',
|
||||
'sls_list': [],
|
||||
|
@ -21,6 +21,7 @@ import salt.crypt
|
||||
import salt.loader
|
||||
import salt.payload
|
||||
import salt.transport
|
||||
import salt.fileserver
|
||||
import salt.utils
|
||||
import salt.utils.templates
|
||||
import salt.utils.gzip_util
|
||||
|
@ -1489,7 +1489,8 @@ class ClearFuncs(object):
|
||||
pass
|
||||
elif os.path.isfile(pubfn_rejected):
|
||||
# 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,
|
||||
'id': load['id'],
|
||||
'pub': load['pub']}
|
||||
@ -2254,14 +2255,17 @@ class ClearFuncs(object):
|
||||
}
|
||||
}
|
||||
# Retrieve the jid
|
||||
if not clear_load['jid']:
|
||||
fstr = '{0}.prep_jid'.format(self.opts['master_job_cache'])
|
||||
try:
|
||||
clear_load['jid'] = self.mminion.returners[fstr](nocache=extra.get('nocache', False))
|
||||
except TypeError: # The returner is not present
|
||||
log.error('The requested returner {0} could not be loaded. Publication not sent.'.format(fstr.split('.')[0]))
|
||||
return {}
|
||||
# TODO Error reporting over the master event bus
|
||||
fstr = '{0}.prep_jid'.format(self.opts['master_job_cache'])
|
||||
try:
|
||||
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
|
||||
log.error('The requested returner {0} could not be loaded. Publication not sent.'.format(fstr.split('.')[0]))
|
||||
return {}
|
||||
# TODO Error reporting over the master event bus
|
||||
|
||||
self.event.fire_event({'minions': minions}, clear_load['jid'])
|
||||
|
||||
new_job_load = {
|
||||
|
@ -105,10 +105,10 @@ def resolve_dns(opts):
|
||||
if opts['retry_dns']:
|
||||
while True:
|
||||
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'])
|
||||
if salt.log.is_console_configured():
|
||||
log.warn(msg)
|
||||
log.error(msg)
|
||||
else:
|
||||
print('WARNING: {0}'.format(msg))
|
||||
time.sleep(opts['retry_dns'])
|
||||
@ -711,6 +711,8 @@ class Minion(MinionBase):
|
||||
' {0}'.format(opts['master']))
|
||||
if opts['master_shuffle']:
|
||||
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
|
||||
# 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
|
||||
'''
|
||||
# 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)
|
||||
log.debug('Syndic {0!r} trying to tune in'.format(self.opts['id']))
|
||||
|
||||
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
|
||||
# Share the poller with the event object
|
||||
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
|
||||
'''
|
||||
versions_as_list = salt.utils.is_true(versions_as_list)
|
||||
# 'removed' not yet implemented or not applicable
|
||||
if salt.utils.is_true(kwargs.get('removed')):
|
||||
# 'removed', 'purge_desired' not yet implemented or not applicable
|
||||
if any([salt.utils.is_true(kwargs.get(x))
|
||||
for x in ('removed', 'purge_desired')]):
|
||||
return {}
|
||||
|
||||
if 'pkg.list_pkgs' in __context__:
|
||||
|
@ -197,6 +197,7 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
|
||||
process_dependency_links=False,
|
||||
__env__=None,
|
||||
saltenv='base',
|
||||
env_vars=None,
|
||||
use_vt=False):
|
||||
'''
|
||||
Install packages with pip
|
||||
@ -311,6 +312,11 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
|
||||
Enable the processing of dependency links
|
||||
use_vt
|
||||
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:
|
||||
|
||||
@ -576,6 +582,9 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
|
||||
if process_dependency_links:
|
||||
cmd.append('--process-dependency-links')
|
||||
|
||||
if env_vars:
|
||||
os.environ.update(env_vars)
|
||||
|
||||
try:
|
||||
cmd_kwargs = dict(runas=user, cwd=cwd, saltenv=saltenv, use_vt=use_vt)
|
||||
if bin_env and os.path.isdir(bin_env):
|
||||
|
@ -29,7 +29,7 @@ def __virtual__():
|
||||
|
||||
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 False
|
||||
|
||||
@ -183,3 +183,34 @@ def file_dict(*packages):
|
||||
files.append(line)
|
||||
ret[pkg] = files
|
||||
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 -*-
|
||||
'''
|
||||
Module for notifications via Slack.
|
||||
See https://slack.com for more info.
|
||||
Module for sending messages to Slack
|
||||
|
||||
.. versionadded:: Lithium
|
||||
|
||||
:depends: - pyslack python module
|
||||
:configuration: Configure this module by specifying the name of a configuration
|
||||
profile in the minion config, minion pillar, or master config.
|
||||
:configuration: This module can be used by either passing an api key and version
|
||||
directly or by specifying both in a configuration profile in the salt
|
||||
master/minion config.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
slack.api_token: <api token>
|
||||
slack.username: salt-bot
|
||||
slack:
|
||||
api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||
'''
|
||||
import requests
|
||||
import logging
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
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
|
||||
from urlparse import urljoin as _urljoin
|
||||
from requests.exceptions import ConnectionError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__virtualname__ = 'slack'
|
||||
|
||||
|
||||
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 False
|
||||
return __virtualname__
|
||||
|
||||
|
||||
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 = {}
|
||||
creds['api_token'] = __salt__['config.option']('slack.api_token')
|
||||
creds['username'] = __salt__['config.option']('slack.username')
|
||||
slack.api_token = creds.get('api_token')
|
||||
return creds
|
||||
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(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:
|
||||
|
||||
.. code-block:: yaml
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' slack.post_message 'Test message'
|
||||
salt '*' slack.list_rooms
|
||||
|
||||
salt '*' slack.list_rooms api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15
|
||||
'''
|
||||
ret = {}
|
||||
creds = _setup()
|
||||
if username is None:
|
||||
username = creds['username']
|
||||
try:
|
||||
ret = slack.chat.post_message(channel, message, username=username)
|
||||
except ChannelNotFoundError as exc:
|
||||
raise CommandExecutionError('Channel "{0}" does not exist. {1}'.format(channel, exc))
|
||||
except NotAuthedError as exc:
|
||||
raise CommandExecutionError('Authentication Failed. {0}'.format(exc))
|
||||
return ret
|
||||
return _query(function='rooms', api_key=api_key)
|
||||
|
||||
|
||||
def list_users(api_key=None):
|
||||
'''
|
||||
List all Slack users.
|
||||
:param api_key: The Slack admin api key.
|
||||
:return: The user list.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. 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
|
||||
if ': ' in line:
|
||||
comps = line.split(': ')
|
||||
ret[comps[0]] = comps[1]
|
||||
ret[comps[0]] = comps[1].lstrip()
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -98,8 +98,6 @@ def __get_conn():
|
||||
- http://libvirt.org/uri.html#URI_config
|
||||
'''
|
||||
connection = __salt__['config.get']('libvirt:connection', 'esx')
|
||||
if connection.startswith('esx://'):
|
||||
return connection
|
||||
return connection
|
||||
|
||||
def __esxi_auth():
|
||||
|
@ -1,6 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
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
|
||||
@ -102,10 +112,27 @@ def _repoquery_pkginfo(repoquery_args):
|
||||
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):
|
||||
'''
|
||||
Runs a repoquery command and returns a list of namedtuples
|
||||
'''
|
||||
_check_repoquery()
|
||||
cmd = 'repoquery --plugins --queryformat="{0}" {1}'.format(
|
||||
query_format, repoquery_args
|
||||
)
|
||||
|
@ -5,6 +5,7 @@ Module for running ZFS zpool command
|
||||
|
||||
# Import Python libs
|
||||
import os
|
||||
import stat
|
||||
import logging
|
||||
|
||||
# Import Salt libs
|
||||
@ -150,15 +151,18 @@ def scrub(pool_name=None):
|
||||
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:
|
||||
|
||||
.. 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 = {}
|
||||
dlist = []
|
||||
@ -170,26 +174,37 @@ def create(pool_name, *vdevs):
|
||||
|
||||
# make sure files are present on filesystem
|
||||
for vdev in vdevs:
|
||||
if not os.path.isfile(vdev):
|
||||
# File is not there error and return
|
||||
ret[vdev] = '{0} not present on filesystem'.format(vdev)
|
||||
return ret
|
||||
else:
|
||||
dlist.append(vdev)
|
||||
if vdev not in ['mirror', 'log', 'cache']:
|
||||
if not os.path.exists(vdev):
|
||||
# Path doesn't exist so error and return
|
||||
ret[vdev] = '{0} not present on filesystem'.format(vdev)
|
||||
return ret
|
||||
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)
|
||||
|
||||
devs = ' '.join(dlist)
|
||||
zpool = _check_zpool()
|
||||
cmd = '{0} create {1} {2}'.format(zpool, pool_name, devs)
|
||||
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)
|
||||
|
||||
# Create storage pool
|
||||
__salt__['cmd.run'](cmd)
|
||||
res = __salt__['cmd.run'](cmd)
|
||||
|
||||
# Check and see if the pools is available
|
||||
if exists(pool_name):
|
||||
ret[pool_name] = 'created'
|
||||
return ret
|
||||
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
|
||||
|
||||
|
@ -7,6 +7,8 @@ Package support for openSUSE via the zypper package manager
|
||||
import copy
|
||||
import logging
|
||||
import re
|
||||
import os
|
||||
from xml.dom import minidom as dom
|
||||
from contextlib import contextmanager as _contextmanager
|
||||
|
||||
# Import salt libs
|
||||
@ -18,6 +20,7 @@ from salt.exceptions import (
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
HAS_ZYPP = False
|
||||
LOCKS = "/etc/zypp/locks"
|
||||
|
||||
try:
|
||||
import zypp
|
||||
@ -847,3 +850,238 @@ def purge(name=None, pkgs=None, **kwargs):
|
||||
salt '*' pkg.purge pkgs='["foo", "bar"]'
|
||||
'''
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
'''
|
||||
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)
|
||||
|
||||
|
||||
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,
|
||||
including returning a custom jid
|
||||
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()
|
||||
|
@ -119,22 +119,28 @@ def _get_ttl():
|
||||
|
||||
|
||||
#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
|
||||
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
|
||||
'''
|
||||
if passed_jid is None:
|
||||
jid = salt.utils.gen_jid()
|
||||
else:
|
||||
jid = passed_jid
|
||||
|
||||
cb_ = _get_connection()
|
||||
|
||||
jid = salt.utils.gen_jid()
|
||||
try:
|
||||
cb_.add(str(jid),
|
||||
{'nocache': nocache},
|
||||
ttl=_get_ttl(),
|
||||
)
|
||||
except couchbase.exceptions.KeyExistsError:
|
||||
return prep_jid(nocache=nocache)
|
||||
# TODO: some sort of sleep or something? Spinning is generally bad practice
|
||||
if passed_jid is None:
|
||||
return prep_jid(nocache=nocache)
|
||||
|
||||
return jid
|
||||
|
||||
|
@ -349,8 +349,8 @@ def set_salt_view():
|
||||
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
|
||||
returning 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()
|
||||
|
@ -168,8 +168,8 @@ def get_minions():
|
||||
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
|
||||
def prep_jid(nocache=False):
|
||||
def prep_jid(nocache=False, passed_jid=None):
|
||||
'''
|
||||
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)
|
||||
So do what you have to do to make sure that stays the case
|
||||
'''
|
||||
jid = salt.utils.gen_jid()
|
||||
if passed_jid is None: # this can be a None of an empty string
|
||||
jid = salt.utils.gen_jid()
|
||||
else:
|
||||
jid = passed_jid
|
||||
|
||||
jid_dir_ = _jid_dir(jid)
|
||||
|
||||
@ -113,7 +116,8 @@ def prep_jid(nocache=False):
|
||||
os.makedirs(jid_dir_)
|
||||
except OSError:
|
||||
# TODO: some sort of sleep or something? Spinning is generally bad practice
|
||||
return prep_jid(nocache=nocache)
|
||||
if passed_jid is None:
|
||||
return prep_jid(nocache=nocache)
|
||||
|
||||
with salt.utils.fopen(os.path.join(jid_dir_, 'jid'), 'w+') as fn_:
|
||||
fn_.write(jid)
|
||||
|
@ -93,11 +93,11 @@ def _get_serv(ret):
|
||||
# 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):
|
||||
|
@ -209,8 +209,8 @@ def get_jids():
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
def prep_jid(nocache=False):
|
||||
def prep_jid(nocache=False, passed_jid=None):
|
||||
'''
|
||||
Call both with prep_jid on all returners in multi_returner
|
||||
|
||||
@ -41,7 +41,7 @@ def prep_jid(nocache=False):
|
||||
returners is non-trivial
|
||||
'''
|
||||
|
||||
jid = None
|
||||
jid = passed_jid
|
||||
for returner in __opts__[CONFIG_KEY]:
|
||||
if jid is None:
|
||||
jid = _mminion().returners['{0}.prep_jid'.format(returner)](nocache=nocache)
|
||||
|
@ -85,6 +85,7 @@ import logging
|
||||
|
||||
# Import salt libs
|
||||
import salt.returners
|
||||
import salt.utils
|
||||
|
||||
# Import third party libs
|
||||
try:
|
||||
@ -148,7 +149,7 @@ def _get_serv(ret=None, commit=False):
|
||||
try:
|
||||
yield cursor
|
||||
except MySQLdb.DatabaseError as err:
|
||||
error, = err.args
|
||||
error = err.args
|
||||
sys.stderr.write(str(error))
|
||||
cursor.execute("ROLLBACK")
|
||||
raise err
|
||||
@ -196,13 +197,11 @@ def get_load(jid):
|
||||
'''
|
||||
with _get_serv(ret=None, commit=True) as cur:
|
||||
|
||||
sql = '''SELECT load FROM `jids`
|
||||
WHERE `jid` = '%s';'''
|
||||
|
||||
sql = '''SELECT `load` FROM `jids` WHERE `jid` = %s;'''
|
||||
cur.execute(sql, (jid,))
|
||||
data = cur.fetchone()
|
||||
if data:
|
||||
return json.loads(data)
|
||||
return json.loads(data[0])
|
||||
return {}
|
||||
|
||||
|
||||
@ -280,3 +279,10 @@ def get_minions():
|
||||
for minion in data:
|
||||
ret.append(minion[0])
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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'))
|
||||
|
||||
|
||||
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()
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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)))
|
||||
|
||||
|
||||
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:
|
||||
data = mminion.returners['{0}.get_jid'.format(returner)](jid)
|
||||
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
|
||||
for minion in data:
|
||||
if u'return' in data[minion]:
|
||||
@ -132,7 +132,7 @@ def list_jobs(ext_source=None,
|
||||
try:
|
||||
ret = mminion.returners['{0}.get_jids'.format(returner)]()
|
||||
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
|
||||
|
||||
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)
|
||||
ret[jid] = _format_jid_instance(jid, job)
|
||||
except TypeError:
|
||||
ret[jid]['Result'] = 'Requested returner {0} is not available. Jobs cannot be retreived. '
|
||||
'Check master log for details.'.format(returner)
|
||||
ret[jid]['Result'] = ('Requested returner {0} is not available. Jobs cannot be retrieved. '
|
||||
'Check master log for details.'.format(returner))
|
||||
return ret
|
||||
ret[jid]['Result'] = mminion.returners['{0}.get_jid'.format(returner)](jid)
|
||||
salt.output.display_output(ret, outputter, opts=__opts__)
|
||||
|
@ -20,7 +20,7 @@ def __virtual__():
|
||||
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.
|
||||
|
||||
@ -33,11 +33,6 @@ def present(name, timespec, tag=None, runas=None, user=None, job=None):
|
||||
tag
|
||||
Make a tag for the job.
|
||||
|
||||
runas
|
||||
Users run the job.
|
||||
|
||||
.. deprecated:: 2014.1.4
|
||||
|
||||
user
|
||||
The user to run the at job
|
||||
|
||||
@ -48,7 +43,7 @@ def present(name, timespec, tag=None, runas=None, user=None, job=None):
|
||||
rose:
|
||||
at.present:
|
||||
- job: 'echo "I love saltstack" > love'
|
||||
- timespec: '9:9 11/09/13'
|
||||
- timespec: '9:09 11/09/13'
|
||||
- tag: love
|
||||
- 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,
|
||||
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')
|
||||
|
||||
if __opts__['test']:
|
||||
|
@ -202,49 +202,3 @@ def change(name, context=None, changes=None, lens=None, **kwargs):
|
||||
ret['changes'] = changes
|
||||
|
||||
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.utils
|
||||
from salt.exceptions import CommandExecutionError, CommandNotFoundError
|
||||
|
||||
|
||||
@ -53,7 +52,6 @@ def __virtual__():
|
||||
def installed(name,
|
||||
composer=None,
|
||||
php=None,
|
||||
runas=None,
|
||||
user=None,
|
||||
prefer_source=None,
|
||||
prefer_dist=None,
|
||||
@ -78,11 +76,6 @@ def installed(name,
|
||||
Location of the php executable to use with composer.
|
||||
(i.e. /usr/bin/php)
|
||||
|
||||
runas
|
||||
Which system user to run composer as.
|
||||
|
||||
.. deprecated:: 2014.1.4
|
||||
|
||||
user
|
||||
Which system user to run composer as.
|
||||
|
||||
@ -114,30 +107,6 @@ def installed(name,
|
||||
'''
|
||||
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:
|
||||
call = __salt__['composer.install'](
|
||||
name,
|
||||
|
@ -2288,7 +2288,8 @@ def replace(name,
|
||||
|
||||
.. 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)
|
||||
@ -2484,138 +2485,6 @@ def blockreplace(
|
||||
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'):
|
||||
'''
|
||||
Comment out specified lines in a file.
|
||||
|
@ -15,9 +15,6 @@ you can specify what ruby version and gemset to target.
|
||||
- ruby: jruby@jgemset
|
||||
'''
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
@ -28,7 +25,6 @@ def __virtual__():
|
||||
|
||||
def installed(name, # pylint: disable=C0103
|
||||
ruby=None,
|
||||
runas=None,
|
||||
user=None,
|
||||
version=None,
|
||||
rdoc=False,
|
||||
@ -44,11 +40,6 @@ def installed(name, # pylint: disable=C0103
|
||||
ruby: None
|
||||
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
|
||||
The user under which to run the ``gem`` command
|
||||
|
||||
@ -72,31 +63,6 @@ def installed(name, # pylint: disable=C0103
|
||||
Format: http://hostname[:port]
|
||||
'''
|
||||
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)
|
||||
if name in gems and version is not None and version in gems[name]:
|
||||
ret['result'] = True
|
||||
@ -128,7 +94,7 @@ def installed(name, # pylint: disable=C0103
|
||||
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.
|
||||
|
||||
@ -138,11 +104,6 @@ def removed(name, ruby=None, runas=None, user=None):
|
||||
ruby: None
|
||||
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
|
||||
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': {}}
|
||||
|
||||
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):
|
||||
ret['result'] = True
|
||||
ret['comment'] = 'Gem is not installed.'
|
||||
|
@ -22,7 +22,6 @@ import os.path
|
||||
import shutil
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -38,7 +37,6 @@ def __virtual__():
|
||||
def latest(name,
|
||||
rev=None,
|
||||
target=None,
|
||||
runas=None,
|
||||
user=None,
|
||||
force=None,
|
||||
force_checkout=False,
|
||||
@ -64,11 +62,6 @@ def latest(name,
|
||||
target
|
||||
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
|
||||
Name of the user performing repository management operations
|
||||
|
||||
@ -162,30 +155,6 @@ def latest(name,
|
||||
return _fail(ret, '"target" option is required')
|
||||
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}
|
||||
if 'shell' in __grains__:
|
||||
run_check_cmd_kwargs['shell'] = __grains__['shell']
|
||||
@ -405,7 +374,7 @@ def latest(name,
|
||||
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
|
||||
|
||||
@ -415,11 +384,6 @@ def present(name, bare=True, runas=None, user=None, force=False):
|
||||
bare
|
||||
Create a bare repository (Default: True)
|
||||
|
||||
runas
|
||||
Name of the user performing repository management operations
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user
|
||||
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)
|
||||
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 os.path.isdir(name):
|
||||
if bare and os.path.isfile(os.path.join(name, 'HEAD')):
|
||||
|
@ -42,7 +42,6 @@ def latest(name,
|
||||
rev=None,
|
||||
target=None,
|
||||
clean=False,
|
||||
runas=None,
|
||||
user=None,
|
||||
force=False,
|
||||
opts=False):
|
||||
@ -61,11 +60,6 @@ def latest(name,
|
||||
clean
|
||||
Force a clean update with -C (Default: False)
|
||||
|
||||
runas
|
||||
Name of the user performing repository management operations
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user
|
||||
Name of the user performing repository management operations
|
||||
|
||||
@ -79,30 +73,6 @@ def latest(name,
|
||||
'''
|
||||
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:
|
||||
return _fail(ret, '"target option is required')
|
||||
|
||||
|
@ -338,6 +338,14 @@ def append(name, family='ipv4', **kwargs):
|
||||
name,
|
||||
command.strip(),
|
||||
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
|
||||
if __opts__['test']:
|
||||
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,
|
||||
family,
|
||||
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
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'iptables rule for {0} needs to be set for {1} ({2})'.format(
|
||||
|
@ -129,7 +129,6 @@ def run(name, **kwargs):
|
||||
return ret
|
||||
|
||||
aspec = salt.utils.get_function_argspec(__salt__[name])
|
||||
|
||||
args = []
|
||||
defaults = {}
|
||||
|
||||
|
@ -20,7 +20,6 @@ for the package which provides npm (simply ``npm`` in most cases). Example:
|
||||
'''
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
from salt.exceptions import CommandExecutionError, CommandNotFoundError
|
||||
|
||||
|
||||
@ -34,7 +33,6 @@ def __virtual__():
|
||||
def installed(name,
|
||||
pkgs=None,
|
||||
dir=None,
|
||||
runas=None,
|
||||
user=None,
|
||||
force_reinstall=False,
|
||||
registry=None,
|
||||
@ -67,11 +65,6 @@ def installed(name,
|
||||
The target directory in which to install the package, or None for
|
||||
global installation
|
||||
|
||||
runas
|
||||
The user to run NPM with
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user
|
||||
The user to run NPM with
|
||||
|
||||
@ -94,37 +87,13 @@ def installed(name,
|
||||
'''
|
||||
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:
|
||||
pkg_list = pkgs
|
||||
else:
|
||||
pkg_list = [name]
|
||||
|
||||
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:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Error looking up {0!r}: {1}'.format(name, err)
|
||||
@ -221,7 +190,6 @@ def installed(name,
|
||||
|
||||
def removed(name,
|
||||
dir=None,
|
||||
runas=None,
|
||||
user=None):
|
||||
'''
|
||||
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
|
||||
global installation
|
||||
|
||||
runas
|
||||
The user to run NPM with
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user
|
||||
The user to run NPM with
|
||||
|
||||
@ -242,30 +205,6 @@ def removed(name,
|
||||
'''
|
||||
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:
|
||||
installed_pkgs = __salt__['npm.list'](dir=dir)
|
||||
except (CommandExecutionError, CommandNotFoundError) as err:
|
||||
@ -295,50 +234,18 @@ def removed(name,
|
||||
|
||||
|
||||
def bootstrap(name,
|
||||
runas=None,
|
||||
user=None):
|
||||
'''
|
||||
Bootstraps a node.js application.
|
||||
|
||||
will execute npm install --json on the specified directory
|
||||
|
||||
|
||||
runas
|
||||
The user to run NPM with
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
Will execute 'npm install --json' on the specified directory.
|
||||
|
||||
user
|
||||
The user to run NPM with
|
||||
|
||||
.. versionadded:: 0.17.0
|
||||
|
||||
|
||||
'''
|
||||
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:
|
||||
call = __salt__['npm.install'](dir=name, runas=user, pkg=None)
|
||||
|
@ -130,6 +130,7 @@ def installed(name,
|
||||
allow_external=None,
|
||||
allow_unverified=None,
|
||||
process_dependency_links=False,
|
||||
env_vars=None,
|
||||
use_vt=False):
|
||||
'''
|
||||
Make sure the package is installed
|
||||
@ -267,6 +268,11 @@ def installed(name,
|
||||
a pip executable. The example below assumes a virtual environment
|
||||
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 terminal emulation (see ouptut while installing)
|
||||
|
||||
@ -554,6 +560,7 @@ def installed(name,
|
||||
allow_unverified=allow_unverified,
|
||||
process_dependency_links=process_dependency_links,
|
||||
saltenv=__env__,
|
||||
env_vars=env_vars,
|
||||
use_vt=use_vt
|
||||
)
|
||||
|
||||
|
@ -30,7 +30,6 @@ def present(name,
|
||||
lc_ctype=None,
|
||||
owner=None,
|
||||
template=None,
|
||||
runas=None,
|
||||
user=None,
|
||||
maintenance_db=None,
|
||||
db_password=None,
|
||||
@ -62,11 +61,6 @@ def present(name,
|
||||
template
|
||||
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
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
@ -95,23 +89,6 @@ def present(name,
|
||||
'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 = {
|
||||
'maintenance_db': maintenance_db,
|
||||
@ -188,7 +165,6 @@ def present(name,
|
||||
|
||||
|
||||
def absent(name,
|
||||
runas=None,
|
||||
user=None,
|
||||
maintenance_db=None,
|
||||
db_password=None,
|
||||
@ -213,11 +189,6 @@ def absent(name,
|
||||
db_port
|
||||
Database port if different from config or default
|
||||
|
||||
runas
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
@ -227,29 +198,6 @@ def absent(name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'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 = {
|
||||
'maintenance_db': maintenance_db,
|
||||
|
@ -14,7 +14,6 @@ The postgres_group module is used to create and manage Postgres groups.
|
||||
# Import Python libs
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import logging
|
||||
|
||||
# Salt imports
|
||||
@ -43,7 +42,6 @@ def present(name,
|
||||
password=None,
|
||||
refresh_password=None,
|
||||
groups=None,
|
||||
runas=None,
|
||||
user=None,
|
||||
maintenance_db=None,
|
||||
db_password=None,
|
||||
@ -109,11 +107,6 @@ def present(name,
|
||||
groups
|
||||
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
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
@ -136,12 +129,6 @@ def present(name,
|
||||
'result': True,
|
||||
'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:
|
||||
createroles = True
|
||||
# default to encrypted passwords
|
||||
@ -151,24 +138,6 @@ def present(name,
|
||||
password = postgres._maybe_encrypt_password(name,
|
||||
password,
|
||||
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 = {
|
||||
'maintenance_db': maintenance_db,
|
||||
'runas': user,
|
||||
@ -250,7 +219,6 @@ def present(name,
|
||||
|
||||
|
||||
def absent(name,
|
||||
runas=None,
|
||||
user=None,
|
||||
maintenance_db=None,
|
||||
db_password=None,
|
||||
@ -263,11 +231,6 @@ def absent(name,
|
||||
name
|
||||
The groupname of the group to remove
|
||||
|
||||
runas
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
@ -290,30 +253,6 @@ def absent(name,
|
||||
'result': True,
|
||||
'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 = {
|
||||
'maintenance_db': maintenance_db,
|
||||
'runas': user,
|
||||
|
@ -14,7 +14,6 @@ The postgres_users module is used to create and manage Postgres users.
|
||||
# Import Python libs
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import logging
|
||||
|
||||
# Salt imports
|
||||
@ -43,7 +42,6 @@ def present(name,
|
||||
password=None,
|
||||
refresh_password=None,
|
||||
groups=None,
|
||||
runas=None,
|
||||
user=None,
|
||||
maintenance_db=None,
|
||||
db_password=None,
|
||||
@ -108,11 +106,6 @@ def present(name,
|
||||
groups
|
||||
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
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
@ -135,12 +128,6 @@ def present(name,
|
||||
'result': True,
|
||||
'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:
|
||||
createroles = True
|
||||
# default to encrypted passwords
|
||||
@ -151,24 +138,6 @@ def present(name,
|
||||
password,
|
||||
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 = {
|
||||
'maintenance_db': maintenance_db,
|
||||
'runas': user,
|
||||
@ -254,7 +223,6 @@ def present(name,
|
||||
|
||||
|
||||
def absent(name,
|
||||
runas=None,
|
||||
user=None,
|
||||
maintenance_db=None,
|
||||
db_password=None,
|
||||
@ -267,11 +235,6 @@ def absent(name,
|
||||
name
|
||||
The username of the user to remove
|
||||
|
||||
runas
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
@ -294,30 +257,6 @@ def absent(name,
|
||||
'result': True,
|
||||
'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 = {
|
||||
'maintenance_db': maintenance_db,
|
||||
'runas': user,
|
||||
|
@ -48,9 +48,6 @@ This is how a state configuration could look like:
|
||||
# Import python libs
|
||||
import re
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
|
||||
def _check_pyenv(ret, user=None):
|
||||
'''
|
||||
@ -99,7 +96,7 @@ def _check_and_install_python(ret, python, default=False, user=None):
|
||||
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
|
||||
installed if necessary.
|
||||
@ -110,11 +107,6 @@ def installed(name, default=False, runas=None, user=None):
|
||||
default : False
|
||||
Whether to make this python the default.
|
||||
|
||||
runas: None
|
||||
The user to run pyenv as.
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user: None
|
||||
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': {}}
|
||||
|
||||
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-'):
|
||||
name = re.sub(r'^python-', '', name)
|
||||
|
||||
@ -179,7 +159,7 @@ def _check_and_uninstall_python(ret, python, user=None):
|
||||
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
|
||||
is installed if necessary.
|
||||
@ -187,11 +167,6 @@ def absent(name, runas=None, user=None):
|
||||
name
|
||||
The version of python to uninstall
|
||||
|
||||
runas: None
|
||||
The user to run pyenv as.
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user: None
|
||||
The user to run pyenv as.
|
||||
|
||||
@ -201,30 +176,6 @@ def absent(name, runas=None, user=None):
|
||||
'''
|
||||
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-'):
|
||||
name = re.sub(r'^python-', '', name)
|
||||
|
||||
|
@ -45,9 +45,6 @@ This is how a state configuration could look like:
|
||||
import re
|
||||
import copy
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
|
||||
def _check_rbenv(ret, user=None):
|
||||
'''
|
||||
@ -96,7 +93,7 @@ def _check_and_install_ruby(ret, ruby, default=False, user=None):
|
||||
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
|
||||
installed if necessary.
|
||||
@ -107,11 +104,6 @@ def installed(name, default=False, runas=None, user=None):
|
||||
default : False
|
||||
Whether to make this ruby the default.
|
||||
|
||||
runas: None
|
||||
The user to run rbenv as.
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user: None
|
||||
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': {}}
|
||||
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-'):
|
||||
name = re.sub(r'^ruby-', '', name)
|
||||
|
||||
@ -187,7 +155,7 @@ def _check_and_uninstall_ruby(ret, ruby, user=None):
|
||||
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
|
||||
is installed if necessary.
|
||||
@ -195,11 +163,6 @@ def absent(name, runas=None, user=None):
|
||||
name
|
||||
The version of ruby to uninstall
|
||||
|
||||
runas: None
|
||||
The user to run rbenv as.
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user: None
|
||||
The user to run rbenv as.
|
||||
|
||||
@ -209,30 +172,6 @@ def absent(name, runas=None, user=None):
|
||||
'''
|
||||
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-'):
|
||||
name = re.sub(r'^ruby-', '', name)
|
||||
|
||||
|
@ -105,9 +105,6 @@ configuration could look like:
|
||||
# Import python libs
|
||||
import re
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
|
||||
def _check_rvm(ret, user=None):
|
||||
'''
|
||||
@ -169,7 +166,7 @@ def _check_ruby(ret, ruby, user=None):
|
||||
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
|
||||
installed when necessary.
|
||||
@ -180,11 +177,6 @@ def installed(name, default=False, runas=None, user=None):
|
||||
default : False
|
||||
Whether to make this ruby the default.
|
||||
|
||||
runas: None
|
||||
The user to run rvm as.
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user: None
|
||||
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': {}}
|
||||
|
||||
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']:
|
||||
ret['comment'] = 'Ruby {0} is set to be installed'.format(name)
|
||||
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)
|
||||
|
||||
|
||||
def gemset_present(name, ruby='default', runas=None, user=None):
|
||||
def gemset_present(name, ruby='default', user=None):
|
||||
'''
|
||||
Verify that the gemset is present.
|
||||
|
||||
@ -241,11 +209,6 @@ def gemset_present(name, ruby='default', runas=None, user=None):
|
||||
ruby: default
|
||||
The ruby version this gemset belongs to.
|
||||
|
||||
runas: None
|
||||
The user to run rvm as.
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user: None
|
||||
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': {}}
|
||||
|
||||
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)
|
||||
if ret['result'] is False:
|
||||
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 logging
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -48,7 +46,6 @@ def running(name,
|
||||
restart=False,
|
||||
update=False,
|
||||
user=None,
|
||||
runas=None,
|
||||
conf_file=None,
|
||||
bin_env=None):
|
||||
'''
|
||||
@ -63,11 +60,6 @@ def running(name,
|
||||
update
|
||||
Whether to update the supervisor configuration.
|
||||
|
||||
runas
|
||||
Name of the user to run the supervisorctl command
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user
|
||||
Name of the user to run the supervisorctl command
|
||||
|
||||
@ -83,30 +75,6 @@ def running(name,
|
||||
'''
|
||||
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__:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Supervisord module not activated. Do you need to install supervisord?'
|
||||
@ -270,7 +238,7 @@ def running(name,
|
||||
log.debug(comment)
|
||||
result = __salt__['supervisord.start'](
|
||||
name,
|
||||
user=runas,
|
||||
user=user,
|
||||
conf_file=conf_file,
|
||||
bin_env=bin_env
|
||||
)
|
||||
@ -285,7 +253,6 @@ def running(name,
|
||||
|
||||
def dead(name,
|
||||
user=None,
|
||||
runas=None,
|
||||
conf_file=None,
|
||||
bin_env=None):
|
||||
'''
|
||||
@ -294,11 +261,6 @@ def dead(name,
|
||||
name
|
||||
Service name as defined in the supervisor configuration file
|
||||
|
||||
runas
|
||||
Name of the user to run the supervisorctl command
|
||||
|
||||
.. deprecated:: 0.17.0
|
||||
|
||||
user
|
||||
Name of the user to run the supervisorctl command
|
||||
|
||||
@ -314,30 +276,6 @@ def dead(name,
|
||||
'''
|
||||
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']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = (
|
||||
@ -347,7 +285,7 @@ def dead(name,
|
||||
log.debug(comment)
|
||||
|
||||
all_processes = __salt__['supervisord.status'](
|
||||
user=runas,
|
||||
user=user,
|
||||
conf_file=conf_file,
|
||||
bin_env=bin_env
|
||||
)
|
||||
@ -397,7 +335,6 @@ def mod_watch(name,
|
||||
restart=True,
|
||||
update=False,
|
||||
user=None,
|
||||
runas=None,
|
||||
conf_file=None,
|
||||
bin_env=None):
|
||||
# Always restart on watch
|
||||
@ -406,7 +343,6 @@ def mod_watch(name,
|
||||
restart=restart,
|
||||
update=update,
|
||||
user=user,
|
||||
runas=runas,
|
||||
conf_file=conf_file,
|
||||
bin_env=bin_env
|
||||
)
|
||||
|
@ -35,7 +35,6 @@ def managed(name,
|
||||
never_download=None,
|
||||
prompt=None,
|
||||
user=None,
|
||||
runas=None,
|
||||
no_chown=False,
|
||||
cwd=None,
|
||||
index_url=None,
|
||||
@ -83,29 +82,6 @@ def managed(name,
|
||||
ret['comment'] = 'Virtualenv was not detected on this system'
|
||||
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():
|
||||
venv_py = os.path.join(name, 'Scripts', 'python.exe')
|
||||
else:
|
||||
|
@ -40,7 +40,6 @@ Available Functions
|
||||
import sys
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
from salt._compat import string_types
|
||||
|
||||
# Define the module's virtual name
|
||||
@ -120,7 +119,6 @@ def installed(name,
|
||||
config='buildout.cfg',
|
||||
quiet=False,
|
||||
parts=None,
|
||||
runas=None,
|
||||
user=None,
|
||||
env=(),
|
||||
buildout_ver=None,
|
||||
@ -154,11 +152,6 @@ def installed(name,
|
||||
parts
|
||||
specific buildout parts to run
|
||||
|
||||
runas
|
||||
user used to run buildout as
|
||||
|
||||
.. deprecated:: 2014.1.4
|
||||
|
||||
user
|
||||
user used to run buildout as
|
||||
|
||||
@ -209,30 +202,6 @@ def installed(name,
|
||||
'''
|
||||
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:
|
||||
test_release = int(test_release)
|
||||
except ValueError:
|
||||
|
@ -526,15 +526,13 @@ def dns_check(addr, safe=False, ipv6=False):
|
||||
if not addr:
|
||||
error = True
|
||||
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)
|
||||
except socket.error:
|
||||
error = True
|
||||
|
||||
if error:
|
||||
err = ('This master address: \'{0}\' was previously resolvable '
|
||||
'but now fails to resolve! The previously resolved ip addr '
|
||||
'will continue to be used').format(addr)
|
||||
err = ('DNS lookup of \'{0}\' failed.').format(addr)
|
||||
if safe:
|
||||
if salt.log.is_console_configured():
|
||||
# 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)
|
||||
|
||||
|
||||
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,
|
||||
data,
|
||||
initial_ret=None,
|
||||
|
@ -367,6 +367,9 @@ def bootstrap(vm_, opts):
|
||||
'known_hosts_file': salt.config.get_cloud_config_value(
|
||||
'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
|
||||
# as some providers need also a 'gateway' configuration
|
||||
@ -428,8 +431,10 @@ def bootstrap(vm_, opts):
|
||||
else:
|
||||
deployed = deploy_script(**deploy_kwargs)
|
||||
|
||||
if deployed:
|
||||
ret['deployed'] = deployed
|
||||
if deployed is not False:
|
||||
ret['deployed'] = True
|
||||
if deployed is not True:
|
||||
ret.update(deployed)
|
||||
log.info('Salt installed on {0}'.format(vm_['name']))
|
||||
return ret
|
||||
|
||||
@ -938,6 +943,7 @@ def deploy_script(host,
|
||||
deploy_command='/tmp/.saltcloud/deploy.sh',
|
||||
opts=None,
|
||||
tmp_dir='/tmp/.saltcloud',
|
||||
file_map=None,
|
||||
**kwargs):
|
||||
'''
|
||||
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(
|
||||
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
|
||||
if minion_pem:
|
||||
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')
|
||||
)
|
||||
if file_map_fail or file_map_success:
|
||||
return {
|
||||
'File Upload Success': file_map_success,
|
||||
'File Upload Failure': file_map_fail,
|
||||
}
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -1500,13 +1539,17 @@ def smb_file(dest_path, contents, kwargs):
|
||||
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
|
||||
'''
|
||||
tmpfh, tmppath = tempfile.mkstemp()
|
||||
with salt.utils.fopen(tmppath, 'w') as tmpfile:
|
||||
tmpfile.write(contents)
|
||||
if contents is not None:
|
||||
tmpfh, tmppath = tempfile.mkstemp()
|
||||
with salt.utils.fopen(tmppath, 'w') as tmpfile:
|
||||
tmpfile.write(contents)
|
||||
|
||||
if local_file is not None:
|
||||
tmppath = local_file
|
||||
|
||||
log.debug('Uploading {0} to {1} (sfcp)'.format(dest_path, kwargs['hostname']))
|
||||
|
||||
|
@ -183,15 +183,12 @@ class CkMinions(object):
|
||||
if not greedy and id_ in minions:
|
||||
minions.remove(id_)
|
||||
continue
|
||||
try:
|
||||
with salt.utils.fopen(datap, 'rb') as fp_:
|
||||
search_results = self.serial.load(fp_).get(search_type)
|
||||
except (IOError, OSError):
|
||||
continue
|
||||
search_results = self.serial.load(
|
||||
salt.utils.fopen(datap, 'rb')
|
||||
).get(search_type)
|
||||
if not salt.utils.subdict_match(search_results,
|
||||
expr,
|
||||
delimiter,
|
||||
regex_match=regex_match):
|
||||
regex_match=regex_match) and id_ in minions:
|
||||
minions.remove(id_)
|
||||
return list(minions)
|
||||
|
||||
@ -205,36 +202,11 @@ class CkMinions(object):
|
||||
'''
|
||||
Return the minions found by looking via grains with PCRE
|
||||
'''
|
||||
cache_enabled = self.opts.get('minion_data_cache', False)
|
||||
|
||||
if greedy:
|
||||
minions = set(
|
||||
os.listdir(os.path.join(self.opts['pki_dir'], self.acc))
|
||||
)
|
||||
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)
|
||||
return self._check_cache_minions(expr,
|
||||
delimiter,
|
||||
greedy,
|
||||
'grains',
|
||||
regex_match=True)
|
||||
|
||||
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.decorators',
|
||||
'salt.utils.openstack',
|
||||
'salt.utils.openstack.pyrax',
|
||||
'salt.utils.validate',
|
||||
'salt.utils.serializers',
|
||||
'salt.wheel',
|
||||
|
@ -1,4 +1,4 @@
|
||||
digitalocean-test:
|
||||
provider: digitalocean-config
|
||||
image: Ubuntu 14.04 x64
|
||||
image: 14.04 x64
|
||||
size: 2GB
|
||||
|
@ -518,40 +518,6 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
|
||||
finally:
|
||||
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):
|
||||
'''
|
||||
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]))
|
||||
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 dummy_func(first, second, third, fourth='fifth'):
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user