Merge branch 'develop' into issue_46189

This commit is contained in:
Nicole Thomas 2018-03-05 12:16:39 -05:00 committed by GitHub
commit e34bb4ac96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
369 changed files with 52847 additions and 10232 deletions

View File

@ -46,6 +46,8 @@ class Mock(object):
data = self.__mapping.get(name)
elif name in ('__file__', '__path__'):
data = '/dev/null'
elif name == '__qualname__':
raise AttributeError("'Mock' object has no attribute '__qualname__'")
else:
data = Mock(mapping=self.__mapping)
return data

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-API" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-API" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-api \- salt-api Command
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-CALL" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-CALL" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-call \- salt-call Documentation
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-CLOUD" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-CLOUD" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-cloud \- Salt Cloud Command
.
@ -197,7 +197,7 @@ New in version 2014.7.0.
.sp
Display a list of configured profiles. Pass in a cloud provider to view
the provider\(aqs associated profiles, such as \fBdigital_ocean\fP, or pass in
the provider\(aqs associated profiles, such as \fBdigitalocean\fP, or pass in
\fBall\fP to list all the configured profiles.
.UNINDENT
.SS Cloud Providers Listings

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-CP" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-CP" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-cp \- salt-cp Documentation
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-KEY" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-KEY" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-key \- salt-key Documentation
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-MASTER" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-MASTER" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-master \- salt-master Documentation
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-MINION" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-MINION" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-minion \- salt-minion Documentation
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-PROXY" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-PROXY" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-proxy \- salt-proxy Documentation
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-RUN" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-RUN" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-run \- salt-run Documentation
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-SSH" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-SSH" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-ssh \- salt-ssh Documentation
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-SYNDIC" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-SYNDIC" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-syndic \- salt-syndic Documentation
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-UNITY" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT-UNITY" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt-unity \- salt-unity Command
.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SALT" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
salt \- salt
.
@ -135,7 +135,7 @@ minions to execute on.
.B \-a EAUTH, \-\-auth=EAUTH
Pass in an external authentication medium to validate against. The
credentials will be prompted for. The options are \fIauto\fP,
\fIkeystone\fP, \fIldap\fP, \fIpam\fP, and \fIstormpath\fP\&. Can be used with the \-T
\fIkeystone\fP, \fIldap\fP, and \fIpam\fP\&. Can be used with the \-T
option.
.UNINDENT
.INDENT 0.0

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SPM" "1" "Jan 24, 2018" "2017.7.3" "Salt"
.TH "SPM" "1" "Feb 23, 2018" "2018.3.0" "Salt"
.SH NAME
spm \- Salt Package Manager Command
.

View File

@ -1398,7 +1398,7 @@ comparison, then by globbing, then by full-string regex matching.
This should still be considered a less than secure option, due to the fact
that trust is based on just the requesting minion id.
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
For security reasons the file must be readonly except for it's owner.
If :conf_master:`permissive_pki_access` is ``True`` the owning group can also
have write access, but if Salt is running as ``root`` it must be a member of that group.
@ -1423,7 +1423,7 @@ membership in the :conf_master:`autosign_file` and the
``autosign_grains_dir``
-----------------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``not defined``
@ -1920,7 +1920,7 @@ Set additional directories to search for runner modules.
``utils_dirs``
---------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``[]``
@ -2130,7 +2130,7 @@ the cloud profile or master config file, no templating will be performed.
``jinja_env``
-------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``{}``
@ -2166,7 +2166,7 @@ The default options are:
``jinja_sls_env``
-----------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``{}``
@ -2236,7 +2236,7 @@ be used if you had not set the line_statement and line_comment options:
``jinja_trim_blocks``
---------------------
.. deprecated:: Oxygen
.. deprecated:: 2018.3.0
Replaced by :conf_master:`jinja_env` and :conf_master:`jinja_sls_env`
.. versionadded:: 2014.1.0
@ -2256,7 +2256,7 @@ to the Jinja environment init variable ``trim_blocks``.
``jinja_lstrip_blocks``
-----------------------
.. deprecated:: Oxygen
.. deprecated:: 2018.3.0
Replaced by :conf_master:`jinja_env` and :conf_master:`jinja_sls_env`
.. versionadded:: 2014.1.0
@ -2666,7 +2666,7 @@ Example:
``roots_update_interval``
*************************
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``60``
@ -2853,7 +2853,7 @@ gitfs remotes.
``gitfs_disable_saltenv_mapping``
*********************************
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``False``
@ -2876,7 +2876,7 @@ parameters <gitfs-per-saltenv-config>`.
``gitfs_ref_types``
*******************
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``['branch', 'tag', 'sha']``
@ -2908,7 +2908,7 @@ are mapped as saltenvs:
***************************
.. versionadded:: 2014.7.0
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
Renamed from ``gitfs_env_whitelist`` to ``gitfs_saltenv_whitelist``
Default: ``[]``
@ -2931,7 +2931,7 @@ information can be found in the :ref:`GitFS Walkthrough
***************************
.. versionadded:: 2014.7.0
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
Renamed from ``gitfs_env_blacklist`` to ``gitfs_saltenv_blacklist``
Default: ``[]``
@ -2983,7 +2983,7 @@ they were created by a different master.
``gitfs_update_interval``
*************************
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``60``
@ -3298,7 +3298,7 @@ bookmark should be used as the ``base`` environment.
**************************
.. versionadded:: 2014.7.0
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
Renamed from ``hgfs_env_whitelist`` to ``hgfs_saltenv_whitelist``
Default: ``[]``
@ -3328,7 +3328,7 @@ blacklist will be exposed as fileserver environments.
**************************
.. versionadded:: 2014.7.0
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
Renamed from ``hgfs_env_blacklist`` to ``hgfs_saltenv_blacklist``
Default: ``[]``
@ -3357,7 +3357,7 @@ blacklist will be exposed as fileserver environments.
``hgfs_update_interval``
************************
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``60``
@ -3525,7 +3525,7 @@ also be configured on a per-remote basis, see :conf_master:`here
***************************
.. versionadded:: 2014.7.0
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
Renamed from ``svnfs_env_whitelist`` to ``svnfs_saltenv_whitelist``
Default: ``[]``
@ -3555,7 +3555,7 @@ will be exposed as fileserver environments.
***************************
.. versionadded:: 2014.7.0
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
Renamed from ``svnfs_env_blacklist`` to ``svnfs_saltenv_blacklist``
Default: ``[]``
@ -3584,7 +3584,7 @@ will be exposed as fileserver environments.
``svnfs_update_interval``
*************************
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``60``
@ -3690,7 +3690,7 @@ exposed.
``minionfs_update_interval``
****************************
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``60``
@ -3719,7 +3719,7 @@ examples.
``azurefs_update_interval``
***************************
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``60``
@ -3741,7 +3741,7 @@ See the :mod:`s3fs documentation <salt.fileserver.s3fs>` for usage examples.
``s3fs_update_interval``
************************
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``60``

View File

@ -138,7 +138,7 @@ name) is set in the :conf_minion:`master` configuration setting.
``master_tops_first``
---------------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``False``
@ -340,7 +340,7 @@ option on the Salt master.
``source_interface_name``
-------------------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The name of the interface to use when establishing the connection to the Master.
@ -379,7 +379,7 @@ Configuration example:
``source_address``
------------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The source IP address or the domain name to be used when connecting the Minion
to the Master.
@ -404,7 +404,7 @@ Configuration example:
``source_ret_port``
-------------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The source port to be used when connecting the Minion to the Master ret server.
@ -427,7 +427,7 @@ Configuration example:
``source_publish_port``
-----------------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The source port to be used when connecting the Minion to the Master publish
server.
@ -1358,7 +1358,7 @@ The password used for HTTP proxy access.
``docker.compare_container_networks``
-------------------------------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``{'static': ['Aliases', 'Links', 'IPAMConfig'], 'automatic': ['IPAddress', 'Gateway', 'GlobalIPv6Address', 'IPv6Gateway']}``
@ -1938,7 +1938,7 @@ enabled and can be disabled by changing this value to ``False``.
``saltenv``
-----------
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
Renamed from ``environment`` to ``saltenv``. If ``environment`` is used,
``saltenv`` will take its value. If both are used, ``environment`` will be
ignored and ``saltenv`` will be used.
@ -1957,7 +1957,7 @@ environments is to isolate via the top file.
``lock_saltenv``
----------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``False``
@ -2489,7 +2489,7 @@ minion's pki directory.
``autosign_grains``
-------------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``not defined``
@ -2682,7 +2682,7 @@ executed in a thread.
``process_count_max``
-------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Default: ``-1``

View File

@ -277,6 +277,7 @@ execution modules
napalm_users
napalm_yang_mod
netaddress
netbox
netbsd_sysctl
netbsdservice
netscaler

View File

@ -0,0 +1,7 @@
==========================
salt.modules.netbox module
==========================
.. automodule:: salt.modules.netbox
:members:

View File

@ -257,7 +257,7 @@ large groups of states easily in any requisite statement.
require_any
~~~~~~~~~~~
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The use of ``require_any`` demands that one of the required states executes before the
dependent state. The state containing the ``require_any`` requisite is defined as the
@ -380,7 +380,7 @@ to Salt ensuring that the service is running.
watch_any
~~~~~~~~~
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The state containing the ``watch_any`` requisite is defined as the watching
state. The states specified in the ``watch_any`` statement are defined as the watched
@ -517,7 +517,7 @@ The ``onfail`` requisite is applied in the same way as ``require`` as ``watch``:
onfail_any
~~~~~~~~~~
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The ``onfail_any`` requisite allows for reactions to happen strictly as a response
to the failure of at least one other state. This can be used in a number of ways, such as
@ -616,7 +616,7 @@ if any of the watched states changes.
onchanges_any
~~~~~~~~~~~~~
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The ``onchanges_any`` requisite makes a state only apply one of the required states
generates changes, and if one of the watched state's "result" is ``True``. This can be

View File

@ -156,7 +156,7 @@ A State Module must return a dict containing the following keys/values:
in test mode without applying the change, ``False`` can be returned.
- **comment:** A list of strings or a single string summarizing the result.
Note that support for lists of strings is available as of Salt Oxygen.
Note that support for lists of strings is available as of Salt 2018.3.0.
Lists of strings will be joined with newlines to form the final comment;
this is useful to allow multiple comments from subparts of a state.
Prefer to keep line lengths short (use multiple lines as needed),

View File

@ -15,9 +15,16 @@ More information about Azure is located at `http://www.windowsazure.com/
Dependencies
============
* `Microsoft Azure SDK for Python <https://pypi.python.org/pypi/azure>`_ >= 2.0rc6
* `Microsoft Azure Storage SDK for Python <https://pypi.python.org/pypi/azure-storage>`_ >= 0.32
* `AutoRest swagger generator Python client runtime (Azure-specific module) <https://pypi.python.org/pypi/msrestazure>`_ >= 0.4
* `azure <https://pypi.python.org/pypi/azure>`_ >= 2.0.0rc6
* `azure-common <https://pypi.python.org/pypi/azure-common>`_ >= 1.1.4
* `azure-mgmt <https://pypi.python.org/pypi/azure-mgmt>`_ >= 0.30.0rc6
* `azure-mgmt-compute <https://pypi.python.org/pypi/azure-mgmt-compute>`_ >= 0.33.0
* `azure-mgmt-network <https://pypi.python.org/pypi/azure-mgmt-network>`_ >= 0.30.0rc6
* `azure-mgmt-resource <https://pypi.python.org/pypi/azure-mgmt-resource>`_ >= 0.30.0
* `azure-mgmt-storage <https://pypi.python.org/pypi/azure-mgmt-storage>`_ >= 0.30.0rc6
* `azure-mgmt-web <https://pypi.python.org/pypi/azure-mgmt-web>`_ >= 0.30.0rc6
* `azure-storage <https://pypi.python.org/pypi/azure-storage>`_ >= 0.32.0
* `msrestazure <https://pypi.python.org/pypi/msrestazure>`_ >= 0.4.21
* A Microsoft Azure account
* `Salt <https://github.com/saltstack/salt>`_

View File

@ -392,7 +392,7 @@ script, a cloud profile using ``file_map`` might look like:
Running Pre-Flight Commands
===========================
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
To execute specified preflight shell commands on a VM before the deploy script is
run, use the ``preflight_cmds`` option. These must be defined as a list in a cloud
@ -413,7 +413,7 @@ These commands will run in sequence **before** the bootstrap script is executed.
Force Minion Config
===================
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The ``force_minion_config`` option requests the bootstrap process to overwrite
an existing minion configuration file and public/private key files.

View File

@ -89,7 +89,7 @@ to it can be verified with Salt:
Destroy Options
---------------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
For obvious reasons, the ``destroy`` action does not actually vaporize hardware.
If the salt master is connected, it can tear down parts of the client machines.
@ -113,7 +113,7 @@ and can execute the following options:
Wake On LAN
-----------
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
In addition to connecting a hardware machine to a Salt master,
you have the option of sending a wake-on-LAN

View File

@ -286,7 +286,7 @@ Set up an initial profile at ``/etc/salt/cloud.profiles`` or
eagerly_scrub
Specifies whether the disk should be rewrite with zeros during thick provisioning or not.
Default is ``eagerly_scrub: False``.
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
controller
Specify the SCSI controller label to which this disk should be attached.
This should be specified only when creating both the specified SCSI

View File

@ -223,7 +223,7 @@ branches, and dot release branches.
.. note::
GitHub will open pull requests against Salt's main branch, ``develop``,
byndefault. Be sure to check which branch is selected when creating the
by default. Be sure to check which branch is selected when creating the
pull request.
The Develop Branch

View File

@ -58,7 +58,7 @@ States. GitFS is a quick and natural way to use Formulas.
3. Restart the Salt master.
Beginning with the Oxygen release, using formulas with GitFS is now much more
Beginning with the 2018.3.0 release, using formulas with GitFS is now much more
convenient for deployments which use many different fileserver environments
(i.e. saltenvs). Using the :ref:`all_saltenvs <gitfs-global-remotes>`
parameter, files from a single git branch/tag will appear in all environments.
@ -1258,7 +1258,7 @@ target platform, and any other installation or usage instructions or tips.
A sample skeleton for the ``README.rst`` file:
.. code-block:: rest
.. code-block:: restructuredtext
===
foo
@ -1266,10 +1266,10 @@ A sample skeleton for the ``README.rst`` file:
Install and configure the FOO service.
.. note::
**NOTE**
See the full `Salt Formulas installation and usage instructions
<http://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html>`_.
See the full `Salt Formulas installation and usage instructions
<https://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html>`_.
Available states
================
@ -1298,7 +1298,7 @@ A sample skeleton for the `CHANGELOG.rst` file:
:file:`CHANGELOG.rst`:
.. code-block:: rest
.. code-block:: restructuredtext
foo formula
===========

View File

@ -834,7 +834,7 @@ Returns:
----------
.. versionadded:: 2017.7.0
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Renamed from ``str_to_num`` to ``to_num``.
Converts a string to its numerical value.
@ -882,7 +882,7 @@ Example:
--------------------
.. versionadded:: 2017.7.0
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Renamed from ``json_decode_list`` to ``json_encode_list``. When you encode
something you get bytes, and when you decode, you get your locale's
encoding (usually a ``unicode`` type). This filter was incorrectly-named
@ -911,7 +911,7 @@ Returns:
--------------------
.. versionadded:: 2017.7.0
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Renamed from ``json_decode_dict`` to ``json_encode_dict``. When you encode
something you get bytes, and when you decode, you get your locale's
encoding (usually a ``unicode`` type). This filter was incorrectly-named
@ -942,7 +942,7 @@ Returns:
---------------
.. versionadded:: 2017.7.0
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Renamed from ``rand_str`` to ``random_hash`` to more accurately describe
what the filter does. ``rand_str`` will be supported until the Neon
release.
@ -1384,7 +1384,7 @@ Example:
.. code-block:: jinja
{{ 'www.google.com' | dns_check }}
{{ 'www.google.com' | dns_check(port=443) }}
Returns:

View File

@ -89,6 +89,6 @@ bare-bones example:
.. note::
If a master_tops module returns :ref:`top file <states-top>` data for a
given minion, it will be added to the states configured in the top file. It
will *not* replace it altogether. The Oxygen release adds additional
will *not* replace it altogether. The 2018.3.0 release adds additional
functionality allowing a minion to treat master_tops as the single source
of truth, irrespective of the top file.

View File

@ -263,16 +263,16 @@ To execute with pillar data.
Return Codes in Runner/Wheel Jobs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
State (``salt.state``) jobs are able to report failure via the :ref:`state
return dictionary <state-return-data>`. Remote execution (``salt.function``)
jobs are able to report failure by setting a ``retcode`` key in the
``__context__`` dictionary. However, runner (``salt.runner``) and wheel
(``salt.wheel``) jobs would only report a ``False`` result when the
runner/wheel function raised an exception. As of the Oxygen release, it is now
possible to set a retcode in runner and wheel functions just as you can do in
remote execution functions. Here is some example pseudocode:
runner/wheel function raised an exception. As of the 2018.3.0 release, it is
now possible to set a retcode in runner and wheel functions just as you can do
in remote execution functions. Here is some example pseudocode:
.. code-block:: python
@ -332,10 +332,9 @@ Given the above setup, the orchestration will be carried out as follows:
3. Finally, the ``ceph`` SLS target will be executed on all minions which have
a grain called ``role`` with a value of ``storage``.
.. note::
Remember, salt-run is always executed on the master.
Remember, salt-run is *always* executed on the master.
.. _orchestrate-runner-parsing-results-programatically:
@ -591,11 +590,11 @@ loadable and parsable format:
}
The Oxygen release includes a couple fixes to make parsing this data easier and
The 2018.3.0 release includes a couple fixes to make parsing this data easier and
more accurate. The first is the ability to set a :ref:`return code
<orchestrate-runner-return-codes-runner-wheel>` in a custom runner or wheel
function, as noted above. The second is a change to how failures are included
in the return data. Prior to the Oxygen release, minions that failed a
in the return data. Prior to the 2018.3.0 release, minions that failed a
``salt.state`` orchestration job would show up in the ``comment`` field of the
return data, in a human-readable string that was not easily parsed. They are
now included in the ``changes`` dictionary alongside the minions that
@ -603,3 +602,32 @@ succeeded. In addition, ``salt.function`` jobs which failed because the
:ref:`fail function <orchestrate-runner-fail-functions>` returned ``False``
used to handle their failures in the same way ``salt.state`` jobs did, and this
has likewise been corrected.
Running States on the Master without a Minion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The orchestrate runner can be used to execute states on the master without
using a minion. For example, assume that ``salt://foo.sls`` contains the
following SLS:
.. code-block:: yaml
/etc/foo.conf:
file.managed:
- source: salt://files/foo.conf
- mode: 0600
In this case, running ``salt-run state.orchestrate foo`` would be the
equivalent of running a ``state.sls foo``, but it would execute on the master
only, and would not require a minion daemon to be running on the master.
This is not technically orchestration, but it can be useful in certain use
cases.
Limitations
^^^^^^^^^^^
Only one SLS target can be run at a time using this method, while using
:py:func:`state.sls <salt.modules.state.sls>` allows for multiple SLS files to
be passed in a comma-separated list.

View File

@ -157,7 +157,8 @@ will need to be restarted to pick up any changes. A corresponding utility funct
In addition, a salt.utils helper function called `is_proxy()` was added to make
it easier to tell when the running minion is a proxy minion. **NOTE: This
function was renamed to salt.utils.platform.is_proxy() for the Oxygen release**
function was renamed to salt.utils.platform.is_proxy() for the 2018.3.0
release**
New in 2015.8
-------------

View File

@ -115,11 +115,10 @@ Name Description
============================== ==================================================================================
.. note::
The ``local`` and ``caller`` reaction types will be renamed for the Oxygen
release. These reaction types were named after Salt's internal client
interfaces, and are not intuitively named. Both ``local`` and ``caller``
will continue to work in Reactor SLS files, but for the Oxygen release the
documentation will be updated to reflect the new preferred naming.
The ``local`` and ``caller`` reaction types will likely be renamed in a
future release. These reaction types were named after Salt's internal
client interfaces, and are not intuitively named. Both ``local`` and
``caller`` will continue to work in Reactor SLS files, however.
Where to Put Reactor SLS Files
==============================

View File

@ -2,7 +2,7 @@
Salt 2016.11.9 Release Notes
============================
Version 2016.11.9 is a bugfix release for :ref:`2016.11.0 <release-2016-11-0>`.]
Version 2016.11.9 is a bugfix release for :ref:`2016.11.0 <release-2016-11-0>`.
Changes for v2016.11.8..v2016.11.9
----------------------------------------------------------------

