mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge pull request #27236 from basepi/merge-forward-develop
Merge forward from 2015.8 to develop
This commit is contained in:
commit
c9255f2bbd
@ -28,6 +28,9 @@
|
||||
# The level of messages to send to the console.
|
||||
# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'.
|
||||
#
|
||||
# The following log levels are considered INSECURE and may log sensitive data:
|
||||
# ['garbage', 'trace', 'debug']
|
||||
#
|
||||
# Default: 'info'
|
||||
#
|
||||
#log_level: info
|
||||
|
@ -692,6 +692,10 @@
|
||||
|
||||
# The level of messages to send to the console.
|
||||
# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'.
|
||||
#
|
||||
# The following log levels are considered INSECURE and may log sensitive data:
|
||||
# ['garbage', 'trace', 'debug']
|
||||
#
|
||||
#log_level: warning
|
||||
|
||||
# The level of messages to send to the log file.
|
||||
|
@ -511,6 +511,10 @@
|
||||
|
||||
# The level of messages to send to the console.
|
||||
# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'.
|
||||
#
|
||||
# The following log levels are considered INSECURE and may log sensitive data:
|
||||
# ['garbage', 'trace', 'debug']
|
||||
#
|
||||
# Default: 'warning'
|
||||
#log_level: warning
|
||||
|
||||
|
@ -25,7 +25,8 @@ Salt Table of Contents
|
||||
topics/highavailability/index
|
||||
topics/topology/index
|
||||
topics/proxyminion/index
|
||||
topics/transports/raet/index
|
||||
topics/spm/index
|
||||
topics/transports/index
|
||||
topics/windows/index
|
||||
topics/cloud/index
|
||||
topics/netapi/index
|
||||
|
17
doc/faq.rst
17
doc/faq.rst
@ -1,3 +1,5 @@
|
||||
.. _faq:
|
||||
|
||||
Frequently Asked Questions
|
||||
==========================
|
||||
|
||||
@ -301,3 +303,18 @@ More information about salting the Salt master can be found in the salt-formula
|
||||
for salt itself:
|
||||
|
||||
https://github.com/saltstack-formulas/salt-formula
|
||||
|
||||
.. _faq-grain-security:
|
||||
|
||||
Is Targeting using Grain Data Secure?
|
||||
=====================================
|
||||
|
||||
Because grains can be set by users that have access to the minion configuration
|
||||
files on the local system, grains are considered less secure than other
|
||||
identifiers in Salt. Use caution when targeting sensitive operations or setting
|
||||
pillar values based on grain data.
|
||||
|
||||
When possible, you should target sensitive operations and data using the Minion
|
||||
ID. If the Minion ID of a system changes, the Salt Minion's public key must be
|
||||
re-accepted by an administrator on the Salt Master, making it less vulnerable
|
||||
to impersonation attacks.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.. _spm:
|
||||
.. _spm-cli:
|
||||
|
||||
=======
|
||||
``spm``
|
||||
|
@ -198,7 +198,7 @@ need to be changed to the ownership of the new user.
|
||||
.. conf_minion:: sudo_user
|
||||
|
||||
``sudo_user``
|
||||
--------
|
||||
-------------
|
||||
|
||||
Default: ``''``
|
||||
|
||||
|
@ -33,3 +33,4 @@ Reference
|
||||
beacons/all/index
|
||||
engines/all/index
|
||||
sdb/all/index
|
||||
serializers/all/index
|
||||
|
@ -65,6 +65,7 @@ Full list of builtin execution modules
|
||||
cpan
|
||||
cron
|
||||
cyg
|
||||
cytest
|
||||
daemontools
|
||||
darwin_pkgutil
|
||||
darwin_sysctl
|
||||
|
@ -238,15 +238,6 @@ The ``__virtual__`` function is used to return either a
|
||||
False is returned then the module is not loaded, if a string is returned then
|
||||
the module is loaded with the name of the string.
|
||||
|
||||
.. note::
|
||||
|
||||
Optionally, modules may additionally return a list of reasons that a module could
|
||||
not be loaded. For example, if a dependency for 'my_mod' was not met, a
|
||||
__virtual__ function could do as follows:
|
||||
|
||||
return False, ['My Module must be installed before this module can be
|
||||
used.']
|
||||
|
||||
This means that the package manager modules can be presented as the ``pkg`` module
|
||||
regardless of what the actual module is named.
|
||||
|
||||
@ -265,6 +256,16 @@ function. Some examples:
|
||||
Modules which return a string from ``__virtual__`` that is already used by a module that
|
||||
ships with Salt will _override_ the stock module.
|
||||
|
||||
Returning Error Information from ``__virtual__``
|
||||
------------------------------------------------
|
||||
|
||||
Optionally, modules may additionally return a list of reasons that a module could
|
||||
not be loaded. For example, if a dependency for 'my_mod' was not met, a
|
||||
__virtual__ function could do as follows:
|
||||
|
||||
return False, ['My Module must be installed before this module can be
|
||||
used.']
|
||||
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
@ -34,6 +34,7 @@ Full list of runner modules
|
||||
queue
|
||||
reactor
|
||||
sdb
|
||||
ssh
|
||||
search
|
||||
spacewalk
|
||||
ssh
|
||||
|
@ -13,13 +13,14 @@ at https://cloud.google.com.
|
||||
|
||||
Dependencies
|
||||
============
|
||||
* Libcloud >= 0.14.0-beta3
|
||||
* PyCrypto >= 2.1.
|
||||
* LibCloud >= 0.14.1
|
||||
* A Google Cloud Platform account with Compute Engine enabled
|
||||
* A registered Service Account for authorization
|
||||
* Oh, and obviously you'll need `salt <https://github.com/saltstack/salt>`_
|
||||
|
||||
|
||||
.. _gce_setup:
|
||||
|
||||
Google Compute Engine Setup
|
||||
===========================
|
||||
#. Sign up for Google Cloud Platform
|
||||
@ -49,17 +50,20 @@ Google Compute Engine Setup
|
||||
To set up authorization, navigate to *APIs & auth* section and then the
|
||||
*Credentials* link and click the *CREATE NEW CLIENT ID* button. Select
|
||||
*Service Account* and click the *Create Client ID* button. This will
|
||||
automatically download a ``.json`` file which can be ignored.
|
||||
automatically download a ``.json`` file, which may or may not be used
|
||||
in later steps, depending on your version of ``libcloud``.
|
||||
|
||||
Look for a new *Service Account* section in the page and record the generated email
|
||||
address for the matching key/fingerprint. The email address will be used
|
||||
in the ``service_account_email_address`` of the ``/etc/salt/cloud`` file.
|
||||
Look for a new *Service Account* section in the page and record the generated
|
||||
email address for the matching key/fingerprint. The email address will be used
|
||||
in the ``service_account_email_address`` of the ``/etc/salt/cloud.providers``
|
||||
or the ``/etc/salt/cloud.providers.d/*.conf`` file.
|
||||
|
||||
#. Key Format
|
||||
|
||||
*If you are using ``libcloud >= 0.17.0`` it is recommended that you use the ``JSON
|
||||
format`` file you downloaded above and skip to the "Configuration" section below, using
|
||||
the JSON file **_in place of 'NEW.pem'_** in the documentation.
|
||||
*If you are using ``libcloud >= 0.17.0`` it is recommended that you use the ``JSON
|
||||
format`` file you downloaded above and skip to the `Provider Configuration`_ section
|
||||
below, using the JSON file **_in place of 'NEW.pem'_** in the documentation.
|
||||
|
||||
If you are using an older version of libcloud or are unsure of the version you
|
||||
have, please follow the instructions below to generate and format a new P12 key.*
|
||||
|
||||
@ -78,35 +82,31 @@ Google Compute Engine Setup
|
||||
|
||||
|
||||
|
||||
Configuration
|
||||
=============
|
||||
Provider Configuration
|
||||
======================
|
||||
|
||||
Set up the cloud config at ``/etc/salt/cloud``:
|
||||
Set up the provider cloud config at ``/etc/salt/cloud.providers`` or
|
||||
``/etc/salt/cloud.providers.d/*.conf``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Note: This example is for /etc/salt/cloud
|
||||
gce-config:
|
||||
# Set up the Project name and Service Account authorization
|
||||
project: "your-project-id"
|
||||
service_account_email_address: "123-a5gt@developer.gserviceaccount.com"
|
||||
service_account_private_key: "/path/to/your/NEW.pem"
|
||||
|
||||
providers:
|
||||
gce-config:
|
||||
# Set up the Project name and Service Account authorization
|
||||
#
|
||||
project: "your-project-id"
|
||||
service_account_email_address: "123-a5gt@developer.gserviceaccount.com"
|
||||
service_account_private_key: "/path/to/your/NEW.pem"
|
||||
# Set up the location of the salt master
|
||||
minion:
|
||||
master: saltmaster.example.com
|
||||
|
||||
# Set up the location of the salt master
|
||||
#
|
||||
minion:
|
||||
master: saltmaster.example.com
|
||||
# Set up grains information, which will be common for all nodes
|
||||
# using this provider
|
||||
grains:
|
||||
node_type: broker
|
||||
release: 1.0.1
|
||||
|
||||
# Set up grains information, which will be common for all nodes
|
||||
# using this provider
|
||||
grains:
|
||||
node_type: broker
|
||||
release: 1.0.1
|
||||
|
||||
driver: gce
|
||||
driver: gce
|
||||
|
||||
.. note::
|
||||
|
||||
@ -122,13 +122,14 @@ Set up the cloud config at ``/etc/salt/cloud``:
|
||||
provides the underlying functionality to connect to a cloud host, while cloud profiles continue
|
||||
to use ``provider`` to refer to provider configurations that you define.
|
||||
|
||||
Cloud Profiles
|
||||
==============
|
||||
Set up an initial profile at ``/etc/salt/cloud.profiles``:
|
||||
Profile Configuration
|
||||
=====================
|
||||
Set up an initial profile at ``/etc/salt/cloud.profiles`` or
|
||||
``/etc/salt/cloud.profiles.d/*.conf``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
all_settings:
|
||||
my-gce-profile:
|
||||
image: centos-6
|
||||
size: n1-standard-1
|
||||
location: europe-west1-b
|
||||
@ -145,18 +146,18 @@ The profile can be realized now with a salt command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-cloud -p all_settings gce-instance
|
||||
salt-cloud -p my-gce-profile gce-instance
|
||||
|
||||
This will create an salt minion instance named ``gce-instance`` in GCE. If
|
||||
the command was executed on the salt-master, its Salt key will automatically
|
||||
be signed on the master.
|
||||
|
||||
Once the instance has been created with salt-minion installed, connectivity to
|
||||
Once the instance has been created with a salt-minion installed, connectivity to
|
||||
it can be verified with Salt:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt 'ami.example.com' test.ping
|
||||
salt gce-instance test.ping
|
||||
|
||||
|
||||
GCE Specific Settings
|
||||
@ -167,7 +168,7 @@ typically also include a hard-coded default.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
all_settings:
|
||||
my-gce-profile:
|
||||
|
||||
# Image is used to define what Operating System image should be used
|
||||
# to for the instance. Examples are Debian 7 (wheezy) and CentOS 6.
|
||||
@ -239,11 +240,12 @@ typically also include a hard-coded default.
|
||||
|
||||
GCE instances do not allow remote access to the root user by default.
|
||||
Instead, another user must be used to run the deploy script using sudo.
|
||||
Append something like this to ``/etc/salt/cloud.profiles``:
|
||||
Append something like this to ``/etc/salt/cloud.profiles`` or
|
||||
``/etc/salt/cloud.profiles.d/*.conf``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
all_settings:
|
||||
my-gce-profile:
|
||||
...
|
||||
|
||||
# SSH to GCE instances as gceuser
|
||||
@ -259,7 +261,7 @@ the metadata setting too:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
all_settings:
|
||||
my-gce-profile:
|
||||
...
|
||||
|
||||
metadata: '{"one": "1", "2": "two",
|
||||
@ -432,7 +434,7 @@ Specify the network name to view information about the network.
|
||||
salt-cloud -f show_network gce name=mynet
|
||||
|
||||
Create address
|
||||
---------------
|
||||
--------------
|
||||
Create a new named static IP address in a region.
|
||||
|
||||
.. code-block:: bash
|
||||
@ -440,7 +442,7 @@ Create a new named static IP address in a region.
|
||||
salt-cloud -f create_address gce name=my-fixed-ip region=us-central1
|
||||
|
||||
Delete address
|
||||
---------------
|
||||
--------------
|
||||
Delete an existing named fixed IP address.
|
||||
|
||||
.. code-block:: bash
|
||||
@ -448,7 +450,7 @@ Delete an existing named fixed IP address.
|
||||
salt-cloud -f delete_address gce name=my-fixed-ip region=us-central1
|
||||
|
||||
Show address
|
||||
---------------
|
||||
------------
|
||||
View details on a named address.
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -41,7 +41,7 @@ To install using the SaltStack yum repository:
|
||||
|
||||
Versions 6 / 7:
|
||||
|
||||
.. code-block:: config
|
||||
.. code-block:: cfg
|
||||
|
||||
####################
|
||||
# Enable SaltStack's package repository
|
||||
@ -54,7 +54,7 @@ To install using the SaltStack yum repository:
|
||||
|
||||
Version 5:
|
||||
|
||||
.. code-block:: config
|
||||
.. code-block:: cfg
|
||||
|
||||
####################
|
||||
# Enable SaltStack's package repository
|
||||
|
@ -64,6 +64,87 @@ installer:
|
||||
Salt-Minion-0.17.0-Setup-amd64.exe /S /master=yoursaltmaster /minion-name=yourminionname
|
||||
|
||||
|
||||
Running the Salt Minion on Windows as an Unprivileged User
|
||||
==========================================================
|
||||
|
||||
Notes:
|
||||
- These instructions were tested with Windows Server 2008 R2
|
||||
- They are generalizable to any version of Windows that supports a salt-minion
|
||||
|
||||
A. Create the Unprivileged User that the Salt Minion will Run As
|
||||
----------------------------------------------------------------
|
||||
|
||||
1. Click "Start", "Control Panel", "User Accounts"
|
||||
|
||||
2. Click "Add or remove user accounts"
|
||||
|
||||
3. Click "Create new account"
|
||||
|
||||
4. Enter "salt-user" (or a name of your preference) in the "New account name" field
|
||||
|
||||
5. Select the "Standard user" radio button
|
||||
|
||||
6. Click the "Create Account" button
|
||||
|
||||
7. Click on the newly created user account
|
||||
|
||||
8. Click the "Create a password" link
|
||||
|
||||
9. In the "New password" and "Confirm new password" fields, provide a password (e.g "SuperSecretMinionPassword4Me!")
|
||||
|
||||
10. In the "Type a password hint" field, provide appropriate text (e.g. "My Salt Password")
|
||||
|
||||
11. Click the "Create password" button
|
||||
|
||||
12. Close the "Change an Account" window
|
||||
|
||||
|
||||
B. Add the New User to the Access Control List for the Salt Folder
|
||||
------------------------------------------------------------------
|
||||
|
||||
1. In a File Explorer window, browse to the path where Salt is installed (the default path is C:\Salt)
|
||||
|
||||
2. Right-click on the "Salt" folder and select "Properties"
|
||||
|
||||
3. Click on the "Security" tab
|
||||
|
||||
4. Click the "Edit" button
|
||||
|
||||
5. Click the "Add" button
|
||||
|
||||
6. Type the name of your designated Salt user and click the "OK" button
|
||||
|
||||
7. Check the box to "Allow" the "Modify" permission
|
||||
|
||||
8. Click the "OK" button
|
||||
|
||||
9. Click the "OK" button to close the "Salt Properties" window
|
||||
|
||||
|
||||
C. Update the Windows Service User for the "salt-minion" Service
|
||||
----------------------------------------------------------------
|
||||
|
||||
1. Click "Start", "Administrative Tools", "Services"
|
||||
|
||||
2. In the list of Services, Right-Click on "salt-minion" and select "Properties"
|
||||
|
||||
3. Click the "Log On" tab
|
||||
|
||||
4. Click the "This account" radio button
|
||||
|
||||
5. Provide the account credentials created in section A
|
||||
|
||||
6. Click the "OK" button
|
||||
|
||||
7. Click the "OK" button to the prompt confirming that the user "has been granted the Log On As A Service right"
|
||||
|
||||
8. Click the "OK" button to the prompt confirming that "The new logon name will not take effect until you stop and restart the service"
|
||||
|
||||
9. Right-Click on "salt-minion" and select "Stop"
|
||||
|
||||
10. Right-Click on "salt-minion" and select "Start"
|
||||
|
||||
|
||||
Setting up a Windows build environment
|
||||
======================================
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
.. _proxy-minion:
|
||||
|
||||
===============================
|
||||
Salt Proxy Minion Documentation
|
||||
===============================
|
||||
=================
|
||||
Salt Proxy Minion
|
||||
=================
|
||||
|
||||
Proxy minions are a developing Salt feature that enables controlling devices
|
||||
that, for whatever reason, cannot run a standard salt-minion. Examples include
|
||||
@ -507,3 +507,8 @@ And then in salt.proxy.rest_sample.py we find
|
||||
return False
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
demo
|
||||
|
8
doc/topics/releases/2015.8.1.rst
Normal file
8
doc/topics/releases/2015.8.1.rst
Normal file
@ -0,0 +1,8 @@
|
||||
===========================
|
||||
Salt 2015.8.1 Release Notes
|
||||
===========================
|
||||
|
||||
Version 2015.8.1 is a bugfix release for :doc:`2015.8.0
|
||||
</topics/releases/2015.8.0>`.
|
||||
|
||||
Changes:
|
@ -1,3 +1,5 @@
|
||||
:orphan:
|
||||
|
||||
===================================
|
||||
Salt Release Notes - Codename Boron
|
||||
===================================
|
||||
|
@ -1,3 +1,5 @@
|
||||
:orphan:
|
||||
|
||||
.. _proxy-2015.8.0:
|
||||
|
||||
=========================
|
||||
|
@ -5,7 +5,7 @@ Release notes
|
||||
See the :doc:`version numbers</topics/releases/version_numbers>` page for more
|
||||
information about the version numbering scheme.
|
||||
|
||||
Latest Stable Release
|
||||
Latest Branch Release
|
||||
=====================
|
||||
|
||||
|current_release_doc|
|
||||
|
@ -1,3 +1,5 @@
|
||||
:orphan:
|
||||
|
||||
===========================================
|
||||
Installing/Testing a Salt Release Candidate
|
||||
===========================================
|
||||
|
@ -1,3 +1,5 @@
|
||||
:orphan:
|
||||
|
||||
===============
|
||||
Version Numbers
|
||||
===============
|
||||
|
@ -333,3 +333,9 @@ The files in this type of package are configuration files for Salt, which
|
||||
normally live in the ``/etc/salt/`` directory. Configuration files for packages
|
||||
other than Salt can and should be handled with a Salt State (using a ``formula``
|
||||
type of package).
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
dev
|
||||
|
@ -141,4 +141,6 @@ http://curvecp.org/
|
||||
Programming Intro
|
||||
=================
|
||||
|
||||
:ref:`Raet Programming Introduction <raet-programming>`
|
||||
.. toctree:
|
||||
|
||||
programming_intro
|
||||
|
@ -39,6 +39,7 @@ Advanced Topics
|
||||
:maxdepth: 2
|
||||
|
||||
walkthrough
|
||||
rooted
|
||||
minionfs
|
||||
esky
|
||||
multimaster
|
||||
@ -50,6 +51,7 @@ Advanced Topics
|
||||
writing_tests
|
||||
http
|
||||
lxc
|
||||
stormpath
|
||||
|
||||
Salt Virt
|
||||
==========
|
||||
|
@ -16,6 +16,7 @@ import logging
|
||||
import salt.utils.parsers as parsers
|
||||
import salt.version
|
||||
import salt.syspaths as syspaths
|
||||
from salt.utils.verify import verify_log
|
||||
|
||||
# Import 3rd-party libs
|
||||
import salt.ext.six as six
|
||||
@ -48,6 +49,7 @@ class SaltAPI(six.with_metaclass(parsers.OptionParserMeta, # pylint: disable=W0
|
||||
import salt.client.netapi
|
||||
self.parse_args()
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
self.daemonize_if_required()
|
||||
client = salt.client.netapi.NetapiClient(self.config)
|
||||
self.set_pidfile()
|
||||
|
@ -4,6 +4,7 @@ from __future__ import absolute_import
|
||||
import os
|
||||
|
||||
from salt.utils import parsers
|
||||
from salt.utils.verify import verify_log
|
||||
from salt.config import _expand_glob_path
|
||||
import salt.cli.caller
|
||||
import salt.defaults.exitcodes
|
||||
@ -42,6 +43,7 @@ class SaltCall(parsers.SaltCallOptionParser):
|
||||
|
||||
# Setup file logging!
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
|
||||
caller = salt.cli.caller.Caller.factory(self.config)
|
||||
|
||||
|
@ -15,6 +15,7 @@ import sys
|
||||
# Import salt libs
|
||||
import salt.client
|
||||
from salt.utils import parsers, print_cli
|
||||
from salt.utils.verify import verify_log
|
||||
import salt.output
|
||||
|
||||
|
||||
@ -31,6 +32,7 @@ class SaltCPCli(parsers.SaltCPOptionParser):
|
||||
|
||||
# Setup file logging!
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
|
||||
cp_ = SaltCP(self.config)
|
||||
cp_.run()
|
||||
|
@ -7,6 +7,7 @@ Make me some salt!
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
import warnings
|
||||
from salt.utils.verify import verify_log
|
||||
|
||||
# All salt related deprecation warnings should be shown once each!
|
||||
warnings.filterwarnings(
|
||||
@ -114,6 +115,7 @@ class Master(parsers.MasterOptionParser):
|
||||
self.shutdown(err.errno)
|
||||
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
logger.info('Setting up the Salt Master')
|
||||
|
||||
# TODO: AIO core is separate from transport
|
||||
@ -232,6 +234,7 @@ class Minion(parsers.MinionOptionParser): # pylint: disable=no-init
|
||||
self.shutdown(err.errno)
|
||||
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
logger.info(
|
||||
'Setting up the Salt Minion "{0}"'.format(
|
||||
self.config['id']
|
||||
@ -408,6 +411,7 @@ class ProxyMinion(parsers.ProxyMinionOptionParser): # pylint: disable=no-init
|
||||
self.shutdown(err.errno)
|
||||
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
logger.info(
|
||||
'Setting up a Salt Proxy Minion "{0}"'.format(
|
||||
self.config['id']
|
||||
@ -507,6 +511,7 @@ class Syndic(parsers.SyndicOptionParser):
|
||||
self.shutdown(err.errno)
|
||||
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
logger.info(
|
||||
'Setting up the Salt Syndic Minion "{0}"'.format(
|
||||
self.config['id']
|
||||
|
@ -3,7 +3,7 @@ from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
|
||||
from salt.utils import parsers
|
||||
from salt.utils.verify import check_user
|
||||
from salt.utils.verify import check_user, verify_log
|
||||
|
||||
|
||||
class SaltKey(parsers.SaltKeyOptionParser):
|
||||
@ -22,6 +22,7 @@ class SaltKey(parsers.SaltKeyOptionParser):
|
||||
multi = True
|
||||
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
|
||||
if multi:
|
||||
key = salt.key.MultiKeyCLI(self.config)
|
||||
|
@ -5,7 +5,7 @@ from __future__ import absolute_import
|
||||
from salt.utils import parsers
|
||||
from salt.utils import activate_profile
|
||||
from salt.utils import output_profile
|
||||
from salt.utils.verify import check_user
|
||||
from salt.utils.verify import check_user, verify_log
|
||||
from salt.exceptions import SaltClientError
|
||||
import salt.defaults.exitcodes # pylint: disable=W0611
|
||||
|
||||
@ -24,6 +24,7 @@ class SaltRun(parsers.SaltRunOptionParser):
|
||||
|
||||
# Setup file logging!
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
profiling_enabled = self.options.profiling_enabled
|
||||
|
||||
runner = salt.runner.Runner(self.config)
|
||||
|
@ -10,6 +10,7 @@ import salt.utils.job
|
||||
from salt.ext.six import string_types
|
||||
from salt.utils import parsers, print_cli
|
||||
from salt.utils.args import yamlify_arg
|
||||
from salt.utils.verify import verify_log
|
||||
from salt.exceptions import (
|
||||
SaltClientError,
|
||||
SaltInvocationError,
|
||||
@ -35,6 +36,7 @@ class SaltCMD(parsers.SaltCMDOptionParser):
|
||||
|
||||
# Setup file logging!
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
|
||||
try:
|
||||
# We don't need to bail on config file permission errors
|
||||
|
@ -4,6 +4,7 @@ from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
import salt.client.ssh
|
||||
from salt.utils import parsers
|
||||
from salt.utils.verify import verify_log
|
||||
|
||||
|
||||
class SaltSSH(parsers.SaltSSHOptionParser):
|
||||
@ -14,6 +15,7 @@ class SaltSSH(parsers.SaltSSHOptionParser):
|
||||
def run(self):
|
||||
self.parse_args()
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
|
||||
ssh = salt.client.ssh.SSH(self.config)
|
||||
ssh.run()
|
||||
|
@ -228,7 +228,7 @@ class CloudClient(object):
|
||||
if a.get('provider', '')]
|
||||
if providers:
|
||||
_providers = opts.get('providers', {})
|
||||
for provider in six.iterkeys(_providers):
|
||||
for provider in _providers.keys():
|
||||
if provider not in providers:
|
||||
_providers.pop(provider)
|
||||
return opts
|
||||
|
@ -25,7 +25,7 @@ import salt.defaults.exitcodes
|
||||
import salt.output
|
||||
import salt.utils
|
||||
from salt.utils import parsers
|
||||
from salt.utils.verify import check_user, verify_env, verify_files
|
||||
from salt.utils.verify import check_user, verify_env, verify_files, verify_log
|
||||
|
||||
# Import salt.cloud libs
|
||||
import salt.cloud
|
||||
@ -80,6 +80,7 @@ class SaltCloud(parsers.SaltCloudParser):
|
||||
|
||||
# Setup log file logging
|
||||
self.setup_logfile_logger()
|
||||
verify_log(self.config)
|
||||
|
||||
if self.options.update_bootstrap:
|
||||
ret = salt.utils.cloud.update_bootstrap(self.config)
|
||||
|
@ -176,57 +176,10 @@ def list_nodes(call=None):
|
||||
raise SaltCloudSystemExit(
|
||||
'The list_nodes function must be called with -f or --function.'
|
||||
)
|
||||
|
||||
fetch = True
|
||||
page = 1
|
||||
ret = {}
|
||||
|
||||
while fetch:
|
||||
items = query(method='droplets', command='?page=' + str(page) + '&per_page=200')
|
||||
for node in items['droplets']:
|
||||
networks = node['networks']
|
||||
v4s = networks.get('v4')
|
||||
v6s = networks.get('v6')
|
||||
public_ips = []
|
||||
private_ips = []
|
||||
|
||||
if v4s:
|
||||
for item in v4s:
|
||||
ip_type = item.get('type')
|
||||
ip_address = item.get('ip_address')
|
||||
if ip_type == 'public':
|
||||
public_ips.append(ip_address)
|
||||
if ip_type == 'private':
|
||||
private_ips.append(ip_address)
|
||||
|
||||
if v6s:
|
||||
for item in v6s:
|
||||
ip_type = item.get('type')
|
||||
ip_address = item.get('ip_address')
|
||||
if ip_type == 'public':
|
||||
public_ips.append(ip_address)
|
||||
if ip_type == 'private':
|
||||
private_ips.append(ip_address)
|
||||
|
||||
ret[node['name']] = {
|
||||
'id': node['id'],
|
||||
'image': node['image']['name'],
|
||||
'name': node['name'],
|
||||
'private_ips': private_ips,
|
||||
'public_ips': public_ips,
|
||||
'size': node['size_slug'],
|
||||
'state': str(node['status']),
|
||||
}
|
||||
page += 1
|
||||
try:
|
||||
fetch = 'next' in items['links']['pages']
|
||||
except KeyError:
|
||||
fetch = False
|
||||
|
||||
return ret
|
||||
return _list_nodes()
|
||||
|
||||
|
||||
def list_nodes_full(call=None, forOutput=True):
|
||||
def list_nodes_full(call=None, for_output=True):
|
||||
'''
|
||||
Return a list of the VMs that are on the provider
|
||||
'''
|
||||
@ -234,26 +187,7 @@ def list_nodes_full(call=None, forOutput=True):
|
||||
raise SaltCloudSystemExit(
|
||||
'The list_nodes_full function must be called with -f or --function.'
|
||||
)
|
||||
|
||||
fetch = True
|
||||
page = 1
|
||||
ret = {}
|
||||
|
||||
while fetch:
|
||||
items = query(method='droplets', command='?page=' + str(page) + '&per_page=200')
|
||||
for node in items['droplets']:
|
||||
ret[node['name']] = {}
|
||||
for item in six.iterkeys(node):
|
||||
value = node[item]
|
||||
if value is not None and forOutput:
|
||||
value = str(value)
|
||||
ret[node['name']][item] = value
|
||||
page += 1
|
||||
try:
|
||||
fetch = 'next' in items['links']['pages']
|
||||
except KeyError:
|
||||
fetch = False
|
||||
return ret
|
||||
return _list_nodes(full=True, for_output=for_output)
|
||||
|
||||
|
||||
def list_nodes_select(call=None):
|
||||
@ -601,7 +535,7 @@ def _get_node(name):
|
||||
attempts = 10
|
||||
while attempts >= 0:
|
||||
try:
|
||||
return list_nodes_full(forOutput=False)[name]
|
||||
return list_nodes_full(for_output=False)[name]
|
||||
except KeyError:
|
||||
attempts -= 1
|
||||
log.debug(
|
||||
@ -855,3 +789,85 @@ def show_pricing(kwargs=None, call=None):
|
||||
ret['_raw'] = raw
|
||||
|
||||
return {profile['profile']: ret}
|
||||
|
||||
|
||||
def _list_nodes(full=False, for_output=False):
|
||||
'''
|
||||
Helper function to format and parse node data.
|
||||
'''
|
||||
fetch = True
|
||||
page = 1
|
||||
ret = {}
|
||||
|
||||
while fetch:
|
||||
items = query(method='droplets',
|
||||
command='?page=' + str(page) + '&per_page=200')
|
||||
for node in items['droplets']:
|
||||
name = node['name']
|
||||
ret[name] = {}
|
||||
if full:
|
||||
ret[name] = _get_full_output(node, for_output=for_output)
|
||||
else:
|
||||
public_ips, private_ips = _get_ips(node['networks'])
|
||||
ret[name] = {
|
||||
'id': node['id'],
|
||||
'image': node['image']['name'],
|
||||
'name': name,
|
||||
'private_ips': private_ips,
|
||||
'public_ips': public_ips,
|
||||
'size': node['size_slug'],
|
||||
'state': str(node['status']),
|
||||
}
|
||||
|
||||
page += 1
|
||||
try:
|
||||
fetch = 'next' in items['links']['pages']
|
||||
except KeyError:
|
||||
fetch = False
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def _get_full_output(node, for_output=False):
|
||||
'''
|
||||
Helper function for _list_nodes to loop through all node information.
|
||||
Returns a dictionary containing the full information of a node.
|
||||
'''
|
||||
ret = {}
|
||||
for item in six.iterkeys(node):
|
||||
value = node[item]
|
||||
if value is not None and for_output:
|
||||
value = str(value)
|
||||
ret[item] = value
|
||||
return ret
|
||||
|
||||
|
||||
def _get_ips(networks):
|
||||
'''
|
||||
Helper function for list_nodes. Returns public and private ip lists based on a
|
||||
given network dictionary.
|
||||
'''
|
||||
v4s = networks.get('v4')
|
||||
v6s = networks.get('v6')
|
||||
public_ips = []
|
||||
private_ips = []
|
||||
|
||||
if v4s:
|
||||
for item in v4s:
|
||||
ip_type = item.get('type')
|
||||
ip_address = item.get('ip_address')
|
||||
if ip_type == 'public':
|
||||
public_ips.append(ip_address)
|
||||
if ip_type == 'private':
|
||||
private_ips.append(ip_address)
|
||||
|
||||
if v6s:
|
||||
for item in v6s:
|
||||
ip_type = item.get('type')
|
||||
ip_address = item.get('ip_address')
|
||||
if ip_type == 'public':
|
||||
public_ips.append(ip_address)
|
||||
if ip_type == 'private':
|
||||
private_ips.append(ip_address)
|
||||
|
||||
return public_ips, private_ips
|
||||
|
@ -3025,6 +3025,11 @@ def list_nodes_full(location=None, call=None):
|
||||
get_location(vm_) for vm_ in six.itervalues(__opts__['profiles'])
|
||||
if _vm_provider_driver(vm_)
|
||||
)
|
||||
# If there aren't any profiles defined for EC2, check
|
||||
# the provider config file, or use the default location.
|
||||
if not locations:
|
||||
locations = [get_location()]
|
||||
|
||||
for loc in locations:
|
||||
ret.update(_list_nodes_full(loc))
|
||||
return ret
|
||||
|
@ -17,30 +17,12 @@ limitations under the License.
|
||||
Google Compute Engine Module
|
||||
============================
|
||||
|
||||
The Google Compute Engine module. This module interfaces with Google Compute
|
||||
Engine. To authenticate to GCE, you will need to create a Service Account.
|
||||
The Google Compute Engine module. This module interfaces with Google Compute
|
||||
Engine (GCE). To authenticate to GCE, you will need to create a Service Account.
|
||||
To set up Service Account Authentication, follow the :ref:`gce_setup` instructions.
|
||||
|
||||
Setting up Service Account Authentication:
|
||||
- Go to the Cloud Console at: https://cloud.google.com/console.
|
||||
- Create or navigate to your desired Project.
|
||||
- Make sure Google Compute Engine service is enabled under the Services
|
||||
section.
|
||||
- Go to "APIs and auth" section, and then the "Credentials" link.
|
||||
- Click the "CREATE NEW CLIENT ID" button.
|
||||
- Select "Service Account" and click "Create Client ID" button.
|
||||
- This will automatically download a .json file; ignore it.
|
||||
- Look for a new "Service Account" section in the page, click on the "Generate New P12 key" button
|
||||
- Copy the Email Address for inclusion in your /etc/salt/cloud file
|
||||
in the 'service_account_email_address' setting.
|
||||
- Download the Private Key
|
||||
- The key that you download is a PKCS12 key. It needs to be converted to
|
||||
the PEM format.
|
||||
- Convert the key using OpenSSL (the default password is 'notasecret'):
|
||||
C{openssl pkcs12 -in PRIVKEY.p12 -passin pass:notasecret \
|
||||
-nodes -nocerts | openssl rsa -out ~/PRIVKEY.pem}
|
||||
- Add the full path name of the converted private key to your
|
||||
/etc/salt/cloud file as 'service_account_private_key' setting.
|
||||
- Consider using a more secure location for your private key.
|
||||
Example Provider Configuration
|
||||
------------------------------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
@ -60,7 +42,6 @@ Setting up Service Account Authentication:
|
||||
|
||||
:maintainer: Eric Johnson <erjohnso@google.com>
|
||||
:depends: libcloud >= 0.14.1
|
||||
:depends: pycrypto >= 2.1
|
||||
'''
|
||||
# pylint: disable=invalid-name,function-redefined
|
||||
|
||||
@ -119,7 +100,7 @@ list_nodes = namespaced_function(list_nodes, globals())
|
||||
list_nodes_full = namespaced_function(list_nodes_full, globals())
|
||||
list_nodes_select = namespaced_function(list_nodes_select, globals())
|
||||
|
||||
GCE_VM_NAME_REGEX = re.compile(r'(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)')
|
||||
GCE_VM_NAME_REGEX = re.compile(r'^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$')
|
||||
|
||||
|
||||
# Only load in this module if the GCE configurations are in place
|
||||
@ -2041,9 +2022,8 @@ def create(vm_=None, call=None):
|
||||
|
||||
if not GCE_VM_NAME_REGEX.match(vm_['name']):
|
||||
raise SaltCloudSystemExit(
|
||||
'The allowed VM names must match the following regular expression: {0}'.format(
|
||||
GCE_VM_NAME_REGEX.pattern
|
||||
)
|
||||
'VM names must start with a letter, only contain letters, numbers, or dashes '
|
||||
'and cannot end in a dash.'
|
||||
)
|
||||
|
||||
try:
|
||||
|
@ -558,7 +558,7 @@ def create_config(kwargs=None, call=None):
|
||||
|
||||
|
||||
def create_disk_from_distro(vm_, linode_id, swap_size=None):
|
||||
'''
|
||||
r'''
|
||||
Creates the disk for the Linode from the distribution.
|
||||
|
||||
vm_
|
||||
@ -601,7 +601,7 @@ def create_disk_from_distro(vm_, linode_id, swap_size=None):
|
||||
|
||||
|
||||
def create_swap_disk(vm_, linode_id, swap_size=None):
|
||||
'''
|
||||
r'''
|
||||
Creates the disk for the specified Linode.
|
||||
|
||||
vm_
|
||||
@ -630,7 +630,7 @@ def create_swap_disk(vm_, linode_id, swap_size=None):
|
||||
|
||||
|
||||
def create_private_ip(vm_, linode_id):
|
||||
'''
|
||||
r'''
|
||||
Creates a private IP for the specified Linode.
|
||||
|
||||
vm_
|
||||
@ -747,7 +747,7 @@ def get_datacenter_id(location):
|
||||
|
||||
|
||||
def get_disk_size(vm_, swap):
|
||||
'''
|
||||
r'''
|
||||
Returns the size of of the root disk in MB.
|
||||
|
||||
vm_
|
||||
@ -761,7 +761,7 @@ def get_disk_size(vm_, swap):
|
||||
|
||||
|
||||
def get_distribution_id(vm_):
|
||||
'''
|
||||
r'''
|
||||
Returns the distribution ID for a VM
|
||||
|
||||
vm_
|
||||
@ -890,7 +890,7 @@ def get_linode_id_from_name(name):
|
||||
|
||||
|
||||
def get_password(vm_):
|
||||
'''
|
||||
r'''
|
||||
Return the password to use for a VM.
|
||||
|
||||
vm_
|
||||
@ -946,7 +946,7 @@ def get_private_ip(vm_):
|
||||
|
||||
|
||||
def get_pub_key(vm_):
|
||||
'''
|
||||
r'''
|
||||
Return the SSH pubkey.
|
||||
|
||||
vm_
|
||||
@ -958,7 +958,7 @@ def get_pub_key(vm_):
|
||||
|
||||
|
||||
def get_swap_size(vm_):
|
||||
'''
|
||||
r'''
|
||||
Returns the amoutn of swap space to be used in MB.
|
||||
|
||||
vm_
|
||||
@ -970,7 +970,7 @@ def get_swap_size(vm_):
|
||||
|
||||
|
||||
def get_vm_size(vm_):
|
||||
'''
|
||||
r'''
|
||||
Returns the VM's size.
|
||||
|
||||
vm_
|
||||
|
@ -492,7 +492,7 @@ def list_nodes_full(mask='mask[id]', call=None):
|
||||
)
|
||||
|
||||
ret = {}
|
||||
conn = get_conn(service='Account')
|
||||
conn = get_conn(service='SoftLayer_Account')
|
||||
response = conn.getVirtualGuests()
|
||||
for node_id in response:
|
||||
ret[node_id['hostname']] = node_id
|
||||
@ -605,5 +605,5 @@ def list_vlans(call=None):
|
||||
'The list_vlans function must be called with -f or --function.'
|
||||
)
|
||||
|
||||
conn = get_conn(service='Account')
|
||||
conn = get_conn(service='SoftLayer_Account')
|
||||
return conn.getNetworkVlans()
|
||||
|
@ -426,7 +426,7 @@ def list_nodes_full(mask='mask[id, hostname, primaryIpAddress, \
|
||||
)
|
||||
|
||||
ret = {}
|
||||
conn = get_conn(service='Account')
|
||||
conn = get_conn(service='SoftLayer_Account')
|
||||
response = conn.getHardware(mask=mask)
|
||||
|
||||
for node in response:
|
||||
@ -546,7 +546,7 @@ def list_vlans(call=None):
|
||||
'The list_vlans function must be called with -f or --function.'
|
||||
)
|
||||
|
||||
conn = get_conn(service='Account')
|
||||
conn = get_conn(service='SoftLayer_Account')
|
||||
return conn.getNetworkVlans()
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ import salt.utils.rsax931
|
||||
import salt.utils.verify
|
||||
import salt.version
|
||||
from salt.exceptions import (
|
||||
AuthenticationError, SaltClientError, SaltReqTimeoutError
|
||||
AuthenticationError, SaltClientError, SaltReqTimeoutError, SaltSystemExit
|
||||
)
|
||||
|
||||
import tornado.gen
|
||||
@ -551,7 +551,7 @@ class AsyncAuth(object):
|
||||
'Salt Minion.\nThe master public key can be found '
|
||||
'at:\n{1}'.format(salt.version.__version__, m_pub_fn)
|
||||
)
|
||||
sys.exit(42)
|
||||
raise SaltSystemExit('Invalid master key')
|
||||
if self.opts.get('syndic_master', False): # Is syndic
|
||||
syndic_finger = self.opts.get('syndic_finger', self.opts.get('master_finger', False))
|
||||
if syndic_finger:
|
||||
|
@ -902,14 +902,22 @@ def add_pool_member(hostname, username, password, name, member):
|
||||
'''
|
||||
A function to connect to a bigip device and add a new member to an existing pool.
|
||||
|
||||
Parameters:
|
||||
hostname: The host/address of the bigip device
|
||||
username: The iControl REST username
|
||||
password: The iControl REST password
|
||||
name: The name of the pool to modify
|
||||
member: The name of the member to add
|
||||
i.e. 10.1.1.2:80
|
||||
hostname
|
||||
The host/address of the bigip device
|
||||
username
|
||||
The iControl REST username
|
||||
password
|
||||
The iControl REST password
|
||||
name
|
||||
The name of the pool to modify
|
||||
member
|
||||
The name of the member to add
|
||||
i.e. 10.1.1.2:80
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' bigip.add_pool_members bigip admin admin my-pool 10.2.2.1:80
|
||||
'''
|
||||
|
||||
|
@ -1024,6 +1024,7 @@ def create_internet_gateway(internet_gateway_name=None, vpc_id=None,
|
||||
returns False if the internet gateways was not created.
|
||||
|
||||
.. versionadded:: 2015.8.0
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -1489,8 +1489,8 @@ def build(path=None,
|
||||
|
||||
except Exception:
|
||||
_invalid(status,
|
||||
out=traceback.format_exc(),
|
||||
comment='Unexpected error while building an image')
|
||||
out=traceback.format_exc(),
|
||||
comment='Unexpected error while building an image')
|
||||
return status
|
||||
|
||||
return status
|
||||
@ -1865,16 +1865,13 @@ def _run_wrapper(status, container, func, cmd, *args, **kwargs):
|
||||
comment = 'Executed {0}'.format(full_cmd)
|
||||
try:
|
||||
ret = __salt__[func](full_cmd, *args, **kwargs)
|
||||
if ((isinstance(ret, dict) and
|
||||
('retcode' in ret) and
|
||||
(ret['retcode'] != 0))
|
||||
or (func == 'cmd.retcode' and ret != 0)):
|
||||
return _invalid(status, id_=container, out=ret,
|
||||
comment=comment)
|
||||
_valid(status, id_=container, out=ret, comment=comment,)
|
||||
if ((isinstance(ret, dict) and ('retcode' in ret) and (ret['retcode'] != 0))
|
||||
or (func == 'cmd.retcode' and ret != 0)):
|
||||
_invalid(status, id_=container, out=ret, comment=comment)
|
||||
else:
|
||||
_valid(status, id_=container, out=ret, comment=comment)
|
||||
except Exception:
|
||||
_invalid(status, id_=container,
|
||||
comment=comment, out=traceback.format_exc())
|
||||
_invalid(status, id_=container, comment=comment, out=traceback.format_exc())
|
||||
return status
|
||||
|
||||
|
||||
@ -1899,9 +1896,7 @@ def load(imagepath):
|
||||
try:
|
||||
dockercmd = ['docker', 'load', '-i', imagepath]
|
||||
ret = __salt__['cmd.run'](dockercmd, python_shell=False)
|
||||
if ((isinstance(ret, dict) and
|
||||
('retcode' in ret) and
|
||||
(ret['retcode'] != 0))):
|
||||
if isinstance(ret, dict) and ('retcode' in ret) and (ret['retcode'] != 0):
|
||||
return _invalid(status, id_=None,
|
||||
out=ret,
|
||||
comment='Command to load image {0} failed.'.format(imagepath))
|
||||
@ -1909,12 +1904,12 @@ def load(imagepath):
|
||||
_valid(status, id_=None, out=ret, comment='Image load success')
|
||||
except Exception:
|
||||
_invalid(status, id_=None,
|
||||
comment="Image not loaded.",
|
||||
out=traceback.format_exc())
|
||||
comment="Image not loaded.",
|
||||
out=traceback.format_exc())
|
||||
else:
|
||||
_invalid(status, id_=None,
|
||||
comment='Image file {0} could not be found.'.format(imagepath),
|
||||
out=traceback.format_exc())
|
||||
comment='Image file {0} could not be found.'.format(imagepath),
|
||||
out=traceback.format_exc())
|
||||
|
||||
return status
|
||||
|
||||
@ -1945,16 +1940,14 @@ def save(image, filename):
|
||||
ok = True
|
||||
except Exception:
|
||||
_invalid(status, id_=image,
|
||||
comment="docker image {0} could not be found.".format(image),
|
||||
out=traceback.format_exc())
|
||||
comment="docker image {0} could not be found.".format(image),
|
||||
out=traceback.format_exc())
|
||||
|
||||
if ok:
|
||||
try:
|
||||
dockercmd = ['docker', 'save', '-o', filename, image]
|
||||
ret = __salt__['cmd.run'](dockercmd)
|
||||
if ((isinstance(ret, dict) and
|
||||
('retcode' in ret) and
|
||||
(ret['retcode'] != 0))):
|
||||
if isinstance(ret, dict) and ('retcode' in ret) and (ret['retcode'] != 0):
|
||||
return _invalid(status,
|
||||
id_=image,
|
||||
out=ret,
|
||||
@ -2099,9 +2092,7 @@ def retcode(container, cmd):
|
||||
command to execute
|
||||
|
||||
.. note::
|
||||
The return is a bit different as we use the docker struct.
|
||||
Output of the command is in 'out' and result is ``False`` if
|
||||
command failed to execute.
|
||||
The return is True or False depending on the commands success.
|
||||
|
||||
.. warning::
|
||||
Be advised that this function allows for raw shell access to the named
|
||||
@ -2116,7 +2107,7 @@ def retcode(container, cmd):
|
||||
'''
|
||||
status = base_status.copy()
|
||||
return _run_wrapper(
|
||||
status, container, 'cmd.retcode', cmd)
|
||||
status, container, 'cmd.retcode', cmd)['status']
|
||||
|
||||
|
||||
def get_container_root(container):
|
||||
|
@ -114,6 +114,7 @@ The following options can be set in the :ref:`minion config
|
||||
- nsenter
|
||||
- lxc-attach
|
||||
- docker-exec
|
||||
|
||||
See :ref:`Executing Commands Within a Running Container <docker-execution-driver>`.
|
||||
|
||||
Functions
|
||||
|
@ -1042,24 +1042,24 @@ def comment_line(path,
|
||||
Comment or Uncomment a line in a text file.
|
||||
|
||||
:param path: string
|
||||
The full path to the text file.
|
||||
The full path to the text file.
|
||||
|
||||
:param regex: string
|
||||
A regex expression that begins with ``^`` that will find the line you wish
|
||||
to comment. Can be as simple as ``^color =``
|
||||
A regex expression that begins with ``^`` that will find the line you wish
|
||||
to comment. Can be as simple as ``^color =``
|
||||
|
||||
:param char: string
|
||||
The character used to comment a line in the type of file you're referencing.
|
||||
Default is ``#``
|
||||
The character used to comment a line in the type of file you're referencing.
|
||||
Default is ``#``
|
||||
|
||||
:param cmnt: boolean
|
||||
True to comment the line. False to uncomment the line. Default is True.
|
||||
True to comment the line. False to uncomment the line. Default is True.
|
||||
|
||||
:param backup: string
|
||||
The file extension to give the backup file. Default is ``.bak``
|
||||
The file extension to give the backup file. Default is ``.bak``
|
||||
|
||||
:return: boolean
|
||||
Returns True if successful, False if not
|
||||
Returns True if successful, False if not
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -1080,7 +1080,7 @@ def comment_line(path,
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' file.comment_line 'C:\salt\conf\minion' '^log_level: (warning|info|debug)' '#' False '.bk'
|
||||
salt '*' file.comment_line 'C:\salt\conf\minion' '^log_level: (warning|info|debug)' '#' False '.bk'
|
||||
'''
|
||||
# Get the regex for comment or uncomment
|
||||
if cmnt:
|
||||
|
@ -885,7 +885,7 @@ def config_get_regexp(key,
|
||||
ignore_retcode=False,
|
||||
**kwargs):
|
||||
r'''
|
||||
.. versionaded:: 2015.8.0
|
||||
.. versionadded:: 2015.8.0
|
||||
|
||||
Get the value of a key or keys in the git configuration file using regexes
|
||||
for more flexible matching. The return data is a dictionary mapping keys to
|
||||
|
@ -221,6 +221,7 @@ def image_create(name, location=None, profile=None, visibility=None,
|
||||
CLI Example, old format:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' glance.image_create name=f16-jeos is_public=true \\
|
||||
disk_format=qcow2 container_format=ovf \\
|
||||
copy_from=http://berrange.fedorapeople.org/\
|
||||
@ -228,6 +229,8 @@ def image_create(name, location=None, profile=None, visibility=None,
|
||||
|
||||
CLI Example, new format resembling Glance API v2:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' glance.image_create name=f16-jeos visibility=public \\
|
||||
disk_format=qcow2 container_format=ovf \\
|
||||
copy_from=http://berrange.fedorapeople.org/\
|
||||
@ -452,9 +455,9 @@ def image_update(id=None, name=None, profile=None, **kwargs): # pylint: disable
|
||||
'''
|
||||
Update properties of given image.
|
||||
Known to work for:
|
||||
- min_ram (in MB)
|
||||
- protected (bool)
|
||||
- visibility ('public' or 'private')
|
||||
- min_ram (in MB)
|
||||
- protected (bool)
|
||||
- visibility ('public' or 'private')
|
||||
'''
|
||||
if id:
|
||||
image = image_show(id=id)
|
||||
|
@ -623,7 +623,7 @@ def import_key(user=None,
|
||||
text=None,
|
||||
filename=None,
|
||||
gnupghome=None):
|
||||
'''
|
||||
r'''
|
||||
Import a key from text or file
|
||||
|
||||
user
|
||||
@ -645,6 +645,7 @@ def import_key(user=None,
|
||||
|
||||
salt '*' gpg.import_key text='-----BEGIN PGP PUBLIC KEY BLOCK-----\n ... -----END PGP PUBLIC KEY BLOCK-----'
|
||||
salt '*' gpg.import_key filename='/path/to/public-key-file'
|
||||
|
||||
'''
|
||||
ret = {
|
||||
'res': True,
|
||||
|
@ -81,7 +81,7 @@ def trigger_event(event=None, **kwargs):
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
TBA
|
||||
'''
|
||||
|
||||
res = {'result': False, 'message': 'Something went wrong'}
|
||||
|
@ -193,7 +193,8 @@ def set_channel_access(channel=14, access_update_mode='non_volatile',
|
||||
Set channel access
|
||||
|
||||
:param channel: number [1:7]
|
||||
:param access_update_mode: one of
|
||||
|
||||
:param access_update_mode:
|
||||
- 'dont_change' = don't set or change Channel Access
|
||||
- 'non_volatile' = set non-volatile Channel Access
|
||||
- 'volatile' = set volatile (active) setting of Channel Access
|
||||
@ -683,21 +684,24 @@ def set_bootdev(bootdev='default', persist=False, uefiboot=False, **kwargs):
|
||||
Set boot device to use on next reboot
|
||||
|
||||
:param bootdev:
|
||||
*network -- Request network boot
|
||||
*hd -- Boot from hard drive
|
||||
*safe -- Boot from hard drive, requesting 'safe mode'
|
||||
*optical -- boot from CD/DVD/BD drive
|
||||
*setup -- Boot into setup utility
|
||||
*default -- remove any IPMI directed boot device
|
||||
request
|
||||
- network: Request network boot
|
||||
- hd: Boot from hard drive
|
||||
- safe: Boot from hard drive, requesting 'safe mode'
|
||||
- optical: boot from CD/DVD/BD drive
|
||||
- setup: Boot into setup utility
|
||||
- default: remove any IPMI directed boot device
|
||||
request
|
||||
|
||||
:param persist: If true, ask that system firmware use this device
|
||||
beyond next boot. Be aware many systems do not honor
|
||||
this
|
||||
|
||||
:param uefiboot: If true, request UEFI boot explicitly. Strictly
|
||||
speaking, the spec sugests that if not set, the system
|
||||
should BIOS boot and offers no "don't care" option.
|
||||
In practice, this flag not being set does not preclude
|
||||
UEFI boot on any system I've encountered.
|
||||
|
||||
:param kwargs:
|
||||
- api_host=127.0.0.1
|
||||
- api_user=admin
|
||||
@ -811,6 +815,7 @@ def get_users(channel=14, **kwargs):
|
||||
get list of users and access information
|
||||
|
||||
:param channel: number [1:7]
|
||||
|
||||
:param kwargs:
|
||||
- api_host=127.0.0.1
|
||||
- api_user=admin
|
||||
@ -819,15 +824,15 @@ def get_users(channel=14, **kwargs):
|
||||
- api_kg=None
|
||||
|
||||
:return:
|
||||
name: (str)
|
||||
uid: (int)
|
||||
channel: (int)
|
||||
access:
|
||||
- name: (str)
|
||||
- uid: (int)
|
||||
- channel: (int)
|
||||
- access:
|
||||
- callback (bool)
|
||||
- link_auth (bool)
|
||||
- ipmi_msg (bool)
|
||||
- privilege_level: (str)[callback, user, operatorm administrator,
|
||||
proprietary, no_access]
|
||||
proprietary, no_access]
|
||||
|
||||
CLI Examples:
|
||||
|
||||
|
@ -279,10 +279,10 @@ def list_sets(family='ipv4'):
|
||||
|
||||
def check_set(set=None, family='ipv4'):
|
||||
'''
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
Check that given ipset set exists.
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
@ -395,7 +395,7 @@ def check(set=None, entry=None, family='ipv4'):
|
||||
An entry in the ipset. This parameter can be a single IP address, a
|
||||
range of IP addresses, or a subnet block. Example:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: cfg
|
||||
|
||||
192.168.0.1
|
||||
192.168.0.2-192.168.0.19
|
||||
|
@ -314,7 +314,10 @@ def create_simple_binding(jboss_config, binding_name, value, profile=None):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' jboss7.create_simple_binding '{"cli_path": "integration.modules.sysmod.SysModuleTest.test_valid_docs", "controller": "10.11.12.13:9999", "cli_user": "jbossadm", "cli_password": "jbossadm"}' my_binding_name my_binding_value
|
||||
salt '*' jboss7.create_simple_binding \\
|
||||
'{"cli_path": "integration.modules.sysmod.SysModuleTest.test_valid_docs", \\
|
||||
"controller": "10.11.12.13:9999", "cli_user": "jbossadm", "cli_password": "jbossadm"}' \\
|
||||
my_binding_name my_binding_value
|
||||
'''
|
||||
log.debug("======================== MODULE FUNCTION: jboss7.create_simple_binding, binding_name=%s, value=%s, profile=%s", binding_name, value, profile)
|
||||
if profile is None:
|
||||
|
@ -2,21 +2,22 @@
|
||||
'''
|
||||
Manage Kerberos KDC
|
||||
|
||||
:configuration: In order to manage your KDC you will need to generate a keytab
|
||||
that can authenticate without requireing a password.
|
||||
:configuration:
|
||||
In order to manage your KDC you will need to generate a keytab
|
||||
that can authenticate without requiring a password.
|
||||
|
||||
.. code-block:: bash
|
||||
.. code-block:: bash
|
||||
|
||||
# ktadd -k /root/secure.keytab kadmin/admin kadmin/changepw
|
||||
# ktadd -k /root/secure.keytab kadmin/admin kadmin/changepw
|
||||
|
||||
On the KDC minion you will need to add the following to the minion
|
||||
configuration file so Salt knows what keytab to use and what principal to
|
||||
authenticate as.
|
||||
|
||||
.. code-block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
auth_keytab: /root/auth.keytab
|
||||
auth_principal: kadmin/admin
|
||||
auth_keytab: /root/auth.keytab
|
||||
auth_principal: kadmin/admin
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
|
@ -424,7 +424,7 @@ def last(attrs=None, where=None):
|
||||
|
||||
|
||||
def listening_ports(attrs=None, where=None):
|
||||
'''
|
||||
r'''
|
||||
Return listening_ports_ information from osquery
|
||||
|
||||
CLI Example:
|
||||
@ -437,7 +437,7 @@ def listening_ports(attrs=None, where=None):
|
||||
|
||||
|
||||
def logged_in_users(attrs=None, where=None):
|
||||
'''
|
||||
r'''
|
||||
Return logged_in_users_ information from osquery
|
||||
|
||||
CLI Example:
|
||||
@ -450,7 +450,7 @@ def logged_in_users(attrs=None, where=None):
|
||||
|
||||
|
||||
def mounts(attrs=None, where=None):
|
||||
'''
|
||||
r'''
|
||||
Return mounts_ information from osquery
|
||||
|
||||
CLI Example:
|
||||
|
@ -150,7 +150,7 @@ def obfuscate(*args):
|
||||
Here are some examples:
|
||||
|
||||
* ``'secret password'`` becomes ``'<str>'``
|
||||
* ``['secret', 1]`` becomes ``['<str>', '<int>']
|
||||
* ``['secret', 1]`` becomes ``['<str>', '<int>']``
|
||||
* ``{'login': 'somelogin', 'pwd': 'secret'}`` becomes
|
||||
``{'login': '<str>', 'pwd': '<str>'}``
|
||||
|
||||
|
@ -58,10 +58,10 @@ def post_message(user=None,
|
||||
:param user: The user or group to send to, must be key of user or group not email address.
|
||||
:param message: The message to send to the PushOver user or group.
|
||||
:param title: Specify who the message is from.
|
||||
:param priority The priority of the message, defaults to 0.
|
||||
:param expire The message should expire after N number of seconds.
|
||||
:param retry The number of times the message should be retried.
|
||||
:param sound The sound to associate with the message.
|
||||
:param priority: The priority of the message, defaults to 0.
|
||||
:param expire: The message should expire after N number of seconds.
|
||||
:param retry: The number of times the message should be retried.
|
||||
:param sound: The sound to associate with the message.
|
||||
:param api_version: The PushOver API version, if not specified in the configuration.
|
||||
:param token: The PushOver token, if not specified in the configuration.
|
||||
:return: Boolean if message was sent successfully.
|
||||
|
@ -667,6 +667,7 @@ def generateBlobs(api_key=None,
|
||||
**kwargs):
|
||||
'''
|
||||
List all Slack users.
|
||||
|
||||
:param api_key: The Random.org api key.
|
||||
:param api_version: The Random.org api version.
|
||||
:param format: Specifies the format in which the
|
||||
|
@ -108,20 +108,19 @@ def __virtual__():
|
||||
|
||||
def read_key(hkey, path, key=None):
|
||||
'''
|
||||
*** Incorrect Usage ***
|
||||
The name of this function is misleading and will be changed to reflect
|
||||
proper usage in the Boron release of Salt. The path option will be removed
|
||||
and the key will be the actual key. See the following issue:
|
||||
.. important::
|
||||
The name of this function is misleading and will be changed to reflect
|
||||
proper usage in the Boron release of Salt. The path option will be removed
|
||||
and the key will be the actual key. See the following issue:
|
||||
|
||||
https://github.com/saltstack/salt/issues/25618
|
||||
https://github.com/saltstack/salt/issues/25618
|
||||
|
||||
In order to not break existing state files this function will call the
|
||||
read_value function if a key is passed. Key will be passed as the value
|
||||
name. If key is not passed, this function will return the default value for
|
||||
the key.
|
||||
In order to not break existing state files this function will call the
|
||||
read_value function if a key is passed. Key will be passed as the value
|
||||
name. If key is not passed, this function will return the default value for
|
||||
the key.
|
||||
|
||||
In the Boron release this function will be removed in favor of read_value.
|
||||
***
|
||||
In the Boron release this function will be removed in favor of read_value.
|
||||
|
||||
Read registry key value
|
||||
|
||||
@ -199,19 +198,25 @@ def read_value(hive, key, vname=None):
|
||||
ret['vname'] = '(Default)'
|
||||
|
||||
registry = Registry()
|
||||
hive = registry.hkeys[hive]
|
||||
hkey = registry.hkeys[hive]
|
||||
|
||||
try:
|
||||
handle = _winreg.OpenKey(hive, key)
|
||||
vdata, vtype = _winreg.QueryValueEx(handle, vname)
|
||||
if vdata:
|
||||
ret['vdata'] = vdata
|
||||
ret['vtype'] = registry.vtype_reverse[vtype]
|
||||
else:
|
||||
ret['comment'] = 'Empty Value'
|
||||
handle = _winreg.OpenKey(hkey, key)
|
||||
try:
|
||||
vdata, vtype = _winreg.QueryValueEx(handle, vname)
|
||||
if vdata or vdata in [0, '']:
|
||||
ret['vtype'] = registry.vtype_reverse[vtype]
|
||||
ret['vdata'] = vdata
|
||||
else:
|
||||
ret['comment'] = 'Empty Value'
|
||||
except WindowsError as exc: # pylint: disable=E0602
|
||||
ret['vdata'] = ('(value not set)')
|
||||
ret['vtype'] = 'REG_SZ'
|
||||
ret['success'] = True
|
||||
except WindowsError as exc: # pylint: disable=E0602
|
||||
log.debug(exc)
|
||||
ret['comment'] = '{0}'.format(exc)
|
||||
log.debug('Cannot find key: {0}\\{1}'.format(hive, key))
|
||||
ret['comment'] = 'Cannot find key: {0}\\{1}'.format(hive, key)
|
||||
ret['success'] = False
|
||||
|
||||
return ret
|
||||
@ -219,20 +224,19 @@ def read_value(hive, key, vname=None):
|
||||
|
||||
def set_key(hkey, path, value, key=None, vtype='REG_DWORD', reflection=True):
|
||||
'''
|
||||
*** Incorrect Usage ***
|
||||
The name of this function is misleading and will be changed to reflect
|
||||
proper usage in the Boron release of Salt. The path option will be removed
|
||||
and the key will be the actual key. See the following issue:
|
||||
.. important ::
|
||||
The name of this function is misleading and will be changed to reflect
|
||||
proper usage in the Boron release of Salt. The path option will be removed
|
||||
and the key will be the actual key. See the following issue:
|
||||
|
||||
https://github.com/saltstack/salt/issues/25618
|
||||
https://github.com/saltstack/salt/issues/25618
|
||||
|
||||
In order to not break existing state files this function will call the
|
||||
set_value function if a key is passed. Key will be passed as the value
|
||||
name. If key is not passed, this function will return the default value for
|
||||
the key.
|
||||
In order to not break existing state files this function will call the
|
||||
set_value function if a key is passed. Key will be passed as the value
|
||||
name. If key is not passed, this function will return the default value for
|
||||
the key.
|
||||
|
||||
In the Boron release this function will be removed in favor of set_value.
|
||||
***
|
||||
In the Boron release this function will be removed in favor of set_value.
|
||||
|
||||
Set a registry key
|
||||
|
||||
@ -312,27 +316,26 @@ def set_value(hive, key, vname=None, vdata=None, vtype='REG_SZ', reflection=True
|
||||
_winreg.CloseKey(handle)
|
||||
return True
|
||||
except (WindowsError, ValueError) as exc: # pylint: disable=E0602
|
||||
log.error(exc)
|
||||
log.error(exc, exc_info=True)
|
||||
return False
|
||||
|
||||
|
||||
def create_key(hkey, path, key=None, value=None, reflection=True):
|
||||
'''
|
||||
*** Incorrect Usage ***
|
||||
The name of this function is misleading and will be changed to reflect
|
||||
proper usage in the Boron release of Salt. The path option will be removed
|
||||
and the key will be the actual key. See the following issue:
|
||||
.. important ::
|
||||
The name of this function is misleading and will be changed to reflect
|
||||
proper usage in the Boron release of Salt. The path option will be removed
|
||||
and the key will be the actual key. See the following issue:
|
||||
|
||||
https://github.com/saltstack/salt/issues/25618
|
||||
https://github.com/saltstack/salt/issues/25618
|
||||
|
||||
In order to not break existing state files this function will call the
|
||||
set_value function if key is passed. Key will be passed as the value name.
|
||||
If key is not passed, this function will return the default value for the
|
||||
key.
|
||||
In order to not break existing state files this function will call the
|
||||
set_value function if key is passed. Key will be passed as the value name.
|
||||
If key is not passed, this function will return the default value for the
|
||||
key.
|
||||
|
||||
In the Boron release path will be removed and key will be the path. You will
|
||||
not pass value.
|
||||
***
|
||||
In the Boron release path will be removed and key will be the path. You will
|
||||
not pass value.
|
||||
|
||||
Create a registry key
|
||||
|
||||
@ -357,21 +360,20 @@ def create_key(hkey, path, key=None, value=None, reflection=True):
|
||||
|
||||
def delete_key(hkey, path, key=None, reflection=True, force=False):
|
||||
'''
|
||||
*** Incorrect Usage ***
|
||||
The name of this function is misleading and will be changed to reflect
|
||||
proper usage in the Boron release of Salt. The path option will be removed
|
||||
and the key will be the actual key. See the following issue:
|
||||
.. important::
|
||||
The name of this function is misleading and will be changed to reflect
|
||||
proper usage in the Boron release of Salt. The path option will be removed
|
||||
and the key will be the actual key. See the following issue:
|
||||
|
||||
https://github.com/saltstack/salt/issues/25618
|
||||
https://github.com/saltstack/salt/issues/25618
|
||||
|
||||
In order to not break existing state files this function will call the
|
||||
delete_value function if a key is passed. Key will be passed as the value
|
||||
name. If key is not passed, this function will return the default value for
|
||||
the key.
|
||||
In order to not break existing state files this function will call the
|
||||
delete_value function if a key is passed. Key will be passed as the value
|
||||
name. If key is not passed, this function will return the default value for
|
||||
the key.
|
||||
|
||||
In the Boron release path will be removed and key will be the path.
|
||||
reflection will also be removed.
|
||||
***
|
||||
In the Boron release path will be removed and key will be the path.
|
||||
reflection will also be removed.
|
||||
|
||||
Delete a registry key
|
||||
|
||||
@ -434,7 +436,7 @@ def delete_key(hkey, path, key=None, reflection=True, force=False):
|
||||
_winreg.DeleteKey(hive, key)
|
||||
return True
|
||||
except WindowsError as exc: # pylint: disable=E0602
|
||||
log.error(exc)
|
||||
log.error(exc, exc_info=True)
|
||||
return False
|
||||
|
||||
|
||||
@ -504,7 +506,7 @@ def delete_key_recursive(hive, key):
|
||||
_winreg.DeleteKey(hkey, keypath)
|
||||
ret['Deleted'].append(r'{0}\{1}'.format(hive, keypath))
|
||||
except WindowsError as exc: # pylint: disable=E0602
|
||||
log.error(exc)
|
||||
log.error(exc, exc_info=True)
|
||||
ret['Failed'].append(r'{0}\{1} {2}'.format(hive, key, exc))
|
||||
|
||||
# Delete the key now that all the subkeys are deleted
|
||||
@ -512,7 +514,7 @@ def delete_key_recursive(hive, key):
|
||||
_winreg.DeleteKey(hkey, key)
|
||||
ret['Deleted'].append(r'{0}\{1}'.format(hive, key))
|
||||
except WindowsError as exc: # pylint: disable=E0602
|
||||
log.error(exc)
|
||||
log.error(exc, exc_info=True)
|
||||
ret['Failed'].append(r'{0}\{1} {2}'.format(hive, key, exc))
|
||||
|
||||
return ret
|
||||
@ -561,5 +563,5 @@ def delete_value(hive, key, vname=None, reflection=True):
|
||||
return True
|
||||
except WindowsError as exc: # pylint: disable=E0602
|
||||
_winreg.CloseKey(handle)
|
||||
log.error(exc)
|
||||
log.error(exc, exc_info=True)
|
||||
return False
|
||||
|
@ -452,7 +452,8 @@ def sync_log_handlers(saltenv=None, refresh=True):
|
||||
def sync_all(saltenv=None, refresh=True):
|
||||
'''
|
||||
Sync down all of the dynamic modules from the file server for a specific
|
||||
environment
|
||||
environment. This function synchronizes custom modules, states, beacons,
|
||||
grains, returners, outputters, renderers, and utils.
|
||||
|
||||
refresh : True
|
||||
Also refresh the execution modules and pillar data available to the minion.
|
||||
|
@ -57,19 +57,23 @@ def splay(fun, *args, **kwargs):
|
||||
Splay a salt function call execution time across minions over
|
||||
a number of seconds (default: 600)
|
||||
|
||||
|
||||
NOTE: You *probably* want to use --async here and look up the job results later.
|
||||
If you're dead set on getting the output from the CLI command, then make
|
||||
sure to set the timeout (with the -t flag) to something greater than the
|
||||
splaytime (max splaytime + time to execute job).
|
||||
Otherwise, it's very likely that the cli will time out before the job returns.
|
||||
.. note::
|
||||
You *probably* want to use --async here and look up the job results later.
|
||||
If you're dead set on getting the output from the CLI command, then make
|
||||
sure to set the timeout (with the -t flag) to something greater than the
|
||||
splaytime (max splaytime + time to execute job).
|
||||
Otherwise, it's very likely that the cli will time out before the job returns.
|
||||
|
||||
|
||||
CLI Example:
|
||||
# With default splaytime
|
||||
salt --async '*' splay.splay pkg.install cowsay version=3.03-8.el6
|
||||
CLI Examples:
|
||||
|
||||
# With specified splaytime (5 minutes) and timeout with 10 second buffer
|
||||
.. code-block:: bash
|
||||
|
||||
salt --async '*' splay.splay pkg.install cowsay version=3.03-8.el6
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# With specified splaytime (5 minutes) and timeout with 10 second buffer
|
||||
salt -t 310 '*' splay.splay 300 pkg.version cowsay
|
||||
'''
|
||||
if fun == 'sudo.salt_call':
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
r'''
|
||||
A salt module for SSL/TLS.
|
||||
Can create a Certificate Authority (CA)
|
||||
or use Self-Signed certificates.
|
||||
@ -891,9 +891,9 @@ def create_csr(ca_name,
|
||||
for the given req. source with a DNS: prefix. To be thorough, you
|
||||
may want to include both DNS: and IP: entries if you are using
|
||||
subjectAltNames for destinations for your TLS connections.
|
||||
e.g.:
|
||||
requests to https://1.2.3.4 will fail from python's
|
||||
requests library w/out the second entry in the above list
|
||||
e.g.:
|
||||
requests to https://1.2.3.4 will fail from python's
|
||||
requests library w/out the second entry in the above list
|
||||
|
||||
.. versionadded:: 2015.8.0
|
||||
|
||||
@ -901,17 +901,19 @@ def create_csr(ca_name,
|
||||
Specify the general certificate type. Can be either `server` or
|
||||
`client`. Indicates the set of common extensions added to the CSR.
|
||||
|
||||
server: {
|
||||
'basicConstraints': 'CA:FALSE',
|
||||
'extendedKeyUsage': 'serverAuth',
|
||||
'keyUsage': 'digitalSignature, keyEncipherment'
|
||||
}
|
||||
.. code-block:: cfg
|
||||
|
||||
client: {
|
||||
'basicConstraints': 'CA:FALSE',
|
||||
'extendedKeyUsage': 'clientAuth',
|
||||
'keyUsage': 'nonRepudiation, digitalSignature, keyEncipherment'
|
||||
}
|
||||
server: {
|
||||
'basicConstraints': 'CA:FALSE',
|
||||
'extendedKeyUsage': 'serverAuth',
|
||||
'keyUsage': 'digitalSignature, keyEncipherment'
|
||||
}
|
||||
|
||||
client: {
|
||||
'basicConstraints': 'CA:FALSE',
|
||||
'extendedKeyUsage': 'clientAuth',
|
||||
'keyUsage': 'nonRepudiation, digitalSignature, keyEncipherment'
|
||||
}
|
||||
|
||||
type_ext
|
||||
boolean. Whether or not to extend the filename with CN_[cert_type]
|
||||
|
@ -1,8 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Interface to Red Hat tuned-adm module
|
||||
|
||||
:maintainer: Syed Ali <alicsyed@gmail.com>
|
||||
:maturity: new
|
||||
:depends: cmd.run
|
||||
:depends: tuned-adm
|
||||
:platform: Linux
|
||||
'''
|
||||
|
||||
|
@ -349,7 +349,7 @@ def get(path, objectType):
|
||||
|
||||
|
||||
def add_ace(path, objectType, user, permission, acetype, propagation):
|
||||
'''
|
||||
r'''
|
||||
add an ace to an object
|
||||
|
||||
path: path to the object (i.e. c:\\temp\\file, HKEY_LOCAL_MACHINE\\SOFTWARE\\KEY, etc)
|
||||
@ -424,7 +424,7 @@ def add_ace(path, objectType, user, permission, acetype, propagation):
|
||||
|
||||
|
||||
def rm_ace(path, objectType, user, permission, acetype, propagation):
|
||||
'''
|
||||
r'''
|
||||
remove an ace to an object
|
||||
|
||||
path: path to the object (i.e. c:\\temp\\file, HKEY_LOCAL_MACHINE\\SOFTWARE\\KEY, etc)
|
||||
|
@ -73,7 +73,7 @@ def get_path():
|
||||
|
||||
salt '*' win_path.get_path
|
||||
'''
|
||||
ret = __salt__['reg.read_key']('HKEY_LOCAL_MACHINE',
|
||||
ret = __salt__['reg.read_value']('HKEY_LOCAL_MACHINE',
|
||||
'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment',
|
||||
'PATH')
|
||||
if isinstance(ret, dict):
|
||||
@ -155,8 +155,8 @@ def add(path, index=0):
|
||||
regedit = __salt__['reg.set_value'](
|
||||
'HKEY_LOCAL_MACHINE',
|
||||
'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment',
|
||||
';'.join(sysPath),
|
||||
'PATH',
|
||||
';'.join(sysPath),
|
||||
'REG_EXPAND_SZ'
|
||||
)
|
||||
|
||||
@ -197,8 +197,8 @@ def remove(path):
|
||||
regedit = __salt__['reg.set_value'](
|
||||
'HKEY_LOCAL_MACHINE',
|
||||
'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment',
|
||||
';'.join(sysPath),
|
||||
'PATH',
|
||||
';'.join(sysPath),
|
||||
'REG_EXPAND_SZ'
|
||||
)
|
||||
if regedit:
|
||||
|
@ -501,11 +501,15 @@ def install(name=None, refresh=False, pkgs=None, saltenv='base', **kwargs):
|
||||
|
||||
If the package is installed by ``pkg.install``:
|
||||
|
||||
.. code-block:: cfg
|
||||
|
||||
{'<package>': {'old': '<old-version>',
|
||||
'new': '<new-version>'}}
|
||||
|
||||
If the package is already installed:
|
||||
|
||||
.. code-block:: cfg
|
||||
|
||||
{'<package>': {'current': '<current-version>'}}
|
||||
|
||||
The following example will refresh the winrepo and install a single package,
|
||||
|
@ -246,7 +246,6 @@ def restart(name):
|
||||
|
||||
def create_win_salt_restart_task():
|
||||
'''
|
||||
|
||||
Create a task in Windows task scheduler to enable restarting the salt-minion
|
||||
|
||||
CLI Example:
|
||||
@ -395,7 +394,7 @@ def create(name,
|
||||
obj=None,
|
||||
password=None,
|
||||
**kwargs):
|
||||
'''
|
||||
r'''
|
||||
Create the named service.
|
||||
|
||||
.. versionadded:: 2015.8.0
|
||||
|
@ -11,7 +11,8 @@ Module for managing Windows Users
|
||||
- win32security
|
||||
- win32ts
|
||||
|
||||
NOTE: This currently only works with local user accounts, not domain accounts
|
||||
.. note::
|
||||
This currently only works with local user accounts, not domain accounts
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
@ -69,36 +70,36 @@ def add(name,
|
||||
Add a user to the minion.
|
||||
|
||||
:param str name:
|
||||
User name
|
||||
User name
|
||||
|
||||
:param str password:
|
||||
User's password in plain text.
|
||||
User's password in plain text.
|
||||
|
||||
:param str fullname:
|
||||
The user's full name.
|
||||
The user's full name.
|
||||
|
||||
:param str description:
|
||||
A brief description of the user account.
|
||||
A brief description of the user account.
|
||||
|
||||
:param list groups:
|
||||
A list of groups to add the user to.
|
||||
A list of groups to add the user to.
|
||||
|
||||
:param str home:
|
||||
The path to the user's home directory.
|
||||
The path to the user's home directory.
|
||||
|
||||
:param str homedrive:
|
||||
The drive letter to assign to the home directory. Must be the Drive Letter
|
||||
followed by a colon. ie: U:
|
||||
The drive letter to assign to the home directory. Must be the Drive Letter
|
||||
followed by a colon. ie: U:
|
||||
|
||||
:param str profile:
|
||||
An explicit path to a profile. Can be a UNC or a folder on the system. If
|
||||
left blank, windows uses it's default profile directory.
|
||||
An explicit path to a profile. Can be a UNC or a folder on the system. If
|
||||
left blank, windows uses it's default profile directory.
|
||||
|
||||
:param str logonscript:
|
||||
Path to a login script to run when the user logs on.
|
||||
Path to a login script to run when the user logs on.
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
True if successful. False is unsuccessful.
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
@ -154,32 +155,32 @@ def update(name,
|
||||
.. versionadded:: 2015.8.0
|
||||
|
||||
:param str name:
|
||||
The user name to update.
|
||||
The user name to update.
|
||||
|
||||
:param str password:
|
||||
New user password in plain text.
|
||||
New user password in plain text.
|
||||
|
||||
:param str fullname:
|
||||
The user's full name.
|
||||
The user's full name.
|
||||
|
||||
:param str description:
|
||||
A brief description of the user account.
|
||||
A brief description of the user account.
|
||||
|
||||
:param str home:
|
||||
The path to the user's home directory.
|
||||
The path to the user's home directory.
|
||||
|
||||
:param str homedrive:
|
||||
The drive letter to assign to the home directory. Must be the Drive Letter
|
||||
followed by a colon. ie: U:
|
||||
The drive letter to assign to the home directory. Must be the Drive Letter
|
||||
followed by a colon. ie: U:
|
||||
|
||||
:param str logonscript:
|
||||
The path to the logon script.
|
||||
The path to the logon script.
|
||||
|
||||
:param str profile:
|
||||
The path to the user's profile directory.
|
||||
The path to the user's profile directory.
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
True if successful. False is unsuccessful.
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
@ -240,18 +241,18 @@ def delete(name,
|
||||
Remove a user from the minion
|
||||
|
||||
:param str name:
|
||||
The name of the user to delete
|
||||
The name of the user to delete
|
||||
|
||||
:param bool purge:
|
||||
Boolean value indicating that the user profile should also be removed when
|
||||
the user account is deleted. If set to True the profile will be removed.
|
||||
Boolean value indicating that the user profile should also be removed when
|
||||
the user account is deleted. If set to True the profile will be removed.
|
||||
|
||||
:param bool force:
|
||||
Boolean value indicating that the user account should be deleted even if the
|
||||
user is logged in. True will log the user out and delete user.
|
||||
Boolean value indicating that the user account should be deleted even if the
|
||||
user is logged in. True will log the user out and delete user.
|
||||
|
||||
:return:
|
||||
True if successful
|
||||
True if successful
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
@ -342,10 +343,10 @@ def getUserSid(username):
|
||||
Get the Security ID for the user
|
||||
|
||||
:param str username:
|
||||
user name for which to look up the SID
|
||||
user name for which to look up the SID
|
||||
|
||||
:return:
|
||||
Returns the user SID
|
||||
Returns the user SID
|
||||
:rtype: str
|
||||
|
||||
CLI Example:
|
||||
@ -367,13 +368,13 @@ def setpassword(name, password):
|
||||
Set the user's password
|
||||
|
||||
:param str name:
|
||||
user name for which to set the password
|
||||
user name for which to set the password
|
||||
|
||||
:param str password:
|
||||
the new password
|
||||
the new password
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
True if successful. False is unsuccessful.
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
@ -390,13 +391,13 @@ def addgroup(name, group):
|
||||
Add user to a group
|
||||
|
||||
:param str name:
|
||||
user name to add to the group
|
||||
user name to add to the group
|
||||
|
||||
:param str group:
|
||||
name of the group to which to add the user
|
||||
name of the group to which to add the user
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
True if successful. False is unsuccessful.
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
@ -425,13 +426,13 @@ def removegroup(name, group):
|
||||
Remove user from a group
|
||||
|
||||
:param str name:
|
||||
user name to remove from the group
|
||||
user name to remove from the group
|
||||
|
||||
:param str group:
|
||||
name of the group from which to remove the user
|
||||
name of the group from which to remove the user
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
True if successful. False is unsuccessful.
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
@ -463,16 +464,16 @@ def chhome(name, home, persist=False):
|
||||
to the new home directory if the old home directory exist.
|
||||
|
||||
:param str name:
|
||||
name of the user whose home directory you wish to change
|
||||
name of the user whose home directory you wish to change
|
||||
|
||||
:param str home:
|
||||
new location of the home directory
|
||||
new location of the home directory
|
||||
|
||||
:param bool persist:
|
||||
True to move the contents of the existing home directory to the new location
|
||||
True to move the contents of the existing home directory to the new location
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
True if successful. False is unsuccessful.
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
@ -509,10 +510,10 @@ def chprofile(name, profile):
|
||||
Change the profile directory of the user
|
||||
|
||||
:param str name:
|
||||
name of the user whose profile you wish to change
|
||||
name of the user whose profile you wish to change
|
||||
|
||||
:param str profile:
|
||||
new location of the profile
|
||||
new location of the profile
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
@ -532,13 +533,13 @@ def chfullname(name, fullname):
|
||||
Change the full name of the user
|
||||
|
||||
:param str name:
|
||||
user name for which to change the full name
|
||||
user name for which to change the full name
|
||||
|
||||
:param str fullname:
|
||||
the new value for the full name
|
||||
the new value for the full name
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
True if successful. False is unsuccessful.
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
@ -556,18 +557,18 @@ def chgroups(name, groups, append=True):
|
||||
member of only the specified groups
|
||||
|
||||
:param str name:
|
||||
user name for which to change groups
|
||||
user name for which to change groups
|
||||
|
||||
:param groups:
|
||||
a single group or a list of groups to assign to the user
|
||||
:type: list, str
|
||||
a single group or a list of groups to assign to the user
|
||||
:type groups: list, str
|
||||
|
||||
:param bool append:
|
||||
True adds the passed groups to the user's current groups
|
||||
False sets the user's groups to the passed groups only
|
||||
True adds the passed groups to the user's current groups
|
||||
False sets the user's groups to the passed groups only
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
True if successful. False is unsuccessful.
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
@ -609,23 +610,23 @@ def info(name):
|
||||
Return user information
|
||||
|
||||
:param str name:
|
||||
Username for which to display information
|
||||
Username for which to display information
|
||||
|
||||
:returns:
|
||||
A dictionary containing user information
|
||||
- fullname
|
||||
- username
|
||||
- SID
|
||||
- passwd (will always return None)
|
||||
- comment (same as description, left here for backwards compatibility)
|
||||
- description
|
||||
- active
|
||||
- logonscript
|
||||
- profile
|
||||
- home
|
||||
- homedrive
|
||||
- groups
|
||||
- gid
|
||||
A dictionary containing user information
|
||||
- fullname
|
||||
- username
|
||||
- SID
|
||||
- passwd (will always return None)
|
||||
- comment (same as description, left here for backwards compatibility)
|
||||
- description
|
||||
- active
|
||||
- logonscript
|
||||
- profile
|
||||
- home
|
||||
- homedrive
|
||||
- groups
|
||||
- gid
|
||||
:rtype: dict
|
||||
|
||||
CLI Example:
|
||||
@ -687,10 +688,10 @@ def list_groups(name):
|
||||
Return a list of groups the named user belongs to
|
||||
|
||||
:param str name:
|
||||
user name for which to list groups
|
||||
user name for which to list groups
|
||||
|
||||
:return:
|
||||
list of groups to which the user belongs
|
||||
list of groups to which the user belongs
|
||||
:rtype: list
|
||||
|
||||
CLI Example:
|
||||
@ -715,11 +716,11 @@ def getent(refresh=False):
|
||||
Return the list of all info for all users
|
||||
|
||||
:param bool refresh:
|
||||
Refresh the cached user information. Default is False. Useful when used from
|
||||
within a state function.
|
||||
Refresh the cached user information. Default is False. Useful when used from
|
||||
within a state function.
|
||||
|
||||
:return:
|
||||
A dictionary containing information about all users on the system
|
||||
A dictionary containing information about all users on the system
|
||||
:rtype: dict
|
||||
|
||||
CLI Example:
|
||||
@ -755,7 +756,7 @@ def list_users():
|
||||
Return a list of users on Windows
|
||||
|
||||
:return:
|
||||
list of users on the system
|
||||
list of users on the system
|
||||
:rtype: list
|
||||
|
||||
CLI Example:
|
||||
@ -790,13 +791,13 @@ def rename(name, new_name):
|
||||
Change the username for a named user
|
||||
|
||||
:param str name:
|
||||
user name to change
|
||||
user name to change
|
||||
|
||||
:param str new_name:
|
||||
the new name for the current user
|
||||
the new name for the current user
|
||||
|
||||
:return:
|
||||
True if successful. False is unsuccessful.
|
||||
True if successful. False is unsuccessful.
|
||||
:rtype: bool
|
||||
|
||||
CLI Example:
|
||||
|
@ -261,46 +261,50 @@ def list_update(name=None,
|
||||
"""
|
||||
Returns details for all updates that match the search criteria
|
||||
|
||||
:param name: str
|
||||
The name of the update you're searching for. This can be the GUID
|
||||
(preferred), a KB number, or the full name of the update. Run list_updates
|
||||
to get the GUID for the update you're looking for.
|
||||
:param str name:
|
||||
The name of the update you're searching for. This can be the GUID
|
||||
(preferred), a KB number, or the full name of the update. Run list_updates
|
||||
to get the GUID for the update you're looking for.
|
||||
|
||||
:param download: bool
|
||||
:param bool download:
|
||||
Download the update returned by this function. Run this function first
|
||||
to see if the update exists, then set download=True to download the
|
||||
update.
|
||||
|
||||
:param install: bool
|
||||
:param bool install:
|
||||
Install the update returned by this function. Run this function first
|
||||
to see if the update exists, then set install=True to install the
|
||||
update. This will override download=True
|
||||
|
||||
:return: dict
|
||||
Returns a dict containing a list of updates that match the name if
|
||||
download and install are both set to False. Should usually be a single
|
||||
update, but can return multiple if a partial name is given. If download or
|
||||
install is set to true it will return the results of
|
||||
win_wua.download_updates::
|
||||
:return:
|
||||
Returns a dict containing a list of updates that match the name if
|
||||
download and install are both set to False. Should usually be a single
|
||||
update, but can return multiple if a partial name is given. If download or
|
||||
install is set to true it will return the results of
|
||||
win_wua.download_updates:
|
||||
|
||||
List of Updates:
|
||||
{'<GUID>': {'Title': <title>,
|
||||
'KB': <KB>,
|
||||
'GUID': <the globally unique identifier for the update>
|
||||
'Description': <description>,
|
||||
'Downloaded': <has the update been downloaded>,
|
||||
'Installed': <has the update been installed>,
|
||||
'Mandatory': <is the update mandatory>,
|
||||
'UserInput': <is user input required>,
|
||||
'EULAAccepted': <has the EULA been accepted>,
|
||||
'Severity': <update severity>,
|
||||
'NeedsReboot': <is the update installed and awaiting reboot>,
|
||||
'RebootBehavior': <will the update require a reboot>,
|
||||
'Categories': [ '<category 1>',
|
||||
'<category 2>',
|
||||
...]
|
||||
}
|
||||
}
|
||||
.. code-block:: cfg
|
||||
|
||||
List of Updates:
|
||||
{'<GUID>': {'Title': <title>,
|
||||
'KB': <KB>,
|
||||
'GUID': <the globally unique identifier for the update>
|
||||
'Description': <description>,
|
||||
'Downloaded': <has the update been downloaded>,
|
||||
'Installed': <has the update been installed>,
|
||||
'Mandatory': <is the update mandatory>,
|
||||
'UserInput': <is user input required>,
|
||||
'EULAAccepted': <has the EULA been accepted>,
|
||||
'Severity': <update severity>,
|
||||
'NeedsReboot': <is the update installed and awaiting reboot>,
|
||||
'RebootBehavior': <will the update require a reboot>,
|
||||
'Categories': [ '<category 1>',
|
||||
'<category 2>',
|
||||
...]
|
||||
}
|
||||
}
|
||||
|
||||
:return type: dict
|
||||
|
||||
CLI Examples:
|
||||
|
||||
@ -392,31 +396,31 @@ def list_updates(software=True,
|
||||
"""
|
||||
Returns a detailed list of available updates or a summary
|
||||
|
||||
:param software: bool
|
||||
:param bool software:
|
||||
Include software updates in the results (default is True)
|
||||
|
||||
:param drivers: bool
|
||||
:param bool drivers:
|
||||
Include driver updates in the results (default is False)
|
||||
|
||||
:param summary: bool
|
||||
:param bool summary:
|
||||
True: Return a summary of updates available for each category.\
|
||||
False (default): Return a detailed list of available updates.
|
||||
|
||||
:param installed: bool
|
||||
:param bool installed:
|
||||
Include installed updates in the results (default if False)
|
||||
|
||||
:param download: bool
|
||||
:param bool download:
|
||||
(Overrides reporting functionality) Download the list of updates
|
||||
returned by this function. Run this function first to see what will be
|
||||
installed, then set download=True to download the updates.
|
||||
|
||||
:param install: bool
|
||||
:param bool install:
|
||||
(Overrides reporting functionality) Install the list of updates
|
||||
returned by this function. Run this function first to see what will be
|
||||
installed, then set install=True to install the updates. This will
|
||||
override download=True
|
||||
|
||||
:param categories: list
|
||||
:param list categories:
|
||||
Specify the categories to list. Must be passed as a list. All
|
||||
categories returned by default.
|
||||
|
||||
@ -436,7 +440,7 @@ def list_updates(software=True,
|
||||
* Windows 8.1 and later drivers
|
||||
* Windows Defender
|
||||
|
||||
:param severities: list
|
||||
:param list severities:
|
||||
Specify the severities to include. Must be passed as a list. All
|
||||
severities returned by default.
|
||||
|
||||
@ -446,36 +450,39 @@ def list_updates(software=True,
|
||||
* Important
|
||||
|
||||
:return:
|
||||
Returns a dict containing either a summary or a list of updates::
|
||||
Returns a dict containing either a summary or a list of updates:
|
||||
|
||||
List of Updates:
|
||||
{'<GUID>': {'Title': <title>,
|
||||
'KB': <KB>,
|
||||
'GUID': <the globally uinique identifier for the update>
|
||||
'Description': <description>,
|
||||
'Downloaded': <has the update been downloaded>,
|
||||
'Installed': <has the update been installed>,
|
||||
'Mandatory': <is the update mandatory>,
|
||||
'UserInput': <is user input required>,
|
||||
'EULAAccepted': <has the EULA been accepted>,
|
||||
'Severity': <update severity>,
|
||||
'NeedsReboot': <is the update installed and awaiting reboot>,
|
||||
'RebootBehavior': <will the update require a reboot>,
|
||||
'Categories': [ '<category 1>',
|
||||
'<category 2>',
|
||||
...]
|
||||
}
|
||||
}
|
||||
.. code-block:: cfg
|
||||
|
||||
Summary of Updates:
|
||||
{'Total': <total number of updates returned>,
|
||||
'Available': <updates that are not downloaded or installed>,
|
||||
'Downloaded': <updates that are downloaded but not installed>,
|
||||
'Installed': <updates installed (usually 0 unless installed=True)>,
|
||||
'Categories': { <category 1>: <total for that category>,
|
||||
<category 2>: <total for category 2>,
|
||||
... }
|
||||
}
|
||||
List of Updates:
|
||||
{'<GUID>': {'Title': <title>,
|
||||
'KB': <KB>,
|
||||
'GUID': <the globally uinique identifier for the update>
|
||||
'Description': <description>,
|
||||
'Downloaded': <has the update been downloaded>,
|
||||
'Installed': <has the update been installed>,
|
||||
'Mandatory': <is the update mandatory>,
|
||||
'UserInput': <is user input required>,
|
||||
'EULAAccepted': <has the EULA been accepted>,
|
||||
'Severity': <update severity>,
|
||||
'NeedsReboot': <is the update installed and awaiting reboot>,
|
||||
'RebootBehavior': <will the update require a reboot>,
|
||||
'Categories': [ '<category 1>',
|
||||
'<category 2>',
|
||||
...]
|
||||
}
|
||||
}
|
||||
|
||||
Summary of Updates:
|
||||
{'Total': <total number of updates returned>,
|
||||
'Available': <updates that are not downloaded or installed>,
|
||||
'Downloaded': <updates that are downloaded but not installed>,
|
||||
'Installed': <updates installed (usually 0 unless installed=True)>,
|
||||
'Categories': { <category 1>: <total for that category>,
|
||||
<category 2>: <total for category 2>,
|
||||
... }
|
||||
}
|
||||
:return type: dict
|
||||
|
||||
CLI Examples:
|
||||
|
||||
@ -934,26 +941,26 @@ def set_wu_settings(level=None,
|
||||
Change Windows Update settings. If no parameters are passed, the current
|
||||
value will be returned.
|
||||
|
||||
:param level: int
|
||||
:param int level:
|
||||
Number from 1 to 4 indicating the update level:
|
||||
1. Never check for updates
|
||||
2. Check for updates but let me choose whether to download and install them
|
||||
3. Download updates but let me choose whether to install them
|
||||
4. Install updates automatically
|
||||
:param recommended: bool
|
||||
:param bool recommended:
|
||||
Boolean value that indicates whether to include optional or recommended
|
||||
updates when a search for updates and installation of updates is
|
||||
performed.
|
||||
:param featured: bool
|
||||
:param bool featured:
|
||||
Boolean value that indicates whether to display notifications for
|
||||
featured updates.
|
||||
:param elevated: bool
|
||||
:param bool elevated:
|
||||
Boolean value that indicates whether non-administrators can perform some
|
||||
update-related actions without administrator approval.
|
||||
:param msupdate: bool
|
||||
:param bool msupdate:
|
||||
Boolean value that indicates whether to turn on Microsoft Update for
|
||||
other Microsoft products
|
||||
:param day: str
|
||||
:param str day:
|
||||
Days of the week on which Automatic Updates installs or uninstalls
|
||||
updates.
|
||||
Accepted values:
|
||||
@ -964,7 +971,7 @@ def set_wu_settings(level=None,
|
||||
- Thursday
|
||||
- Friday
|
||||
- Saturday
|
||||
:param time: str
|
||||
:param str time:
|
||||
Time at which Automatic Updates installs or uninstalls updates. Must be
|
||||
in the ##:## 24hr format, eg. 3:00 PM would be 15:00
|
||||
|
||||
@ -1118,39 +1125,39 @@ def get_wu_settings():
|
||||
Get current Windows Update settings.
|
||||
|
||||
:return:
|
||||
Featured Updates:
|
||||
Boolean value that indicates whether to display notifications for
|
||||
featured updates.
|
||||
Group Policy Required (Read-only):
|
||||
Boolean value that indicates whether Group Policy requires the Automatic
|
||||
Updates service.
|
||||
Microsoft Update:
|
||||
Boolean value that indicates whether to turn on Microsoft Update for
|
||||
other Microsoft Products
|
||||
Needs Reboot:
|
||||
Boolean value that indicates whether the machine is in a reboot pending
|
||||
state.
|
||||
Non Admins Elevated:
|
||||
Boolean value that indicates whether non-administrators can perform some
|
||||
update-related actions without administrator approval.
|
||||
Notification Level:
|
||||
Number 1 to 4 indicating the update level:
|
||||
1. Never check for updates
|
||||
2. Check for updates but let me choose whether to download and install them
|
||||
3. Download updates but let me choose whether to install them
|
||||
4. Install updates automatically
|
||||
Read Only (Read-only):
|
||||
Boolean value that indicates whether the Automatic Update
|
||||
settings are read-only.
|
||||
Recommended Updates:
|
||||
Boolean value that indicates whether to include optional or recommended
|
||||
updates when a search for updates and installation of updates is
|
||||
performed.
|
||||
Scheduled Day:
|
||||
Days of the week on which Automatic Updates installs or uninstalls
|
||||
updates.
|
||||
Scheduled Time:
|
||||
Time at which Automatic Updates installs or uninstalls updates.
|
||||
Featured Updates:
|
||||
Boolean value that indicates whether to display notifications for
|
||||
featured updates.
|
||||
Group Policy Required (Read-only):
|
||||
Boolean value that indicates whether Group Policy requires the Automatic
|
||||
Updates service.
|
||||
Microsoft Update:
|
||||
Boolean value that indicates whether to turn on Microsoft Update for
|
||||
other Microsoft Products
|
||||
Needs Reboot:
|
||||
Boolean value that indicates whether the machine is in a reboot pending
|
||||
state.
|
||||
Non Admins Elevated:
|
||||
Boolean value that indicates whether non-administrators can perform some
|
||||
update-related actions without administrator approval.
|
||||
Notification Level:
|
||||
Number 1 to 4 indicating the update level:
|
||||
1. Never check for updates
|
||||
2. Check for updates but let me choose whether to download and install them
|
||||
3. Download updates but let me choose whether to install them
|
||||
4. Install updates automatically
|
||||
Read Only (Read-only):
|
||||
Boolean value that indicates whether the Automatic Update
|
||||
settings are read-only.
|
||||
Recommended Updates:
|
||||
Boolean value that indicates whether to include optional or recommended
|
||||
updates when a search for updates and installation of updates is
|
||||
performed.
|
||||
Scheduled Day:
|
||||
Days of the week on which Automatic Updates installs or uninstalls
|
||||
updates.
|
||||
Scheduled Time:
|
||||
Time at which Automatic Updates installs or uninstalls updates.
|
||||
|
||||
CLI Examples:
|
||||
|
||||
|
@ -1921,21 +1921,21 @@ class WebsocketEndpoint(object):
|
||||
|
||||
.. http:get:: /ws/(token)
|
||||
|
||||
:query format_events: The event stream will undergo server-side
|
||||
formatting if the ``format_events`` URL parameter is included
|
||||
in the request. This can be useful to avoid formatting on the
|
||||
client-side:
|
||||
:query format_events: The event stream will undergo server-side
|
||||
formatting if the ``format_events`` URL parameter is included
|
||||
in the request. This can be useful to avoid formatting on the
|
||||
client-side:
|
||||
|
||||
.. code-block:: bash
|
||||
.. code-block:: bash
|
||||
|
||||
curl -NsS <...snip...> localhost:8000/ws?format_events
|
||||
curl -NsS <...snip...> localhost:8000/ws?format_events
|
||||
|
||||
:reqheader X-Auth-Token: an authentication token from
|
||||
:py:class:`~Login`.
|
||||
:reqheader X-Auth-Token: an authentication token from
|
||||
:py:class:`~Login`.
|
||||
|
||||
:status 101: switching to the websockets protocol
|
||||
:status 401: |401|
|
||||
:status 406: |406|
|
||||
:status 101: switching to the websockets protocol
|
||||
:status 401: |401|
|
||||
:status 406: |406|
|
||||
|
||||
**Example request:**
|
||||
|
||||
|
@ -108,10 +108,14 @@ class AsyncRemotePillar(object):
|
||||
'cmd': '_pillar'}
|
||||
if self.ext:
|
||||
load['ext'] = self.ext
|
||||
ret_pillar = yield self.channel.crypted_transfer_decode_dictentry(
|
||||
load,
|
||||
dictkey='pillar',
|
||||
)
|
||||
try:
|
||||
ret_pillar = yield self.channel.crypted_transfer_decode_dictentry(
|
||||
load,
|
||||
dictkey='pillar',
|
||||
)
|
||||
except:
|
||||
log.exception('Exception getting pillar:')
|
||||
raise SaltClientError('Exception getting pillar.')
|
||||
|
||||
if not isinstance(ret_pillar, dict):
|
||||
msg = ('Got a bad pillar from master, type {0}, expecting dict: '
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014 Floris Bruynooghe <flub@devork.be>
|
||||
|
||||
'''
|
||||
r'''
|
||||
Use remote Mercurial repository as a Pillar source.
|
||||
|
||||
.. versionadded:: 2015.8.0
|
||||
|
@ -20,66 +20,72 @@ Return data to a cassandra server
|
||||
IP address. No assumption or default will be used for the cluster IPs.
|
||||
The cluster IPs will be tried in the order listed. The port, username,
|
||||
and password values shown below will be the assumed defaults if you do
|
||||
not provide values.::
|
||||
not provide values.:
|
||||
|
||||
cassandra:
|
||||
cluster:
|
||||
- 192.168.50.11
|
||||
- 192.168.50.12
|
||||
- 192.168.50.13
|
||||
port: 9042
|
||||
username: salt
|
||||
password: salt
|
||||
.. code-block:: yaml
|
||||
|
||||
Use the following cassandra database schema::
|
||||
cassandra:
|
||||
cluster:
|
||||
- 192.168.50.11
|
||||
- 192.168.50.12
|
||||
- 192.168.50.13
|
||||
port: 9042
|
||||
username: salt
|
||||
password: salt
|
||||
|
||||
CREATE KEYSPACE IF NOT EXISTS salt
|
||||
WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};
|
||||
Use the following cassandra database schema:
|
||||
|
||||
CREATE USER IF NOT EXISTS salt WITH PASSWORD 'salt' NOSUPERUSER;
|
||||
.. code-block:: sql
|
||||
|
||||
GRANT ALL ON KEYSPACE salt TO salt;
|
||||
CREATE KEYSPACE IF NOT EXISTS salt
|
||||
WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};
|
||||
|
||||
USE salt;
|
||||
CREATE USER IF NOT EXISTS salt WITH PASSWORD 'salt' NOSUPERUSER;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS salt.salt_returns (
|
||||
jid text,
|
||||
minion_id text,
|
||||
fun text,
|
||||
alter_time timestamp,
|
||||
full_ret text,
|
||||
return text,
|
||||
success boolean,
|
||||
PRIMARY KEY (jid, minion_id, fun)
|
||||
) WITH CLUSTERING ORDER BY (minion_id ASC, fun ASC);
|
||||
CREATE INDEX IF NOT EXISTS salt_returns_minion_id ON salt.salt_returns (minion_id);
|
||||
CREATE INDEX IF NOT EXISTS salt_returns_fun ON salt.salt_returns (fun);
|
||||
GRANT ALL ON KEYSPACE salt TO salt;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS salt.jids (
|
||||
jid text PRIMARY KEY,
|
||||
load text
|
||||
);
|
||||
USE salt;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS salt.minions (
|
||||
minion_id text PRIMARY KEY,
|
||||
last_fun text
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS minions_last_fun ON salt.minions (last_fun);
|
||||
CREATE TABLE IF NOT EXISTS salt.salt_returns (
|
||||
jid text,
|
||||
minion_id text,
|
||||
fun text,
|
||||
alter_time timestamp,
|
||||
full_ret text,
|
||||
return text,
|
||||
success boolean,
|
||||
PRIMARY KEY (jid, minion_id, fun)
|
||||
) WITH CLUSTERING ORDER BY (minion_id ASC, fun ASC);
|
||||
CREATE INDEX IF NOT EXISTS salt_returns_minion_id ON salt.salt_returns (minion_id);
|
||||
CREATE INDEX IF NOT EXISTS salt_returns_fun ON salt.salt_returns (fun);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS salt.salt_events (
|
||||
id timeuuid,
|
||||
tag text,
|
||||
alter_time timestamp,
|
||||
data text,
|
||||
master_id text,
|
||||
PRIMARY KEY (id, tag)
|
||||
) WITH CLUSTERING ORDER BY (tag ASC);
|
||||
CREATE INDEX tag ON salt.salt_events (tag);
|
||||
CREATE TABLE IF NOT EXISTS salt.jids (
|
||||
jid text PRIMARY KEY,
|
||||
load text
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS salt.minions (
|
||||
minion_id text PRIMARY KEY,
|
||||
last_fun text
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS minions_last_fun ON salt.minions (last_fun);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS salt.salt_events (
|
||||
id timeuuid,
|
||||
tag text,
|
||||
alter_time timestamp,
|
||||
data text,
|
||||
master_id text,
|
||||
PRIMARY KEY (id, tag)
|
||||
) WITH CLUSTERING ORDER BY (tag ASC);
|
||||
CREATE INDEX tag ON salt.salt_events (tag);
|
||||
|
||||
|
||||
Required python modules: cassandra-driver
|
||||
|
||||
To use the cassandra returner, append '--return cassandra' to the salt command. ex:
|
||||
To use the cassandra returner, append '--return cassandra' to the salt command. ex:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' test.ping --return cassandra
|
||||
'''
|
||||
|
@ -23,7 +23,7 @@ def cmd(
|
||||
Execute a single command via the salt-ssh subsystem and return all
|
||||
routines at once
|
||||
|
||||
.. versionaddedd:: 2015.2
|
||||
.. versionadded:: 2015.2
|
||||
|
||||
A wrapper around the :py:meth:`SSHClient.cmd
|
||||
<salt.client.ssh.client.SSHClient.cmd>` method.
|
||||
|
@ -176,7 +176,7 @@ def event(tagmatch='*',
|
||||
|
||||
.. seealso::
|
||||
|
||||
See :glob:`tests/eventlisten.sh` for an example of usage within a shell
|
||||
See :blob:`tests/eventlisten.sh` for an example of usage within a shell
|
||||
script.
|
||||
'''
|
||||
statemod = salt.loader.raw_mod(__opts__, 'state', None)
|
||||
|
@ -1,39 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Connection module for Amazon Cloud Formation
|
||||
Connection module for Amazon Cloud Formation
|
||||
|
||||
.. versionadded:: 2015.8.0
|
||||
.. versionadded:: 2015.8.0
|
||||
|
||||
:configuration: This module accepts explicit AWS credentials but can also utilize
|
||||
IAM roles assigned to the instance trough Instance Profiles. Dynamic
|
||||
:depends: boto
|
||||
:configuration: This module accepts explicit AWS credentials but can also utilize
|
||||
IAM roles assigned to the instance through Instance Profiles. Dynamic
|
||||
credentials are then automatically obtained from AWS API and no further
|
||||
configuration is necessary. More Information available at::
|
||||
|
||||
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
|
||||
configuration is necessary. More Information available at
|
||||
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
|
||||
|
||||
If IAM roles are not used you need to specify them either in a pillar or
|
||||
in the minion's config file::
|
||||
in the minion's config file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||
key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
stack-present:
|
||||
boto_cfn.present:
|
||||
- name: mystack
|
||||
- template_body: salt://base/mytemplate.json
|
||||
- disable_rollback: true
|
||||
- region: eu-west-1
|
||||
- keyid: 'AKIAJHTMIQ2ASDFLASDF'
|
||||
- key: 'fdkjsafkljsASSADFalkfjasdf'
|
||||
stack-present:
|
||||
boto_cfn.present:
|
||||
- name: mystack
|
||||
- template_body: salt://base/mytemplate.json
|
||||
- disable_rollback: true
|
||||
- region: eu-west-1
|
||||
- keyid: 'AKIAJHTMIQ2ASDFLASDF'
|
||||
- key: 'fdkjsafkljsASSADFalkfjasdf'
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
stack-absent:
|
||||
boto_cfn.absent:
|
||||
- name: mystack
|
||||
:depends: boto
|
||||
stack-absent:
|
||||
boto_cfn.absent:
|
||||
- name: mystack
|
||||
'''
|
||||
|
||||
from __future__ import absolute_import
|
||||
@ -116,6 +117,8 @@ def present(name, template_body=None, template_url=None, parameters=None, notifi
|
||||
|
||||
profile (dict) - A dict with region, key and keyid, or a pillar key (string) that contains a dict with region, key
|
||||
and keyid.
|
||||
|
||||
.. _ sns_console: https://console.aws.amazon.com/sns
|
||||
'''
|
||||
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
||||
|
||||
|
@ -38,43 +38,41 @@ pillars or minion config:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Ensure DynamoDB table does not exist:
|
||||
boto_dynamodb.absent:
|
||||
- table_name: new_table
|
||||
- keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||
- key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||
- region: us-east-1
|
||||
|
||||
Ensure DynamoDB table exists:
|
||||
boto_dynamodb.present:
|
||||
- table_name: new_table
|
||||
- read_capacity_units: 1
|
||||
- write_capacity_units: 2
|
||||
- hash_key: primary_id
|
||||
- hash_key_data_type: N
|
||||
- range_key: start_timestamp
|
||||
- range_key_data_type: N
|
||||
- keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||
- key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||
- region: us-east-1
|
||||
- local_indexes:
|
||||
- index:
|
||||
- name: "primary_id_end_timestamp_index"
|
||||
- hash_key: primary_id
|
||||
- hash_key_data_type: N
|
||||
- range_key: end_timestamp
|
||||
- range_key_data_type: N
|
||||
- global_indexes:
|
||||
- index:
|
||||
- name: "name_end_timestamp_index"
|
||||
- hash_key: name
|
||||
- hash_key_data_type: S
|
||||
- range_key: end_timestamp
|
||||
- range_key_data_type: N
|
||||
- read_capacity_units: 3
|
||||
- write_capacity_units: 4
|
||||
|
||||
Ensure DynamoDB table does not exist:
|
||||
boto_dynamodb.absent:
|
||||
- table_name: new_table
|
||||
- keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||
- key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||
- region: us-east-1
|
||||
|
||||
Ensure DynamoDB table exists:
|
||||
boto_dynamodb.present:
|
||||
- table_name: new_table
|
||||
- read_capacity_units: 1
|
||||
- write_capacity_units: 2
|
||||
- hash_key: primary_id
|
||||
- hash_key_data_type: N
|
||||
- range_key: start_timestamp
|
||||
- range_key_data_type: N
|
||||
- keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||
- key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||
- region: us-east-1
|
||||
- local_indexes:
|
||||
- index:
|
||||
- name: "primary_id_end_timestamp_index"
|
||||
- hash_key: primary_id
|
||||
- hash_key_data_type: N
|
||||
- range_key: end_timestamp
|
||||
- range_key_data_type: N
|
||||
- global_indexes:
|
||||
- index:
|
||||
- name: "name_end_timestamp_index"
|
||||
- hash_key: name
|
||||
- hash_key_data_type: S
|
||||
- range_key: end_timestamp
|
||||
- range_key_data_type: N
|
||||
- read_capacity_units: 3
|
||||
- write_capacity_units: 4
|
||||
'''
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
|
@ -374,12 +374,12 @@ def register_instances(name, instances, region=None, key=None, keyid=None,
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
add-instances:
|
||||
boto_elb.register_instances:
|
||||
- name: myloadbalancer
|
||||
- instances:
|
||||
- instance-id1
|
||||
- instance-id2
|
||||
add-instances:
|
||||
boto_elb.register_instances:
|
||||
- name: myloadbalancer
|
||||
- instances:
|
||||
- instance-id1
|
||||
- instance-id2
|
||||
'''
|
||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||
ret['name'] = name
|
||||
|
@ -300,8 +300,8 @@ def _parse_volumes(volumes):
|
||||
contvolumes.append(str(vol))
|
||||
continue
|
||||
bindvolumes[source] = {
|
||||
'bind': target,
|
||||
'ro': read_only
|
||||
'bind': target,
|
||||
'ro': read_only
|
||||
}
|
||||
result = {'bindvols': bindvolumes, 'contvols': contvolumes}
|
||||
log.trace("Finished parsing volumes, with result: " + str(result))
|
||||
@ -507,9 +507,9 @@ def loaded(name, tag='latest', source=None, source_hash='', force=False):
|
||||
|
||||
tmp_filename = salt.utils.mkstemp()
|
||||
__salt__['state.single']('file.managed',
|
||||
name=tmp_filename,
|
||||
source=source,
|
||||
source_hash=source_hash)
|
||||
name=tmp_filename,
|
||||
source=source,
|
||||
source_hash=source_hash)
|
||||
changes = {}
|
||||
|
||||
if image_infos['status']:
|
||||
@ -517,9 +517,8 @@ def loaded(name, tag='latest', source=None, source_hash='', force=False):
|
||||
remove_image = __salt__['docker.remove_image']
|
||||
remove_info = remove_image(image_name)
|
||||
if not remove_info['status']:
|
||||
return _invalid(
|
||||
name=name,
|
||||
comment='Image could not be removed: {0}'.format(image_name))
|
||||
return _invalid(name=name,
|
||||
comment='Image could not be removed: {0}'.format(name))
|
||||
|
||||
load = __salt__['docker.load']
|
||||
returned = load(tmp_filename)
|
||||
@ -757,23 +756,23 @@ def absent(name):
|
||||
is_gone = __salt__['docker.exists'](cid)
|
||||
if is_gone:
|
||||
return _valid(comment=('Container {0!r}'
|
||||
' was stopped and destroyed, '.format(cid)),
|
||||
changes={name: True})
|
||||
' was stopped and destroyed, '.format(cid)),
|
||||
changes={name: True})
|
||||
else:
|
||||
return _valid(comment=('Container {0!r}'
|
||||
' was stopped but could not be destroyed,'.format(cid)),
|
||||
changes={name: True})
|
||||
' was stopped but could not be destroyed,'.format(cid)),
|
||||
changes={name: True})
|
||||
else:
|
||||
__salt__['docker.remove_container'](cid)
|
||||
is_gone = __salt__['docker.exists'](cid)
|
||||
if is_gone:
|
||||
return _valid(comment=('Container {0!r}'
|
||||
' is stopped and was destroyed, '.format(cid)),
|
||||
changes={name: True})
|
||||
'is stopped and was destroyed, '.format(cid)),
|
||||
changes={name: True})
|
||||
else:
|
||||
return _valid(comment=('Container {0!r}'
|
||||
' is stopped but could not be destroyed,'.format(cid)),
|
||||
changes={name: True})
|
||||
' is stopped but could not be destroyed,'.format(cid)),
|
||||
changes={name: True})
|
||||
else:
|
||||
return _valid(comment="Container {0!r} not found".format(name))
|
||||
|
||||
@ -862,7 +861,7 @@ def run(name,
|
||||
if not onlyif:
|
||||
return valid(comment='onlyif execution failed')
|
||||
elif isinstance(onlyif, string_types):
|
||||
if retcode(cid, onlyif) != 0:
|
||||
if not __salt__['cmd.retcode'](onlyif) == 0:
|
||||
return valid(comment='onlyif execution failed')
|
||||
|
||||
if unless is not None:
|
||||
@ -870,7 +869,7 @@ def run(name,
|
||||
if unless:
|
||||
return valid(comment='unless execution succeeded')
|
||||
elif isinstance(unless, string_types):
|
||||
if retcode(cid, unless) == 0:
|
||||
if __salt__['cmd.retcode'](unless) == 0:
|
||||
return valid(comment='unless execution succeeded')
|
||||
|
||||
if docked_onlyif is not None:
|
||||
@ -878,7 +877,7 @@ def run(name,
|
||||
if not docked_onlyif:
|
||||
return valid(comment='docked_onlyif execution failed')
|
||||
elif isinstance(docked_onlyif, string_types):
|
||||
if retcode(cid, docked_onlyif) != 0:
|
||||
if not retcode(cid, docked_onlyif):
|
||||
return valid(comment='docked_onlyif execution failed')
|
||||
|
||||
if docked_unless is not None:
|
||||
@ -886,7 +885,7 @@ def run(name,
|
||||
if docked_unless:
|
||||
return valid(comment='docked_unless execution succeeded')
|
||||
elif isinstance(docked_unless, string_types):
|
||||
if retcode(cid, docked_unless) == 0:
|
||||
if retcode(cid, docked_unless):
|
||||
return valid(comment='docked_unless execution succeeded')
|
||||
|
||||
if __opts__['test']:
|
||||
@ -1266,9 +1265,8 @@ def running(name,
|
||||
if is_running:
|
||||
changes.append('Container {0!r} started.\n'.format(name))
|
||||
else:
|
||||
return _invalid(comment=(
|
||||
'Container {0!r} cannot be started\n{1!s}'
|
||||
.format(name, started['out'],)))
|
||||
return _invalid(comment=('Container {0!r} cannot be started\n{1!s}'
|
||||
.format(name, started['out'],)))
|
||||
else:
|
||||
changes.append('Container {0!r} started.\n'.format(name))
|
||||
return _valid(comment='\n'.join(changes), changes={name: True})
|
||||
|
@ -1464,6 +1464,8 @@ def managed(name,
|
||||
ret['comment'] = 'The file {0} is set to be changed'.format(name)
|
||||
if show_diff and 'diff' in ret['pchanges']:
|
||||
ret['changes']['diff'] = ret['pchanges']['diff']
|
||||
if not show_diff:
|
||||
ret['changes']['diff'] = '<show_diff=False>'
|
||||
else:
|
||||
ret['result'] = True
|
||||
ret['comment'] = 'The file {0} is in the correct state'.format(name)
|
||||
|
@ -7,7 +7,7 @@ Schedules and users can be referenced by pagerduty ID, or by name, or by email a
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
ensure test escalation policy:
|
||||
pagerduty_escalation_policy.present:
|
||||
|
@ -186,7 +186,7 @@ def present(name, value=None, vname=None, vdata=None, vtype='REG_SZ', reflection
|
||||
# This is for backwards compatibility
|
||||
# If 'value' is passed a value, vdata becomes value and the vname is
|
||||
# obtained from the key path
|
||||
if value:
|
||||
if value or value in [0, '']:
|
||||
hive, key, vname = _parse_key_value(name)
|
||||
vdata = value
|
||||
ret['comment'] = 'State file is using deprecated syntax. Please update.'
|
||||
@ -208,7 +208,7 @@ def present(name, value=None, vname=None, vdata=None, vtype='REG_SZ', reflection
|
||||
|
||||
add_change = {'Key': r'{0}\{1}'.format(hive, key),
|
||||
'Entry': '{0}'.format(vname if vname else '(Default)'),
|
||||
'Value': '{0}'.format(vdata if vdata else '(Empty String)')}
|
||||
'Value': '{0}'.format(vdata)}
|
||||
|
||||
# Check for test option
|
||||
if __opts__['test']:
|
||||
@ -256,9 +256,15 @@ def absent(name, vname=None):
|
||||
hive, key = _parse_key(name)
|
||||
|
||||
# Determine what to do
|
||||
if not __salt__['reg.read_value'](hive, key, vname)['success']:
|
||||
hive, key, vname = _parse_key_value(name)
|
||||
if not __salt__['reg.read_value'](hive, key, vname)['success']:
|
||||
reg_check = __salt__['reg.read_value'](hive, key, vname)
|
||||
if not reg_check['success'] or reg_check['vdata'] == '(value not set)':
|
||||
if not vname:
|
||||
hive, key, vname = _parse_key_value(name)
|
||||
reg_check = __salt__['reg.read_value'](hive, key, vname)
|
||||
if not reg_check['success'] or reg_check['vdata'] == '(value not set)':
|
||||
ret['comment'] = '{0} is already absent'.format(name)
|
||||
return ret
|
||||
else:
|
||||
ret['comment'] = '{0} is already absent'.format(name)
|
||||
return ret
|
||||
|
||||
@ -275,11 +281,10 @@ def absent(name, vname=None):
|
||||
ret['result'] = __salt__['reg.delete_value'](hive, key, vname)
|
||||
if not ret['result']:
|
||||
ret['changes'] = {}
|
||||
ret['comment'] = r'Failed to remove {0} from {1}\{2}'.format(name, hive,
|
||||
key)
|
||||
ret['comment'] = r'Failed to remove {0} from {1}'.format(key, hive)
|
||||
else:
|
||||
ret['changes'] = {'reg': {'Removed': remove_change}}
|
||||
ret['comment'] = r'Removed {0} from {1}\{2}'.format(name, hive, key)
|
||||
ret['comment'] = r'Removed {0} from {1}'.format(key, hive)
|
||||
|
||||
return ret
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Interface to Red Hat tuned-adm module
|
||||
|
||||
:maintainer: Syed Ali <alicsyed@gmail.com>
|
||||
:maturity: new
|
||||
:depends: cmd.run
|
||||
|
@ -984,6 +984,9 @@ def deploy_windows(host,
|
||||
newtimeout = timeout - (time.mktime(time.localtime()) - starttime)
|
||||
|
||||
smb_conn = salt.utils.smb.get_conn(host, username, password)
|
||||
if smb_conn is False:
|
||||
log.error('Please install impacket to enable SMB functionality')
|
||||
return False
|
||||
|
||||
creds = "-U '{0}%{1}' //{2}".format(
|
||||
username, password, host)
|
||||
|
@ -47,6 +47,9 @@ def get_conn(host=None, username=None, password=None):
|
||||
'''
|
||||
Get an SMB connection
|
||||
'''
|
||||
if not HAS_IMPACKET:
|
||||
return False
|
||||
|
||||
conn = impacket.smbconnection.SMBConnection(
|
||||
remoteName='*SMBSERVER',
|
||||
remoteHost=host,
|
||||
@ -65,6 +68,9 @@ def mkdirs(path, share='C$', conn=None, host=None, username=None, password=None)
|
||||
if conn is None:
|
||||
conn = get_conn(host, username, password)
|
||||
|
||||
if conn is False:
|
||||
return False
|
||||
|
||||
comps = path.split('/')
|
||||
pos = 1
|
||||
for comp in comps:
|
||||
@ -85,5 +91,8 @@ def put_str(content, path, share='C$', conn=None, host=None, username=None, pass
|
||||
if conn is None:
|
||||
conn = get_conn(host, username, password)
|
||||
|
||||
if conn is False:
|
||||
return False
|
||||
|
||||
fh_ = StrHandle(content)
|
||||
conn.putFile(share, path, fh_.string)
|
||||
|
@ -510,3 +510,11 @@ def safe_py_code(code):
|
||||
if code.count(bad):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def verify_log(opts):
|
||||
'''
|
||||
If an insecre logging configuration is found, show a warning
|
||||
'''
|
||||
if opts.get('log_level') in ('garbage', 'trace', 'debug'):
|
||||
log.warn('Insecure logging configuration detected! Sensitive data may be logged.')
|
||||
|
@ -70,7 +70,7 @@ class WinPathTestCase(TestCase):
|
||||
Test to Returns the system path
|
||||
'''
|
||||
mock = MagicMock(return_value={'vdata': 'c:\\salt'})
|
||||
with patch.dict(win_path.__salt__, {'reg.read_key': mock}):
|
||||
with patch.dict(win_path.__salt__, {'reg.read_value': mock}):
|
||||
self.assertListEqual(win_path.get_path(), ['c:\\salt'])
|
||||
|
||||
def test_exists(self):
|
||||
|
@ -80,34 +80,37 @@ class RegTestCase(TestCase):
|
||||
'''
|
||||
Test to remove a registry entry.
|
||||
'''
|
||||
name = 'HKEY_CURRENT_USER\\SOFTWARE\\Salt'
|
||||
hive = 'HKEY_CURRENT_USER'
|
||||
key = 'SOFTWARE\\Salt'
|
||||
name = hive + '\\' + key
|
||||
vname = 'version'
|
||||
vdata = '0.15.3'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': '{0} is already absent'.format(name)}
|
||||
|
||||
mock_read = MagicMock(side_effect=[{'success': False},
|
||||
{'success': False},
|
||||
{'success': True},
|
||||
{'success': True}])
|
||||
mock_read_true = MagicMock(return_value={'success': True, 'vdata': vdata})
|
||||
mock_read_false = MagicMock(return_value={'success': False, 'vdata': False})
|
||||
|
||||
mock_t = MagicMock(return_value=True)
|
||||
with patch.dict(reg.__salt__, {'reg.read_value': mock_read,
|
||||
with patch.dict(reg.__salt__, {'reg.read_value': mock_read_false,
|
||||
'reg.delete_value': mock_t}):
|
||||
self.assertDictEqual(reg.absent(name, vname), ret)
|
||||
|
||||
with patch.dict(reg.__salt__, {'reg.read_value': mock_read_true}):
|
||||
with patch.dict(reg.__opts__, {'test': True}):
|
||||
ret.update({'comment': '', 'result': None,
|
||||
'changes': {'reg': {'Will remove': {'Entry': vname,
|
||||
'Key': name}}}})
|
||||
'changes': {'reg': {'Will remove': {'Entry': vname, 'Key': name}}}})
|
||||
self.assertDictEqual(reg.absent(name, vname), ret)
|
||||
|
||||
with patch.dict(reg.__salt__, {'reg.read_value': mock_read_true,
|
||||
'reg.delete_value': mock_t}):
|
||||
with patch.dict(reg.__opts__, {'test': False}):
|
||||
ret.update({'result': True,
|
||||
'changes': {'reg': {'Removed': {'Entry': vname,
|
||||
'Key': name}}},
|
||||
'comment': 'Removed {0} from {0}'.format(name)})
|
||||
'changes': {'reg': {'Removed': {'Entry': vname, 'Key': name}}},
|
||||
'comment': 'Removed {0} from {1}'.format(key, hive)})
|
||||
self.assertDictEqual(reg.absent(name, vname), ret)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user