View File

@ -0,0 +1,112 @@
===========================
Salt 2017.7.4 Release Notes
===========================
Version 2017.7.4 is a bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.
Changes for v2017.7.3..v2017.7.4
---------------------------------------------------------------
Extended changelog courtesy of Todd Stansell (https://github.com/tjstansell/salt-changelogs):
*Generated at: 2018-02-16T16:44:38Z*
Statistics:
- Total Merges: **7**
- Total Issue references: **4**
- Total PR references: **11**
Changes:
- **PR** `#46066`_: (*rallytime*) Pin tornado version in requirements file
@ *2018-02-16T16:40:05Z*
- **ISSUE** `#45790`_: (*bdarnell*) Test with Tornado 5.0b1
| refs: `#46066`_
* 32f3d00e44 Merge pull request `#46066`_ from rallytime/pin-tornado
* 6dc1a3b9dc Pin tornado version in requirements file
- **PR** `#46036`_: (*terminalmage*) git.latest: Fix regression with identity file usage
@ *2018-02-16T13:57:23Z*
* 85761ee650 Merge pull request `#46036`_ from terminalmage/issue43769
* e2140d9a84 Mock the ssh.key_is_encrypted utils func
* 169924b3fe Move ssh.key_is_encrypted to a utils module temporarily
* 54f4d78f7a Only keep ssh.py in the Windows installer
* 5f04531e1b Keep ssh state and execution modules in the installer
* f2b69f703d git.latest: Fix regression with identity file usage
- **PR** `#46009`_: (*Ch3LL*) Add 2017.7.4 Release Notes with PRs
@ *2018-02-13T16:40:30Z*
* 6d534c6e7e Merge pull request `#46009`_ from Ch3LL/rn_7.4
* ac0baf4b34 Add 2017.7.4 Release Notes with PRs
- **PR** `#45981`_: (*gtmanfred*) use local config for vault when masterless
@ *2018-02-13T15:22:01Z*
- **ISSUE** `#45976`_: (*grobinson-blockchain*) 6a5e0f9 introduces regression that breaks Vault module for salt masterless
| refs: `#45981`_
* ca76a0b328 Merge pull request `#45981`_ from gtmanfred/2017.7.3
* 0d448457dc apparently local is not set by default
* 2a92f4bc16 use local config for vault when masterless
- **PR** `#45953`_: (*rallytime*) Back-port `#45928`_ to 2017.7.3
@ *2018-02-09T22:29:10Z*
- **ISSUE** `#45915`_: (*MatthiasKuehneEllerhold*) 2017.7.3: Salt-SSH & Vault Pillar: Permission denied "minion.pem"
| refs: `#45928`_
- **PR** `#45928`_: (*garethgreenaway*) [2017.7] Fixing vault when used with pillar over salt-ssh
| refs: `#45953`_
* 6530649dbc Merge pull request `#45953`_ from rallytime/`bp-45928`_-2017.7.3
* 85363189d1 Fixing vault when used with pillar over salt-ssh
- **PR** `#45934`_: (*rallytime*) Back-port `#45902`_ to 2017.7.3
@ *2018-02-09T16:31:08Z*
- **ISSUE** `#45893`_: (*CrackerJackMack*) archive.extracted ValueError "No path specified" in 2017.7.3
| refs: `#45902`_
- **PR** `#45902`_: (*terminalmage*) Check the effective saltenv for cached archive
| refs: `#45934`_
* fb378cebb0 Merge pull request `#45934`_ from rallytime/`bp-45902`_
* bb83e8b345 Add regression test for issue 45893
* cdda66d759 Remove duplicated section in docstring and fix example
* 4b6351cda6 Check the effective saltenv for cached archive
- **PR** `#45935`_: (*rallytime*) Back-port `#45742`_ to 2017.7.3
@ *2018-02-09T14:02:26Z*
- **PR** `#45742`_: (*marccardinal*) list.copy() is not compatible with python 2.7
| refs: `#45935`_
* 0d74151c71 Merge pull request `#45935`_ from rallytime/`bp-45742`_
* 6a0b5f7af3 Removed the chained copy
* ad1150fad4 list.copy() is not compatible with python 2.7
.. _`#45742`: https://github.com/saltstack/salt/pull/45742
.. _`#45790`: https://github.com/saltstack/salt/issues/45790
.. _`#45893`: https://github.com/saltstack/salt/issues/45893
.. _`#45902`: https://github.com/saltstack/salt/pull/45902
.. _`#45915`: https://github.com/saltstack/salt/issues/45915
.. _`#45928`: https://github.com/saltstack/salt/pull/45928
.. _`#45934`: https://github.com/saltstack/salt/pull/45934
.. _`#45935`: https://github.com/saltstack/salt/pull/45935
.. _`#45953`: https://github.com/saltstack/salt/pull/45953
.. _`#45976`: https://github.com/saltstack/salt/issues/45976
.. _`#45981`: https://github.com/saltstack/salt/pull/45981
.. _`#46009`: https://github.com/saltstack/salt/pull/46009
.. _`#46036`: https://github.com/saltstack/salt/pull/46036
.. _`#46066`: https://github.com/saltstack/salt/pull/46066
.. _`bp-45742`: https://github.com/saltstack/salt/pull/45742
.. _`bp-45902`: https://github.com/saltstack/salt/pull/45902
.. _`bp-45928`: https://github.com/saltstack/salt/pull/45928

View File

@ -0,0 +1,5 @@
===========================
Salt 2017.7.5 Release Notes
===========================
Version 2017.7.5 is a bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.

View File

@ -1,8 +1,8 @@
:orphan:
.. _release-2018-3-0:
====================================
Salt Release Notes - Codename Oxygen
====================================
=============================================
Salt 2018.3.0 Release Notes - Codename Oxygen
=============================================
Lots of Docker Improvements
---------------------------
@ -79,7 +79,7 @@ with release Neon.
The functions have been moved as follows:
- ``salt.utils.appendproctitle``: use ``salt.utils.process.appendproctitle``
- ``salt.utils.appendproctitle``: use ``salt.utils.process.appendproctitle``
instead.
- ``salt.utils.daemonize``: use ``salt.utils.process.daemonize`` instead.
- ``salt.utils.daemonize_if``: use ``salt.utils.process.daemonize_if`` instead.
@ -94,22 +94,22 @@ The functions have been moved as follows:
- ``salt.utils.is_hex``: use ``salt.utils.stringutils.is_hex`` instead.
- ``salt.utils.is_bin_str``: use ``salt.utils.stringutils.is_bin_str`` instead.
- ``salt.utils.rand_string``: use ``salt.utils.stringutils.random`` instead.
- ``salt.utils.contains_whitespace``: use
- ``salt.utils.contains_whitespace``: use
``salt.utils.stringutils.contains_whitespace`` instead.
- ``salt.utils.build_whitespace_split_regex``: use
- ``salt.utils.build_whitespace_split_regex``: use
``salt.utils.stringutils.build_whitespace_split_regex`` instead.
- ``salt.utils.expr_match``: use ``salt.utils.stringutils.expr_match`` instead.
- ``salt.utils.check_whitelist_blacklist``: use
- ``salt.utils.check_whitelist_blacklist``: use
``salt.utils.stringutils.check_whitelist_blacklist`` instead.
- ``salt.utils.check_include_exclude``: use
- ``salt.utils.check_include_exclude``: use
``salt.utils.stringutils.check_include_exclude`` instead.
- ``salt.utils.print_cli``: use ``salt.utils.stringutils.print_cli`` instead.
- ``salt.utils.clean_kwargs``: use ``salt.utils.args.clean_kwargs`` instead.
- ``salt.utils.invalid_kwargs``: use ``salt.utils.args.invalid_kwargs``
- ``salt.utils.invalid_kwargs``: use ``salt.utils.args.invalid_kwargs``
instead.
- ``salt.utils.shlex_split``: use ``salt.utils.args.shlex_split`` instead.
- ``salt.utils.arg_lookup``: use ``salt.utils.args.arg_lookup`` instead.
- ``salt.utils.argspec_report``: use ``salt.utils.args.argspec_report``
- ``salt.utils.argspec_report``: use ``salt.utils.args.argspec_report``
instead.
- ``salt.utils.split_input``: use ``salt.utils.args.split_input`` instead.
- ``salt.utils.test_mode``: use ``salt.utils.args.test_mode`` instead.
@ -118,7 +118,7 @@ The functions have been moved as follows:
- ``salt.utils.which_bin``: use ``salt.utils.path.which_bin`` instead.
- ``salt.utils.path_join``: use ``salt.utils.path.join`` instead.
- ``salt.utils.check_or_die``: use ``salt.utils.path.check_or_die`` instead.
- ``salt.utils.sanitize_win_path_string``: use
- ``salt.utils.sanitize_win_path_string``: use
``salt.utils.path.sanitize_win_path`` instead.
- ``salt.utils.rand_str``: use ``salt.utils.hashutils.random_hash`` instead.
- ``salt.utils.get_hash``: use ``salt.utils.hashutils.get_hash`` instead.
@ -128,9 +128,9 @@ The functions have been moved as follows:
- ``salt.utils.is_darwin``: use ``salt.utils.platform.is_darwin`` instead.
- ``salt.utils.is_sunos``: use ``salt.utils.platform.is_sunos`` instead.
- ``salt.utils.is_smartos``: use ``salt.utils.platform.is_smartos`` instead.
- ``salt.utils.is_smartos_globalzone``: use
- ``salt.utils.is_smartos_globalzone``: use
``salt.utils.platform.is_smartos_globalzone`` instead.
- ``salt.utils.is_smartos_zone``: use ``salt.utils.platform.is_smartos_zone``
- ``salt.utils.is_smartos_zone``: use ``salt.utils.platform.is_smartos_zone``
instead.
- ``salt.utils.is_freebsd``: use ``salt.utils.platform.is_freebsd`` instead.
- ``salt.utils.is_netbsd``: use ``salt.utils.platform.is_netbsd`` instead.
@ -147,55 +147,55 @@ The functions have been moved as follows:
- ``salt.utils.is_bin_file``: use ``salt.utils.files.is_binary`` instead.
- ``salt.utils.list_files``: use ``salt.utils.files.list_files`` instead.
- ``salt.utils.safe_walk``: use ``salt.utils.files.safe_walk`` instead.
- ``salt.utils.st_mode_to_octal``: use ``salt.utils.files.st_mode_to_octal``
- ``salt.utils.st_mode_to_octal``: use ``salt.utils.files.st_mode_to_octal``
instead.
- ``salt.utils.normalize_mode``: use ``salt.utils.files.normalize_mode``
- ``salt.utils.normalize_mode``: use ``salt.utils.files.normalize_mode``
instead.
- ``salt.utils.human_size_to_bytes``: use
- ``salt.utils.human_size_to_bytes``: use
``salt.utils.files.human_size_to_bytes`` instead.
- ``salt.utils.backup_minion``: use ``salt.utils.files.backup_minion`` instead.
- ``salt.utils.str_version_to_evr``: use ``salt.utils.pkg.rpm.version_to_evr``
instead.
- ``salt.utils.parse_docstring``: use ``salt.utils.doc.parse_docstring``
- ``salt.utils.parse_docstring``: use ``salt.utils.doc.parse_docstring``
instead.
- ``salt.utils.compare_versions``: use ``salt.utils.versions.compare`` instead.
- ``salt.utils.version_cmp``: use ``salt.utils.versions.version_cmp`` instead.
- ``salt.utils.warn_until``: use ``salt.utils.versions.warn_until`` instead.
- ``salt.utils.kwargs_warn_until``: use
- ``salt.utils.kwargs_warn_until``: use
``salt.utils.versions.kwargs_warn_until`` instead.
- ``salt.utils.get_color_theme``: use ``salt.utils.color.get_color_theme``
- ``salt.utils.get_color_theme``: use ``salt.utils.color.get_color_theme``
instead.
- ``salt.utils.get_colors``: use ``salt.utils.color.get_colors`` instead.
- ``salt.utils.gen_state_tag``: use ``salt.utils.state.gen_tag`` instead.
- ``salt.utils.search_onfail_requisites``: use
- ``salt.utils.search_onfail_requisites``: use
``salt.utils.state.search_onfail_requisites`` instead.
- ``salt.utils.check_state_result``: use ``salt.utils.state.check_result``
- ``salt.utils.check_state_result``: use ``salt.utils.state.check_result``
instead.
- ``salt.utils.get_user``: use ``salt.utils.user.get_user`` instead.
- ``salt.utils.get_uid``: use ``salt.utils.user.get_uid`` instead.
- ``salt.utils.get_specific_user``: use ``salt.utils.user.get_specific_user``
- ``salt.utils.get_specific_user``: use ``salt.utils.user.get_specific_user``
instead.
- ``salt.utils.chugid``: use ``salt.utils.user.chugid`` instead.
- ``salt.utils.chugid_and_umask``: use ``salt.utils.user.chugid_and_umask``
- ``salt.utils.chugid_and_umask``: use ``salt.utils.user.chugid_and_umask``
instead.
- ``salt.utils.get_default_group``: use ``salt.utils.user.get_default_group``
- ``salt.utils.get_default_group``: use ``salt.utils.user.get_default_group``
instead.
- ``salt.utils.get_group_list``: use ``salt.utils.user.get_group_list``
- ``salt.utils.get_group_list``: use ``salt.utils.user.get_group_list``
instead.
- ``salt.utils.get_group_dict``: use ``salt.utils.user.get_group_dict``
- ``salt.utils.get_group_dict``: use ``salt.utils.user.get_group_dict``
instead.
- ``salt.utils.get_gid_list``: use ``salt.utils.user.get_gid_list`` instead.
- ``salt.utils.get_gid``: use ``salt.utils.user.get_gid`` instead.
- ``salt.utils.enable_ctrl_logoff_handler``: use
- ``salt.utils.enable_ctrl_logoff_handler``: use
``salt.utils.win_functions.enable_ctrl_logoff_handler`` instead.
- ``salt.utils.traverse_dict``: use ``salt.utils.data.traverse_dict`` instead.
- ``salt.utils.traverse_dict_and_list``: use
- ``salt.utils.traverse_dict_and_list``: use
``salt.utils.data.traverse_dict_and_list`` instead.
- ``salt.utils.filter_by``: use ``salt.utils.data.filter_by`` instead.
- ``salt.utils.subdict_match``: use ``salt.utils.data.subdict_match`` instead.
- ``salt.utils.substr_in_list``: use ``salt.utils.data.substr_in_list`` instead.
- ``salt.utils.is_dictlist``: use ``salt.utils.data.is_dictlist``.
- ``salt.utils.repack_dictlist``: use ``salt.utils.data.repack_dictlist``
- ``salt.utils.repack_dictlist``: use ``salt.utils.data.repack_dictlist``
instead.
- ``salt.utils.compare_dicts``: use ``salt.utils.data.compare_dicts`` instead.
- ``salt.utils.compare_lists``: use ``salt.utils.data.compare_lists`` instead.
@ -208,33 +208,33 @@ The functions have been moved as follows:
- ``salt.utils.isorted``: use ``salt.utils.data.sorted_ignorecase`` instead.
- ``salt.utils.is_true``: use ``salt.utils.data.is_true`` instead.
- ``salt.utils.mysql_to_dict``: use ``salt.utils.data.mysql_to_dict`` instead.
- ``salt.utils.simple_types_filter``: use
- ``salt.utils.simple_types_filter``: use
``salt.utils.data.simple_types_filter`` instead.
- ``salt.utils.ip_bracket``: use ``salt.utils.zeromq.ip_bracket`` instead.
- ``salt.utils.gen_mac``: use ``salt.utils.network.gen_mac`` instead.
- ``salt.utils.mac_str_to_bytes``: use ``salt.utils.network.mac_str_to_bytes``
- ``salt.utils.mac_str_to_bytes``: use ``salt.utils.network.mac_str_to_bytes``
instead.
- ``salt.utils.refresh_dns``: use ``salt.utils.network.refresh_dns`` instead.
- ``salt.utils.dns_check``: use ``salt.utils.network.dns_check`` instead.
- ``salt.utils.get_context``: use ``salt.utils.templates.get_context`` instead.
- ``salt.utils.get_master_key``: use ``salt.utils.master.get_master_key``
- ``salt.utils.get_context``: use ``salt.utils.stringutils.get_context`` instead.
- ``salt.utils.get_master_key``: use ``salt.utils.master.get_master_key``
instead.
- ``salt.utils.get_values_of_matching_keys``: use
- ``salt.utils.get_values_of_matching_keys``: use
``salt.utils.master.get_values_of_matching_keys`` instead.
- ``salt.utils.date_cast``: use ``salt.utils.dateutils.date_cast`` instead.
- ``salt.utils.date_format``: use ``salt.utils.dateutils.strftime`` instead.
- ``salt.utils.total_seconds``: use ``salt.utils.dateutils.total_seconds``
- ``salt.utils.total_seconds``: use ``salt.utils.dateutils.total_seconds``
instead.
- ``salt.utils.find_json``: use ``salt.utils.json.find_json`` instead.
- ``salt.utils.import_json``: use ``salt.utils.json.import_json`` instead.
- ``salt.utils.namespaced_function``: use
- ``salt.utils.namespaced_function``: use
``salt.utils.functools.namespaced_function`` instead.
- ``salt.utils.alias_function``: use ``salt.utils.functools.alias_function``
- ``salt.utils.alias_function``: use ``salt.utils.functools.alias_function``
instead.
- ``salt.utils.profile_func``: use ``salt.utils.profile.profile_func`` instead.
- ``salt.utils.activate_profile``: use ``salt.utils.profile.activate_profile``
- ``salt.utils.activate_profile``: use ``salt.utils.profile.activate_profile``
instead.
- ``salt.utils.output_profile``: use ``salt.utils.profile.output_profile``
- ``salt.utils.output_profile``: use ``salt.utils.profile.output_profile``
instead.
State and Execution Module Support for ``docker run`` Functionality
@ -353,7 +353,7 @@ Prior to this release, fileservers would be updated as part of a dedicated
performed. This tied the update interval to the :conf_master:`loop_interval`
config option, and also forced all fileservers to update at the same interval.
Oxygen adds the following configuration options for the various fileserver
2018.3.0 adds the following configuration options for the various fileserver
backends:
- :conf_master:`roots_update_interval`
@ -1680,8 +1680,8 @@ Utils Deprecations
The ``salt.utils.cloud.py`` file had the following change:
- The ``fire_event`` function now requires a ``sock_dir`` argument. It was previously
optional.
- The ``fire_event`` function now requires a ``sock_dir`` argument. It was
previously optional.
Other Miscellaneous Deprecations
================================
@ -1690,9 +1690,9 @@ The ``version.py`` file had the following changes:
- The ``rc_info`` function was removed. Please use ``pre_info`` instead.
Warnings for moving away from the ``env`` option were removed. ``saltenv`` should be
used instead. The removal of these warnings does not have a behavior change. Only
the warning text was removed.
Warnings for moving away from the ``env`` option were removed. ``saltenv``
should be used instead. The removal of these warnings does not have a behavior
change. Only the warning text was removed.
Sentry Log Handler
------------------
@ -1705,6 +1705,6 @@ RAET transport
--------------
We haven't been doing development on RAET for quite some time and decided that
Oxygen is the time to announce the deprecation. RAET support will be removed in
Neon. Please consider to move to ``zeromq`` or ``tcp`` transport instead of
2018.3.0 is the time to announce the deprecation. RAET support will be removed
in Neon. Please consider to move to ``zeromq`` or ``tcp`` transport instead of
``raet``.

View File

@ -20,6 +20,7 @@ Previous Releases
:maxdepth: 1
:glob:
2018.3.*
2017.7.*
2016.11.*
2016.3.*

View File

@ -8,7 +8,7 @@ Installing/Testing a Salt Release Candidate
It's time for a new feature release of Salt! Follow the instructions below to
install the latest release candidate of Salt, and try :ref:`all the shiny new
features <release-2017-7-0>`! Be sure to report any bugs you find on `Github
features <release-2018-3-0>`! Be sure to report any bugs you find on `Github
<https://github.com/saltstack/salt/issues/new/>`_.
Installing Using Packages
@ -47,14 +47,14 @@ You can install a release candidate of Salt using `Salt Bootstrap
.. code-block:: bash
curl -o install_salt.sh -L https://bootstrap.saltstack.com
sudo sh install_salt.sh -P git v2017.7.0rc1
sudo sh install_salt.sh -P git v2018.3.0rc1
If you want to also install a master using Salt Bootstrap, use the ``-M`` flag:
.. code-block:: bash
curl -o install_salt.sh -L https://bootstrap.saltstack.com
sudo sh install_salt.sh -P -M git v2017.7.0rc1
sudo sh install_salt.sh -P -M git v2018.3.0rc1
If you want to install only a master and not a minion using Salt Bootstrap, use
the ``-M`` and ``-N`` flags:
@ -62,13 +62,13 @@ the ``-M`` and ``-N`` flags:
.. code-block:: bash
curl -o install_salt.sh -L https://bootstrap.saltstack.com
sudo sh install_salt.sh -P -M -N git v2017.7.0rc1
sudo sh install_salt.sh -P -M -N git v2018.3.0rc1
Installing Using PyPI
=====================
Installing from the `source archive
<https://pypi.python.org/packages/5c/cf/13c14f8bcd7b5076b9a8c3580f9582c1c4ea8b0458793ac6744ea66c0baf/salt-2017.7.0rc1.tar.gz>`_ on
<https://pypi.python.org/pypi?:action=display&name=salt&version=2018.3.0rc1>`_ on
`PyPI <https://pypi.python.org/pypi>`_ is fairly straightforward.
.. note::
@ -106,4 +106,4 @@ Then install salt using the following command:
.. code-block:: bash
sudo pip install salt==2017.7.0rc1
sudo pip install salt==2018.3.0rc1

View File

@ -34,7 +34,7 @@ Assigned codenames:
- Boron: ``2016.3.0``
- Carbon: ``2016.11.0``
- Nitrogen: ``2017.7.0``
- Oxygen: ``TBD``
- Oxygen: ``2018.3.0``
- Fluorine: ``TBD``
Example
@ -69,10 +69,10 @@ Example arguments for `git checkout`:
+------------+----------------------------------------------------------------------------+
| v2016.11.1 | Tag signaling the commit that the 2016.11.1 release is based on. |
+------------+----------------------------------------------------------------------------+
Further reading on `release branch and develop branch
Further reading on `release branch and develop branch
<https://docs.saltstack.com/en/latest/topics/development/contributing.html#which-salt-branch>`_.
Influence of the `git checkout` argument on `git describe`:
+------------+----------------------------+-----------------------------------------------+
@ -97,4 +97,4 @@ Some details of v2016.11.1-220-g9a1550d (from `git describe` after `git checkout
|220 | Commits on top of the most recent tag, relative to your local git fetch |
+---------------+-------------------------------------------------------------------------+
|gf2eb3dc | 'g' + git SHA ("abbreviated name") of the most recent commit |
+---------------+-------------------------------------------------------------------------+
+---------------+-------------------------------------------------------------------------+

View File

@ -4,7 +4,7 @@
Slots
=====
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
.. note:: This functionality is under development and could be changed in the
future releases

View File

@ -4,7 +4,7 @@
Autoaccept minions from Grains
==============================
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
To automatically accept minions based on certain characteristics, e.g. the ``uuid``
you can specify certain grain values on the salt master. Minions with matching grains

View File

@ -196,7 +196,7 @@ master:
- gitfs
.. note::
``git`` also works here. Prior to the Oxygen release, *only* ``git``
``git`` also works here. Prior to the 2018.3.0 release, *only* ``git``
would work.
2. Specify one or more ``git://``, ``https://``, ``file://``, or ``ssh://``
@ -314,9 +314,9 @@ configured gitfs remotes):
* :conf_master:`gitfs_privkey` (**pygit2 only**, new in 2014.7.0)
* :conf_master:`gitfs_passphrase` (**pygit2 only**, new in 2014.7.0)
* :conf_master:`gitfs_refspecs` (new in 2017.7.0)
* :conf_master:`gitfs_disable_saltenv_mapping` (new in Oxygen)
* :conf_master:`gitfs_ref_types` (new in Oxygen)
* :conf_master:`gitfs_update_interval` (new in Oxygen)
* :conf_master:`gitfs_disable_saltenv_mapping` (new in 2018.3.0)
* :conf_master:`gitfs_ref_types` (new in 2018.3.0)
* :conf_master:`gitfs_update_interval` (new in 2018.3.0)
.. note::
pygit2 only supports disabling SSL verification in versions 0.23.2 and
@ -370,7 +370,7 @@ tremendous amount of customization. Here's some example usage:
``name``, ``saltenv``, and ``all_saltenvs`` parameters, which are only
available to per-remote configurations.
The ``all_saltenvs`` parameter is new in the Oxygen release.
The ``all_saltenvs`` parameter is new in the 2018.3.0 release.
In the example configuration above, the following is true:
@ -526,7 +526,7 @@ would only fetch branches and tags (the default).
Global Remotes
==============
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The ``all_saltenvs`` per-remote configuration parameter overrides the logic
Salt uses to map branches/tags to fileserver environments (i.e. saltenvs). This
@ -553,7 +553,7 @@ single branch.
Update Intervals
================
Prior to the Oxygen release, GitFS would update its fileserver backends as part
Prior to the 2018.3.0 release, GitFS would update its fileserver backends as part
of a dedicated "maintenance" process, in which various routine maintenance
tasks were performed. This tied the update interval to the
:conf_master:`loop_interval` config option, and also forced all fileservers to

View File

@ -4,7 +4,7 @@
Using Apache Libcloud for declarative and procedural multi-cloud orchestration
==============================================================================
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
.. note::

View File

@ -86,8 +86,8 @@ option on the master:
- minionfs
.. note::
``minion`` also works here. Prior to the Oxygen release, *only* ``minion``
would work.
``minion`` also works here. Prior to the 2018.3.0 release, *only*
``minion`` would work.
Also, as described earlier, ``file_recv: True`` is needed to enable the
master to receive files pushed from minions. As always, changes to the

View File

@ -81,7 +81,7 @@ the ``foo`` utility module with a ``__virtual__`` function.
def bar():
return 'baz'
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Instantiating objects from classes declared in util modules works with
Master side modules, such as Runners, Outputters, etc.

View File

@ -302,25 +302,30 @@ can define multiple versions for the same piece of software. The lines following
the version are indented two more spaces and contain all the information needed
to install that package.
.. warning:: The package name and the ``full_name`` must be unique to all
other packages in the software repository.
.. warning::
The package name and the ``full_name`` must be unique to all other packages
in the software repository.
The version line is the version for the package to be installed. It is used when
you need to install a specific version of a piece of software.
.. warning:: The version must be enclosed in quotes, otherwise the yaml parser
will remove trailing zeros.
.. warning::
The version must be enclosed in quotes, otherwise the yaml parser will
remove trailing zeros.
.. note::
There are unique situations where previous versions are unavailable. Take
Google Chrome for example. There is only one url provided for a standalone
installation of Google Chrome.
.. note:: There are unique situations where previous versions are unavailable.
Take Google Chrome for example. There is only one url provided for a
standalone installation of Google Chrome.
(https://dl.google.com/edgedl/chrome/install/GoogleChromeStandaloneEnterprise.msi)
When a new version is released, the url just points to the new version. To
handle situations such as these, set the version to `latest`. Salt will
install the version of Chrome at the URL and report that version. Here's an
example:
.. code-block:: bash
.. code-block:: yaml
chrome:
latest:
@ -335,200 +340,237 @@ you need to install a specific version of a piece of software.
Available parameters are as follows:
:param str full_name: The Full Name for the software as shown in "Programs and
Features" in the control panel. You can also get this information by
installing the package manually and then running ``pkg.list_pkgs``. Here's
an example of the output from ``pkg.list_pkgs``:
:param str full_name:
The Full Name for the software as shown in "Programs and Features" in the
control panel. You can also get this information by installing the package
manually and then running ``pkg.list_pkgs``. Here's an example of the output
from ``pkg.list_pkgs``:
.. code-block:: bash
.. code-block:: bash
salt 'test-2008' pkg.list_pkgs
test-2008
----------
7-Zip 9.20 (x64 edition):
9.20.00.0
Microsoft .NET Framework 4 Client Profile:
4.0.30319,4.0.30319
Microsoft .NET Framework 4 Extended:
4.0.30319,4.0.30319
Microsoft Visual C++ 2008 Redistributable - x64 9.0.21022:
9.0.21022
Mozilla Firefox 17.0.1 (x86 en-US):
17.0.1
Mozilla Maintenance Service:
17.0.1
NSClient++ (x64):
0.3.8.76
Notepad++:
6.4.2
Salt Minion 0.16.0:
0.16.0
salt 'test-2008' pkg.list_pkgs
test-2008
----------
7-Zip 9.20 (x64 edition):
9.20.00.0
Microsoft .NET Framework 4 Client Profile:
4.0.30319,4.0.30319
Microsoft .NET Framework 4 Extended:
4.0.30319,4.0.30319
Microsoft Visual C++ 2008 Redistributable - x64 9.0.21022:
9.0.21022
Mozilla Firefox 17.0.1 (x86 en-US):
17.0.1
Mozilla Maintenance Service:
17.0.1
NSClient++ (x64):
0.3.8.76
Notepad++:
6.4.2
Salt Minion 0.16.0:
0.16.0
Notice the Full Name for Firefox: Mozilla Firefox 17.0.0 (x86 en-US). That's
exactly what's in the ``full_name`` parameter in the software definition file.
Notice the Full Name for Firefox: ``Mozilla Firefox 17.0.0 (x86 en-US)``.
That's exactly what's in the ``full_name`` parameter in the software
definition file.
If any of the software insalled on the machine matches one of the software
definition files in the repository the full_name will be automatically renamed
to the package name. The example below shows the ``pkg.list_pkgs`` for a
machine that already has Mozilla Firefox 17.0.1 installed.
If any of the software installed on the machine matches one of the software
definition files in the repository, the full_name will be automatically
renamed to the package name. The example below shows the ``pkg.list_pkgs``
for a machine that already has Mozilla Firefox 17.0.1 installed.
.. code-block:: bash
.. code-block:: bash
test-2008:
----------
7zip:
9.20.00.0
Microsoft .NET Framework 4 Client Profile:
4.0.30319,4.0.30319
Microsoft .NET Framework 4 Extended:
4.0.30319,4.0.30319
Microsoft Visual C++ 2008 Redistributable - x64 9.0.21022:
9.0.21022
Mozilla Maintenance Service:
17.0.1
Notepad++:
6.4.2
Salt Minion 0.16.0:
0.16.0
firefox:
17.0.1
nsclient:
0.3.9.328
.. important::
The version number and ``full_name`` need to match the output from
``pkg.list_pkgs`` so that the status can be verified when running a
highstate.
.. note::
It is still possible to successfully install packages using
``pkg.install``, even if the ``full_name`` or the version number don't
match. However, this can make troubleshooting issues difficult, so be
careful.
.. tip::
To force salt to display the full name when there's already an existing
package definition file on the system, you can pass a bogus ``saltenv``
parameter to the command like so: ``pkg.list_pkgs saltenv=NotARealEnv``
:param str installer:
The path to the ``.exe`` or ``.msi`` to use to install the package. This can
be a path or a URL. If it is a URL or a salt path (``salt://``), the package
will be cached locally and then executed. If it is a path to a file on disk
or a file share, it will be executed directly.
.. note::
If storing software in the same location as the winrepo it is best
practice to place each installer in its own directory rather than the
root of winrepo. Then you can place your package definition file in the
same directory. It is best practice to name the file ``init.sls``. This
will be picked up by ``pkg.refresh_db`` and processed properly.
:param str install_flags:
Any flags that need to be passed to the installer to make it perform a
silent install. These can often be found by adding ``/?`` or ``/h`` when
running the installer from the command-line. A great resource for finding
these silent install flags can be found on the WPKG project's wiki_:
.. warning::
Salt will not return if the installer is waiting for user input so it is
imperative that the software package being installed has the ability to
install silently.
:param str uninstaller:
The path to the program used to uninstall this software. This can be the
path to the same `exe` or `msi` used to install the software. It can also be
a GUID. You can find this value in the registry under the following keys:
- Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall
- Software\\Wow6432None\\Microsoft\\Windows\\CurrentVersion\\Uninstall
:param str uninstall_flags:
Any flags that need to be passed to the uninstaller to make it perform a
silent uninstall. These can often be found by adding ``/?`` or ``/h`` when
running the uninstaller from the command-line. A great resource for finding
these silent install flags can be found on the WPKG project's wiki_:
.. warning::
Salt will not return if the uninstaller is waiting for user input so it
is imperative that the software package being uninstalled has the
ability to uninstall silently.
Here are some examples of installer and uninstaller settings:
.. code-block:: yaml
test-2008:
----------
7zip:
9.20.00.0
Microsoft .NET Framework 4 Client Profile:
4.0.30319,4.0.30319
Microsoft .NET Framework 4 Extended:
4.0.30319,4.0.30319
Microsoft Visual C++ 2008 Redistributable - x64 9.0.21022:
9.0.21022
Mozilla Maintenance Service:
17.0.1
Notepad++:
6.4.2
Salt Minion 0.16.0:
0.16.0
firefox:
17.0.1
nsclient:
0.3.9.328
'9.20.00.0':
installer: salt://win/repo/7zip/7z920-x64.msi
full_name: 7-Zip 9.20 (x64 edition)
reboot: False
install_flags: '/qn /norestart'
msiexec: True
uninstaller: '{23170F69-40C1-2702-0920-000001000000}'
uninstall_flags: '/qn /norestart'
.. important:: The version number and ``full_name`` need to match the output
from ``pkg.list_pkgs`` so that the status can be verified when running
highstate.
Alternatively the ``uninstaller`` can also simply repeat the URL of an msi
file:
.. note:: It is still possible to successfully install packages using
``pkg.install`` even if they don't match. This can make troubleshooting
difficult so be careful.
.. code-block:: yaml
:param str installer: The path to the ``.exe`` or ``.msi`` to use to install the
package. This can be a path or a URL. If it is a URL or a salt path
(salt://), the package will be cached locally and then executed. If it is a
path to a file on disk or a file share, it will be executed directly.
7zip:
'9.20.00.0':
installer: salt://win/repo/7zip/7z920-x64.msi
full_name: 7-Zip 9.20 (x64 edition)
reboot: False
install_flags: '/qn /norestart'
msiexec: True
uninstaller: salt://win/repo/7zip/7z920-x64.msi
uninstall_flags: '/qn /norestart'
:param str install_flags: Any flags that need to be passed to the installer to
make it perform a silent install. These can often be found by adding ``/?``
or ``/h`` when running the installer from the command-line. A great resource
for finding these silent install flags can be found on the WPKG project's wiki_:
:param msiexec:
This tells salt to use ``msiexec /i`` to install the package and
``msiexec /x`` to uninstall. This is for ``.msi`` installations. Possible
options are: True, False or the path to ``msiexec.exe`` on your system
Salt will not return if the installer is waiting for user input so these are
important.
.. code-block:: yaml
:param str uninstaller: The path to the program used to uninstall this software.
This can be the path to the same `exe` or `msi` used to install the
software. It can also be a GUID. You can find this value in the registry
under the following keys:
7zip:
'9.20.00.0':
installer: salt://win/repo/7zip/7z920-x64.msi
full_name: 7-Zip 9.20 (x64 edition)
reboot: False
install_flags: '/qn /norestart'
msiexec: 'C:\Windows\System32\msiexec.exe'
uninstaller: salt://win/repo/7zip/7z920-x64.msi
uninstall_flags: '/qn /norestart'
- Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall
- Software\\Wow6432None\\Microsoft\\Windows\\CurrentVersion\\Uninstall
:param bool allusers:
This parameter is specific to ``.msi`` installations. It tells ``msiexec``
to install the software for all users. The default is ``True``.
:param str uninstall_flags: Any flags that need to be passed to the uninstaller
to make it perform a silent uninstall. These can often be found by adding
``/?`` or ``/h`` when running the uninstaller from the command-line. A great
resource for finding these silent install flags can be found on the WPKG
project's wiki_:
:param bool cache_dir:
If ``True`` and the installer URL begins with ``salt://``, the entire
directory where the installer resides will be recursively cached. This is
useful for installers that depend on other files in the same directory for
installation.
Salt will not return if the uninstaller is waiting for user input so these are
important.
Here are some examples of installer and uninstaller settings:
.. code-block:: yaml
7zip:
'9.20.00.0':
installer: salt://win/repo/7zip/7z920-x64.msi
full_name: 7-Zip 9.20 (x64 edition)
reboot: False
install_flags: '/qn /norestart'
msiexec: True
uninstaller: '{23170F69-40C1-2702-0920-000001000000}'
uninstall_flags: '/qn /norestart'
Alternatively the ``uninstaller`` can also simply repeat the URL of the msi file.
.. code-block:: yaml
7zip:
'9.20.00.0':
installer: salt://win/repo/7zip/7z920-x64.msi
full_name: 7-Zip 9.20 (x64 edition)
reboot: False
install_flags: '/qn /norestart'
msiexec: True
uninstaller: salt://win/repo/7zip/7z920-x64.msi
uninstall_flags: '/qn /norestart'
:param msiexec: This tells salt to use ``msiexec /i`` to install the
package and ``msiexec /x`` to uninstall. This is for `.msi` installations.
Possible options are: True, False or path to msiexec on your system
7zip:
'9.20.00.0':
installer: salt://win/repo/7zip/7z920-x64.msi
full_name: 7-Zip 9.20 (x64 edition)
reboot: False
install_flags: '/qn /norestart'
msiexec: 'C:\Windows\System32\msiexec.exe'
uninstaller: salt://win/repo/7zip/7z920-x64.msi
uninstall_flags: '/qn /norestart'
:param str arch: This selects which ``msiexec.exe`` to use. Possible values:
``x86``, ``x64``
:param bool allusers: This parameter is specific to `.msi` installations. It
tells `msiexec` to install the software for all users. The default is True.
:param bool cache_dir: If true when installer URL begins with salt://, the
entire directory where the installer resides will be recursively cached.
This is useful for installers that depend on other files in the same
directory for installation.
.. warning::
Be aware that all files and directories in the same location as the
installer file will be copied down to the minion. If you place your
installer file in the root of winrepo (``/srv/salt/win/repo-ng``) and
``cache_dir: True`` the entire contents of winrepo will be cached to
the minion. Therefore, it is best practice to place your installer files
in a subdirectory if they are to be stored in winrepo.
:param str cache_file:
When installer URL begins with salt://, this indicates single file to copy
down for use with the installer. Copied to the same location as the
installer. Use this over ``cache_dir`` if there are many files in the
When the installer URL begins with ``salt://``, this indicates a single file
to copy down for use with the installer. It is copied to the same location
as the installer. Use this over ``cache_dir`` if there are many files in the
directory and you only need a specific file and don't want to cache
additional files that may reside in the installer directory.
Here's an example for a software package that has dependent files:
Here's an example for a software package that has dependent files:
.. code-block:: yaml
.. code-block:: yaml
sqlexpress:
'12.0.2000.8':
installer: 'salt://win/repo/sqlexpress/setup.exe'
full_name: Microsoft SQL Server 2014 Setup (English)
reboot: False
install_flags: '/ACTION=install /IACCEPTSQLSERVERLICENSETERMS /Q'
cache_dir: True
sqlexpress:
'12.0.2000.8':
installer: 'salt://win/repo/sqlexpress/setup.exe'
full_name: Microsoft SQL Server 2014 Setup (English)
reboot: False
install_flags: '/ACTION=install /IACCEPTSQLSERVERLICENSETERMS /Q'
cache_dir: True
:param bool use_scheduler: If true, windows will use the task scheduler to run
the installation. This is useful for running the salt installation itself as
the installation process kills any currently running instances of salt.
:param bool use_scheduler:
If ``True``, Windows will use the task scheduler to run the installation.
This is useful for running the Salt installation itself as the installation
process kills any currently running instances of Salt.
:param str source_hash: This tells salt to compare a hash sum of the installer
to the provided hash sum before execution. The value can be formatted as
``hash_algorithm=hash_sum``, or it can be a URI to a file containing the hash
sum.
For a list of supported algorithms, see the `hashlib documentation
<https://docs.python.org/2/library/hashlib.html>`_.
:param str source_hash:
This tells Salt to compare a hash sum of the installer to the provided hash
sum before execution. The value can be formatted as
``<hash_algorithm>=<hash_sum>``, or it can be a URI to a file containing the
hash sum.
Here's an example of source_hash usage:
For a list of supported algorithms, see the `hashlib documentation
<https://docs.python.org/2/library/hashlib.html>`_.
.. code-block:: yaml
Here's an example of source_hash usage:
messageanalyzer:
'4.0.7551.0':
full_name: 'Microsoft Message Analyzer'
installer: 'salt://win/repo/messageanalyzer/MessageAnalyzer64.msi'
install_flags: '/quiet /norestart'
uninstaller: '{1CC02C23-8FCD-487E-860C-311EC0A0C933}'
uninstall_flags: '/quiet /norestart'
msiexec: True
source_hash: 'sha1=62875ff451f13b10a8ff988f2943e76a4735d3d4'
.. code-block:: yaml
messageanalyzer:
'4.0.7551.0':
full_name: 'Microsoft Message Analyzer'
installer: 'salt://win/repo/messageanalyzer/MessageAnalyzer64.msi'
install_flags: '/quiet /norestart'
uninstaller: '{1CC02C23-8FCD-487E-860C-311EC0A0C933}'
uninstall_flags: '/quiet /norestart'
msiexec: True
source_hash: 'sha1=62875ff451f13b10a8ff988f2943e76a4735d3d4'
:param bool reboot: Not implemented

View File

@ -3,6 +3,6 @@ msgpack-python>0.3
PyYAML
MarkupSafe
requests>=1.0.0
tornado>=4.2.1
tornado>=4.2.1,<5.0
# Required by Tornado to handle threads stuff.
futures>=2.0

View File

@ -389,7 +389,7 @@ class LoadAuth(object):
def check_authentication(self, load, auth_type, key=None, show_username=False):
'''
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Go through various checks to see if the token/eauth/user can be authenticated.

View File

@ -2,7 +2,7 @@
'''
Provide authentication using local files
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
The `file` auth module allows simple authentication via local files. Different
filetypes are supported, including:

View File

@ -12,6 +12,8 @@ from salt.ext import six
# Import salt libs
from salt.exceptions import CommandExecutionError, SaltInvocationError
import salt.utils.stringutils
import salt.utils.data
log = logging.getLogger(__name__)
# Import third party libs
@ -39,6 +41,7 @@ __defopts__ = {'auth.ldap.basedn': '',
'auth.ldap.persontype': 'person',
'auth.ldap.groupclass': 'posixGroup',
'auth.ldap.activedirectory': False,
'auth.ldap.freeipa': False,
'auth.ldap.minion_stripdomains': [],
}
@ -290,10 +293,10 @@ def auth(username, password):
if bind:
log.debug('LDAP authentication successful')
return True
else:
log.error('LDAP _bind authentication FAILED')
return False
return bind
log.error('LDAP _bind authentication FAILED')
return False
def groups(username, **kwargs):
@ -312,14 +315,7 @@ def groups(username, **kwargs):
'''
group_list = []
# If bind credentials are configured, use them instead of user's
if _config('binddn', mandatory=False) and _config('bindpw', mandatory=False):
bind = _bind_for_search(anonymous=_config('anonymous', mandatory=False))
else:
bind = _bind(username, kwargs.get('password', ''),
anonymous=_config('auth_by_group_membership_only', mandatory=False)
and _config('anonymous', mandatory=False))
bind = auth(username, kwargs.get('password', None))
if bind:
log.debug('ldap bind to determine group membership succeeded!')
@ -331,7 +327,7 @@ def groups(username, **kwargs):
_config('persontype'))
user_dn_results = bind.search_s(_config('basedn'),
ldap.SCOPE_SUBTREE,
get_user_dn_search, ['distinguishedName'])
get_user_dn_search, [str('distinguishedName')]) # future lint: disable=blacklisted-function
except Exception as e:
log.error('Exception thrown while looking up user DN in AD: %s', e)
return group_list
@ -346,13 +342,13 @@ def groups(username, **kwargs):
search_results = bind.search_s(_config('basedn'),
ldap.SCOPE_SUBTREE,
ldap_search_string,
[_config('accountattributename'), 'cn'])
[salt.utils.stringutils.to_str(_config('accountattributename')), str('cn')]) # future lint: disable=blacklisted-function
except Exception as e:
log.error('Exception thrown while retrieving group membership in AD: %s', e)
return group_list
for _, entry in search_results:
if 'cn' in entry:
group_list.append(entry['cn'][0])
group_list.append(salt.utils.stringutils.to_unicode(entry['cn'][0]))
log.debug('User %s is a member of groups: %s', username, group_list)
elif _config('freeipa'):
@ -362,11 +358,11 @@ def groups(username, **kwargs):
search_results = bind.search_s(search_base,
ldap.SCOPE_SUBTREE,
search_string,
[_config('accountattributename'), 'cn', _config('groupattribute'), 'cn'])
[salt.utils.stringutils.to_str(_config('accountattributename')), str('cn')]) # future lint: disable=blacklisted-function
for entry, result in search_results:
for user in result[_config('accountattributename'), _config('groupattribute')]:
if username == user.split(',')[0].split('=')[-1]:
if username == salt.utils.stringutils.to_unicode(user).split(',')[0].split('=')[-1]:
group_list.append(entry.split(',')[0].split('=')[-1])
log.debug('User %s is a member of groups: %s', username, group_list)
@ -384,14 +380,16 @@ def groups(username, **kwargs):
search_results = bind.search_s(search_base,
ldap.SCOPE_SUBTREE,
search_string,
[_config('accountattributename'), 'cn', _config('groupattribute')])
[salt.utils.stringutils.to_str(_config('accountattributename')),
str('cn'), # future lint: disable=blacklisted-function
salt.utils.stringutils.to_str(_config('groupattribute'))])
for _, entry in search_results:
if username in entry[_config('accountattributename')]:
group_list.append(entry['cn'][0])
if username in salt.utils.data.decode(entry[_config('accountattributename')]):
group_list.append(salt.utils.stringutils.to_unicode(entry['cn'][0]))
for user, entry in search_results:
if username == user.split(',')[0].split('=')[-1]:
for group in entry[_config('groupattribute')]:
group_list.append(group.split(',')[0].split('=')[-1])
if username == salt.utils.stringutils.to_unicode(user).split(',')[0].split('=')[-1]:
for group in salt.utils.data.decode(entry[_config('groupattribute')]):
group_list.append(salt.utils.stringutils.to_unicode(group).split(',')[0].split('=')[-1])
log.debug('User %s is a member of groups: %s', username, group_list)
# Only test user auth on first call for job.
@ -445,7 +443,7 @@ def __expand_ldap_entries(entries, opts=None):
search_results = bind.search_s(search_base,
ldap.SCOPE_SUBTREE,
search_string,
['cn'])
[str('cn')]) # future lint: disable=blacklisted-function
for ldap_match in search_results:
try:
minion_id = ldap_match[1]['cn'][0].lower()

View File

@ -2,7 +2,7 @@
'''
Beacon to fire event when we notice a AIX user is locked due to many failed login attempts.
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
:depends: none
'''

View File

@ -3,7 +3,7 @@
NAPALM functions
================
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Watch NAPALM functions and fire events on specific triggers.

14
salt/cache/localfs.py vendored
View File

@ -14,6 +14,7 @@ from __future__ import absolute_import, print_function, unicode_literals
import logging
import os
import os.path
import errno
import shutil
import tempfile
@ -45,13 +46,14 @@ def store(bank, key, data, cachedir):
Store information in a file.
'''
base = os.path.join(cachedir, os.path.normpath(bank))
if not os.path.isdir(base):
try:
os.makedirs(base)
except OSError as exc:
try:
os.makedirs(base)
except OSError as exc:
if exc.errno != errno.EEXIST:
raise SaltCacheError(
'The cache directory, {0}, does not exist and could not be '
'created: {1}'.format(base, exc)
'The cache directory, {0}, could not be created: {1}'.format(
base, exc
)
)
outfile = os.path.join(base, '{0}.p'.format(key))

View File

@ -119,11 +119,12 @@ class Master(salt.utils.parsers.MasterOptionParser, DaemonsMixin): # pylint: di
Creates a master server
'''
def _handle_signals(self, signum, sigframe): # pylint: disable=unused-argument
# escalate signal to the process manager processes
self.master.process_manager.stop_restarting()
self.master.process_manager.send_signal_to_processes(signum)
# kill any remaining processes
self.master.process_manager.kill_children()
if hasattr(self.master, 'process_manager'): # IofloMaster has no process manager
# escalate signal to the process manager processes
self.master.process_manager.stop_restarting()
self.master.process_manager.send_signal_to_processes(signum)
# kill any remaining processes
self.master.process_manager.kill_children()
super(Master, self)._handle_signals(signum, sigframe)
def prepare(self):
@ -151,7 +152,6 @@ class Master(salt.utils.parsers.MasterOptionParser, DaemonsMixin): # pylint: di
os.path.join(self.config['cachedir'], 'jobs'),
os.path.join(self.config['cachedir'], 'proc'),
self.config['sock_dir'],
self.config['key_dir'],
self.config['token_dir'],
self.config['syndic_dir'],
self.config['sqlite_queue_dir'],
@ -166,7 +166,7 @@ class Master(salt.utils.parsers.MasterOptionParser, DaemonsMixin): # pylint: di
self.config['user'],
permissive=self.config['permissive_pki_access'],
root_dir=self.config['root_dir'],
sensitive_dirs=[self.config['pki_dir'], self.config['key_dir']],
pki_dir=self.config['pki_dir'],
)
# Clear out syndics from cachedir
for syndic_file in os.listdir(self.config['syndic_dir']):
@ -234,7 +234,8 @@ class Minion(salt.utils.parsers.MinionOptionParser, DaemonsMixin): # pylint: di
def _handle_signals(self, signum, sigframe): # pylint: disable=unused-argument
# escalate signal to the process manager processes
self.minion.stop(signum)
if hasattr(self.minion, 'stop'):
self.minion.stop(signum)
super(Minion, self)._handle_signals(signum, sigframe)
# pylint: disable=no-member
@ -287,7 +288,7 @@ class Minion(salt.utils.parsers.MinionOptionParser, DaemonsMixin): # pylint: di
self.config['user'],
permissive=self.config['permissive_pki_access'],
root_dir=self.config['root_dir'],
sensitive_dirs=[self.config['pki_dir']],
pki_dir=self.config['pki_dir'],
)
except OSError as error:
self.environment_failure(error)
@ -392,7 +393,7 @@ class Minion(salt.utils.parsers.MinionOptionParser, DaemonsMixin): # pylint: di
:param exitmsg
'''
self.action_log_info('Shutting down')
if hasattr(self, 'minion'):
if hasattr(self, 'minion') and hasattr(self.minion, 'destroy'):
self.minion.destroy()
super(Minion, self).shutdown(
exitcode, ('The Salt {0} is shutdown. {1}'.format(
@ -469,7 +470,7 @@ class ProxyMinion(salt.utils.parsers.ProxyMinionOptionParser, DaemonsMixin): #
self.config['user'],
permissive=self.config['permissive_pki_access'],
root_dir=self.config['root_dir'],
sensitive_dirs=[self.config['pki_dir']],
pki_dir=self.config['pki_dir'],
)
except OSError as error:
self.environment_failure(error)
@ -578,7 +579,7 @@ class Syndic(salt.utils.parsers.SyndicOptionParser, DaemonsMixin): # pylint: di
self.config['user'],
permissive=self.config['permissive_pki_access'],
root_dir=self.config['root_dir'],
sensitive_dirs=[self.config['pki_dir']],
pki_dir=self.config['pki_dir'],
)
except OSError as error:
self.environment_failure(error)

View File

@ -10,6 +10,7 @@ import os
import salt.utils.job
import salt.utils.parsers
import salt.utils.stringutils
import salt.log
from salt.utils.args import yamlify_arg
from salt.utils.verify import verify_log
from salt.exceptions import (
@ -38,9 +39,10 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
import salt.client
self.parse_args()
# Setup file logging!
self.setup_logfile_logger()
verify_log(self.config)
if self.config['log_level'] not in ('quiet', ):
# Setup file logging!
self.setup_logfile_logger()
verify_log(self.config)
try:
# We don't need to bail on config file permission errors
@ -82,7 +84,7 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
if 'token' in self.config:
import salt.utils.files
try:
with salt.utils.files.fopen(os.path.join(self.config['key_dir'], '.root_key'), 'r') as fp_:
with salt.utils.files.fopen(os.path.join(self.config['cachedir'], '.root_key'), 'r') as fp_:
kwargs['key'] = fp_.readline()
except IOError:
kwargs['token'] = self.config['token']

View File

@ -57,11 +57,6 @@ from salt.exceptions import (
# Import third party libs
from salt.ext import six
# pylint: disable=import-error
try:
import zmq
HAS_ZMQ = True
except ImportError:
HAS_ZMQ = False
# Try to import range from https://github.com/ytoolshed/range
HAS_RANGE = False
@ -194,11 +189,11 @@ class LocalClient(object):
# The username may contain '\' if it is in Windows
# 'DOMAIN\username' format. Fix this for the keyfile path.
key_user = key_user.replace('\\', '_')
keyfile = os.path.join(self.opts['key_dir'],
keyfile = os.path.join(self.opts['cachedir'],
'.{0}_key'.format(key_user))
try:
# Make sure all key parent directories are accessible
salt.utils.verify.check_path_traversal(self.opts['key_dir'],
salt.utils.verify.check_path_traversal(self.opts['cachedir'],
key_user,
self.skip_perm_errors)
with salt.utils.files.fopen(keyfile, 'r') as key:

View File

@ -384,7 +384,11 @@ class SyncClientMixin(object):
# Initialize a context for executing the method.
with tornado.stack_context.StackContext(self.functions.context_dict.clone):
data['return'] = self.functions[fun](*args, **kwargs)
func = self.functions[fun]
try:
data['return'] = func(*args, **kwargs)
except TypeError as exc:
data['return'] = '\nPassed invalid arguments: {0}\n\nUsage:\n{1}'.format(exc, func.__doc__)
try:
data['success'] = self.context.get('retcode', 0) == 0
except AttributeError:

View File

@ -60,11 +60,7 @@ try:
HAS_WINSHELL = False
except ImportError:
HAS_WINSHELL = False
try:
import zmq
HAS_ZMQ = True
except ImportError:
HAS_ZMQ = False
from salt.utils.zeromq import zmq
# The directory where salt thin is deployed
DEFAULT_THIN_DIR = '/var/tmp/.%%USER%%_%%FQDNUUID%%_salt'
@ -161,17 +157,17 @@ do
py_cmd_path=`"$py_cmd" -c \
'from __future__ import print_function;
import sys; print(sys.executable);'`
cmdpath=$(command -v $py_cmd 2>/dev/null || which $py_cmd 2>/dev/null)
cmdpath=`command -v $py_cmd 2>/dev/null || which $py_cmd 2>/dev/null`
if file $cmdpath | grep "shell script" > /dev/null
then
ex_vars="'PATH', 'LD_LIBRARY_PATH', 'MANPATH', \
'XDG_DATA_DIRS', 'PKG_CONFIG_PATH'"
export $($py_cmd -c \
export `$py_cmd -c \
"from __future__ import print_function;
import sys;
import os;
map(sys.stdout.write, ['{{{{0}}}}={{{{1}}}} ' \
.format(x, os.environ[x]) for x in [$ex_vars]])")
.format(x, os.environ[x]) for x in [$ex_vars]])"`
exec $SUDO PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH \
MANPATH=$MANPATH XDG_DATA_DIRS=$XDG_DATA_DIRS \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH \
@ -214,7 +210,7 @@ class SSH(object):
def __init__(self, opts):
self.__parsed_rosters = {SSH.ROSTER_UPDATE_FLAG: True}
pull_sock = os.path.join(opts['sock_dir'], 'master_event_pull.ipc')
if os.path.exists(pull_sock) and HAS_ZMQ:
if os.path.exists(pull_sock) and zmq:
self.event = salt.utils.event.get_event(
'master',
opts['sock_dir'],
@ -444,7 +440,7 @@ class SSH(object):
if target.get('passwd', False) or self.opts['ssh_passwd']:
self._key_deploy_run(host, target, False)
return ret
if ret[host].get('stderr', '').count('Permission denied'):
if (ret[host].get('stderr') or '').count('Permission denied'):
target = self.targets[host]
# permission denied, attempt to auto deploy ssh key
print(('Permission denied for host {0}, do you want to deploy '
@ -662,7 +658,9 @@ class SSH(object):
host = next(six.iterkeys(ret))
self.cache_job(jid, host, ret[host], fun)
if self.event:
_, data = next(six.iteritems(ret))
id_, data = next(six.iteritems(ret))
if 'id' not in data:
data['id'] = id_
data['jid'] = jid # make the jid in the payload the same as the jid in the tag
self.event.fire_event(
data,
@ -755,7 +753,7 @@ class SSH(object):
self.cache_job(jid, host, ret[host], fun)
ret = self.key_deploy(host, ret)
if isinstance(ret[host], dict) and ret[host].get('stderr', '').startswith('ssh:'):
if isinstance(ret[host], dict) and (ret[host].get('stderr') or '').startswith('ssh:'):
ret[host] = ret[host]['stderr']
if not isinstance(ret[host], dict):
@ -773,7 +771,9 @@ class SSH(object):
outputter,
self.opts)
if self.event:
_, data = next(six.iteritems(ret))
id_, data = next(six.iteritems(ret))
if 'id' not in data:
data['id'] = id_
data['jid'] = jid # make the jid in the payload the same as the jid in the tag
self.event.fire_event(
data,
@ -880,6 +880,7 @@ class Single(object):
# Pre apply changeable defaults
self.minion_opts = {
'grains_cache': True,
'log_file': 'salt-call.log',
}
self.minion_opts.update(opts.get('ssh_minion_opts', {}))
if minion_opts is not None:
@ -889,7 +890,6 @@ class Single(object):
'root_dir': os.path.join(self.thin_dir, 'running_data'),
'id': self.id,
'sock_dir': '/',
'log_file': 'salt-call.log',
'fileserver_list_cache_time': 3,
})
self.minion_config = salt.serializers.yaml.serialize(self.minion_opts)

View File

@ -125,7 +125,7 @@ class FunctionWrapper(object):
'stderr': stderr,
'retcode': retcode}
try:
ret = salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
ret = salt.utils.json.loads(stdout)
if len(ret) < 2 and 'local' in ret:
ret = ret['local']
ret = ret.get('return', {})

View File

@ -197,7 +197,7 @@ def sls(mods, saltenv='base', test=None, exclude=None, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -341,7 +341,7 @@ def low(data, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -432,7 +432,7 @@ def high(data, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -677,7 +677,7 @@ def highstate(test=None, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -760,7 +760,7 @@ def top(topfn, test=None, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -1133,7 +1133,7 @@ def single(fun, name, test=None, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))

View File

@ -823,7 +823,7 @@ def query(params=None):
content = request.text
result = salt.utils.json.loads(content, object_hook=salt.utils.data.encode_dict)
result = salt.utils.json.loads(content)
if 'Code' in result:
raise SaltCloudSystemExit(
pprint.pformat(result.get('Message', {}))

View File

@ -10,9 +10,16 @@ Azure ARM Cloud Module
The Azure ARM cloud module is used to control access to Microsoft Azure Resource Manager
:depends:
* `Microsoft Azure SDK for Python <https://pypi.python.org/pypi/azure>`_ >= 2.0rc6
* `Microsoft Azure Storage SDK for Python <https://pypi.python.org/pypi/azure-storage>`_ >= 0.32
* `AutoRest swagger generator Python client runtime (Azure-specific module) <https://pypi.python.org/pypi/msrestazure>`_ >= 0.4
* `azure <https://pypi.python.org/pypi/azure>`_ >= 2.0.0rc6
* `azure-common <https://pypi.python.org/pypi/azure-common>`_ >= 1.1.4
* `azure-mgmt <https://pypi.python.org/pypi/azure-mgmt>`_ >= 0.30.0rc6
* `azure-mgmt-compute <https://pypi.python.org/pypi/azure-mgmt-compute>`_ >= 0.33.0
* `azure-mgmt-network <https://pypi.python.org/pypi/azure-mgmt-network>`_ >= 0.30.0rc6
* `azure-mgmt-resource <https://pypi.python.org/pypi/azure-mgmt-resource>`_ >= 0.30.0
* `azure-mgmt-storage <https://pypi.python.org/pypi/azure-mgmt-storage>`_ >= 0.30.0rc6
* `azure-mgmt-web <https://pypi.python.org/pypi/azure-mgmt-web>`_ >= 0.30.0rc6
* `azure-storage <https://pypi.python.org/pypi/azure-storage>`_ >= 0.32.0
* `msrestazure <https://pypi.python.org/pypi/msrestazure>`_ >= 0.4.21
:configuration:
Required provider parameters:
@ -774,6 +781,25 @@ def create_network_interface(call=None, kwargs=None):
ip_kwargs = {}
ip_configurations = None
if 'load_balancer_backend_address_pools' in kwargs:
pool_dicts = kwargs['load_balancer_backend_address_pools']
if isinstance(pool_dicts, dict):
pool_ids = []
for load_bal, be_pools in pool_dicts.items():
for pool in be_pools:
try:
lbbep_data = netconn.load_balancer_backend_address_pools.get(
kwargs['resource_group'],
load_bal,
pool,
)
pool_ids.append({'id': lbbep_data.as_dict()['id']})
except CloudError as exc:
log.error('There was a cloud error: %s', six.text_type(exc))
except KeyError as exc:
log.error('There was an error getting the Backend Pool ID: %s', six.text_type(exc))
ip_kwargs['load_balancer_backend_address_pools'] = pool_ids
if 'private_ip_address' in kwargs.keys():
ip_kwargs['private_ip_address'] = kwargs['private_ip_address']
ip_kwargs['private_ip_allocation_method'] = IPAllocationMethod.static
@ -930,6 +956,11 @@ def request_instance(vm_):
compute_models, 'VirtualMachineSizeTypes'
)
subscription_id = config.get_cloud_config_value(
'subscription_id',
get_configured_provider(), __opts__, search_global=False
)
if vm_.get('driver') is None:
vm_['driver'] = 'azurearm'
@ -1039,6 +1070,24 @@ def request_instance(vm_):
)
os_kwargs['admin_password'] = vm_password
availability_set = config.get_cloud_config_value(
'availability_set',
vm_,
__opts__,
search_global=False,
default=None
)
if availability_set is not None and isinstance(availability_set, six.string_types):
availability_set = {
'id': '/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Compute/availabilitySets/{2}'.format(
subscription_id,
vm_['resource_group'],
availability_set
)
}
else:
availability_set = None
cloud_env = _get_cloud_environment()
storage_endpoint_suffix = cloud_env.suffixes.storage_endpoint
@ -1147,7 +1196,10 @@ def request_instance(vm_):
img_pub, img_off, img_sku, img_ver = vm_['image'].split('|')
source_image = None
os_type = None
os_disk = None
os_disk = OSDisk(
create_option=DiskCreateOptionTypes.from_image,
disk_size_gb=vm_.get('os_disk_size_gb')
)
img_ref = ImageReference(
publisher=img_pub,
offer=img_off,
@ -1235,6 +1287,7 @@ def request_instance(vm_):
NetworkInterfaceReference(vm_['iface_id']),
],
),
availability_set=availability_set,
)
__utils__['cloud.fire_event'](
@ -1257,15 +1310,15 @@ def request_instance(vm_):
parameters=params
)
vm_create.wait()
vm_result = vm_create.result()
vm_result = vm_result.as_dict()
if custom_extension:
create_or_update_vmextension(kwargs=custom_extension)
except CloudError as exc:
__utils__['azurearm.log_cloud_error']('compute', exc.message)
vm_result = {}
try:
return show_instance(vm_['name'], call='action')
except CloudError:
return {}
return vm_result
def create(vm_):
@ -1304,7 +1357,12 @@ def create(vm_):
log.info('Creating Cloud VM %s in %s', vm_['name'], location)
request_instance(vm_=vm_)
vm_request = request_instance(vm_=vm_)
if not vm_request or 'error' in vm_request:
err_message = 'Error creating VM {0}! ({1})'.format(vm_['name'], six.text_type(vm_request))
log.error(err_message)
raise SaltCloudSystemExit(err_message)
def _query_node_data(name, bootstrap_interface):
'''

View File

@ -42,10 +42,11 @@ from salt.ext import six
# pylint: disable=import-error
try:
from libcloud.compute.drivers.cloudstack import CloudStackNetwork
# This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0.
# However, older versions of libcloud must still be supported with this work-around.
# This work-around can be removed when the required minimum version of libcloud is
# 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen).
# This work-around for Issue #32743 is no longer needed for libcloud >=
# 1.4.0. However, older versions of libcloud must still be supported with
# this work-around. This work-around can be removed when the required
# minimum version of libcloud is 2.0.0 (See PR #40837 - which is
# implemented in Salt 2018.3.0).
if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'):
# See https://github.com/saltstack/salt/issues/32743
import libcloud.security

View File

@ -32,7 +32,7 @@ from salt.utils.versions import LooseVersion as _LooseVersion
# Import libcloud
try:
import libcloud
from libcloud.compute.base import NodeState
from libcloud.compute.base import NodeDriver, NodeState
from libcloud.compute.base import NodeAuthPassword
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
@ -40,10 +40,11 @@ try:
from libcloud.loadbalancer.types import Provider as Provider_lb
from libcloud.loadbalancer.providers import get_driver as get_driver_lb
# This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0.
# However, older versions of libcloud must still be supported with this work-around.
# This work-around can be removed when the required minimum version of libcloud is
# 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen).
# This work-around for Issue #32743 is no longer needed for libcloud >=
# 1.4.0. However, older versions of libcloud must still be supported with
# this work-around. This work-around can be removed when the required
# minimum version of libcloud is 2.0.0 (See PR #40837 - which is
# implemented in Salt 2018.3.0).
if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'):
# See https://github.com/saltstack/salt/issues/32743
import libcloud.security
@ -52,9 +53,6 @@ try:
except ImportError:
HAS_LIBCLOUD = False
# Import generic libcloud functions
# from salt.cloud.libcloudfuncs import *
# Import salt.cloud libs
from salt.cloud.libcloudfuncs import * # pylint: disable=redefined-builtin,wildcard-import,unused-wildcard-import
from salt.utils.functools import namespaced_function
@ -217,7 +215,6 @@ def create(vm_):
log.info('Creating Cloud VM %s', vm_['name'])
conn = get_conn()
rootPw = NodeAuthPassword(vm_['auth'])
location = conn.ex_get_location_by_id(vm_['location'])
images = conn.list_images(location=location)
@ -248,15 +245,13 @@ def create(vm_):
kwargs = {
'name': vm_['name'],
'image': image,
'auth': rootPw,
'ex_description': vm_['description'],
'ex_network_domain': network_domain,
'ex_vlan': vlan,
'ex_is_started': vm_['is_started']
}
event_data = kwargs.copy()
del event_data['auth']
event_data = _to_event_data(kwargs)
__utils__['cloud.fire_event'](
'event',
@ -267,6 +262,10 @@ def create(vm_):
transport=__opts__['transport']
)
# Initial password (excluded from event payload)
initial_password = NodeAuthPassword(vm_['auth'])
kwargs['auth'] = initial_password
try:
data = conn.create_node(**kwargs)
except Exception as exc:
@ -280,7 +279,7 @@ def create(vm_):
return False
try:
data = salt.utils.cloud.wait_for_ip(
data = __utils__['cloud.wait_for_ip'](
_query_node_data,
update_args=(vm_, data),
timeout=config.get_cloud_config_value(
@ -306,7 +305,7 @@ def create(vm_):
ip_address = preferred_ip(vm_, data.public_ips)
log.debug('Using IP address %s', ip_address)
if salt.utils.cloud.get_salt_interface(vm_, __opts__) == 'private_ips':
if __utils__['cloud.get_salt_interface'](vm_, __opts__) == 'private_ips':
salt_ip_address = preferred_ip(vm_, data.private_ips)
log.info('Salt interface set to: %s', salt_ip_address)
else:
@ -322,7 +321,7 @@ def create(vm_):
vm_['ssh_host'] = ip_address
vm_['password'] = vm_['auth']
ret = salt.utils.cloud.bootstrap(vm_, __opts__)
ret = __utils__['cloud.bootstrap'](vm_, __opts__)
ret.update(data.__dict__)
@ -414,11 +413,13 @@ def create_lb(kwargs=None, call=None):
log.debug('Network Domain: %s', network_domain.id)
lb_conn.ex_set_current_network_domain(network_domain.id)
event_data = _to_event_data(kwargs)
__utils__['cloud.fire_event'](
'event',
'create load_balancer',
'salt/cloud/loadbalancer/creating',
args=kwargs,
args=event_data,
sock_dir=__opts__['sock_dir'],
transport=__opts__['transport']
)
@ -427,11 +428,13 @@ def create_lb(kwargs=None, call=None):
name, port, protocol, algorithm, members
)
event_data = _to_event_data(kwargs)
__utils__['cloud.fire_event'](
'event',
'created load_balancer',
'salt/cloud/loadbalancer/created',
args=kwargs,
args=event_data,
sock_dir=__opts__['sock_dir'],
transport=__opts__['transport']
)
@ -573,3 +576,46 @@ def get_lb_conn(dd_driver=None):
'Missing dimensiondata_driver for get_lb_conn method.'
)
return get_driver_lb(Provider_lb.DIMENSIONDATA)(user_id, key, region=region)
def _to_event_data(obj):
'''
Convert the specified object into a form that can be serialised by msgpack as event data.
:param obj: The object to convert.
'''
if obj is None:
return None
if isinstance(obj, bool):
return obj
if isinstance(obj, int):
return obj
if isinstance(obj, float):
return obj
if isinstance(obj, str):
return obj
if isinstance(obj, bytes):
return obj
if isinstance(obj, dict):
return obj
if isinstance(obj, NodeDriver): # Special case for NodeDriver (cyclic references)
return obj.name
if isinstance(obj, list):
return [_to_event_data(item) for item in obj]
event_data = {}
for attribute_name in dir(obj):
if attribute_name.startswith('_'):
continue
attribute_value = getattr(obj, attribute_name)
if callable(attribute_value): # Strip out methods
continue
event_data[attribute_name] = _to_event_data(attribute_value)
return event_data

View File

@ -200,8 +200,7 @@ def get_dependencies():
'''
deps = {
'requests': HAS_REQUESTS,
'm2crypto': HAS_M2,
'pycrypto': HAS_PYCRYPTO
'pycrypto or m2crypto': HAS_M2 or HAS_PYCRYPTO
}
return config.check_driver_dependencies(
__virtualname__,

View File

@ -70,10 +70,11 @@ try:
ResourceInUseError,
ResourceNotFoundError,
)
# This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0.
# However, older versions of libcloud must still be supported with this work-around.
# This work-around can be removed when the required minimum version of libcloud is
# 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen).
# This work-around for Issue #32743 is no longer needed for libcloud >=
# 1.4.0. However, older versions of libcloud must still be supported with
# this work-around. This work-around can be removed when the required
# minimum version of libcloud is 2.0.0 (See PR #40837 - which is
# implemented in Salt 2018.3.0).
if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'):
# See https://github.com/saltstack/salt/issues/32743
import libcloud.security

View File

@ -758,7 +758,7 @@ def get_template_image(kwargs=None, call=None):
'''
Returns a template's image from the given template name.
.. versionadded:: oxygen
.. versionadded:: 2018.3.0
.. code-block:: bash
@ -921,7 +921,7 @@ def _get_device_template(disk, disk_info, template=None):
'''
Returns the template format to create a disk in open nebula
.. versionadded:: oxygen
.. versionadded:: 2018.3.0
'''
def _require_disk_opts(*args):

View File

@ -355,7 +355,7 @@ def _get_ips(node, addr_type='public'):
ret = []
for _, interface in node.addresses.items():
for addr in interface:
if addr_type in ('floating', 'fixed') and addr_type == addr['OS-EXT-IPS:type']:
if addr_type in ('floating', 'fixed') and addr_type == addr.get('OS-EXT-IPS:type'):
ret.append(addr['addr'])
elif addr_type == 'public' and __utils__['cloud.is_public_ip'](addr['addr']):
ret.append(addr['addr'])

View File

@ -188,7 +188,7 @@ def query(params=None):
log.debug(request.url)
content = request.text
result = salt.utils.json.loads(content, object_hook=salt.utils.data.encode_dict)
result = salt.utils.json.loads(content)
# print('response:')
# pprint.pprint(result)

View File

@ -9,7 +9,7 @@ The Saltify module is designed to install Salt on a remote machine, virtual or
bare metal, using SSH. This module is useful for provisioning machines which
are already installed, but not Salted.
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
The wake_on_lan capability, and actions destroy, reboot, and query functions were added.
Use of this module requires some configuration in cloud profile and provider
@ -88,7 +88,7 @@ def avail_images(call=None):
returns a list of available profiles.
..versionadded:: Oxygen
..versionadded:: 2018.3.0
'''
vm_ = get_configured_provider()
@ -118,7 +118,7 @@ def list_nodes(call=None):
returns a list of dictionaries of defined standard fields.
..versionadded:: Oxygen
..versionadded:: 2018.3.0
'''
nodes = _list_nodes_full(call)
@ -164,7 +164,7 @@ def list_nodes_full(call=None):
for 'saltify' minions, returns dict of grains (enhanced).
..versionadded:: Oxygen
..versionadded:: 2018.3.0
'''
ret = _list_nodes_full(call)
@ -399,7 +399,7 @@ def _verify(vm_):
def destroy(name, call=None):
''' Destroy a node.
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
Disconnect a minion from the master, and remove its keys.
@ -489,7 +489,7 @@ def reboot(name, call=None):
'''
Reboot a saltify minion.
..versionadded:: Oxygen
..versionadded:: 2018.3.0
name
The name of the VM to reboot.

View File

@ -10,7 +10,7 @@ Use of this module requires some configuration in cloud profile and provider
files as described in the
:ref:`Getting Started with Vagrant <getting-started-with-vagrant>` documentation.
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
'''

View File

@ -565,11 +565,6 @@ def create(vm_):
record = {}
ret = {}
# Since using "provider: <provider-engine>" is deprecated, alias provider
# to use driver: "driver: <provider-engine>"
if 'provider' in vm_:
vm_['driver'] = vm_.pop('provider')
# fire creating event
__utils__['cloud.fire_event'](
'event',

View File

@ -197,9 +197,6 @@ VALID_OPTS = {
# The directory used to store public key data
'pki_dir': six.string_types,
# The directory to store authentication keys of a master's local environment.
'key_dir': six.string_types,
# A unique identifier for this daemon
'id': six.string_types,
@ -284,6 +281,7 @@ VALID_OPTS = {
# Location of the files a minion should look for. Set to 'local' to never ask the master.
'file_client': six.string_types,
'local': bool,
# When using a local file_client, this parameter is used to allow the client to connect to
# a master for remote execution.
@ -1250,6 +1248,7 @@ DEFAULT_MINION_OPTS = {
'base': [salt.syspaths.BASE_THORIUM_ROOTS_DIR],
},
'file_client': 'remote',
'local': False,
'use_master_when_local': False,
'file_roots': {
'base': [salt.syspaths.BASE_FILE_ROOTS_DIR,
@ -1500,7 +1499,6 @@ DEFAULT_MASTER_OPTS = {
'archive_jobs': False,
'root_dir': salt.syspaths.ROOT_DIR,
'pki_dir': os.path.join(salt.syspaths.CONFIG_DIR, 'pki', 'master'),
'key_dir': os.path.join(salt.syspaths.CONFIG_DIR, 'key'),
'key_cache': '',
'cachedir': os.path.join(salt.syspaths.CACHE_DIR, 'master'),
'file_roots': {
@ -1530,6 +1528,7 @@ DEFAULT_MASTER_OPTS = {
'pillarenv': None,
'default_top': 'base',
'file_client': 'local',
'local': True,
# Update intervals
'roots_update_interval': DEFAULT_INTERVAL,
@ -1816,7 +1815,6 @@ DEFAULT_MASTER_OPTS = {
'schedule': {},
'auth_events': True,
'minion_data_cache_events': True,
'enable_ssh': False,
'enable_ssh_minions': False,
}
@ -2316,6 +2314,12 @@ def prepend_root_dir(opts, path_options):
path = tmp_path_root_dir
else:
path = tmp_path_def_root_dir
elif salt.utils.platform.is_windows() and not os.path.splitdrive(path)[0]:
# In windows, os.path.isabs resolves '/' to 'C:\\' or whatever
# the root drive is. This elif prevents the next from being
# hit, so that the root_dir is prefixed in cases where the
# drive is not prefixed on a config option
pass
elif os.path.isabs(path):
# Absolute path (not default or overriden root_dir)
# No prepending required
@ -2503,7 +2507,7 @@ def syndic_config(master_config_path,
opts.update(syndic_opts)
# Prepend root_dir to other paths
prepend_root_dirs = [
'pki_dir', 'key_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules',
'pki_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules',
'autosign_file', 'autoreject_file', 'token_dir', 'autosign_grains_dir'
]
for config_key in ('log_file', 'key_logfile', 'syndic_log_file'):
@ -3651,7 +3655,7 @@ def _adjust_log_file_override(overrides, default_log_file):
if overrides.get('log_dir'):
# Adjust log_file if a log_dir override is introduced
if overrides.get('log_file'):
if not os.path.abspath(overrides['log_file']):
if not os.path.isabs(overrides['log_file']):
# Prepend log_dir if log_file is relative
overrides['log_file'] = os.path.join(overrides['log_dir'],
overrides['log_file'])
@ -3940,7 +3944,7 @@ def apply_master_config(overrides=None, defaults=None):
# Prepend root_dir to other paths
prepend_root_dirs = [
'pki_dir', 'key_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules',
'pki_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules',
'autosign_file', 'autoreject_file', 'token_dir', 'syndic_dir',
'sqlite_queue_dir', 'autosign_grains_dir'
]

View File

@ -806,7 +806,7 @@ class AsyncAuth(object):
pubkey_path = os.path.join(self.opts['pki_dir'], self.mpub)
pub = get_rsa_pub_key(pubkey_path)
if HAS_M2:
payload['token'] = pub.public_encrypt(six.b(self.token), RSA.pkcs1_oaep_padding)
payload['token'] = pub.public_encrypt(self.token, RSA.pkcs1_oaep_padding)
else:
cipher = PKCS1_OAEP.new(pub)
payload['token'] = cipher.encrypt(self.token)
@ -845,7 +845,8 @@ class AsyncAuth(object):
log.debug('Decrypting the current master AES key')
key = self.get_keys()
if HAS_M2:
key_str = key.private_decrypt(six.b(payload['aes']), RSA.pkcs1_oaep_padding)
key_str = key.private_decrypt(payload['aes'],
RSA.pkcs1_oaep_padding)
else:
cipher = PKCS1_OAEP.new(key)
key_str = cipher.decrypt(payload['aes'])
@ -876,7 +877,8 @@ class AsyncAuth(object):
else:
if 'token' in payload:
if HAS_M2:
token = key.private_decrypt(six.b(payload['token']), RSA.pkcs1_oaep_padding)
token = key.private_decrypt(payload['token'],
RSA.pkcs1_oaep_padding)
else:
token = cipher.decrypt(payload['token'])
return key_str, token

View File

@ -121,6 +121,7 @@ class IofloMinion(object):
'''
warn_deprecated()
self.opts = opts
self.restart = False
def tune_in(self, behaviors=None):
'''

View File

@ -62,7 +62,10 @@ def jobber_check(self):
rms.append(jid)
data = self.shells.value[jid]
stdout, stderr = data['proc'].communicate()
ret = salt.utils.json.loads(stdout, object_hook=salt.utils.data.encode_dict)['local']
ret = salt.utils.json.loads(
stdout,
object_hook=salt.utils.data.encode_dict if six.PY2 else None
)['local']
route = {'src': (self.stack.value.local.name, 'manor', 'jid_ret'),
'dst': (data['msg']['route']['src'][0], None, 'remote_cmd')}
ret['cmd'] = '_return'

View File

@ -15,16 +15,12 @@ import errno
# Import ioflo libs
import ioflo.base.deeding
# Import third party libs
try:
import zmq
import salt.master
import salt.crypt
import salt.daemons.masterapi
import salt.payload
import salt.utils.stringutils
HAS_ZMQ = True
except ImportError:
HAS_ZMQ = False
from salt.utils.zeromq import zmq
import salt.master
import salt.crypt
import salt.daemons.masterapi
import salt.payload
import salt.utils.stringutils
log = logging.getLogger(__name__)
@ -160,7 +156,7 @@ class SaltZmqPublisher(ioflo.base.deeding.Deed):
'''
Set up tracking value(s)
'''
if not HAS_ZMQ:
if not zmq:
return
self.created = False
self.serial = salt.payload.Serial(self.opts.value)

View File

@ -186,11 +186,11 @@ def mk_key(opts, user):
# The username may contain '\' if it is in Windows
# 'DOMAIN\username' format. Fix this for the keyfile path.
keyfile = os.path.join(
opts['key_dir'], '.{0}_key'.format(user.replace('\\', '_'))
opts['cachedir'], '.{0}_key'.format(user.replace('\\', '_'))
)
else:
keyfile = os.path.join(
opts['key_dir'], '.{0}_key'.format(user)
opts['cachedir'], '.{0}_key'.format(user)
)
if os.path.exists(keyfile):

View File

@ -11,7 +11,12 @@ framer minionudpstack be active first start
exit
do salt raet road stack closer per inode ".salt.road.manor."
framer bootstrap be active first join
framer bootstrap be active first setup
frame setup
enter
do salt raet road usher minion setup per inode ".salt.road.manor."
go join
frame join
print Joining...
enter
@ -44,7 +49,7 @@ framer bootstrap be active first join
frame message
print Messaging...
enter
do raet road stack messenger to contents "Minion 1 Hello" code 15 \
do raet road stack messenger with contents "Minion 1 Hello" code 15 \
per inode ".salt.road.manor."
go next

View File

@ -22,6 +22,10 @@ def test():
if not os.path.exists(pkiDirpath):
os.makedirs(pkiDirpath)
keyDirpath = os.path.join('/tmp', 'raet', 'testo', 'key')
if not os.path.exists(keyDirpath):
os.makedirs(keyDirpath)
acceptedDirpath = os.path.join(pkiDirpath, 'accepted')
if not os.path.exists(acceptedDirpath):
os.makedirs(acceptedDirpath)
@ -64,10 +68,12 @@ def test():
client_acl=dict(),
publisher_acl=dict(),
pki_dir=pkiDirpath,
key_dir=keyDirpath,
sock_dir=sockDirpath,
cachedir=cacheDirpath,
open_mode=True,
auto_accept=True,
client_acl_verify=True,
)
master = salt.daemons.flo.IofloMaster(opts=opts)

View File

@ -348,8 +348,8 @@ if __name__ == '__main__' and __package__ is None:
#console.reinit(verbosity=console.Wordage.concise)
#runAll() # run all unittests
runAll() # run all unittests
runSome() # only run some
#runSome() # only run some
#runOne('testParseHostname')

View File

@ -5,6 +5,7 @@ Raet Ioflo Behavior Unittests
from __future__ import absolute_import, print_function, unicode_literals
import sys
from salt.ext.six.moves import map
import importlib
# pylint: disable=blacklisted-import
if sys.version_info < (2, 7):
import unittest2 as unittest
@ -40,6 +41,9 @@ class PresenterTestCase(testing.FrameIofloTestCase):
'''
Call super if override so House Framer and Frame are setup correctly
'''
behaviors = ['salt.daemons.flo', 'salt.daemons.test.plan']
for behavior in behaviors:
mod = importlib.import_module(behavior)
super(PresenterTestCase, self).setUp()
def tearDown(self):

View File

@ -7,6 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals
# pylint: skip-file
# pylint: disable=C0103
import sys
import salt.utils.stringutils
from salt.ext.six.moves import map
if sys.version_info < (2, 7):
import unittest2 as unittest
@ -30,12 +31,15 @@ from raet.road import estating, keeping, stacking
from salt.key import RaetKey
def setUpModule():
console.reinit(verbosity=console.Wordage.concise)
def tearDownModule():
pass
class BasicTestCase(unittest.TestCase):
""""""
@ -47,7 +51,7 @@ class BasicTestCase(unittest.TestCase):
pkiDirpath = os.path.join(self.saltDirpath, 'pki')
if not os.path.exists(pkiDirpath):
os.makedirs(pkiDirpath)
os.makedirs(pkiDirpath)
acceptedDirpath = os.path.join(pkiDirpath, 'accepted')
if not os.path.exists(acceptedDirpath):
@ -81,7 +85,7 @@ class BasicTestCase(unittest.TestCase):
)
self.mainKeeper = RaetKey(opts=self.opts)
self.baseDirpath = tempfile.mkdtemp(prefix="salt", suffix="base", dir='/tmp')
self.baseDirpath = tempfile.mkdtemp(prefix="salt", suffix="base", dir='/tmp')
def tearDown(self):
if os.path.exists(self.saltDirpath):
@ -119,9 +123,9 @@ class BasicTestCase(unittest.TestCase):
self.opts['auto_accept'] = True
self.assertTrue(self.opts['auto_accept'])
self.assertDictEqual(self.mainKeeper.all_keys(), {'accepted': [],
'local': [],
'rejected': [],
'pending': []})
'local': [],
'rejected': [],
'pending': []})
localkeys = self.mainKeeper.read_local()
self.assertDictEqual(localkeys, {})
@ -129,8 +133,9 @@ class BasicTestCase(unittest.TestCase):
main = self.createRoadData(name='main', base=self.baseDirpath)
self.mainKeeper.write_local(main['prihex'], main['sighex'])
localkeys = self.mainKeeper.read_local()
self.assertDictEqual(localkeys, {'priv': main['prihex'],
'sign': main['sighex']})
self.assertDictEqual(localkeys,
{'priv': salt.utils.stringutils.to_str(main['prihex']),
'sign': salt.utils.stringutils.to_str(main['sighex'])})
allkeys = self.mainKeeper.all_keys()
self.assertDictEqual(allkeys, {'accepted': [],
'local': [self.localFilepath],
@ -147,39 +152,38 @@ class BasicTestCase(unittest.TestCase):
allkeys = self.mainKeeper.all_keys()
self.assertDictEqual(allkeys, {'accepted': ['other1', 'other2'],
'local': [self.localFilepath],
'pending': [],
'rejected': []} )
'local': [self.localFilepath],
'pending': [],
'rejected': []})
remotekeys = self.mainKeeper.read_remote(other1['name'])
self.assertDictEqual(remotekeys, { 'minion_id': 'other1',
'pub': other1['pubhex'],
'verify': other1['verhex']} )
self.assertDictEqual(remotekeys, {'minion_id': 'other1',
'pub': salt.utils.stringutils.to_str(other1['pubhex']),
'verify': salt.utils.stringutils.to_str(other1['verhex'])})
remotekeys = self.mainKeeper.read_remote(other2['name'])
self.assertDictEqual(remotekeys, { 'minion_id': 'other2',
'pub': other2['pubhex'],
'verify': other2['verhex']} )
self.assertDictEqual(remotekeys, {'minion_id': 'other2',
'pub': salt.utils.stringutils.to_str(other2['pubhex']),
'verify': salt.utils.stringutils.to_str(other2['verhex'])})
listkeys = self.mainKeeper.list_keys()
self.assertDictEqual(listkeys, {'accepted': ['other1', 'other2'],
'rejected': [],
'pending': []})
allremotekeys = self.mainKeeper.read_all_remote()
self.assertDictEqual(allremotekeys, {'other1':
{'verify': other1['verhex'],
'minion_id': 'other1',
'acceptance': 'accepted',
'pub': other1['pubhex'],},
'other2':
{'verify': other2['verhex'],
'minion_id': 'other2',
'acceptance': 'accepted',
'pub': other2['pubhex'],}
})
self.assertDictEqual(allremotekeys,
{'other1':
{'verify': salt.utils.stringutils.to_str(other1['verhex']),
'minion_id': 'other1',
'acceptance': 'accepted',
'pub': salt.utils.stringutils.to_str(other1['pubhex']), },
'other2':
{'verify': salt.utils.stringutils.to_str(other2['verhex']),
'minion_id': 'other2',
'acceptance': 'accepted',
'pub': salt.utils.stringutils.to_str(other2['pubhex']), }
})
def testManualAccept(self):
'''
@ -189,9 +193,9 @@ class BasicTestCase(unittest.TestCase):
self.opts['auto_accept'] = False
self.assertFalse(self.opts['auto_accept'])
self.assertDictEqual(self.mainKeeper.all_keys(), {'accepted': [],
'local': [],
'rejected': [],
'pending': []})
'local': [],
'rejected': [],
'pending': []})
localkeys = self.mainKeeper.read_local()
self.assertDictEqual(localkeys, {})
@ -199,8 +203,9 @@ class BasicTestCase(unittest.TestCase):
main = self.createRoadData(name='main', base=self.baseDirpath)
self.mainKeeper.write_local(main['prihex'], main['sighex'])
localkeys = self.mainKeeper.read_local()
self.assertDictEqual(localkeys, {'priv': main['prihex'],
'sign': main['sighex']})
self.assertDictEqual(localkeys,
{'priv': salt.utils.stringutils.to_str(main['prihex']),
'sign': salt.utils.stringutils.to_str(main['sighex'])})
allkeys = self.mainKeeper.all_keys()
self.assertDictEqual(allkeys, {'accepted': [],
'local': [self.localFilepath],
@ -217,9 +222,9 @@ class BasicTestCase(unittest.TestCase):
allkeys = self.mainKeeper.all_keys()
self.assertDictEqual(allkeys, {'accepted': [],
'local': [self.localFilepath],
'pending': ['other1', 'other2'],
'rejected': []} )
'local': [self.localFilepath],
'pending': ['other1', 'other2'],
'rejected': []})
remotekeys = self.mainKeeper.read_remote(other1['name'])
self.assertDictEqual(remotekeys, {})
@ -232,56 +237,60 @@ class BasicTestCase(unittest.TestCase):
'rejected': [],
'pending': ['other1', 'other2']})
allremotekeys = self.mainKeeper.read_all_remote()
self.assertDictEqual(allremotekeys, {'other1':
{'verify': other1['verhex'],
'minion_id': 'other1',
'acceptance': 'pending',
'pub': other1['pubhex'],},
'other2':
{'verify': other2['verhex'],
'minion_id': 'other2',
'acceptance': 'pending',
'pub': other2['pubhex'],}
})
self.assertDictEqual(allremotekeys,
{'other1':
{'verify': salt.utils.stringutils.to_str(other1['verhex']),
'minion_id': 'other1',
'acceptance': 'pending',
'pub': salt.utils.stringutils.to_str(other1['pubhex']),
},
'other2':
{'verify': salt.utils.stringutils.to_str(other2['verhex']),
'minion_id': 'other2',
'acceptance': 'pending',
'pub': salt.utils.stringutils.to_str(other2['pubhex']),
}
})
self.mainKeeper.accept_all()
allkeys = self.mainKeeper.all_keys()
self.assertDictEqual(allkeys, {'accepted': ['other1', 'other2'],
'local': [self.localFilepath],
'pending': [],
'rejected': []} )
'local': [self.localFilepath],
'pending': [],
'rejected': []})
remotekeys = self.mainKeeper.read_remote(other1['name'])
self.assertDictEqual(remotekeys, { 'minion_id': 'other1',
'pub': other1['pubhex'],
'verify': other1['verhex']} )
self.assertDictEqual(remotekeys, {'minion_id': 'other1',
'pub': salt.utils.stringutils.to_str(other1['pubhex']),
'verify': salt.utils.stringutils.to_str(other1['verhex'])})
remotekeys = self.mainKeeper.read_remote(other2['name'])
self.assertDictEqual(remotekeys, { 'minion_id': 'other2',
'pub': other2['pubhex'],
'verify': other2['verhex']} )
self.assertDictEqual(remotekeys, {'minion_id': 'other2',
'pub': salt.utils.stringutils.to_str(other2['pubhex']),
'verify': salt.utils.stringutils.to_str(other2['verhex'])})
listkeys = self.mainKeeper.list_keys()
self.assertDictEqual(listkeys, {'accepted': ['other1', 'other2'],
'rejected': [],
'pending': []})
allremotekeys = self.mainKeeper.read_all_remote()
self.assertDictEqual(allremotekeys, {'other1':
{'verify': other1['verhex'],
'minion_id': 'other1',
'acceptance': 'accepted',
'pub': other1['pubhex'],},
'other2':
{'verify': other2['verhex'],
'minion_id': 'other2',
'acceptance': 'accepted',
'pub': other2['pubhex'],}
})
self.assertDictEqual(allremotekeys,
{'other1':
{'verify': salt.utils.stringutils.to_str(other1['verhex']),
'minion_id': 'other1',
'acceptance': 'accepted',
'pub': salt.utils.stringutils.to_str(other1['pubhex']),
},
'other2':
{'verify': salt.utils.stringutils.to_str(other2['verhex']),
'minion_id': 'other2',
'acceptance': 'accepted',
'pub': salt.utils.stringutils.to_str(other2['pubhex']),
}
})
def testDelete(self):
'''
@ -291,9 +300,9 @@ class BasicTestCase(unittest.TestCase):
self.opts['auto_accept'] = True
self.assertTrue(self.opts['auto_accept'])
self.assertDictEqual(self.mainKeeper.all_keys(), {'accepted': [],
'local': [],
'rejected': [],
'pending': []})
'local': [],
'rejected': [],
'pending': []})
localkeys = self.mainKeeper.read_local()
self.assertDictEqual(localkeys, {})
@ -301,8 +310,9 @@ class BasicTestCase(unittest.TestCase):
main = self.createRoadData(name='main', base=self.baseDirpath)
self.mainKeeper.write_local(main['prihex'], main['sighex'])
localkeys = self.mainKeeper.read_local()
self.assertDictEqual(localkeys, {'priv': main['prihex'],
'sign': main['sighex']})
self.assertDictEqual(localkeys,
{'priv': salt.utils.stringutils.to_str(main['prihex']),
'sign': salt.utils.stringutils.to_str(main['sighex'])})
allkeys = self.mainKeeper.all_keys()
self.assertDictEqual(allkeys, {'accepted': [],
'local': [self.localFilepath],
@ -319,70 +329,73 @@ class BasicTestCase(unittest.TestCase):
allkeys = self.mainKeeper.all_keys()
self.assertDictEqual(allkeys, {'accepted': ['other1', 'other2'],
'local': [self.localFilepath],
'pending': [],
'rejected': []} )
'local': [self.localFilepath],
'pending': [],
'rejected': []})
remotekeys = self.mainKeeper.read_remote(other1['name'])
self.assertDictEqual(remotekeys, { 'minion_id': 'other1',
'pub': other1['pubhex'],
'verify': other1['verhex']} )
self.assertDictEqual(remotekeys, {'minion_id': 'other1',
'pub': salt.utils.stringutils.to_str(other1['pubhex']),
'verify': salt.utils.stringutils.to_str(other1['verhex']),
})
remotekeys = self.mainKeeper.read_remote(other2['name'])
self.assertDictEqual(remotekeys, { 'minion_id': 'other2',
'pub': other2['pubhex'],
'verify': other2['verhex']} )
self.assertDictEqual(remotekeys, {'minion_id': 'other2',
'pub': salt.utils.stringutils.to_str(other2['pubhex']),
'verify': salt.utils.stringutils.to_str(other2['verhex']),
})
listkeys = self.mainKeeper.list_keys()
self.assertDictEqual(listkeys, {'accepted': ['other1', 'other2'],
'rejected': [],
'pending': []})
allremotekeys = self.mainKeeper.read_all_remote()
self.assertDictEqual(allremotekeys, {'other1':
{'verify': other1['verhex'],
'minion_id': 'other1',
'acceptance': 'accepted',
'pub': other1['pubhex']},
'other2':
{'verify': other2['verhex'],
'minion_id': 'other2',
'acceptance': 'accepted',
'pub': other2['pubhex'],}
})
self.assertDictEqual(allremotekeys,
{'other1':
{'verify': salt.utils.stringutils.to_str(other1['verhex']),
'minion_id': 'other1',
'acceptance': 'accepted',
'pub': salt.utils.stringutils.to_str(other1['pubhex'])
},
'other2':
{'verify': salt.utils.stringutils.to_str(other2['verhex']),
'minion_id': 'other2',
'acceptance': 'accepted',
'pub': salt.utils.stringutils.to_str(other2['pubhex']),
}
})
self.mainKeeper.delete_key(match=other1['name'])
allkeys = self.mainKeeper.all_keys()
self.assertDictEqual(allkeys, {'accepted': ['other2'],
'local': [self.localFilepath],
'pending': [],
'rejected': []} )
'local': [self.localFilepath],
'pending': [],
'rejected': []})
remotekeys = self.mainKeeper.read_remote(other1['name'])
self.assertDictEqual(remotekeys, {} )
self.assertDictEqual(remotekeys, {})
remotekeys = self.mainKeeper.read_remote(other2['name'])
self.assertDictEqual(remotekeys, { 'minion_id': 'other2',
'pub': other2['pubhex'],
'verify': other2['verhex']} )
self.assertDictEqual(remotekeys, {'minion_id': 'other2',
'pub': salt.utils.stringutils.to_str(other2['pubhex']),
'verify': salt.utils.stringutils.to_str(other2['verhex'])})
listkeys = self.mainKeeper.list_keys()
self.assertDictEqual(listkeys, {'accepted': [ 'other2'],
self.assertDictEqual(listkeys, {'accepted': ['other2'],
'rejected': [],
'pending': []})
allremotekeys = self.mainKeeper.read_all_remote()
self.assertDictEqual(allremotekeys, {
'other2':
{'verify': other2['verhex'],
'minion_id': 'other2',
'acceptance': 'accepted',
'pub': other2['pubhex'],}
})
self.assertDictEqual(allremotekeys,
{'other2':
{'verify': salt.utils.stringutils.to_str(other2['verhex']),
'minion_id': 'other2',
'acceptance': 'accepted',
'pub': salt.utils.stringutils.to_str(other2['pubhex']),
}
})
def runOne(test):
@ -393,11 +406,12 @@ def runOne(test):
suite = unittest.TestSuite([test])
unittest.TextTestRunner(verbosity=2).run(suite)
def runSome():
'''
Unittest runner
'''
tests = []
tests = []
names = ['testAutoAccept',
'testManualAccept',
'testDelete']
@ -407,6 +421,7 @@ def runSome():
suite = unittest.TestSuite(tests)
unittest.TextTestRunner(verbosity=2).run(suite)
def runAll():
'''
Unittest runner
@ -416,12 +431,12 @@ def runAll():
unittest.TextTestRunner(verbosity=2).run(suite)
if __name__ == '__main__' and __package__ is None:
# console.reinit(verbosity=console.Wordage.concise)
#console.reinit(verbosity=console.Wordage.concise)
runAll() # run all unittests
runAll() #run all unittests
# runSome() #only run some
#runSome()#only run some
#runOne('testDelete')
# runOne('testDelete')

View File

@ -13,10 +13,11 @@ else:
# pylint: enable=blacklisted-import
import os
import stat
import time
import tempfile
import shutil
import socket
import stat
import tempfile
import time
from ioflo.aid.odicting import odict
from ioflo.aid.timing import StoreTimer
@ -29,6 +30,7 @@ from raet.road import estating, stacking
from salt.daemons import salting
import salt.utils.kinds as kinds
import salt.utils.stringutils
def setUpModule():
@ -232,20 +234,21 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
os.path.join('main', 'raet', 'main_master')))
self.assertTrue(main.ha, ("0.0.0.0", raeting.RAET_PORT))
self.assertIs(main.keep.auto, raeting.AutoMode.never.value)
self.assertDictEqual(main.keep.loadLocalData(), {'name': mainData['name'],
'uid': 1,
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
})
self.assertDictEqual(main.keep.loadLocalData(),
{'name': mainData['name'],
'uid': 1,
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
data1 = self.createRoadData(role='remote1',
kind=kinds.APPL_KIND_NAMES[kinds.applKinds.minion],
@ -282,7 +285,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7532],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data1['kind'],
@ -290,8 +293,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data1['role'],
'acceptance': 0,
'verhex': data1['verhex'],
'pubhex': data1['pubhex'],
'verhex': salt.utils.stringutils.to_str(data1['verhex']),
'pubhex': salt.utils.stringutils.to_str(data1['pubhex']),
},
'remote2_minion':
{'name': data2['name'],
@ -300,7 +303,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7533],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data2['kind'],
@ -308,8 +311,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data2['role'],
'acceptance': 0,
'verhex': data2['verhex'],
'pubhex': data2['pubhex'],
'verhex': salt.utils.stringutils.to_str(data2['verhex']),
'pubhex': salt.utils.stringutils.to_str(data2['pubhex']),
}
})
@ -362,14 +365,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7531],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7531],
'role': otherData['role'],
'sighex': otherData['sighex'],
'prihex': otherData['prihex'],
'sighex': salt.utils.stringutils.to_str(otherData['sighex']),
'prihex': salt.utils.stringutils.to_str(otherData['prihex']),
})
data3 = self.createRoadData(role='remote3',
@ -405,7 +408,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7534],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data3['kind'],
@ -413,8 +416,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data3['role'],
'acceptance': 0,
'verhex': data3['verhex'],
'pubhex': data3['pubhex'],
'verhex': salt.utils.stringutils.to_str(data3['verhex']),
'pubhex': salt.utils.stringutils.to_str(data3['pubhex']),
},
'remote4_minion':
{
@ -424,7 +427,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7535],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data4['kind'],
@ -432,8 +435,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data4['role'],
'acceptance': 0,
'verhex': data4['verhex'],
'pubhex': data4['pubhex'],
'verhex': salt.utils.stringutils.to_str(data4['verhex']),
'pubhex': salt.utils.stringutils.to_str(data4['pubhex']),
}
})
@ -477,14 +480,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
data1 = self.createRoadData(role='remote1',
@ -520,7 +523,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7532],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data1['kind'],
@ -528,8 +531,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data1['role'],
'acceptance': 1,
'verhex': data1['verhex'],
'pubhex': data1['pubhex'],
'verhex': salt.utils.stringutils.to_str(data1['verhex']),
'pubhex': salt.utils.stringutils.to_str(data1['pubhex']),
},
'remote2_minion':
{'name': data2['name'],
@ -538,7 +541,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7533],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data2['kind'],
@ -546,8 +549,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data2['role'],
'acceptance': 1,
'verhex': data2['verhex'],
'pubhex': data2['pubhex'],
'verhex': salt.utils.stringutils.to_str(data2['verhex']),
'pubhex': salt.utils.stringutils.to_str(data2['pubhex']),
}
})
@ -600,14 +603,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7531],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7531],
'role': otherData['role'],
'sighex': otherData['sighex'],
'prihex': otherData['prihex'],
'sighex': salt.utils.stringutils.to_str(otherData['sighex']),
'prihex': salt.utils.stringutils.to_str(otherData['prihex']),
})
data3 = self.createRoadData(role='remote3',
@ -643,7 +646,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7534],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data3['kind'],
@ -651,8 +654,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data3['role'],
'acceptance': 1,
'verhex': data3['verhex'],
'pubhex': data3['pubhex'],
'verhex': salt.utils.stringutils.to_str(data3['verhex']),
'pubhex': salt.utils.stringutils.to_str(data3['pubhex']),
},
'remote4_minion':
{
@ -662,7 +665,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7535],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data4['kind'],
@ -670,8 +673,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data4['role'],
'acceptance': 1,
'verhex': data4['verhex'],
'pubhex': data4['pubhex'],
'verhex': salt.utils.stringutils.to_str(data4['verhex']),
'pubhex': salt.utils.stringutils.to_str(data4['pubhex']),
}
})
@ -715,13 +718,13 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
'role': mainData['role'],
})
@ -759,7 +762,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7532],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data1['kind'],
@ -767,8 +770,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data1['role'],
'acceptance': 1,
'verhex': data1['verhex'],
'pubhex': data1['pubhex'],
'verhex': salt.utils.stringutils.to_str(data1['verhex']),
'pubhex': salt.utils.stringutils.to_str(data1['pubhex']),
},
'remote2_minion':
{
@ -778,7 +781,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7533],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data2['kind'],
@ -786,8 +789,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data2['role'],
'acceptance': 1,
'verhex': data2['verhex'],
'pubhex': data2['pubhex'],
'verhex': salt.utils.stringutils.to_str(data2['verhex']),
'pubhex': salt.utils.stringutils.to_str(data2['pubhex']),
}
})
@ -840,14 +843,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7531],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7531],
'role': otherData['role'],
'sighex': otherData['sighex'],
'prihex': otherData['prihex'],
'sighex': salt.utils.stringutils.to_str(otherData['sighex']),
'prihex': salt.utils.stringutils.to_str(otherData['prihex']),
})
data3 = self.createRoadData(role='remote3',
@ -883,7 +886,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7534],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data3['kind'],
@ -891,8 +894,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data3['role'],
'acceptance': 1,
'verhex': data3['verhex'],
'pubhex': data3['pubhex'],
'verhex': salt.utils.stringutils.to_str(data3['verhex']),
'pubhex': salt.utils.stringutils.to_str(data3['pubhex']),
},
'remote4_minion':
{
@ -902,7 +905,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7535],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data4['kind'],
@ -910,8 +913,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data4['role'],
'acceptance': 1,
'verhex': data4['verhex'],
'pubhex': data4['pubhex'],
'verhex': salt.utils.stringutils.to_str(data4['verhex']),
'pubhex': salt.utils.stringutils.to_str(data4['pubhex']),
}
})
@ -955,14 +958,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
# add multiple remotes all with same role
@ -1006,7 +1009,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7532],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data1['kind'],
@ -1014,8 +1017,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data1['role'],
'acceptance': 0,
'verhex': data1['verhex'],
'pubhex': data1['pubhex'],
'verhex': salt.utils.stringutils.to_str(data1['verhex']),
'pubhex': salt.utils.stringutils.to_str(data1['pubhex']),
},
'primary_caller':
{
@ -1025,7 +1028,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7533],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data2['kind'],
@ -1033,8 +1036,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data1['role'],
'acceptance': 0,
'verhex': data1['verhex'],
'pubhex': data1['pubhex'],
'verhex': salt.utils.stringutils.to_str(data1['verhex']),
'pubhex': salt.utils.stringutils.to_str(data1['pubhex']),
}
})
@ -1104,14 +1107,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
# add multiple remotes all with same role
@ -1149,7 +1152,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7532],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data1['kind'],
@ -1157,8 +1160,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data1['role'],
'acceptance': 1,
'verhex': data2['verhex'],
'pubhex': data2['pubhex'],
'verhex': salt.utils.stringutils.to_str(data2['verhex']),
'pubhex': salt.utils.stringutils.to_str(data2['pubhex']),
},
'primary_syndic':
{
@ -1168,7 +1171,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7533],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data2['kind'],
@ -1176,8 +1179,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data2['role'],
'acceptance': 1,
'verhex': data2['verhex'],
'pubhex': data2['pubhex'],
'verhex': salt.utils.stringutils.to_str(data2['verhex']),
'pubhex': salt.utils.stringutils.to_str(data2['pubhex']),
}
})
@ -1248,14 +1251,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
# add multiple remotes all with same role but different keys
@ -1300,7 +1303,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7532],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data1['kind'],
@ -1308,8 +1311,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data1['role'],
'acceptance': 1,
'verhex': data1['verhex'],
'pubhex': data1['pubhex'],
'verhex': salt.utils.stringutils.to_str(data1['verhex']),
'pubhex': salt.utils.stringutils.to_str(data1['pubhex']),
},
'primary_syndic':
{
@ -1319,7 +1322,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7533],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'main': False,
'kind': data2['kind'],
@ -1327,8 +1330,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'joined': None,
'role': data2['role'],
'acceptance': 1,
'verhex': data1['verhex'],
'pubhex': data1['pubhex'],
'verhex': salt.utils.stringutils.to_str(data1['verhex']),
'pubhex': salt.utils.stringutils.to_str(data1['pubhex']),
}
})
@ -1399,14 +1402,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
opts = self.createOpts(role='other',
@ -1441,14 +1444,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7531],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7531],
'role': otherData['role'],
'sighex': otherData['sighex'],
'prihex': otherData['prihex'],
'sighex': salt.utils.stringutils.to_str(otherData['sighex']),
'prihex': salt.utils.stringutils.to_str(otherData['prihex']),
})
self.join(other, main)
@ -1524,14 +1527,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
opts = self.createOpts(role='other',
@ -1566,14 +1569,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7531],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7531],
'role': otherData['role'],
'sighex': otherData['sighex'],
'prihex': otherData['prihex'],
'sighex': salt.utils.stringutils.to_str(otherData['sighex']),
'prihex': salt.utils.stringutils.to_str(otherData['prihex']),
})
self.join(other, main)
@ -1645,14 +1648,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
opts = self.createOpts(role='other',
@ -1687,13 +1690,13 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7531],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7531],
'sighex': otherData['sighex'],
'prihex': otherData['prihex'],
'sighex': salt.utils.stringutils.to_str(otherData['sighex']),
'prihex': salt.utils.stringutils.to_str(otherData['prihex']),
'role': otherData['role'],
})
@ -1766,14 +1769,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
opts = self.createOpts(role='primary',
@ -1808,14 +1811,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7531],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7531],
'role': other1Data['role'],
'sighex': other1Data['sighex'],
'prihex': other1Data['prihex'],
'sighex': salt.utils.stringutils.to_str(other1Data['sighex']),
'prihex': salt.utils.stringutils.to_str(other1Data['prihex']),
})
self.join(other1, main)
@ -1876,13 +1879,13 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7532],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7532],
'sighex': other2Data['sighex'],
'prihex': other2Data['prihex'],
'sighex': salt.utils.stringutils.to_str(other2Data['sighex']),
'prihex': salt.utils.stringutils.to_str(other2Data['prihex']),
'role': other2Data['role'],
})
@ -1936,14 +1939,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7532],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7532],
'role': other2Data['role'],
'sighex': other1Data['sighex'],
'prihex': other1Data['prihex'],
'sighex': salt.utils.stringutils.to_str(other1Data['sighex']),
'prihex': salt.utils.stringutils.to_str(other1Data['prihex']),
})
# should join since same role and keys
@ -2021,14 +2024,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7530],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7530],
'role': mainData['role'],
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'sighex': salt.utils.stringutils.to_str(mainData['sighex']),
'prihex': salt.utils.stringutils.to_str(mainData['prihex']),
})
opts = self.createOpts(role='primary',
@ -2063,14 +2066,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7531],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7531],
'role': other1Data['role'],
'sighex': other1Data['sighex'],
'prihex': other1Data['prihex'],
'sighex': salt.utils.stringutils.to_str(other1Data['sighex']),
'prihex': salt.utils.stringutils.to_str(other1Data['prihex']),
})
self.join(other1, main)
@ -2130,14 +2133,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class
'ha': ['127.0.0.1', 7532],
'iha': None,
'natted': None,
'fqdn': '1.0.0.127.in-addr.arpa',
'fqdn': socket.getfqdn('127.0.0.1'),
'dyned': None,
'sid': 0,
'puid': 1,
'aha': ['0.0.0.0', 7532],
'role': other2Data['role'],
'sighex': other2Data['sighex'],
'prihex': other2Data['prihex'],
'sighex': salt.utils.stringutils.to_str(other2Data['sighex']),
'prihex': salt.utils.stringutils.to_str(other2Data['prihex']),
})
# should join since open mode
@ -2225,8 +2228,8 @@ if __name__ == '__main__' and __package__ is None:
#console.reinit(verbosity=console.Wordage.concise)
#runAll() # run all unittests
runAll() # run all unittests
runSome() # only run some
#runSome() # only run some
#runOne('testBootstrapRoleAuto')

View File

@ -5,6 +5,7 @@ Raet Ioflo Behavior Unittests
from __future__ import absolute_import, print_function, unicode_literals
import sys
from salt.ext.six.moves import map
import importlib
# pylint: disable=blacklisted-import
if sys.version_info < (2, 7):
import unittest2 as unittest
@ -43,6 +44,9 @@ class StatsEventerTestCase(testing.FrameIofloTestCase):
'''
Call super if override so House Framer and Frame are setup correctly
'''
behaviors = ['salt.daemons.flo', 'salt.daemons.test.plan']
for behavior in behaviors:
mod = importlib.import_module(behavior)
super(StatsEventerTestCase, self).setUp()
def tearDown(self):
@ -723,8 +727,8 @@ if __name__ == '__main__' and __package__ is None:
# console.reinit(verbosity=console.Wordage.concise)
#runAll() # run all unittests
runAll() # run all unittests
runSome() # only run some
#runSome() # only run some
#runOne('testMasterLaneStats')

View File

@ -41,7 +41,8 @@ def __virtual__():
def start(docker_url='unix://var/run/docker.sock',
timeout=CLIENT_TIMEOUT,
tag='salt/engines/docker_events'):
tag='salt/engines/docker_events',
filters=None):
'''
Scan for Docker events and fire events
@ -52,10 +53,18 @@ def start(docker_url='unix://var/run/docker.sock',
engines:
- docker_events:
docker_url: unix://var/run/docker.sock
filters:
event:
- start
- stop
- die
- oom
The config above sets up engines to listen
for events from the Docker daemon and publish
them to the Salt event bus.
For filter reference, see https://docs.docker.com/engine/reference/commandline/events/
'''
if __opts__.get('__role') == 'master':
@ -81,7 +90,7 @@ def start(docker_url='unix://var/run/docker.sock',
client = docker.Client(base_url=docker_url, timeout=timeout)
try:
events = client.events()
events = client.events(filters=filters)
for event in events:
data = salt.utils.json.loads(event.decode(__salt_system_encoding__, errors='replace'))
# https://github.com/docker/cli/blob/master/cli/command/system/events.go#L109

View File

@ -6,7 +6,7 @@ HTTP Logstash engine
An engine that reads messages from the salt event bus and pushes
them onto a logstash endpoint via HTTP requests.
.. versionchanged:: Oxygen
.. versionchanged:: 2018.3.0
.. note::
By default, this engine take everything from the Salt bus and exports into

View File

@ -173,11 +173,7 @@ from __future__ import absolute_import, print_function, unicode_literals
import logging
# Import third party libraries
try:
import zmq
HAS_ZMQ = True
except ImportError:
HAS_ZMQ = False
from salt.utils.zeromq import zmq
try:
# pylint: disable=W0611
@ -209,7 +205,7 @@ def __virtual__():
'''
Load only if napalm-logs is installed.
'''
if not HAS_NAPALM_LOGS or not HAS_ZMQ:
if not HAS_NAPALM_LOGS or not zmq:
return (False, 'napalm_syslog could not be loaded. \
Please install napalm-logs library amd ZeroMQ.')
return True

View File

@ -285,7 +285,7 @@ class SaltRenderError(SaltException):
if self.line_num and self.buffer:
# Avoid circular import
import salt.utils.templates
self.context = salt.utils.templates.get_context(
self.context = salt.utils.stringutils.get_context(
self.buffer,
self.line_num,
marker=marker

View File

@ -37,7 +37,7 @@ def inet_pton(address_family, ip_string):
# This will catch IP Addresses such as 10.1.2
if address_family == socket.AF_INET:
try:
ipaddress.ip_address(six.u(ip_string))
ipaddress.ip_address(six.text_type(ip_string))
except ValueError:
raise socket.error('illegal IP address string passed to inet_pton')
return socket.inet_aton(ip_string)

View File

@ -12,9 +12,9 @@ the Master config file.
fileserver_backend:
- azurefs
Starting in Oxygen, this fileserver requires the standalone Azure Storage SDK
for Python. Theoretically any version >= v0.20.0 should work, but it was
developed against the v0.33.0 version.
Starting in Salt 2018.3.0, this fileserver requires the standalone Azure
Storage SDK for Python. Theoretically any version >= v0.20.0 should work, but
it was developed against the v0.33.0 version.
Each storage container will be mapped to an environment. By default, containers
will be mapped to the ``base`` environment. You can override this behavior with

View File

@ -14,7 +14,7 @@ Master config file.
- gitfs
.. note::
``git`` also works here. Prior to the Oxygen release, *only* ``git``
``git`` also works here. Prior to the 2018.3.0 release, *only* ``git``
would work.
The Git fileserver backend supports both pygit2_ and GitPython_, to provide the

View File

@ -11,7 +11,7 @@ Master config file.
- hgfs
.. note::
``hg`` also works here. Prior to the Oxygen release, *only* ``hg`` would
``hg`` also works here. Prior to the 2018.3.0 release, *only* ``hg`` would
work.
After enabling this backend, branches, bookmarks, and tags in a remote

View File

@ -17,8 +17,8 @@ allowed to push files to the Master), and ``minionfs`` must be added to the
- minionfs
.. note::
``minion`` also works here. Prior to the Oxygen release, *only* ``minion``
would work.
``minion`` also works here. Prior to the 2018.3.0 release, *only*
``minion`` would work.
Other minionfs settings include: :conf_master:`minionfs_whitelist`,
:conf_master:`minionfs_blacklist`, :conf_master:`minionfs_mountpoint`, and

View File

@ -13,8 +13,8 @@ Master config file.
- svnfs
.. note::
``svn`` also works here. Prior to the Oxygen release, *only* ``svn`` would
work.
``svn`` also works here. Prior to the 2018.3.0 release, *only* ``svn``
would work.
This backend assumes a standard svn layout with directories for ``branches``,
``tags``, and ``trunk``, at the repository root.

View File

@ -24,6 +24,13 @@ import uuid
from errno import EACCES, EPERM
import datetime
# pylint: disable=import-error
try:
import dateutil.tz
_DATEUTIL_TZ = True
except ImportError:
_DATEUTIL_TZ = False
__proxyenabled__ = ['*']
__FQDN__ = None
@ -1333,19 +1340,22 @@ def _get_interfaces():
return _INTERFACES
def _parse_os_release():
def _parse_os_release(os_release_files):
'''
Parse /etc/os-release and return a parameter dictionary
Parse os-release and return a parameter dictionary
See http://www.freedesktop.org/software/systemd/man/os-release.html
for specification of the file format.
'''
filename = '/etc/os-release'
if not os.path.isfile(filename):
filename = '/usr/lib/os-release'
data = dict()
for filename in os_release_files:
if os.path.isfile(filename):
break
else:
# None of the specified os-release files exist
return data
with salt.utils.files.fopen(filename) as ifile:
regex = re.compile('^([\\w]+)=(?:\'|")?(.*?)(?:\'|")?$')
for line in ifile:
@ -1540,13 +1550,15 @@ def os_data():
# to be incorrectly set to "Arch".
grains['osfullname'] = 'Antergos Linux'
elif 'lsb_distrib_id' not in grains:
if os.path.isfile('/etc/os-release') or os.path.isfile('/usr/lib/os-release'):
os_release = _parse_os_release()
os_release = _parse_os_release(['/etc/os-release', '/usr/lib/os-release'])
if os_release:
if 'NAME' in os_release:
grains['lsb_distrib_id'] = os_release['NAME'].strip()
if 'VERSION_ID' in os_release:
grains['lsb_distrib_release'] = os_release['VERSION_ID']
if 'PRETTY_NAME' in os_release:
if 'VERSION_CODENAME' in os_release:
grains['lsb_distrib_codename'] = os_release['VERSION_CODENAME']
elif 'PRETTY_NAME' in os_release:
codename = os_release['PRETTY_NAME']
# https://github.com/saltstack/salt/issues/44108
if os_release['ID'] == 'debian':
@ -1810,7 +1822,7 @@ def os_data():
grains['osrelease_info']
)
os_name = grains['os' if grains.get('os') in (
'FreeBSD', 'OpenBSD', 'NetBSD', 'Mac', 'Raspbian') else 'osfullname']
'Debian', 'FreeBSD', 'OpenBSD', 'NetBSD', 'Mac', 'Raspbian') else 'osfullname']
grains['osfinger'] = '{0}-{1}'.format(
os_name, grains['osrelease'] if os_name in ('Ubuntu',) else grains['osrelease_info'][0])
@ -1840,6 +1852,8 @@ def locale_info():
grains['locale_info']['defaultlanguage'] = 'unknown'
grains['locale_info']['defaultencoding'] = 'unknown'
grains['locale_info']['detectedencoding'] = __salt_system_encoding__
if _DATEUTIL_TZ:
grains['locale_info']['timezone'] = datetime.datetime.now(dateutil.tz.tzlocal()).tzname()
return grains
@ -2517,13 +2531,16 @@ def _linux_iqn():
ret = []
initiator = '/etc/iscsi/initiatorname.iscsi'
if os.path.isfile(initiator):
try:
with salt.utils.files.fopen(initiator, 'r') as _iscsi:
for line in _iscsi:
line = line.strip()
if line.startswith('InitiatorName='):
ret.append(line.split('=', 1)[1])
except IOError as ex:
if ex.errno != os.errno.ENOENT:
log.debug("Error while accessing '%s': %s", initiator, ex)
return ret

View File

@ -7,7 +7,7 @@ ZFS grain provider
:depends: salt.utils, salt.module.cmdmod
:platform: illumos,freebsd,linux
.. versionadded:: Oxygen
.. versionadded:: 2018.3.0
'''
from __future__ import absolute_import, print_function, unicode_literals

View File

@ -125,7 +125,7 @@ class KeyCLI(object):
if self.opts['eauth']:
if 'token' in self.opts:
try:
with salt.utils.files.fopen(os.path.join(self.opts['key_dir'], '.root_key'), 'r') as fp_:
with salt.utils.files.fopen(os.path.join(self.opts['cachedir'], '.root_key'), 'r') as fp_:
low['key'] = \
salt.utils.stringutils.to_unicode(fp_.readline())
except IOError:
@ -1082,6 +1082,8 @@ class RaetKey(Key):
pre_path = os.path.join(pre, minion_id)
rej_path = os.path.join(rej, minion_id)
# open mode is turned on, force accept the key
pub = salt.utils.stringutils.to_str(pub)
verify = salt.utils.stringutils.to_str(verify)
keydata = {
'minion_id': minion_id,
'pub': pub,
@ -1148,7 +1150,7 @@ class RaetKey(Key):
verify: <verify>
'''
path = os.path.join(self.opts['pki_dir'], status, minion_id)
with salt.utils.files.fopen(path, 'r') as fp_:
with salt.utils.files.fopen(path, 'rb') as fp_:
keydata = self.serial.loads(fp_.read())
return 'pub: {0}\nverify: {1}'.format(
keydata['pub'],
@ -1158,7 +1160,7 @@ class RaetKey(Key):
'''
Return a sha256 kingerprint for the key
'''
with salt.utils.files.fopen(path, 'r') as fp_:
with salt.utils.files.fopen(path, 'rb') as fp_:
keydata = self.serial.loads(fp_.read())
key = 'pub: {0}\nverify: {1}'.format(
keydata['pub'],
@ -1442,7 +1444,7 @@ class RaetKey(Key):
if os.path.exists(path):
#mode = os.stat(path).st_mode
os.chmod(path, stat.S_IWUSR | stat.S_IRUSR)
with salt.utils.files.fopen(path, 'w+') as fp_:
with salt.utils.files.fopen(path, 'w+b') as fp_:
fp_.write(self.serial.dumps(keydata))
os.chmod(path, stat.S_IRUSR)
os.umask(c_umask)

View File

@ -17,6 +17,7 @@ import logging.handlers
# Import salt libs
from salt.log.mixins import NewStyleClassMixIn, ExcInfoOnLogLevelFormatMixIn
from salt.ext.six.moves import queue
log = logging.getLogger(__name__)
@ -176,9 +177,9 @@ if sys.version_info < (3, 2):
'''
try:
self.queue.put_nowait(record)
except self.queue.Full:
except queue.Full:
sys.stderr.write('[WARNING ] Message queue is full, '
'unable to write "{0}" to log', record
'unable to write "{0}" to log'.format(record)
)
def prepare(self, record):

Some files were not shown because too many files have changed in this diff Show More