Merge remote-tracking branch 'upstream/2015.8' into merge-forward-develop

Conflicts:
    doc/topics/cloud/digitalocean.rst
    salt/cloud/clouds/digital_ocean.py
    salt/cloud/clouds/linode.py
    salt/loader.py
    salt/modules/blockdev.py
    salt/modules/boto_route53.py
    salt/modules/boto_vpc.py
    salt/modules/bsd_shadow.py
    salt/modules/file.py
    salt/modules/rabbitmq.py
    salt/modules/schedule.py
    salt/modules/win_network.py
    salt/runners/state.py
    salt/spm/__init__.py
    tests/unit/modules/blockdev_test.py
This commit is contained in:
Colton Myers 2015-11-02 18:19:01 -07:00
commit 32969b2408
119 changed files with 2772 additions and 1068 deletions

View File

@ -4,7 +4,7 @@
``spm``
=======
Salt Package Manager
:ref:`Salt Package Manager <spm>`
Synopsis
========

View File

@ -14,13 +14,25 @@ More information about Azure is located at `http://www.windowsazure.com/
Dependencies
============
* The `Azure <https://pypi.python.org/pypi/azure>`_ Python SDK >= 0.11.1.
* The `Azure <https://pypi.python.org/pypi/azure>`_ Python SDK >= 0.10.2 and < 1.0.0
* The python-requests library, for Python < 2.7.9.
* A Microsoft Azure account
* OpenSSL (to generate the certificates)
* `Salt <https://github.com/saltstack/salt>`_
.. note::
The Azure driver is currently being updated to work with the new version of
the Python Azure SDK, 1.0.0. However until that process is complete, this
driver will not work with Azure 1.0.0. Please be sure you're running on a
minimum version of 0.10.2 and less than version 1.0.0.
See `Issue #27980`_ for more information.
.. _Issue #27980: https://github.com/saltstack/salt/issues/27980
Configuration
=============

View File

@ -45,14 +45,14 @@ Set up an initial profile at ``/etc/salt/cloud.profiles`` or in the
.. code-block:: yaml
digitalocean-ubuntu:
provider: my-digitalocean-config
image: 14.04 x64
size: 512MB
location: New York 1
private_networking: True
backups_enabled: True
ipv6: True
create_dns_record: True
provider: my-digitalocean-config
image: 14.04 x64
size: 512MB
location: New York 1
private_networking: True
backups_enabled: True
ipv6: True
create_dns_record: True
Locations can be obtained using the ``--list-locations`` option for the ``salt-cloud``
command:
@ -134,6 +134,28 @@ command:
True
...SNIP...
Profile Specifics:
------------------
ssh_username
------------
If using a FreeBSD image from Digital Ocean, you'll need to set the ``ssh_username``
setting to ``freebsd`` in your profile configuration.
.. code-block:: yaml
digitalocean-freebsd:
provider: my-digitalocean-config
image: 10.2
size: 512MB
ssh_username: freebsd
Miscellaneous Information
=========================
.. note::
DigitalOcean's concept of ``Applications`` is nothing more than a

View File

@ -414,13 +414,17 @@ from the Salt Master. For example:
{% set some_data = salt.pillar.get('some_data', {'sane default': True}) %}
{# or #}
{% import_yaml 'path/to/file.yaml' as some_data %}
{# or #}
{% load_json 'path/to/file.json' as some_data %}
{% import_json 'path/to/file.json' as some_data %}
{# or #}
{% load_text 'path/to/ssh_key.pub' as ssh_pub_key %}
{% import_text 'path/to/ssh_key.pub' as ssh_pub_key %}
{# or #}

View File

@ -55,13 +55,18 @@ Silent Installer Options
========================
The installer can be run silently by providing the `/S` option at the command
line. The options `/master` and `/minion-name` allow for configuring the master
hostname and minion name, respectively. Here's an example of using the silent
installer:
line. The installer also accepts the following options for configuring the Salt
Minion silently:
- `/master=` A string value to set the IP address or host name of the master. Default value is 'salt'
- `/minion-name=` A string value to set the minion name. Default is 'hostname'
- `/start-service=` Either a 1 or 0. '1' will start the service, '0' will not. Default is to start the service after installation.
Here's an example of using the silent installer:
.. code-block:: bat
Salt-Minion-0.17.0-Setup-amd64.exe /S /master=yoursaltmaster /minion-name=yourminionname
Salt-Minion-2015.5.6-Setup-amd64.exe /S /master=yoursaltmaster /minion-name=yourminionname /start-service=0
Running the Salt Minion on Windows as an Unprivileged User

View File

@ -39,6 +39,12 @@ SPM (Salt Package Manager)
Allows Salt formulas to be packaged for ease of deployment. See :ref:`spm <spm>`.
.. note::
The spm executable was not included in the Debian or Ubuntu packages for the
2015.8.0 or the 2015.8.1 releases. This executable will be included in an
upcoming release. As a workaround, copy the SPM script from the salt library
installation into ``/usr/local/bin`` or your local equivalent.
Specify a Single Environment for Top Files
==========================================

View File

@ -3,7 +3,7 @@
====================
Salt Package Manager
====================
The Salt Package Manager, or SPM, allows Salt formulas to be packaged, for ease
The Salt Package Manager, or :ref:`SPM <spm-cli>`, allows Salt formulas to be packaged, for ease
of deployment. The design of SPM was influenced by other existing packaging
systems including RPM, Yum, and Pacman.
@ -60,6 +60,10 @@ For instance, if this version was released in June 2015, the package version
should be ``201506``. If multiple releases are made in a month, the ``release``
field should be used.
minimum_version
~~~~~~~~~~~~~~~
Minimum recommended version of Salt to use this formula. Not currently enforced.
release
~~~~~~~
This field refers primarily to a release of a version, but also to multiple
@ -71,6 +75,7 @@ summary
A one-line description of the package.
description
~~~~~~~~~~~
A more detailed description of the package which can contain more than one line.
Optional Fields
@ -94,7 +99,15 @@ are already treated specially, such as ``pillar.example`` and ``_modules/``.
dependencies
~~~~~~~~~~~~
A list of packages which must be installed before this package can function.
A list of packages which must be installed before this package can function. If
a matching package is found in an SPM repository, the dependency is installed
automatically.
recommended
~~~~~~~~~~~
A list of optional packages that are recommended to be installed with the
package. This list is displayed in an informational message
when the package is installed to SPM.
Building a Package
------------------
@ -167,11 +180,11 @@ To install from a repository, use the ``spm install`` command:
spm install apache
To install from a local file, use the ``spm local_install`` command:
To install from a local file, use the ``spm local install`` command:
.. code-block:: bash
spm local_install /srv/spm/apache-201506-1.spm
spm local install /srv/spm/apache-201506-1.spm
Currently, SPM does not check to see if files are already in place before
installing them. That means that existing files will be overwritten without
@ -243,8 +256,8 @@ By default, package files are installed using the ``local`` module. This module
applies files to the local filesystem, on the machine that the package is
installed on.
Please see the SPM Development Guide for information on creating new modules
for package file management.
Please see the :ref:`SPM Development Guide <spm-development>` for information
on creating new modules for package file management.
SPM Configuration

View File

@ -67,3 +67,42 @@ nodegroup`` on the line directly following the nodegroup name.
A limited amount of functionality, such as targeting with -N from the command-line may be
available without a restart.
Using Nodegroups in SLS files
=============================
To use Nodegroups in Jinja logic for SLS files, the :conf_master:`pillar_opts` option in
``/etc/salt/master`` must be set to "True". This will pass the master's configuration as
Pillar data to each minion.
.. note::
If the master's configuration contains any sensitive data, this will be passed to each minion.
Do not enable this option if you have any configuration data that you do not want to get
on your minions.
Also, if you make changes to your nodegroups, you might need to run
``salt '*' saltutil.refresh_pillar`` after restarting the master.
Once pillar_opts is enabled, you can find the nodegroups under the "master" pillar.
To make sure that only the correct minions are targeted,
you should use each matcher for the nodegroup definition.
For example, to check if a minion is in the 'webserver' nodegroup:
.. code-block:: yaml
nodegroups:
webserver: 'G@os:Debian and L@minion1,minion2'
.. code-block:: yaml
{% if grains.id in salt['pillar.get']('master:nodegroups:webserver', [])
and grains.os in salt['pillar.get']('master:nodegroups:webserver', []) %}
...
{% endif %}
.. note::
If you do not include all of the matchers used to define a nodegroup,
Salt might incorrectly target minions that meet some of the nodegroup
requirements, but not all of them.

View File

@ -4,10 +4,26 @@
MinionFS Backend Walkthrough
============================
Propagating Files
=================
.. versionadded:: 2014.1.0
Sometimes, you might need to propagate files that are generated on a minion.
Salt already has a feature to send files from a minion to the master:
Sometimes, one might need to propagate files that are generated on a minion.
Salt already has a feature to send files from a minion to the master.
Enabling File Propagation
=========================
To enable propagation, the :conf_master:`file_recv` option needs to be set to ``True``.
.. code-block:: yaml
file_recv: True
These changes require a restart of the master, then new requests for the
``salt://minion-id/`` protocol will send files that are pushed by ``cp.push``
from ``minion-id`` to the master.
.. code-block:: bash
@ -24,6 +40,9 @@ This command will store the file, including its full path, under
<salt.modules.cp.push>`. To get up to speed, check out the
:doc:`walkthrough </topics/tutorials/walkthrough>`.
MinionFS Backend
================
Since it is not a good idea to expose the whole :conf_master:`cachedir`, MinionFS
should be used to send these files to other minions.
@ -136,4 +155,4 @@ Or we can use a more elegant and salty way to add an SSH key:
.. [*] Yes, that was the actual key on my server, but the server is already destroyed.
.. [*] Yes, that was the actual key on my server, but the server is already destroyed.

View File

@ -321,6 +321,19 @@ Nested pillar values can also be set via the command line:
the key that is passed in will overwrite the entire value of that key,
rather than merging only the specified value set via the command line.
The example below will swap the value for vim with telnet in the previously
specified list, notice the nested pillar dict:
.. code-block:: bash
salt '*' state.sls edit.vim pillar='{"pkgs": {"vim": "telnet"}}'
.. note::
This will attempt to install telnet on your minions, feel free to
uninstall the package or replace telnet value with anything else.
More On Pillar
==============

View File

@ -31,6 +31,14 @@ You can specify multiple :ref:`state-declaration` under an
Try stopping Apache before running ``state.highstate`` once again and observe
the output.
.. note::
For those running RedhatOS derivatives (Centos, AWS), you will want to specify the
service name to be httpd. More on state service here, :mod:`service state
<salt.states.service>`. With the example above, just add "- name: httpd"
above the require line and with the same spacing.
Require other states
====================

View File

@ -6,7 +6,7 @@
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
; MUI 1.67 compatible ------
!include "MUI.nsh"
!include "MUI2.nsh"
!include "nsDialogs.nsh"
!include "LogicLib.nsh"
@ -36,6 +36,7 @@ Var MasterHost
Var MasterHost_State
Var MinionName
Var MinionName_State
Var StartService
; MUI Settings
!define MUI_ABORTWARNING
@ -54,6 +55,7 @@ Page custom nsDialogsPage nsDialogsPageLeave
!insertmacro MUI_PAGE_INSTFILES
; Finish page
!define MUI_PAGE_CUSTOMFUNCTION_SHOW FinishPage.Show
!define MUI_FINISHPAGE_RUN "$INSTDIR\nssm"
!define MUI_FINISHPAGE_RUN_PARAMETERS "start salt-minion"
!insertmacro MUI_PAGE_FINISH
@ -76,6 +78,7 @@ Page custom nsDialogsPage nsDialogsPageLeave
Function nsDialogsPage
nsDialogs::Create 1018
Pop $Dialog
@ -110,6 +113,68 @@ Function nsDialogsPageLeave
FunctionEnd
Function getMinionConfig
confFind:
IfFileExists "$INSTDIR\conf\minion" confFound confNotFound
confNotFound:
${If} $INSTDIR == "c:\salt\bin\Scripts"
StrCpy $INSTDIR "C:\salt"
goto confFind
${Else}
goto confReallyNotFound
${EndIf}
confFound:
FileOpen $0 "$INSTDIR\conf\minion" r
confLoop:
FileRead $0 $1
IfErrors EndOfFile
${StrLoc} $2 $1 "master:" ">"
${If} $2 == 0
${StrStrAdv} $2 $1 "master: " ">" ">" "0" "0" "0"
${Trim} $2 $2
StrCpy $MasterHost_State $2
${EndIf}
${StrLoc} $2 $1 "id:" ">"
${If} $2 == 0
${StrStrAdv} $2 $1 "id: " ">" ">" "0" "0" "0"
${Trim} $2 $2
StrCpy $MinionName_State $2
${EndIf}
Goto confLoop
EndOfFile:
FileClose $0
confReallyNotFound:
Push $R0
Push $R1
Push $R2
${GetParameters} $R0
${GetOptions} $R0 "/master=" $R1
${GetOptions} $R0 "/minion-name=" $R2
${IfNot} $R1 == ""
StrCpy $MasterHost_State $R1
${ElseIf} $MasterHost_State == ""
StrCpy $MasterHost_State "salt"
${EndIf}
${IfNot} $R2 == ""
StrCpy $MinionName_State $R2
${ElseIf} $MinionName_State == ""
StrCpy $MinionName_State "hostname"
${EndIf}
Pop $R2
Pop $R1
Pop $R0
FunctionEnd
Function updateMinionConfig
ClearErrors
@ -181,13 +246,54 @@ Section -Post
RMDir /R "$INSTDIR\var\cache\salt" ; removing cache from old version
Call updateMinionConfig
Call checkStartService
SectionEnd
Function FinishPage.Show
${IfNot} $StartService == 1
SendMessage $mui.FinishPage.Run ${BM_SETCHECK} ${BST_UNCHECKED} 0
${EndIf}
FunctionEnd
Function checkStartService
; Check if the start-service option was passed
Push $R0
Push $R1
${GetParameters} $R0
${GetOptions} $R0 "/start-service=" $R1
; If start-service was passed something, then set it
${IfNot} $R1 == ""
StrCpy $StartService $R1
; Otherwise default to 1
${Else}
StrCpy $StartService 1
${EndIf}
Pop $R0
Pop $R1
FunctionEnd
Function .onInstSuccess
; If the installer is running Silently, start the service
IfSilent 0 +2
Exec 'net start salt-minion'
; If the installer is running Silently, start the service
IfSilent silentOption notSilent
silentOption:
; If start-service is 1, then start the service
${If} $StartService == 1
Exec 'net start salt-minion'
${EndIf}
notSilent:
FunctionEnd
@ -233,62 +339,37 @@ Function .onInit
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
confFind:
IfFileExists "$INSTDIR\conf\minion" confFound confNotFound
Call getMinionConfig
confNotFound:
; Check for existing installation
ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString"
StrCmp $R0 "" skipUninstall
; Found existing installation, prompt to uninstall
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "${PRODUCT_NAME} is already installed. $\n$\nClick `OK` to remove the existing installation." /SD IDOK IDOK uninst
Abort
uninst:
; Make sure we're in the right directory
${If} $INSTDIR == "c:\salt\bin\Scripts"
StrCpy $INSTDIR "C:\salt"
goto confFind
${Else}
goto confReallyNotFound
${EndIf}
confFound:
FileOpen $0 "$INSTDIR\conf\minion" r
; Stop and remove the salt-minion service
ExecWait "net stop salt-minion"
ExecWait "sc delete salt-minion"
confLoop:
FileRead $0 $1
IfErrors EndOfFile
${StrLoc} $2 $1 "master:" ">"
${If} $2 == 0
${StrStrAdv} $2 $1 "master: " ">" ">" "0" "0" "0"
${Trim} $2 $2
StrCpy $MasterHost_State $2
${EndIf}
; Remove salt binaries and batch files
Delete "$INSTDIR\uninst.exe"
Delete "$INSTDIR\nssm.exe"
Delete "$INSTDIR\salt*"
RMDir /r "$INSTDIR\bin"
${StrLoc} $2 $1 "id:" ">"
${If} $2 == 0
${StrStrAdv} $2 $1 "id: " ">" ">" "0" "0" "0"
${Trim} $2 $2
StrCpy $MinionName_State $2
${EndIf}
; Remove registry entries
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
Goto confLoop
EndOfFile:
FileClose $0
confReallyNotFound:
Push $R0
Push $R1
Push $R2
${GetParameters} $R0
${GetOptions} $R0 "/master=" $R1
${GetOptions} $R0 "/minion-name=" $R2
${IfNot} $R1 == ""
StrCpy $MasterHost_State $R1
${ElseIf} $MasterHost_State == ""
StrCpy $MasterHost_State "salt"
${EndIf}
${IfNot} $R2 == ""
StrCpy $MinionName_State $R2
${ElseIf} $MinionName_State == ""
StrCpy $MinionName_State "hostname"
${EndIf}
Pop $R2
Pop $R1
Pop $R0
skipUninstall:
FunctionEnd

View File

@ -46,6 +46,7 @@ from salt.exceptions import (
)
import salt.ext.six as six
from salt.ext.six.moves import zip
from salt.ext.six import string_types
# Import Third Party Libs
try:
@ -206,6 +207,9 @@ def get_image(vm_):
vm_image = config.get_cloud_config_value(
'image', vm_, __opts__, search_global=False
)
if not isinstance(vm_image, string_types):
vm_image = str(vm_image)
for image in images:
if vm_image in (images[image]['name'],
images[image]['slug'],

View File

@ -568,7 +568,7 @@ def create_disk_from_distro(vm_, linode_id, swap_size=None):
r'''
Creates the disk for the Linode from the distribution.
vm_
vm\_
The VM profile to create the disk for.
linode_id
@ -609,7 +609,7 @@ def create_swap_disk(vm_, linode_id, swap_size=None):
r'''
Creates the disk for the specified Linode.
vm_
vm\_
The VM profile to create the swap disk for.
linode_id
@ -752,7 +752,7 @@ def get_disk_size(vm_, swap, linode_id):
r'''
Returns the size of of the root disk in MB.
vm_
vm\_
The VM to get the disk size for.
'''
disk_size = get_linode(kwargs={'linode_id': linode_id})['TOTALHD']
@ -765,7 +765,7 @@ def get_distribution_id(vm_):
r'''
Returns the distribution ID for a VM
vm_
vm\_
The VM to get the distribution ID for
'''
distributions = _query('avail', 'distributions')['DATA']
@ -894,7 +894,7 @@ def get_password(vm_):
r'''
Return the password to use for a VM.
vm_
vm\_
The configuration to obtain the password from.
'''
return config.get_cloud_config_value(
@ -960,7 +960,7 @@ def get_pub_key(vm_):
r'''
Return the SSH pubkey.
vm_
vm\_
The configuration to obtain the public key from.
'''
return config.get_cloud_config_value(
@ -972,7 +972,7 @@ def get_swap_size(vm_):
r'''
Returns the amoutn of swap space to be used in MB.
vm_
vm\_
The VM profile to obtain the swap size from.
'''
return config.get_cloud_config_value(
@ -984,7 +984,7 @@ def get_vm_size(vm_):
r'''
Returns the VM's size.
vm_
vm\_
The VM to get the size for.
'''
vm_size = config.get_cloud_config_value('size', vm_, __opts__)

View File

@ -645,7 +645,7 @@ def create(vm_):
return
rackconnectv3 = config.get_cloud_config_value(
'rackconnectv3', vm_, __opts__, default='False',
'rackconnectv3', vm_, __opts__, default=False,
search_global=False
)
@ -721,21 +721,29 @@ def create(vm_):
data.public_ips = access_ip
return data
# populate return data with private_ips
# when ssh_interface is set to private_ips and public_ips exist
if not result and ssh_interface(vm_) == 'private_ips':
for private_ip in private:
ignore_ip = ignore_cidr(vm_, private_ip)
if private_ip not in data.private_ips and not ignore_ip:
result.append(private_ip)
if cloudnetwork(vm_) is True:
data.public_ips = access_ip
return data
if public:
data.public_ips = public
if ssh_interface(vm_) != 'private_ips':
return data
if result:
log.debug('result = {0}'.format(result))
data.private_ips = result
if ssh_interface(vm_) == 'private_ips':
return data
if public:
data.public_ips = public
if ssh_interface(vm_) != 'private_ips':
return data
try:
data = salt.utils.cloud.wait_for_ip(
__query_node_data,

View File

@ -2,6 +2,7 @@
'''
Saltify Module
==============
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.

View File

@ -2748,6 +2748,8 @@ def apply_minion_config(overrides=None,
if overrides:
opts.update(overrides)
opts['__cli'] = os.path.basename(sys.argv[0])
if len(opts['sock_dir']) > len(opts['cachedir']) + 10:
opts['sock_dir'] = os.path.join(opts['cachedir'], '.salt-unix')

View File

@ -28,6 +28,7 @@ import salt.utils.templates
import salt.utils.url
import salt.utils.gzip_util
import salt.utils.http
from salt.utils.locales import sdecode
from salt.utils.openstack.swift import SaltSwift
# pylint: disable=no-name-in-module,import-error
@ -213,8 +214,7 @@ class Client(object):
ret = []
path = salt.utils.locales.sdecode(path)
path = self._check_proto(path)
path = self._check_proto(sdecode(path))
# We want to make sure files start with this *directory*, use
# '/' explicitly because the master (that's generating the
# list of files) only runs on POSIX
@ -229,7 +229,6 @@ class Client(object):
# go through the list of all files finding ones that are in
# the target directory and caching them
for fn_ in self.file_list(saltenv):
fn_ = salt.utils.locales.sdecode(fn_)
if fn_.strip() and fn_.startswith(path):
if salt.utils.check_include_exclude(
fn_, include_pat, exclude_pat):
@ -794,12 +793,8 @@ class LocalClient(Client):
os.path.join(path, prefix), followlinks=True
):
for fname in files:
ret.append(
os.path.relpath(
os.path.join(root, fname),
path
)
)
relpath = os.path.relpath(os.path.join(root, fname), path)
ret.append(sdecode(relpath))
return ret
def file_list_emptydirs(self, saltenv='base', prefix='', env=None):
@ -826,7 +821,7 @@ class LocalClient(Client):
os.path.join(path, prefix), followlinks=True
):
if len(dirs) == 0 and len(files) == 0:
ret.append(os.path.relpath(root, path))
ret.append(sdecode(os.path.relpath(root, path)))
return ret
def dir_list(self, saltenv='base', prefix='', env=None):
@ -852,7 +847,7 @@ class LocalClient(Client):
for root, dirs, files in os.walk(
os.path.join(path, prefix), followlinks=True
):
ret.append(os.path.relpath(root, path))
ret.append(sdecode(os.path.relpath(root, path)))
return ret
def hash_file(self, path, saltenv='base', env=None):

View File

@ -1537,6 +1537,7 @@ def fqdn_ip6():
def ip_interfaces():
'''
Provide a dict of the connected interfaces and their ip addresses
The addresses will be passed as a list for each interface
'''
# Provides:
# ip_interfaces
@ -1564,6 +1565,7 @@ def ip_interfaces():
def ip4_interfaces():
'''
Provide a dict of the connected interfaces and their ip4 addresses
The addresses will be passed as a list for each interface
'''
# Provides:
# ip_interfaces
@ -1588,6 +1590,7 @@ def ip4_interfaces():
def ip6_interfaces():
'''
Provide a dict of the connected interfaces and their ip6 addresses
The addresses will be passed as a list for each interface
'''
# Provides:
# ip_interfaces

37
salt/grains/fx2.py Normal file
View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
'''
Generate baseline proxy minion grains
'''
from __future__ import absolute_import
import salt.utils
__proxyenabled__ = ['rest_sample']
__virtualname__ = 'rest_sample'
def __virtual__():
if not salt.utils.is_proxy():
return False
else:
return __virtualname__
def kernel():
return {'kernel': 'proxy'}
def os():
return {'os': 'RestExampleOS'}
def location():
return {'location': 'In this darn virtual machine. Let me out!'}
def os_family():
return {'os_family': 'proxy'}
def os_data():
return {'os_data': 'funkyHttp release 1.0.a.4.g'}

View File

@ -43,11 +43,10 @@ def defaults():
def facts():
if 'proxymodule' in __opts__:
if 'junos.facts' in __opts__['proxymodule']:
facts = __opts__['proxymodule']['junos.facts']()
facts['version_info'] = 'override'
return facts
if 'junos.facts' in __proxy__:
facts = __proxy__['junos.facts']()
facts['version_info'] = 'override'
return facts
return None

View File

@ -581,7 +581,7 @@ def grain_funcs(opts):
)
def grains(opts, force_refresh=False):
def grains(opts, force_refresh=False, proxy=None):
'''
Return the functions for the dynamic grains and the values for the static
grains.
@ -1095,7 +1095,7 @@ class LazyLoader(salt.utils.lazy.LazyDict):
log.error('Module/package collision: {0!r} and {1!r}'.format(
fpath, self.file_mapping[f_noext][0]
))
if suffix_order.index(ext) >= suffix_order.index(curr_ext):
if not curr_ext or suffix_order.index(ext) >= suffix_order.index(curr_ext):
continue # Next filename
# Made it this far - add it

View File

@ -1206,6 +1206,13 @@ class Minion(MinionBase):
salt.utils.appendproctitle(data['jid'])
# this seems awkward at first, but it's a workaround for Windows
# multiprocessing communication.
if sys.platform.startswith('win') and \
opts['multiprocessing'] and \
not salt.log.is_logging_configured():
# We have to re-init the logging system for Windows
salt.log.setup_console_logger(log_level=opts.get('log_level', 'info'))
if opts.get('log_file'):
salt.log.setup_logfile_logger(opts['log_file'], opts.get('log_level_logfile', 'info'))
if not minion_instance:
minion_instance = cls(opts)
ret = {

View File

@ -298,7 +298,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def version(*names, **kwargs):

View File

@ -14,17 +14,28 @@ import logging
# Import salt libs
import salt.utils
import salt.utils.decorators as decorators
log = logging.getLogger(__name__)
__func_alias__ = {
'format_': 'format'
}
__virtualname__ = 'blockdev'
def __virtual__():
'''
Only work on POSIX-like systems
Only load this module if the blockdev utility is available
'''
if salt.utils.is_windows():
return False
return True
return (False, ('The {0} execution module '
'is not supported on windows'.format(__virtualname__)))
elif not salt.utils.which('blockdev'):
return (False, ('Cannot load the {0} execution module: '
'blockdev utility not found'.format(__virtualname__)))
return __virtualname__
def tune(device, **kwargs):
@ -38,7 +49,7 @@ def tune(device, **kwargs):
.. code-block:: bash
salt '*' blockdev.tune /dev/sda1 read-ahead=1024 read-write=True
salt '*' blockdev.tune /dev/sdX1 read-ahead=1024 read-write=True
Valid options are: ``read-ahead``, ``filesystem-read-ahead``,
``read-only``, ``read-write``.
@ -53,6 +64,7 @@ def tune(device, **kwargs):
return __salt__['disk.tune'](device, **kwargs)
@decorators.which('wipefs')
def wipe(device):
'''
Remove the filesystem information
@ -64,7 +76,7 @@ def wipe(device):
.. code-block:: bash
salt '*' blockdev.wipe /dev/sda1
salt '*' blockdev.wipe /dev/sdX1
'''
salt.utils.warn_until(
'Carbon',
@ -80,10 +92,14 @@ def dump(device, args=None):
.. deprecated:: Boron
Use `disk.dump`
args
a list containing only the desired arguments to return
CLI Example:
.. code-block:: bash
salt '*' extfs.dump /dev/sda1
salt '*' blockdev.dump /dev/sdX1
'''
salt.utils.warn_until(
'Carbon',
@ -92,6 +108,94 @@ def dump(device, args=None):
return __salt__['disk.dump'](device, args)
@decorators.which('sync')
@decorators.which('mkfs')
def format_(device, fs_type='ext4', inode_size=None, lazy_itable_init=None):
'''
Format a filesystem onto a block device
.. versionadded:: 2015.8.2
device
The block device in which to create the new filesystem
fs_type
The type of filesystem to create
inode_size
Size of the inodes
This option is only enabled for ext and xfs filesystems
lazy_itable_init
If enabled and the uninit_bg feature is enabled, the inode table will
not be fully initialized by mke2fs. This speeds up filesystem
initialization noticeably, but it requires the kernel to finish
initializing the filesystem in the background when the filesystem
is first mounted. If the option value is omitted, it defaults to 1 to
enable lazy inode table zeroing.
This option is only enabled for ext filesystems
CLI Example:
.. code-block:: bash
salt '*' blockdev.format /dev/sdX1
'''
cmd = ['mkfs', '-t', str(fs_type)]
if inode_size is not None:
if fs_type[:3] == 'ext':
cmd.extend(['-i', str(inode_size)])
elif fs_type == 'xfs':
cmd.extend(['-i', 'size={0}'.format(inode_size)])
if lazy_itable_init is not None:
if fs_type[:3] == 'ext':
cmd.extend(['-E', 'lazy_itable_init={0}'.format(lazy_itable_init)])
cmd.append(str(device))
mkfs_success = __salt__['cmd.retcode'](cmd, ignore_retcode=True) == 0
sync_success = __salt__['cmd.retcode']('sync', ignore_retcode=True) == 0
return all([mkfs_success, sync_success])
@decorators.which_bin(['lsblk', 'df'])
def fstype(device):
'''
Return the filesystem name of a block device
.. versionadded:: 2015.8.2
device
The name of the block device
CLI Example:
.. code-block:: bash
salt '*' blockdev.fstype /dev/sdX1
'''
if salt.utils.which('lsblk'):
lsblk_out = __salt__['cmd.run']('lsblk -o fstype {0}'.format(device)).splitlines()
if len(lsblk_out) > 1:
fs_type = lsblk_out[1].strip()
if fs_type:
return fs_type
if salt.utils.which('df'):
# the fstype was not set on the block device, so inspect the filesystem
# itself for its type
df_out = __salt__['cmd.run']('df -T {0}'.format(device)).splitlines()
if len(df_out) > 1:
fs_type = df_out[1]
if fs_type:
return fs_type
return ''
@decorators.which('resize2fs')
def resize2fs(device):
'''
Resizes the filesystem.
@ -102,7 +206,7 @@ def resize2fs(device):
CLI Example:
.. code-block:: bash
salt '*' blockdev.resize2fs /dev/sda1
salt '*' blockdev.resize2fs /dev/sdX1
'''
salt.utils.warn_until(
'Carbon',

View File

@ -338,7 +338,7 @@ def subnet_group_exists(name, tags=None, region=None, key=None, keyid=None, prof
salt myminion boto_elasticache.subnet_group_exists my-param-group \
region=us-east-1
'''
conn = _get_conn(region, key, keyid, profile)
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if not conn:
return False
try:
@ -364,7 +364,7 @@ def create_subnet_group(name, description, subnet_ids, tags=None, region=None,
"group description" '[subnet-12345678, subnet-87654321]' \
region=us-east-1
'''
conn = _get_conn(region, key, keyid, profile)
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if not conn:
return False
if subnet_group_exists(name, tags, region, key, keyid, profile):
@ -438,7 +438,7 @@ def delete_subnet_group(name, region=None, key=None, keyid=None, profile=None):
salt myminion boto_elasticache.delete_subnet_group my-subnet-group \
region=us-east-1
'''
conn = _get_conn(region, key, keyid, profile)
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if not conn:
return False
try:

View File

@ -164,7 +164,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def remove(name=None, pkgs=None, **kwargs):

View File

@ -146,7 +146,7 @@ def set_expire(name, expire):
def del_password(name):
'''
.. versionadded:: 2015.8.3
.. versionadded:: 2015.8.2
Delete the password from name user

View File

@ -102,20 +102,34 @@ def chocolatey_version():
'''
if 'chocolatey._version' in __context__:
return __context__['chocolatey._version']
cmd = [_find_chocolatey(__context__, __salt__)]
out = __salt__['cmd.run'](cmd, python_shell=False)
for line in out.splitlines():
line = line.lower()
if line.startswith('chocolatey v'):
__context__['chocolatey._version'] = line[12:]
return __context__['chocolatey._version']
elif line.startswith('version: '):
try:
__context__['chocolatey._version'] = \
line.split(None, 1)[-1].strip("'")
def find_version(legacy=False):
cmd = [_find_chocolatey(__context__, __salt__)]
if legacy:
cmd.append('help')
out = __salt__['cmd.run'](cmd, python_shell=False)
for line in out.splitlines():
line = line.lower()
if line.startswith('chocolatey v'):
__context__['chocolatey._version'] = line[12:]
return __context__['chocolatey._version']
except Exception:
pass
elif line.startswith('version: '):
try:
__context__['chocolatey._version'] = \
line.split(None, 1)[-1].strip("'")
return __context__['chocolatey._version']
except Exception:
pass
return None
# First try to find if we have a newer version of choco
# which doesn't contain the help command,
# else try for a legacy version
for legacy in [False, True]:
ver = find_version(legacy=legacy)
if ver is not None:
return ver
raise CommandExecutionError('Unable to determine Chocolatey version')

View File

@ -316,7 +316,7 @@ def list_tab(user):
return ret
# For consistency's sake
ls = list_tab # pylint: disable=C0103
ls = salt.utils.alias_function(list_tab, 'ls')
def set_special(user, special, cmd):
@ -526,7 +526,7 @@ def rm_job(user,
return comdat['stderr']
return ret
rm = rm_job # pylint: disable=C0103
rm = salt.utils.alias_function(rm_job, 'rm')
def set_env(user, name, value=None):

View File

@ -882,9 +882,9 @@ def _parse_settings_bond_1(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)
@ -968,9 +968,9 @@ def _parse_settings_bond_3(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)
@ -1012,9 +1012,9 @@ def _parse_settings_bond_4(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)
@ -1055,9 +1055,9 @@ def _parse_settings_bond_5(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)
@ -1091,9 +1091,9 @@ def _parse_settings_bond_6(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)

View File

@ -3018,7 +3018,7 @@ def copy_from(name, source, dest, overwrite=False, makedirs=False):
# Docker cp gets a file from the container, alias this to copy_from
cp = copy_from
cp = salt.utils.alias_function(copy_from, 'cp')
@_ensure_exists
@ -4302,7 +4302,7 @@ def pause(name):
.format(name))}
return _change_state(name, 'pause', 'paused')
freeze = pause
freeze = salt.utils.alias_function(pause, 'freeze')
@_ensure_exists
@ -4497,7 +4497,7 @@ def unpause(name):
.format(name))}
return _change_state(name, 'unpause', 'running')
unfreeze = unpause
unfreeze = salt.utils.alias_function(unpause, 'unfreeze')
def wait(name):

View File

@ -42,10 +42,10 @@ def __parse_drac(output):
drac[section].update(dict(
[[prop.strip() for prop in i.split('=')]]
))
else:
section = i.strip()[:-1]
if section not in drac and section:
drac[section] = {}
else:
section = i.strip()[1:-1]
if section not in drac and section:
drac[section] = {}
return drac
@ -125,11 +125,37 @@ def __execute_ret(command, host=None,
if len(l.strip()) == 0:
continue
fmtlines.append(l)
if '=' in l:
continue
break
cmd['stdout'] = '\n'.join(fmtlines)
return cmd
def get_dns_dracname(host=None,
admin_username=None, admin_password=None):
import pydevd
pydevd.settrace('172.16.207.1', port=65500, stdoutToServer=True, stderrToServer=True)
ret = __execute_ret('get iDRAC.NIC.DNSRacName', host=host,
admin_username=admin_username,
admin_password=admin_password)
parsed = __parse_drac(ret['stdout'])
return parsed
def set_dns_dracname(name,
host=None,
admin_username=None, admin_password=None):
ret = __execute_ret('set iDRAC.NIC.DNSRacName {0}'.format(name),
host=host,
admin_username=admin_username,
admin_password=admin_password)
return ret
def system_info(host=None,
admin_username=None, admin_password=None,
module=None):
@ -645,6 +671,41 @@ def set_network(ip, netmask, gateway, host=None,
))
def server_power(status, host=None,
admin_username=None,
admin_password=None,
module=None):
'''
status
One of 'powerup', 'powerdown', 'powercycle', 'hardreset',
'graceshutdown'
host
The chassis host.
admin_username
The username used to access the chassis.
admin_password
The password used to access the chassis.
module
The element to reboot on the chassis such as a blade. If not provided,
the chassis will be rebooted.
CLI Example:
.. code-block:: bash
salt dell dracr.server_reboot
salt dell dracr.server_reboot module=server-1
'''
return __execute_cmd('serveraction {0}'.format(status),
host=host, admin_username=admin_username,
admin_password=admin_password, module=module)
def server_reboot(host=None,
admin_username=None,
admin_password=None,
@ -946,10 +1007,9 @@ def set_slotname(slot, name, host=None,
admin_username=root admin_password=secret
'''
return __execute_cmd('setslotname -i {0} {1}'.format(
slot, name[0:14], host=host,
admin_username=admin_username,
admin_password=admin_password))
return __execute_cmd('config -g cfgServerInfo -o cfgServerName -i {0} {1}'.format(slot, name),
host=host, admin_username=admin_username,
admin_password=admin_password)
def set_chassis_name(name,
@ -1147,8 +1207,67 @@ def get_chassis_location(host=None,
'''
return system_info(host=host,
admin_username=admin_username,
admin_password=admin_password)['Chassis Information']['Chassis Location']
admin_username=admin_username,
admin_password=admin_password)['Chassis Information']['Chassis Location']
def set_chassis_datacenter(location,
host=None,
admin_username=None,
admin_password=None):
'''
Set the location of the chassis.
location
The name of the datacenter to be set on the chassis.
host
The chassis host.
admin_username
The username used to access the chassis.
admin_password
The password used to access the chassis.
CLI Example:
.. code-block:: bash
salt '*' dracr.set_chassis_datacenter datacenter-name host=111.222.333.444
admin_username=root admin_password=secret
'''
return set_general('cfgLocation', 'cfgLocationDatacenter', location,
host=host, admin_username=admin_username,
admin_password=admin_password)
def get_chassis_datacenter(host=None,
admin_username=None,
admin_password=None):
'''
Get the datacenter of the chassis.
host
The chassis host.
admin_username
The username used to access the chassis.
admin_password
The password used to access the chassis.
CLI Example:
.. code-block:: bash
salt '*' dracr.set_chassis_location host=111.222.333.444
admin_username=root admin_password=secret
'''
return get_general('cfgLocation', 'cfgLocationDatacenter', host=host,
admin_username=admin_username, admin_password=admin_password)
def set_general(cfg_sec, cfg_var, val, host=None,

View File

@ -237,7 +237,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def _get_upgradable(backtrack=3):

View File

@ -51,16 +51,23 @@ def fire_master(data, tag, preload=None):
pass
return True
if preload:
if preload or __opts__.get('__cli') == 'salt-call':
# If preload is specified, we must send a raw event (this is
# slower because it has to independently authenticate)
load = preload
if 'master_uri' not in __opts__:
__opts__['master_uri'] = 'tcp://{ip}:{port}'.format(
ip=salt.utils.ip_bracket(__opts__['interface']),
port=__opts__.get('ret_port', '4506') # TODO, no fallback
)
auth = salt.crypt.SAuth(__opts__)
load.update({'id': __opts__['id'],
load = {'id': __opts__['id'],
'tag': tag,
'data': data,
'tok': auth.gen_token('salt'),
'cmd': '_minion_event'})
'cmd': '_minion_event'}
if isinstance(preload, dict):
load.update(preload)
channel = salt.transport.Channel.factory(__opts__)
try:

View File

@ -30,6 +30,7 @@ import tempfile
import time
import glob
import hashlib
import mmap
from functools import reduce # pylint: disable=redefined-builtin
from collections import Iterable, Mapping
@ -1636,7 +1637,7 @@ def replace(path,
pattern,
repl,
count=0,
flags=0,
flags=8,
bufsize=1,
append_if_not_found=False,
prepend_if_not_found=False,
@ -1670,14 +1671,14 @@ def replace(path,
A list of flags defined in the :ref:`re module documentation
<contents-of-module-re>`. Each list item should be a string that will
correlate to the human-friendly flag name. E.g., ``['IGNORECASE',
'MULTILINE']``. Note: multiline searches must specify ``file`` as the
``bufsize`` argument below.
'MULTILINE']``. Optionally, ``flags`` may be an int, with a value
corresponding to the XOR (``|``) of all the desired flags. Defaults to
8 (which supports 'MULTILINE').
bufsize (int or str)
How much of the file to buffer into memory at once. The
default value ``1`` processes one line at a time. The special value
``file`` may be specified which will read the entire file into memory
before processing. Note: multiline searches must specify ``file``
buffering.
before processing.
append_if_not_found
.. versionadded:: 2014.7.0
@ -1778,8 +1779,9 @@ def replace(path,
flags_num = _get_flags(flags)
cpattern = re.compile(str(pattern), flags_num)
filesize = os.path.getsize(path)
if bufsize == 'file':
bufsize = os.path.getsize(path)
bufsize = filesize
# Search the file; track if any changes have been made for the return val
has_changes = False
@ -1800,60 +1802,57 @@ def replace(path,
append_if_not_found) \
else repl
if search_only:
# mmap throws a ValueError if the file is empty, but if it is empty we
# should be able to skip the search anyway. NOTE: Is there a use case for
# searching an empty file with an empty pattern?
if filesize is not 0:
# First check the whole file, determine whether to make the replacement
# Searching first avoids modifying the time stamp if there are no changes
try:
# allow multiline searching
with salt.utils.filebuffer.BufferedReader(path) as breader:
for chunk in breader:
if re.search(cpattern, chunk):
return True
return False
# Use a read-only handle to open the file
with salt.utils.fopen(path,
mode='rb',
buffering=bufsize) as r_file:
r_data = mmap.mmap(r_file.fileno(),
0,
access=mmap.ACCESS_READ)
if search_only:
# Just search; bail as early as a match is found
if re.search(cpattern, r_data):
return True # `with` block handles file closure
else:
result, nrepl = re.subn(cpattern, repl, r_data, count)
# found anything? (even if no change)
if nrepl > 0:
found = True
# Identity check the potential change
has_changes = True if pattern != repl else has_changes
if prepend_if_not_found or append_if_not_found:
# Search for content, to avoid pre/appending the
# content if it was pre/appended in a previous run.
if re.search('^{0}$'.format(re.escape(content)),
r_data,
flags=flags_num):
# Content was found, so set found.
found = True
# Keep track of show_changes here, in case the file isn't
# modified
if show_changes or append_if_not_found or \
prepend_if_not_found:
orig_file = r_data.read(filesize).splitlines(True)
new_file = result.splitlines(True)
except (OSError, IOError) as exc:
raise CommandExecutionError(
"Unable to read file '{0}'. Exception: {1}".format(path, exc)
"Unable to open file '{0}'. "
"Exception: {1}".format(path, exc)
)
# First check the whole file, determine whether to make the replacement
# Searching first avoids modifying the time stamp if there are no changes
try:
# Use a read-only handle to open the file
with salt.utils.fopen(path,
mode='r',
buffering=bufsize) as r_file:
count_replaced = 0
for line in r_file:
if count == 0 or count_replaced <= count:
result, nrepl = re.subn(cpattern, repl, line, count)
count_replaced += nrepl
else:
break
# found anything? (even if no change)
if nrepl > 0:
found = True
if prepend_if_not_found or append_if_not_found:
# Search for content, so we don't continue pre/appending
# the content if it's been pre/appended in a previous run.
if re.search('^{0}$'.format(re.escape(content)), line):
# Content was found, so set found.
found = True
# Identity check each potential change until one change is made
if has_changes is False and result != line:
has_changes = True
# Keep track of show_changes here, in case the file isn't
# modified
if show_changes or append_if_not_found or \
prepend_if_not_found:
orig_file.append(line)
new_file.append(result)
except (OSError, IOError) as exc:
raise CommandExecutionError(
"Unable to open file '{0}'. Exception: {1}".format(path, exc)
)
finally:
if r_data and isinstance(r_data, mmap.mmap):
r_data.close()
if has_changes and not dry_run:
# Write the replacement text in this block.
@ -1874,26 +1873,25 @@ def replace(path,
with salt.utils.fopen(temp_file,
mode='r',
buffering=bufsize) as r_file:
count_replaced = 0
for line in r_file:
result, nrepl = re.subn(cpattern, repl,
line, count)
if count == 0 or count_replaced <= count:
result, nrepl = re.subn(cpattern, repl, line, count)
count_replaced += nrepl
else:
result = line
try:
w_file.write(result)
except (OSError, IOError) as exc:
raise CommandExecutionError(
"Unable to write file '{0}'. Contents may "
"be truncated. Temporary file contains copy "
"at '{1}'. "
"Exception: {2}".format(path, temp_file, exc)
)
r_data = mmap.mmap(r_file.fileno(),
0,
access=mmap.ACCESS_READ)
result, nrepl = re.subn(cpattern, repl,
r_data, count)
try:
w_file.write(result)
except (OSError, IOError) as exc:
raise CommandExecutionError(
"Unable to write file '{0}'. Contents may "
"be truncated. Temporary file contains copy "
"at '{1}'. "
"Exception: {2}".format(path, temp_file, exc)
)
except (OSError, IOError) as exc:
raise CommandExecutionError("Exception: {0}".format(exc))
finally:
if r_data and isinstance(r_data, mmap.mmap):
r_data.close()
except (OSError, IOError) as exc:
raise CommandExecutionError("Exception: {0}".format(exc))
@ -2178,7 +2176,7 @@ def blockreplace(path,
def search(path,
pattern,
flags=0,
flags=8,
bufsize=1,
ignore_if_missing=False,
multiline=False
@ -4720,7 +4718,7 @@ def list_backups(path, limit=None):
[files[x] for x in sorted(files, reverse=True)[:limit]]
)))
list_backup = list_backups
list_backup = salt.utils.alias_function(list_backups, 'list_backup')
def list_backups_dir(path, limit=None):
@ -4892,7 +4890,7 @@ def delete_backup(path, backup_id):
return ret
remove_backup = delete_backup
remove_backup = salt.utils.alias_function(delete_backup, 'remove_backup')
def grep(path,

View File

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
'''
Support for firewalld.
@ -12,6 +11,7 @@ import logging
import re
# Import Salt Libs
from salt.exceptions import CommandExecutionError
import salt.utils
log = logging.getLogger(__name__)
@ -31,16 +31,18 @@ def __firewall_cmd(cmd):
'''
Return the firewall-cmd location
'''
out = __salt__['cmd.run']('{0} {1}'.format(
salt.utils.which('firewall-cmd'),
cmd))
firewall_cmd = '{0} {1}'.format(salt.utils.which('firewall-cmd'), cmd)
out = __salt__['cmd.run_all'](firewall_cmd)
if out == 'success':
return 'success'
elif 'Error' in out:
return out[5:-5]
return out
if out['retcode'] != 0:
if not out['stderr']:
msg = out['stdout']
else:
msg = out['stderr']
raise CommandExecutionError(
'firewall-cmd failed: {0}'.format(msg)
)
return out['stdout']
def __mgmt(name, _type, action):

View File

@ -192,7 +192,7 @@ def latest_version(*names, **kwargs):
return '' if len(names) == 1 else dict((x, '') for x in names)
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def version(*names, **kwargs):
@ -463,9 +463,9 @@ def remove(name=None, pkgs=None, **kwargs):
return salt.utils.compare_dicts(old, new)
# Support pkg.delete to remove packages to more closely match pkg_delete
delete = remove
delete = salt.utils.alias_function(remove, 'delete')
# No equivalent to purge packages, use remove instead
purge = remove
purge = salt.utils.alias_function(remove, 'purge')
def _rehash():

View File

@ -978,7 +978,7 @@ def config_get_regexp(key,
ret.setdefault(param, []).append(value)
return ret
config_get_regex = config_get_regexp
config_get_regex = salt.utils.alias_function(config_get_regexp, 'config_get_regex')
def config_set(key,

View File

@ -7,6 +7,9 @@ Virtual machine image management tools
from __future__ import absolute_import
import logging
# Import salt libs
import salt.utils
# Import 3rd-party libs
import salt.ext.six as six
@ -36,7 +39,7 @@ def mount_image(location):
return ''
# compatibility for api change
mnt_image = mount_image
mnt_image = salt.utils.alias_function(mount_image, 'mnt_image')
def umount_image(mnt):

View File

@ -211,7 +211,7 @@ def list_tab(user):
return ret
# For consistency's sake
ls = list_tab # pylint: disable=C0103
ls = salt.utils.alias_function(list_tab, 'ls')
def set_job(user, path, mask, cmd):
@ -315,4 +315,4 @@ def rm_job(user,
return ret
rm = rm_job # pylint: disable=C0103
rm = salt.utils.alias_function(rm_job, 'rm')

View File

@ -261,6 +261,9 @@ def build_rule(table='filter', chain=None, command=None, position='', full=None,
del kwargs[multiport_arg]
if 'comment' in kwargs:
if '-m comment' not in rule:
rule.append('-m comment')
rule.append('--comment "{0}"'.format(kwargs['comment']))
del kwargs['comment']

View File

@ -52,17 +52,16 @@ def facts_refresh():
Reload the facts dictionary from the device. Usually only needed
if the device configuration is changed by some other actor.
'''
return __opts__['proxymodule']['junos.refresh']()
return __proxy__['junos.refresh']()
def call_rpc():
return __opts__['proxymodule']['junos.rpc']()
return __proxy__['junos.rpc']()
def set_hostname(hostname=None, commit_change=True):
conn = __opts__['proxymodule']['junos.conn']()
conn = __proxy__['junos.conn']()
ret = dict()
if hostname is None:
ret['out'] = False
@ -84,7 +83,7 @@ def set_hostname(hostname=None, commit_change=True):
def commit():
conn = __opts__['proxymodule']['junos.conn']()
conn = __proxy__['junos.conn']()
ret = {}
commit_ok = conn.cu.commit_check()
if commit_ok:
@ -104,7 +103,7 @@ def commit():
def rollback():
ret = dict()
conn = __opts__['proxymodule']['junos.conn']()
conn = __proxy__['junos.conn']()
ret['out'] = conn.cu.rollback(0)
@ -118,7 +117,7 @@ def rollback():
def diff():
conn = __opts__['proxymodule']['junos.conn']()
conn = __proxy__['junos.conn']()
ret = dict()
ret['out'] = True
ret['message'] = conn.cu.diff()
@ -128,7 +127,18 @@ def diff():
def ping():
conn = __opts__['proxymodule']['junos.conn']()
conn = __proxy__['junos.conn']()
ret = dict()
ret['message'] = conn.probe()
ret['out'] = True
return ret
def cli(command):
conn = __proxy__['junos.conn']()
ret = dict()
ret['message'] = conn.cli(command)
ret['out'] = True
return ret

View File

@ -2612,7 +2612,7 @@ def destroy(name, stop=False, path=None):
return _change_state('lxc-destroy', name, None, path=path)
# Compatibility between LXC and nspawn
remove = destroy
remove = salt.utils.alias_function(destroy, 'remove')
def exists(name, path=None):
@ -2955,7 +2955,7 @@ def set_password(name, users, password, encrypted=True, path=None):
)
return True
set_pass = set_password
set_pass = salt.utils.alias_function(set_password, 'set_pass')
def update_lxc_conf(name, lxc_conf, lxc_conf_unset, path=None):
@ -4272,7 +4272,7 @@ def copy_to(name, source, dest, overwrite=False, makedirs=False, path=None):
overwrite=overwrite,
makedirs=makedirs)
cp = copy_to
cp = salt.utils.alias_function(copy_to, 'cp')
def read_conf(conf_file, out_format='simple'):

View File

@ -189,7 +189,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def remove(name=None, pkgs=None, **kwargs):

View File

@ -333,7 +333,7 @@ def filter_by(lookup, expr_form='compound', minion_id=None):
for key in lookup:
if minion_id and expr_funcs[expr_form](key, minion_id):
return lookup[key]
elif expr_funcs[expr_form](key, minion_id):
elif expr_funcs[expr_form](key):
return lookup[key]
return None

View File

@ -12,6 +12,7 @@ from __future__ import absolute_import
import logging
# Import salt libs
import salt.utils
from salt.exceptions import CommandExecutionError, SaltInvocationError
from salt.ext.six import integer_types
@ -234,7 +235,7 @@ def increment(key, delta=1, host=DEFAULT_HOST, port=DEFAULT_PORT):
except ValueError:
raise SaltInvocationError('Delta value must be an integer')
incr = increment
incr = salt.utils.alias_function(increment, 'incr')
def decrement(key, delta=1, host=DEFAULT_HOST, port=DEFAULT_PORT):
@ -265,4 +266,4 @@ def decrement(key, delta=1, host=DEFAULT_HOST, port=DEFAULT_PORT):
except ValueError:
raise SaltInvocationError('Delta value must be an integer')
decr = decrement
decr = salt.utils.alias_function(decrement, 'decr')

View File

@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
'''
Provides access to randomness generators.
=========================================
.. versionadded:: 2014.7.0
Provides access to randomness generators.
'''
from __future__ import absolute_import
# Import python libs

View File

@ -728,7 +728,7 @@ def hw_addr(iface):
return salt.utils.network.hw_addr(iface)
# Alias hwaddr to preserve backward compat
hwaddr = hw_addr
hwaddr = salt.utils.alias_function(hw_addr, 'hwaddr')
def interface(iface):
@ -874,7 +874,7 @@ def ip_addrs(interface=None, include_loopback=False, cidr=None):
else:
return addrs
ipaddrs = ip_addrs
ipaddrs = salt.utils.alias_function(ip_addrs, 'ipaddrs')
def ip_addrs6(interface=None, include_loopback=False, cidr=None):
@ -898,7 +898,7 @@ def ip_addrs6(interface=None, include_loopback=False, cidr=None):
else:
return addrs
ipaddrs6 = ip_addrs6
ipaddrs6 = salt.utils.alias_function(ip_addrs6, 'ipaddrs6')
def get_hostname():

View File

@ -862,7 +862,7 @@ def list_running():
# 'machinectl list' shows only running containers, so allow this to work as an
# alias to nspawn.list_running
list_ = list_running
list_ = salt.utils.alias_function(list_running, 'list_')
def list_stopped():
@ -1236,7 +1236,7 @@ def remove(name, stop=False):
# Compatibility between LXC and nspawn
destroy = remove
destroy = salt.utils.alias_function(remove, 'destroy')
@_ensure_exists
@ -1292,7 +1292,7 @@ def copy_to(name, source, dest, overwrite=False, makedirs=False):
overwrite=overwrite,
makedirs=makedirs)
cp = copy_to
cp = salt.utils.alias_function(copy_to, 'cp')
# Everything below requres systemd >= 219
@ -1455,4 +1455,4 @@ def pull_dkr(url, name, index):
'''
return _pull_image('dkr', url, name, index=index)
pull_docker = pull_dkr
pull_docker = salt.utils.alias_function(pull_dkr, 'pull_docker')

View File

@ -116,7 +116,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def version(*names, **kwargs):

View File

@ -99,7 +99,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def upgrade_available(name):

View File

@ -121,7 +121,7 @@ def list_windows(profile=None, api_key=None):
# The long version, added for consistency
list_maintenance_windows = list_windows
list_maintenance_windows = salt.utils.alias_function(list_windows, 'list_maintenance_windows')
def list_policies(profile=None, api_key=None):
@ -143,7 +143,7 @@ def list_policies(profile=None, api_key=None):
# The long version, added for consistency
list_escalation_policies = list_policies
list_escalation_policies = salt.utils.alias_function(list_policies, 'list_escalation_policies')
def create_event(service_key=None, description=None, details=None,

View File

@ -443,7 +443,7 @@ def mkpart(device, part_type, fs_type=None, start=None, end=None):
'''
_validate_device(device)
if not start or not end:
if start in [None, ''] or end in [None, '']:
raise CommandExecutionError(
'partition.mkpart requires a start and an end'
)

View File

@ -114,7 +114,7 @@ def items(*args, **kwargs):
return pillar.compile_pillar()
# Allow pillar.data to also be used to return pillar data
data = items
data = salt.utils.alias_function(items, 'data')
def _obfuscate_inner(var):

View File

@ -178,7 +178,7 @@ def latest_version(*names, **kwargs):
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def version(*names, **kwargs):

View File

@ -193,7 +193,7 @@ def version(*names, **kwargs):
])
# Support pkg.info get version info, since this is the CLI usage
info = version
info = salt.utils.alias_function(version, 'info')
def refresh_db(jail=None, chroot=None, force=False):
@ -236,7 +236,7 @@ def refresh_db(jail=None, chroot=None, force=False):
# Support pkg.update to refresh the db, since this is the CLI usage
update = refresh_db
update = salt.utils.alias_function(refresh_db, 'update')
def latest_version(*names, **kwargs):
@ -305,7 +305,7 @@ def latest_version(*names, **kwargs):
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def list_pkgs(versions_as_list=False,
@ -952,9 +952,9 @@ def remove(name=None,
return salt.utils.compare_dicts(old, new)
# Support pkg.delete to remove packages, since this is the CLI usage
delete = remove
delete = salt.utils.alias_function(remove, 'delete')
# No equivalent to purge packages, use remove instead
purge = remove
purge = salt.utils.alias_function(remove, 'purge')
def upgrade(*names, **kwargs):

View File

@ -226,7 +226,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def install(name=None, refresh=False, version=None, pkgs=None, **kwargs):

View File

@ -18,6 +18,7 @@ import salt.utils.itertools
import salt.ext.six as six
from salt.exceptions import SaltInvocationError
from salt.ext.six.moves import range
from salt.exceptions import CommandExecutionError
log = logging.getLogger(__name__)
@ -30,14 +31,15 @@ def __virtual__():
def _format_response(response, msg):
error = 'RabbitMQ command failed: {0}'.format(response)
if isinstance(response, dict):
if response['retcode'] != 0:
msg = 'Error'
raise CommandExecutionError(error)
else:
msg = response['stdout']
else:
if 'Error' in response:
msg = 'Error'
raise CommandExecutionError(error)
return {
msg: response
}
@ -703,8 +705,12 @@ def plugin_is_enabled(name, runas=None):
if runas is None:
runas = salt.utils.get_user()
cmd = [_get_rabbitmq_plugin(), 'list', '-m', '-e']
ret = __salt__['cmd.run'](cmd, runas=runas, python_shell=False)
return bool(name in ret)
ret = __salt__['cmd.run_all'](cmd, python_shell=False, runas=runas)
if ret['retcode'] != 0:
raise CommandExecutionError(
'RabbitMQ command failed: {0}'.format(ret['stderr'])
)
return bool(name in ret['stdout'])
def enable_plugin(name, runas=None):

View File

@ -67,9 +67,9 @@ class Registry(object):
"HKU": _winreg.HKEY_USERS,
}
self.reflection_mask = {
True: _winreg.KEY_ALL_ACCESS,
False: _winreg.KEY_ALL_ACCESS | _winreg.KEY_WOW64_64KEY,
self.registry_32 = {
True: _winreg.KEY_ALL_ACCESS | _winreg.KEY_WOW64_32KEY,
False: _winreg.KEY_ALL_ACCESS,
}
self.vtype = {
@ -106,7 +106,30 @@ def __virtual__():
return False
def read_key(hkey, path, key=None):
def _key_exists(hive, key, use_32bit_registry=False):
'''
Check that the key is found in the registry
:param str hive: The hive to connect to.
:param str key: The key to check
:param bool use_32bit_registry: Look in the 32bit portion of the registry
:return: Returns True if found, False if not found
:rtype: bool
'''
registry = Registry()
hkey = registry.hkeys[hive]
access_mask = registry.registry_32[use_32bit_registry]
try:
handle = _winreg.OpenKey(hkey, key, 0, access_mask)
_winreg.CloseKey(handle)
return True
except WindowsError as exc: # pylint: disable=E0602
return False
def read_key(hkey, path, key=None, use_32bit_registry=False):
'''
.. important::
The name of this function is misleading and will be changed to reflect
@ -146,36 +169,41 @@ def read_key(hkey, path, key=None):
'removed in Salt Boron')
return read_value(hive=hkey,
key=path,
vname=key)
vname=key,
use_32bit_registry=use_32bit_registry)
return read_value(hive=hkey, key=path)
return read_value(hive=hkey,
key=path,
use_32bit_registry=use_32bit_registry)
def read_value(hive, key, vname=None):
def read_value(hive, key, vname=None, use_32bit_registry=False):
r'''
Reads a registry value entry or the default value for a key.
:param str hive:
The name of the hive. Can be one of the following
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param str hive: The name of the hive. Can be one of the following
:param str key:
The key (looks like a path) to the value name.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param str vname:
The value name. These are the individual name/data pairs under the key.
If not passed, the key (Default) value will be returned
:param str key: The key (looks like a path) to the value name.
:return:
A dictionary containing the passed settings as well as the value_data if
successful. If unsuccessful, sets success to False
:param str vname: The value name. These are the individual name/data pairs
under the key. If not passed, the key (Default) value will be returned
:param bool use_32bit_registry: Accesses the 32bit portion of the registry
on 64 bit installations. On 32bit machines this is ignored.
:return: A dictionary containing the passed settings as well as the
value_data if successful. If unsuccessful, sets success to False
If vname is not passed:
- Returns the first unnamed value (Default) as a string.
- Returns none if first unnamed value is empty.
- Returns False if key not found.
If vname is not passed:
- Returns the first unnamed value (Default) as a string.
- Returns none if first unnamed value is empty.
- Returns False if key not found.
:rtype: dict
CLI Example:
@ -199,9 +227,10 @@ def read_value(hive, key, vname=None):
registry = Registry()
hkey = registry.hkeys[hive]
access_mask = registry.registry_32[use_32bit_registry]
try:
handle = _winreg.OpenKey(hkey, key)
handle = _winreg.OpenKey(hkey, key, 0, access_mask)
try:
vdata, vtype = _winreg.QueryValueEx(handle, vname)
if vdata or vdata in [0, '']:
@ -212,7 +241,6 @@ def read_value(hive, key, vname=None):
except WindowsError as exc: # pylint: disable=E0602
ret['vdata'] = ('(value not set)')
ret['vtype'] = 'REG_SZ'
ret['success'] = True
except WindowsError as exc: # pylint: disable=E0602
log.debug(exc)
log.debug('Cannot find key: {0}\\{1}'.format(hive, key))
@ -222,7 +250,13 @@ def read_value(hive, key, vname=None):
return ret
def set_key(hkey, path, value, key=None, vtype='REG_DWORD', reflection=True):
def set_key(hkey,
path,
value,
key=None,
vtype='REG_DWORD',
reflection=True,
use_32bit_registry=False):
'''
.. important ::
The name of this function is misleading and will be changed to reflect
@ -257,46 +291,57 @@ def set_key(hkey, path, value, key=None, vtype='REG_DWORD', reflection=True):
key=path,
vname=key,
vdata=value,
vtype=vtype)
vtype=vtype,
use_32bit_registry=use_32bit_registry)
return set_value(hive=hkey, key=path, vdata=value, vtype=vtype)
return set_value(hive=hkey,
key=path,
vdata=value,
vtype=vtype,
use_32bit_registry=use_32bit_registry)
def set_value(hive, key, vname=None, vdata=None, vtype='REG_SZ', reflection=True):
def set_value(hive,
key,
vname=None,
vdata=None,
vtype='REG_SZ',
reflection=True,
use_32bit_registry=False):
'''
Sets a registry value entry or the default value for a key.
:param str hive:
The name of the hive. Can be one of the following
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param str hive: The name of the hive. Can be one of the following
:param str key:
The key (looks like a path) to the value name.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param str vname:
The value name. These are the individual name/data pairs under the key.
If not passed, the key (Default) value will be set.
:param str key: The key (looks like a path) to the value name.
:param str vdata:
The value data to be set.
:param str vname: The value name. These are the individual name/data pairs
under the key. If not passed, the key (Default) value will be set.
:param str vtype:
The value type. Can be one of the following:
- REG_BINARY
- REG_DWORD
- REG_EXPAND_SZ
- REG_MULTI_SZ
- REG_SZ
:param str vdata: The value data to be set.
:param bool reflection:
A boolean value indicating that the value should also be set in the
Wow6432Node portion of the registry. Only applies to 64 bit Windows.
This setting is ignored for 32 bit Windows.
:param str vtype: The value type. Can be one of the following:
:return:
Returns True if successful, False if not
- REG_BINARY
- REG_DWORD
- REG_EXPAND_SZ
- REG_MULTI_SZ
- REG_SZ
:param bool reflection: A boolean value indicating that the value should
also be set in the Wow6432Node portion of the registry. Only applies to 64
bit Windows. This setting is ignored for 32 bit Windows.
.. deprecated:: 2015.8.2
Use `use_32bit_registry` instead. The parameter seems to have no effect
since Windows 7 / Windows 2008R2 removed support for reflection. The
parameter will be removed in Boron.
:return: Returns True if successful, False if not
:rtype: bool
CLI Example:
@ -306,21 +351,29 @@ def set_value(hive, key, vname=None, vdata=None, vtype='REG_SZ', reflection=True
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2'
'''
registry = Registry()
hive = registry.hkeys[hive]
hkey = registry.hkeys[hive]
vtype = registry.vtype[vtype]
access_mask = registry.reflection_mask[reflection]
access_mask = registry.registry_32[use_32bit_registry]
try:
handle = _winreg.CreateKeyEx(hive, key, 0, access_mask)
handle = _winreg.CreateKeyEx(hkey, key, 0, access_mask)
if vtype == registry.vtype['REG_SZ']\
or vtype == registry.vtype['REG_BINARY']:
vdata = str(vdata)
_winreg.SetValueEx(handle, vname, 0, vtype, vdata)
_winreg.CloseKey(handle)
return True
except (WindowsError, ValueError) as exc: # pylint: disable=E0602
except (WindowsError, ValueError, TypeError) as exc: # pylint: disable=E0602
log.error(exc, exc_info=True)
return False
def create_key(hkey, path, key=None, value=None, reflection=True):
def create_key(hkey,
path,
key=None,
value=None,
reflection=True,
use_32bit_registry=False):
'''
.. important ::
The name of this function is misleading and will be changed to reflect
@ -353,12 +406,17 @@ def create_key(hkey, path, key=None, value=None, reflection=True):
key=path,
vname=key,
vdata=value,
vtype='REG_SZ')
use_32bit_registry=use_32bit_registry)
return set_value(hive=hkey, key=path)
return set_value(hive=hkey, key=path, use_32bit_registry=use_32bit_registry)
def delete_key(hkey, path, key=None, reflection=True, force=False):
def delete_key(hkey,
path,
key=None,
reflection=True,
force=False,
use_32bit_registry=False):
'''
.. important::
The name of this function is misleading and will be changed to reflect
@ -383,34 +441,31 @@ def delete_key(hkey, path, key=None, reflection=True, force=False):
salt '*' reg.delete_key HKEY_CURRENT_USER 'SOFTWARE\\Salt'
:param str hkey: (will be changed to hive)
The name of the hive. Can be one of the following
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param str hkey: (will be changed to hive) The name of the hive. Can be one
of the following
:param str path: (will be changed to key)
The key (looks like a path) to remove.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param str key: (used incorrectly)
Will be removed in Boron
:param str path: (will be changed to key) The key (looks like a path) to
remove.
:param bool reflection:
A boolean value indicating that the value should also be removed from
the Wow6432Node portion of the registry. Only applies to 64 bit Windows.
This setting is ignored for 32 bit Windows.
:param str key: (used incorrectly) Will be removed in Boron
Only applies to delete value. If the key parameter is passed, this
function calls delete_value instead. Will be changed in Boron.
:param bool reflection: A boolean value indicating that the value should
also be removed from the Wow6432Node portion of the registry. Only applies
to 64 bit Windows. This setting is ignored for 32 bit Windows.
:param bool force:
A boolean value indicating that all subkeys should be removed as well.
If this is set to False (default) and there are subkeys, the delete_key
function will fail.
Only applies to delete value. If the key parameter is passed, this function
calls delete_value instead. Will be changed in Boron.
:return:
Returns True if successful, False if not
If force=True, the results of delete_key_recursive are returned.
:param bool force: A boolean value indicating that all subkeys should be
removed as well. If this is set to False (default) and there are subkeys,
the delete_key function will fail.
:return: Returns True if successful, False if not. If force=True, the
results of delete_key_recursive are returned.
:rtype: bool
'''
@ -422,42 +477,46 @@ def delete_key(hkey, path, key=None, reflection=True, force=False):
return delete_value(hive=hkey,
key=path,
vname=key,
reflection=reflection)
reflection=reflection,
use_32bit_registry=use_32bit_registry)
if force:
return delete_key_recursive(hkey, path)
return delete_key_recursive(hkey,
path,
use_32bit_registry=use_32bit_registry)
registry = Registry()
hive = registry.hkeys[hkey]
key = path
access_mask = registry.registry_32[use_32bit_registry]
try:
# Can't use delete_value to delete a key
_winreg.DeleteKey(hive, key)
key_handle = _winreg.OpenKey(hive, key, 0, access_mask)
_winreg.DeleteKey(key_handle, '')
_winreg.CloseKey(key_handle)
return True
except WindowsError as exc: # pylint: disable=E0602
log.error(exc, exc_info=True)
return False
def delete_key_recursive(hive, key):
def delete_key_recursive(hive, key, use_32bit_registry=False):
'''
.. versionadded:: 2015.5.4
Delete a registry key to include all subkeys.
:param hive:
The name of the hive. Can be one of the following
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param hive: The name of the hive. Can be one of the following
:param key:
The key to remove (looks like a path)
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:return:
A dictionary listing the keys that deleted successfully as well as those
that failed to delete.
:param key: The key to remove (looks like a path)
:return: A dictionary listing the keys that deleted successfully as well as
those that failed to delete.
:rtype: dict
The following example will remove ``salt`` and all its subkeys from the
@ -469,6 +528,15 @@ def delete_key_recursive(hive, key):
salt '*' reg.delete_key_recursive HKLM SOFTWARE\\salt
'''
# Instantiate the registry object
registry = Registry()
hkey = registry.hkeys[hive]
key_path = key
access_mask = registry.registry_32[use_32bit_registry]
if not _key_exists(hive, key, use_32bit_registry):
return False
# Functions for traversing the registry tree
def subkeys(key):
i = 0
@ -480,70 +548,61 @@ def delete_key_recursive(hive, key):
except WindowsError: # pylint: disable=E0602
break
def traverse_registry_tree(hkey, keypath, ret):
key = _winreg.OpenKey(hkey, keypath, 0, _winreg.KEY_READ)
def traverse_registry_tree(hkey, keypath, ret, access_mask):
key = _winreg.OpenKey(hkey, keypath, 0, access_mask)
for subkeyname in subkeys(key):
subkeypath = r'{0}\{1}'.format(keypath, subkeyname)
ret = traverse_registry_tree(hkey, subkeypath, ret)
ret = traverse_registry_tree(hkey, subkeypath, ret, access_mask)
ret.append('{0}'.format(subkeypath))
return ret
# Instantiate the registry object
registry = Registry()
hkey = registry.hkeys[hive]
keypath = key
# Get a reverse list of registry keys to be deleted
key_list = []
key_list = traverse_registry_tree(hkey, keypath, key_list)
key_list = traverse_registry_tree(hkey, key_path, key_list, access_mask)
# Add the top level key last, all subkeys must be deleted first
key_list.append(r'{0}'.format(key_path))
ret = {'Deleted': [],
'Failed': []}
# Delete all subkeys
for keypath in key_list:
# Delete all sub_keys
for sub_key_path in key_list:
try:
_winreg.DeleteKey(hkey, keypath)
ret['Deleted'].append(r'{0}\{1}'.format(hive, keypath))
key_handle = _winreg.OpenKey(hkey, sub_key_path, 0, access_mask)
_winreg.DeleteKey(key_handle, '')
ret['Deleted'].append(r'{0}\{1}'.format(hive, sub_key_path))
except WindowsError as exc: # pylint: disable=E0602
log.error(exc, exc_info=True)
ret['Failed'].append(r'{0}\{1} {2}'.format(hive, key, exc))
# Delete the key now that all the subkeys are deleted
try:
_winreg.DeleteKey(hkey, key)
ret['Deleted'].append(r'{0}\{1}'.format(hive, key))
except WindowsError as exc: # pylint: disable=E0602
log.error(exc, exc_info=True)
ret['Failed'].append(r'{0}\{1} {2}'.format(hive, key, exc))
ret['Failed'].append(r'{0}\{1} {2}'.format(hive, sub_key_path, exc))
return ret
def delete_value(hive, key, vname=None, reflection=True):
def delete_value(hive, key, vname=None, reflection=True, use_32bit_registry=False):
'''
Delete a registry value entry or the default value for a key.
:param str hive:
The name of the hive. Can be one of the following
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param str hive: The name of the hive. Can be one of the following
:param str key:
The key (looks like a path) to the value name.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param str vname:
The value name. These are the individual name/data pairs under the key.
If not passed, the key (Default) value will be deleted.
:param str key: The key (looks like a path) to the value name.
:param bool reflection:
A boolean value indicating that the value should also be set in the
Wow6432Node portion of the registry. Only applies to 64 bit Windows.
This setting is ignored for 32 bit Windows.
:param str vname: The value name. These are the individual name/data pairs
under the key. If not passed, the key (Default) value will be deleted.
:return:
Returns True if successful, False if not
:param bool reflection: A boolean value indicating that the value should
also be set in the Wow6432Node portion of the registry. Only applies to 64
bit Windows. This setting is ignored for 32 bit Windows.
.. deprecated:: 2015.8.2
Use `use_32bit_registry` instead. The parameter seems to have no effect
since Windows 7 / Windows 2008R2 removed support for reflection. The
parameter will be removed in Boron.
:return: Returns True if successful, False if not
:rtype: bool
CLI Example:
@ -554,7 +613,7 @@ def delete_value(hive, key, vname=None, reflection=True):
'''
registry = Registry()
hive = registry.hkeys[hive]
access_mask = registry.reflection_mask[reflection]
access_mask = registry.registry_32[use_32bit_registry]
try:
handle = _winreg.OpenKey(hive, key, 0, access_mask)
@ -562,6 +621,5 @@ def delete_value(hive, key, vname=None, reflection=True):
_winreg.CloseKey(handle)
return True
except WindowsError as exc: # pylint: disable=E0602
_winreg.CloseKey(handle)
log.error(exc, exc_info=True)
return False

View File

@ -325,9 +325,9 @@ def _parse_settings_bond_1(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)
@ -411,9 +411,9 @@ def _parse_settings_bond_3(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)
@ -455,9 +455,9 @@ def _parse_settings_bond_4(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)
@ -498,9 +498,9 @@ def _parse_settings_bond_5(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)
@ -534,9 +534,9 @@ def _parse_settings_bond_6(opts, iface, bond_def):
if 'use_carrier' in opts:
if opts['use_carrier'] in _CONFIG_TRUE:
bond.update({'use_carrier': 'on'})
bond.update({'use_carrier': '1'})
elif opts['use_carrier'] in _CONFIG_FALSE:
bond.update({'use_carrier': 'off'})
bond.update({'use_carrier': '0'})
else:
valid = _CONFIG_TRUE + _CONFIG_FALSE
_raise_error_iface(iface, 'use_carrier', valid)

View File

@ -427,7 +427,7 @@ def sync_output(saltenv=None, refresh=True):
refresh_modules()
return ret
sync_outputters = sync_output
sync_outputters = salt.utils.alias_function(sync_output, 'sync_outputters')
def sync_utils(saltenv=None, refresh=True):
@ -554,7 +554,7 @@ def refresh_pillar():
ret = False # Effectively a no-op, since we can't really return without an event system
return ret
pillar_refresh = refresh_pillar
pillar_refresh = salt.utils.alias_function(refresh_pillar, 'pillar_refresh')
def refresh_modules(async=True):

View File

@ -350,7 +350,7 @@ def build_schedule_item(name, **kwargs):
schedule[name]['splay'] = kwargs['splay']
for item in ['range', 'when', 'once', 'once_fmt', 'cron', 'returner',
'return_config', 'return_kwargs', 'until']:
'return_config', 'return_kwargs', 'until', 'enabled']:
if item in kwargs:
schedule[name][item] = kwargs[item]

View File

@ -259,7 +259,7 @@ def latest_version(name, **kwargs):
return ''
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def get_fmri(name, **kwargs):

View File

@ -150,7 +150,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def upgrade_available(name):

133
salt/modules/ssh_service.py Normal file
View File

@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
'''
Provide the service module for the proxy-minion SSH sample
.. versionadded:: 2015.8.2
'''
# Import python libs
from __future__ import absolute_import
import logging
__proxyenabled__ = ['ssh_sample']
log = logging.getLogger(__name__)
__func_alias__ = {
'list_': 'list'
}
# Define the module's virtual name
__virtualname__ = 'service'
def __virtual__():
'''
Only work on systems that are a proxy minion
'''
if __grains__['os'] == 'proxy':
return __virtualname__
return False
def get_all():
'''
Return a list of all available services
CLI Example:
.. code-block:: bash
salt '*' service.get_all
'''
proxy_fn = 'ssh_sample.service_list'
return __proxy__[proxy_fn]()
def list_():
'''
Return a list of all available services.
CLI Example:
.. code-block:: bash
salt '*' service.list
'''
return get_all()
def start(name, sig=None):
'''
Start the specified service on the rest_sample
CLI Example:
.. code-block:: bash
salt '*' service.start <service name>
'''
proxy_fn = 'ssh_sample.service_start'
return __proxy__[proxy_fn](name)
def stop(name, sig=None):
'''
Stop the specified service on the rest_sample
CLI Example:
.. code-block:: bash
salt '*' service.stop <service name>
'''
proxy_fn = 'ssh_sample.service_stop'
return __proxy__[proxy_fn](name)
def restart(name, sig=None):
'''
Restart the specified service with rest_sample
CLI Example:
.. code-block:: bash
salt '*' service.restart <service name>
'''
proxy_fn = 'ssh_sample.service_restart'
return __proxy__[proxy_fn](name)
def status(name, sig=None):
'''
Return the status for a service via rest_sample, returns a bool
whether the service is running.
CLI Example:
.. code-block:: bash
salt '*' service.status <service name>
'''
proxy_fn = 'ssh_sample.service_status'
resp = __proxy__[proxy_fn](name)
if resp['comment'] == 'stopped':
return False
if resp['comment'] == 'running':
return True
def running(name, sig=None):
'''
Return whether this service is running.
'''
return status(name).get(name, False)
def enabled(name, sig=None):
'''
Only the 'redbull' service is 'enabled' in the test
'''
return name == 'redbull'

View File

@ -190,7 +190,7 @@ def versions_report():
return '\n'.join(salt.version.versions_report())
versions = versions_report
versions = salt.utils.alias_function(versions_report, 'versions')
def conf_test():

View File

@ -231,7 +231,7 @@ def hw_addr(iface):
return salt.utils.network.hw_addr(iface)
# Alias hwaddr to preserve backward compat
hwaddr = hw_addr
hwaddr = salt.utils.alias_function(hw_addr, 'hwaddr')
def subnets():
@ -275,7 +275,7 @@ def ip_addrs(interface=None, include_loopback=False):
return salt.utils.network.ip_addrs(interface=interface,
include_loopback=include_loopback)
ipaddrs = ip_addrs
ipaddrs = salt.utils.alias_function(ip_addrs, 'ipaddrs')
def ip_addrs6(interface=None, include_loopback=False):
@ -293,7 +293,7 @@ def ip_addrs6(interface=None, include_loopback=False):
return salt.utils.network.ip_addrs6(interface=interface,
include_loopback=include_loopback)
ipaddrs6 = ip_addrs6
ipaddrs6 = salt.utils.alias_function(ip_addrs6, 'ipaddrs6')
def connect(host, port=None, **kwargs):

View File

@ -110,7 +110,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def upgrade_available(name):

View File

@ -24,35 +24,91 @@ def info(name):
Return information for the specified user
This is just returns dummy data so that salt states can work.
:param str name: The name of the user account to show.
CLI Example:
.. code-block:: bash
salt '*' shadow.info root
'''
ret = {
'name': name,
'passwd': '',
'lstchg': '',
'min': '',
'max': '',
'warn': '',
'inact': '',
'expire': ''}
info = __salt__['user.info'](name=name)
ret = {'name': name,
'passwd': '',
'lstchg': '',
'min': '',
'max': '',
'warn': '',
'inact': '',
'expire': ''}
if info:
ret = {'name': info['name'],
'passwd': 'Unavailable',
'lstchg': info['password_changed'],
'min': '',
'max': '',
'warn': '',
'inact': '',
'expire': info['expiration_date']}
return ret
def set_expire(name, expire):
'''
Set the expiration date for a user account.
:param name: The name of the user account to edit.
:param expire: The date the account will expire.
:return: True if successful. False if unsuccessful.
:rtype: bool
'''
return __salt__['user.update'](name, expiration_date=expire)
def require_password_change(name):
'''
Require the user to change their password the next time they log in.
:param name: The name of the user account to require a password change.
:return: True if successful. False if unsuccessful.
:rtype: bool
'''
return __salt__['user.update'](name, expired=True)
def unlock_account(name):
'''
Unlocks a user account.
:param name: The name of the user account to unlock.
:return: True if successful. False if unsuccessful.
:rtype: bool
'''
return __salt__['user.update'](name, unlock_account=True)
def set_password(name, password):
'''
Set the password for a named user.
:param str name: The name of the user account
:param str password: The new password
:return: True if successful. False if unsuccessful.
:rtype: bool
CLI Example:
.. code-block:: bash
salt '*' shadow.set_password root mysecretpassword
'''
cmd = ['net', 'user', name, password]
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
return not ret['retcode']
return __salt__['user.update'](name=name, password=password)

View File

@ -401,7 +401,7 @@ def set_computer_desc(desc=None):
return {'Computer Description': get_computer_desc()}
set_computer_description = set_computer_desc
set_computer_description = salt.utils.alias_function(set_computer_desc, 'set_computer_description')
def get_system_info():
@ -434,7 +434,7 @@ def get_computer_desc():
return desc if desc else False
get_computer_description = get_computer_desc
get_computer_description = salt.utils.alias_function(get_computer_desc, 'get_computer_description')
def get_hostname():

View File

@ -15,6 +15,8 @@ Module for managing Windows Users
This currently only works with local user accounts, not domain accounts
'''
from __future__ import absolute_import
from datetime import datetime
import time
try:
from shlex import quote as _cmd_quote # pylint: disable=E0611
@ -57,6 +59,59 @@ def __virtual__():
return False
def _get_date_time_format(dt_string):
'''
Copied from win_system.py (_get_date_time_format)
Function that detects the date/time format for the string passed.
:param str dt_string:
A date/time string
:return: The format of the passed dt_string
:rtype: str
'''
valid_formats = [
'%Y-%m-%d %I:%M:%S %p',
'%m-%d-%y %I:%M:%S %p',
'%m-%d-%Y %I:%M:%S %p',
'%m/%d/%y %I:%M:%S %p',
'%m/%d/%Y %I:%M:%S %p',
'%Y/%m/%d %I:%M:%S %p',
'%Y-%m-%d %I:%M:%S',
'%m-%d-%y %I:%M:%S',
'%m-%d-%Y %I:%M:%S',
'%m/%d/%y %I:%M:%S',
'%m/%d/%Y %I:%M:%S',
'%Y/%m/%d %I:%M:%S',
'%Y-%m-%d %I:%M %p',
'%m-%d-%y %I:%M %p',
'%m-%d-%Y %I:%M %p',
'%m/%d/%y %I:%M %p',
'%m/%d/%Y %I:%M %p',
'%Y/%m/%d %I:%M %p',
'%Y-%m-%d %I:%M',
'%m-%d-%y %I:%M',
'%m-%d-%Y %I:%M',
'%m/%d/%y %I:%M',
'%m/%d/%Y %I:%M',
'%Y/%m/%d %I:%M',
'%Y-%m-%d',
'%m-%d-%y',
'%m-%d-%Y',
'%m/%d/%y',
'%m/%d/%Y',
'%Y/%m/%d',
]
for dt_format in valid_formats:
try:
datetime.strptime(dt_string, dt_format)
return dt_format
except ValueError:
continue
return False
def add(name,
password=None,
fullname=False,
@ -147,7 +202,13 @@ def update(name,
home=None,
homedrive=None,
logonscript=None,
profile=None):
profile=None,
expiration_date=None,
expired=None,
account_disabled=None,
unlock_account=None,
password_never_expires=None,
disallow_change_password=None):
r'''
Updates settings for the windows user. Name is the only required parameter.
Settings will only be changed if the parameter is passed a value.
@ -179,6 +240,27 @@ def update(name,
:param str profile:
The path to the user's profile directory.
:param date expiration_date: The date and time when the account expires. Can
be a valid date/time string. To set to never expire pass the string 'Never'.
:param bool expired: Pass `True` to expire the account. The user will be
prompted to change their password at the next logon. Pass `False` to mark
the account as 'not expired'. You can't use this to negate the expiration if
the expiration was caused by the account expiring. You'll have to change
the `expiration_date` as well.
:param bool account_disabled: True disables the account. False enables the
account.
:param bool unlock_account: True unlocks a locked user account. False is
ignored.
:param bool password_never_expires: True sets the password to never expire.
False allows the password to expire.
:param bool disallow_change_password: True blocks the user from changing
the password. False allows the user to change the password.
:return:
True if successful. False is unsuccessful.
:rtype: bool
@ -219,6 +301,39 @@ def update(name,
user_info['full_name'] = fullname
if profile:
user_info['profile'] = profile
if expiration_date:
if expiration_date == 'Never':
user_info['acct_expires'] = win32netcon.TIMEQ_FOREVER
else:
date_format = _get_date_time_format(expiration_date)
if date_format:
dt_obj = datetime.strptime(expiration_date, date_format)
else:
return 'Invalid start_date'
user_info['acct_expires'] = time.mktime(dt_obj.timetuple())
if expired is not None:
if expired:
user_info['password_expired'] = 1
else:
user_info['password_expired'] = 0
if account_disabled is not None:
if account_disabled:
user_info['flags'] |= win32netcon.UF_ACCOUNTDISABLE
else:
user_info['flags'] ^= win32netcon.UF_ACCOUNTDISABLE
if unlock_account is not None:
if unlock_account:
user_info['flags'] ^= win32netcon.UF_LOCKOUT
if password_never_expires is not None:
if password_never_expires:
user_info['flags'] |= win32netcon.UF_DONT_EXPIRE_PASSWD
else:
user_info['flags'] ^= win32netcon.UF_DONT_EXPIRE_PASSWD
if disallow_change_password is not None:
if disallow_change_password:
user_info['flags'] |= win32netcon.UF_PASSWD_CANT_CHANGE
else:
user_info['flags'] ^= win32netcon.UF_PASSWD_CANT_CHANGE
# Apply new settings
try:
@ -626,6 +741,14 @@ def info(name):
- home
- homedrive
- groups
- password_changed
- successful_logon_attempts
- failed_logon_attempts
- last_logon
- account_disabled
- account_locked
- password_never_expires
- disallow_change_password
- gid
:rtype: dict
@ -658,6 +781,19 @@ def info(name):
ret['active'] = (not bool(items['flags'] & win32netcon.UF_ACCOUNTDISABLE))
ret['logonscript'] = items['script_path']
ret['profile'] = items['profile']
ret['failed_logon_attempts'] = items['bad_pw_count']
ret['successful_logon_attempts'] = items['num_logons']
secs = time.mktime(datetime.now().timetuple()) - items['password_age']
ret['password_changed'] = datetime.fromtimestamp(secs). \
strftime('%Y-%m-%d %H:%M:%S')
if items['last_logon'] == 0:
ret['last_logon'] = 'Never'
else:
ret['last_logon'] = datetime.fromtimestamp(items['last_logon']).\
strftime('%Y-%m-%d %H:%M:%S')
ret['expiration_date'] = datetime.fromtimestamp(items['acct_expires']).\
strftime('%Y-%m-%d %H:%M:%S')
ret['expired'] = items['password_expired'] == 1
if not ret['profile']:
ret['profile'] = _get_userprofile_from_registry(name, ret['uid'])
ret['home'] = items['home_dir']
@ -665,9 +801,30 @@ def info(name):
if not ret['home']:
ret['home'] = ret['profile']
ret['groups'] = groups
if items['flags'] & win32netcon.UF_DONT_EXPIRE_PASSWD == 0:
ret['password_never_expires'] = False
else:
ret['password_never_expires'] = True
if items['flags'] & win32netcon.UF_ACCOUNTDISABLE == 0:
ret['account_disabled'] = False
else:
ret['account_disabled'] = True
if items['flags'] & win32netcon.UF_LOCKOUT == 0:
ret['account_locked'] = False
else:
ret['account_locked'] = True
if items['flags'] & win32netcon.UF_PASSWD_CANT_CHANGE == 0:
ret['disallow_change_password'] = False
else:
ret['disallow_change_password'] = True
ret['gid'] = ''
return ret
return ret
else:
return False
def _get_userprofile_from_registry(user, sid):

View File

@ -439,7 +439,7 @@ def latest_version(*names, **kwargs):
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def upgrade_available(name):
@ -1808,7 +1808,7 @@ def group_install(name,
return install(pkgs=pkgs, **kwargs)
groupinstall = group_install
groupinstall = salt.utils.alias_function(group_install, 'groupinstall')
def list_repos(basedir=None):
@ -1978,6 +1978,14 @@ def mod_repo(repo, basedir=None, **kwargs):
del repo_opts[key]
todelete.append(key)
# convert disabled=True to enabled=0 from pkgrepo state
if 'disabled' in repo_opts:
kw_disabled = repo_opts['disabled']
if kw_disabled is True or str(kw_disabled).lower() == 'true':
repo_opts['enabled'] = 0
del repo_opts['disabled']
todelete.append('disabled')
# Add baseurl or mirrorlist to the 'todelete' list if the other was
# specified in the repo_opts
if 'mirrorlist' in repo_opts:

View File

@ -95,7 +95,7 @@ def list_upgrades(refresh=True):
return ret
# Provide a list_updates function for those used to using zypper list-updates
list_updates = list_upgrades
list_updates = salt.utils.alias_function(list_upgrades, 'list_updates')
def info_installed(*names):
@ -175,10 +175,10 @@ def info_available(*names, **kwargs):
if nfo.get('name'):
name = nfo.pop('name')
ret[name] = nfo
if nfo.get("status"):
nfo['status'] = nfo.get("status").split(" ")[0]
if nfo.get("installed"):
nfo['installed'] = nfo.get("installed").lower() == "yes" and True or False
if nfo.get('status'):
nfo['status'] = nfo.get('status')
if nfo.get('installed'):
nfo['installed'] = nfo.get('installed').lower() == 'yes' and True or False
return ret
@ -227,13 +227,17 @@ def latest_version(*names, **kwargs):
for name in names:
pkg_info = package_info.get(name, {})
if pkg_info.get('status', '').lower() in ['not installed', 'out-of-date']:
ret[name] = pkg_info
ret[name] = pkg_info.get('version')
# Return a string if only one package name passed
if len(names) == 1 and len(ret):
return ret[names[0]]
return ret
# available_version is being deprecated
available_version = latest_version
available_version = salt.utils.alias_function(latest_version, 'available_version')
def upgrade_available(name):

View File

@ -446,10 +446,12 @@ class Pillar(object):
self.opts.get('nodegroups', {}),
):
if saltenv not in matches:
matches[saltenv] = []
matches[saltenv] = env_matches = []
else:
env_matches = matches[saltenv]
for item in data:
if isinstance(item, six.string_types):
matches[saltenv].append(item)
if isinstance(item, six.string_types) and item not in env_matches:
env_matches.append(item)
return matches
def render_pstate(self, sls, saltenv, mods, defaults=None):
@ -528,20 +530,20 @@ class Pillar(object):
mods,
defaults
)
if nstate:
if key:
nstate = {
key: nstate
}
if nstate:
if key:
nstate = {
key: nstate
}
state = merge(
state,
nstate,
self.merge_strategy,
self.opts.get('renderer', 'yaml'))
state = merge(
state,
nstate,
self.merge_strategy,
self.opts.get('renderer', 'yaml'))
if err:
errors += err
if err:
errors += err
return state, mods, errors
def render_pillar(self, matches):

View File

@ -397,9 +397,9 @@ def _legacy_git_pillar(minion_id, repo_string, pillar_dirs):
log.warning('Unrecognized extra parameter: {0}'.format(key))
# environment is "different" from the branch
branch, _, environment = branch_env.partition(':')
cfg_branch, _, environment = branch_env.partition(':')
gitpil = _LegacyGitPillar(branch, repo_location, __opts__)
gitpil = _LegacyGitPillar(cfg_branch, repo_location, __opts__)
branch = gitpil.branch
if environment == '':
@ -413,7 +413,9 @@ def _legacy_git_pillar(minion_id, repo_string, pillar_dirs):
pillar_dirs.setdefault(pillar_dir, {})
if pillar_dirs[pillar_dir].get(branch, False):
if cfg_branch == '__env__' and branch not in ['master', 'base']:
gitpil.update()
elif pillar_dirs[pillar_dir].get(branch, False):
return {} # we've already seen this combo
pillar_dirs[pillar_dir].setdefault(branch, True)
@ -429,7 +431,7 @@ def _legacy_git_pillar(minion_id, repo_string, pillar_dirs):
pil = Pillar(opts, __grains__, minion_id, branch)
return pil.compile_pillar()
return pil.compile_pillar(ext=False)
def _update(branch, repo_location):

View File

@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
'''
======
fx2.py
======
Dell FX2 chassis
================
.. versionadded:: 2015.8.2
@ -218,6 +217,13 @@ def chconfig(cmd, *args, **kwargs):
for k in kwargs.keys():
if k.startswith('__pub_'):
kwargs.pop(k)
# Catch password reset
if cmd == 'change_password':
if 'username' in kwargs:
DETAILS['admin_username'] = kwargs['username']
if 'password' in kwargs:
DETAILS['admin_password'] = kwargs['password']
if 'dracr.'+cmd not in __salt__:
return {'retcode': -1, 'message': 'dracr.' + cmd + ' is not available'}
else:

View File

@ -10,9 +10,9 @@ from __future__ import absolute_import
import logging
# Import 3rd-party libs
# import jnpr.junos
# import jnpr.junos.utils
# import jnpr.junos.utils.config
import jnpr.junos
import jnpr.junos.utils
import jnpr.junos.utils.config
import json
HAS_JUNOS = True
@ -22,17 +22,18 @@ thisproxy = {}
log = logging.getLogger(__name__)
# def __init__(opts):
# '''
# Open the connection to the Junos device, login, and bind to the
# Resource class
# '''
# log.debug('Opening connection to junos')
# thisproxy['conn'] = jnpr.junos.Device(user=opts['proxy']['username'],
# host=opts['proxy']['host'],
# password=opts['proxy']['passwd'])
# thisproxy['conn'].open()
# thisproxy['conn'].bind(cu=jnpr.junos.utils.config.Config)
def init(opts):
'''
Open the connection to the Junos device, login, and bind to the
Resource class
'''
log.debug('Opening connection to junos')
thisproxy['conn'] = jnpr.junos.Device(user=opts['proxy']['username'],
host=opts['proxy']['host'],
password=opts['proxy']['passwd'])
thisproxy['conn'].open()
thisproxy['conn'].bind(cu=jnpr.junos.utils.config.Config)
def conn():

View File

@ -51,6 +51,19 @@ def init(opts):
return False
def ping():
'''
Required.
Ping the device on the other end of the connection
'''
try:
out, err = DETAILS['server'].sendline('help')
return True
except TerminalException as e:
log.error(e)
return False
def shutdown(opts):
'''
Disconnect
@ -96,13 +109,11 @@ def package_list():
def package_install(name, **kwargs):
'''
Install a "package" on the REST server
Install a "package" on the ssh server
'''
cmd = 'pkg_install ' + name
if 'version' in kwargs:
cmd += '/'+kwargs['version']
else:
cmd += '/1.0'
cmd += ' ' + kwargs['version']
# Send the command to execute
out, err = DETAILS['server'].sendline(cmd)
@ -113,7 +124,7 @@ def package_install(name, **kwargs):
def package_remove(name):
'''
Remove a "package" on the REST server
Remove a "package" on the ssh server
'''
cmd = 'pkg_remove ' + name
@ -122,3 +133,63 @@ def package_remove(name):
# "scrape" the output and return the right fields as a dict
return parse(out)
def service_list():
'''
Start a "service" on the ssh server
.. versionadded:: 2015.8.2
'''
cmd = 'ps'
# Send the command to execute
out, err = DETAILS['server'].sendline(cmd)
# "scrape" the output and return the right fields as a dict
return parse(out)
def service_start(name):
'''
Start a "service" on the ssh server
.. versionadded:: 2015.8.2
'''
cmd = 'start ' + name
# Send the command to execute
out, err = DETAILS['server'].sendline(cmd)
# "scrape" the output and return the right fields as a dict
return parse(out)
def service_stop(name):
'''
Stop a "service" on the ssh server
.. versionadded:: 2015.8.2
'''
cmd = 'stop ' + name
# Send the command to execute
out, err = DETAILS['server'].sendline(cmd)
# "scrape" the output and return the right fields as a dict
return parse(out)
def service_restart(name):
'''
Restart a "service" on the ssh server
.. versionadded:: 2015.8.2
'''
cmd = 'restart ' + name
# Send the command to execute
out, err = DETAILS['server'].sendline(cmd)
# "scrape" the output and return the right fields as a dict
return parse(out)

View File

@ -120,7 +120,7 @@ def list_windows(profile=None, api_key=None):
# The long version, added for consistency
list_maintenance_windows = list_windows
list_maintenance_windows = salt.utils.alias_function(list_windows, 'list_maintenance_windows')
def list_policies(profile=None, api_key=None):
@ -142,7 +142,7 @@ def list_policies(profile=None, api_key=None):
# The long version, added for consistency
list_escalation_policies = list_policies
list_escalation_policies = salt.utils.alias_function(list_policies, 'list_escalation_policies')
def create_event(service_key=None, description=None, details=None,

View File

@ -8,6 +8,7 @@ import logging
# Import salt libs
import salt.loader
import salt.utils
import salt.utils.event
from salt.exceptions import SaltInvocationError
@ -62,8 +63,8 @@ def orchestrate(mods, saltenv='base', test=None, exclude=None, pillar=None):
return ret
# Aliases for orchestrate runner
orch = orchestrate # pylint: disable=invalid-name
sls = orchestrate # pylint: disable=invalid-name
orch = salt.utils.alias_function(orchestrate, 'orch')
sls = salt.utils.alias_function(orchestrate, 'sls')
def orchestrate_single(fun, name, test=None, queue=False, pillar=None, **kwargs):

View File

@ -653,6 +653,10 @@ class SPMClient(object):
self.formula_conf = formula_conf
formula_tar = tarfile.open(out_path, 'w:bz2')
# Add FORMULA first, to speed up create_repo on large packages
formula_tar.add(formula_path, formula_conf['name'], filter=self._exclude)
try:
formula_tar.add(self.abspath, formula_conf['name'], filter=self._exclude)
except TypeError:

View File

@ -48,7 +48,7 @@ import salt.utils.yamlloader as yamlloader
# Import third party libs
# pylint: disable=import-error,no-name-in-module,redefined-builtin
import salt.ext.six as six
from salt.ext.six.moves import range
from salt.ext.six.moves import map, range
# pylint: enable=import-error,no-name-in-module,redefined-builtin
log = logging.getLogger(__name__)
@ -549,7 +549,7 @@ class Compiler(object):
if isinstance(entry, dict):
low_name = next(six.iterkeys(entry))
live['name'] = low_name
live.update(entry[low_name][0])
list(map(live.update, entry[low_name]))
else:
live['name'] = entry
live['name_order'] = name_order
@ -1228,7 +1228,7 @@ class State(object):
if isinstance(entry, dict):
low_name = next(six.iterkeys(entry))
live['name'] = low_name
live.update(entry[low_name][0])
list(map(live.update, entry[low_name]))
else:
live['name'] = entry
live['name_order'] = name_order

View File

@ -83,9 +83,9 @@ def present(name, timespec, tag=None, user=None, job=None):
ret['comment'] = 'User: {0} is not exists'.format(user)
ret['result'] = False
return ret
ret['comment'] = __salt__['cmd.run']('{0}'.format(cmd), runas=user)
ret['comment'] = __salt__['cmd.run']('{0}'.format(cmd), runas=user, python_shell=True)
else:
ret['comment'] = __salt__['cmd.run']('{0}'.format(cmd))
ret['comment'] = __salt__['cmd.run']('{0}'.format(cmd), python_shell=True)
return ret

View File

@ -29,14 +29,17 @@ import os.path
# Import salt libs
import salt.utils
__virtualname__ = 'blockdev'
def __virtual__():
'''
Only work on POSIX-like systems
Only load this module if the blockdev execution module is available
'''
if salt.utils.is_windows():
return False
return True
if 'blockdev.tune' in __salt__:
return __virtualname__
return (False, ('Cannot load the {0} state module: '
'blockdev execution module not found'.format(__virtualname__)))
def tuned(name, **kwargs):
@ -146,25 +149,8 @@ def formatted(name, fs_type='ext4', **kwargs):
ret['result'] = None
return ret
cmd = 'mkfs -t {0} '.format(fs_type)
if 'inode_size' in kwargs:
if fs_type[:3] == 'ext':
cmd += '-i {0} '.format(kwargs['inode_size'])
elif fs_type == 'xfs':
cmd += '-i size={0} '.format(kwargs['inode_size'])
if 'lazy_itable_init' in kwargs:
if fs_type[:3] == 'ext':
cmd += '-E lazy_itable_init={0} '.format(kwargs['lazy_itable_init'])
cmd += name
__salt__['cmd.run'](cmd).splitlines()
__salt__['cmd.run']('sync').splitlines()
blk = __salt__['cmd.run']('lsblk -o fstype {0}'.format(name)).splitlines()
if len(blk) == 1:
current_fs = ''
else:
current_fs = blk[1]
__salt__['blockdev.format'](name, fs_type, **kwargs)
current_fs = __salt__['blockdev.fstype'](name)
if current_fs == fs_type:
ret['comment'] = ('{0} has been formatted '

View File

@ -2,7 +2,7 @@
'''
Manage Elasticache
==================
replication_group_description
.. versionadded:: 2014.7.0
Create, destroy and update Elasticache clusters. Be aware that this interacts

View File

@ -71,6 +71,12 @@ passed in as a dict, or as a string to pull from pillars or minion config:
key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
'''
# Import Python Libs
from __future__ import absolute_import
# Import Salt Libs
from salt.utils import SaltInvocationError
def __virtual__():
'''
@ -144,10 +150,15 @@ def present(
if isinstance(value, list):
value = ','.join(value)
record = __salt__['boto_route53.get_record'](name, zone, record_type,
False, region, key, keyid,
profile, split_dns,
private_zone)
try:
record = __salt__['boto_route53.get_record'](name, zone, record_type,
False, region, key, keyid,
profile, split_dns,
private_zone)
except SaltInvocationError as err:
ret['comment'] = 'Error: {0}'.format(err)
ret['result'] = False
return ret
if isinstance(record, dict) and not record:
if __opts__['test']:

View File

@ -217,6 +217,7 @@ except ImportError:
pass
# Import salt libs
import salt.utils
from salt.exceptions import CommandExecutionError, SaltRenderError
from salt.ext.six import string_types
@ -494,7 +495,7 @@ def wait(name,
# Alias "cmd.watch" to "cmd.wait", as this is a common misconfiguration
watch = wait
watch = salt.utils.alias_function(wait, 'watch')
def wait_script(name,

View File

@ -4,24 +4,131 @@ Manage chassis via Salt Proxies.
.. versionadded:: 2015.8.2
Example managing a Dell chassis:
Below is an example state that sets parameters just to show the basics.
.. code-block:: yaml
my-dell-chassis:
chassis.dell:
- name: my-dell-chassis
dellchassis.chassis:
- chassis_name: my-dell-chassis
- datacenter: dc-1-us
- location: my-location
- mode: 2
- idrac_launch: 1
- slot_names:
- 1: my-slot-name
- 2: my-other-slot-name
- server-1: my-slot-name
- server-2: my-other-slot-name
- blade_power_states:
- server-1: on
- server-2: off
- server-3: powercycle
However, it is possible to place the entire set of chassis configuration
data in pillar. Here's an example pillar
structure:
.. code-block:: yaml
proxy:
host: 10.27.20.18
admin_username: root
admin_password: saltstack
proxytype: fx2
chassis:
name: fx2-1
username: root
password: saltstack1
datacenter: london
location: rack-1-shelf-3
management_mode: 2
idrac_launch: 0
slot_names:
- 'server-1': blade1
- 'server-2': blade2
blades:
blade1:
idrac_password: saltstack1
ipmi_over_lan: True
ip: 172.17.17.1
subnet: 255.255.0.0
netmask: 172.17.255.255
blade2:
idrac_password: saltstack1
ipmi_over_lan: True
ip: 172.17.17.2
subnet: 255.255.0.0
netmask: 172.17.255.255
blade3:
idrac_password: saltstack1
ipmi_over_lan: True
ip: 172.17.17.2
subnet: 255.255.0.0
netmask: 172.17.255.255
blade4:
idrac_password: saltstack1
ipmi_over_lan: True
ip: 172.17.17.2
subnet: 255.255.0.0
netmask: 172.17.255.255
switches:
switch-1:
ip: 192.168.1.2
netmask: 255.255.255.0
broadcast: 192.168.1.255
snmp: nonpublic
password: saltstack1
switch-2:
ip: 192.168.1.3
netmask: 255.255.255.0
broadcast: 192.168.1.255
snmp: nonpublic
password: saltstack1
And to go with it, here's an example state that pulls the data from pillar
.. code-block:: yaml
{% set details = pillar['chassis'] with context %}
standup-step1:
dellchassis.chassis:
- name: {{ details['name'] }}
- location: {{ details['location'] }}
- mode: {{ details['management_mode'] }}
- idrac_launch: {{ details['idrac_launch'] }}
- slot_names
{% for k, v in details['chassis']['slot_names'].iteritems() %}
- {{ k }}: {{ v }}
{% endfor %}
{% for k, v in details['chassis']['switches'].iteritems() %}
standup-switches-{{ k }}:
dellchassis.dell_switch:
- name: {{ k }}
- ip: {{ v['ip'] }}
- netmask: {{ v['netmask'] }}
- gateway: {{ v['gateway'] }}
- password: {{ v['password'] }}
- snmp: {{ v['snmp'] }}
{% endfor %}
dellchassis
{% for k, v in details['chassis']['slot_names'].iteritems() %}
- {{ k }}: {{ v }}
{% endfor %}
blade_powercycle:
chassis.dell_chassis:
- blade_power_states:
- server-1: powercycle
- server-2: powercycle
- server-3: powercycle
- server-4: powercycle
'''
# Import python libs
@ -35,13 +142,13 @@ def __virtual__():
return 'chassis.cmd' in __salt__
def blade_idrac(name, idrac_password=None, idrac_ipmi=None,
def blade_idrac(idrac_password=None, idrac_ipmi=None,
idrac_ip=None, idrac_netmask=None, idrac_gateway=None,
idrac_dnsname=None,
drac_dhcp=None):
'''
Set parameters for iDRAC in a blade.
:param name: The name of the blade to address
:param idrac_password: Password to establish for the iDRAC interface
:param idrac_ipmi: Enable/Disable IPMI over LAN
:param idrac_ip: Set IP address for iDRAC
@ -52,20 +159,58 @@ def blade_idrac(name, idrac_password=None, idrac_ipmi=None,
:return: A standard Salt changes dictionary
'''
pass
ret = {'result': True,
'changes': {},
'comment': ''}
if not idrac_password:
password = __pillar__['proxy']['admin_password']
else:
password = idrac_password
if idrac_ipmi:
if idrac_ipmi is True:
idrac_ipmi = '1'
if idrac_ipmi is False:
idrac_ipmi = '0'
current_ipmi = __salt__['dracr.get_general']('cfgIpmiLan', 'cfgIpmiLanEnable',
host=idrac_ip, admin_username='root',
admin_password=password)
if current_ipmi != idrac_ipmi:
ch = {'Old': current_ipmi, 'New': idrac_ipmi}
ret['changes']['IPMI'] = ch
if idrac_dnsname:
dnsret = __salt__['dracr.get_dns_dracname'](host=idrac_ip, admin_username='root',
admin_password=password)
current_dnsname = dnsret['Key=iDRAC.Embedded.1#NIC.1']['DNSRacName']
if current_dnsname != idrac_dnsname:
ch = {'Old': current_dnsname,
'New': idrac_dnsname}
ret['changes']['DNSRacName'] = ch
return ret
def chassis(name, location=None, mode=None, idrac_launch=None, slot_names=None,
blade_power_states=None):
def chassis(name, chassis_name=None, password=None, datacenter=None,
location=None, mode=None, idrac_launch=None, slot_names=None,
blade_power_states=None):
'''
Manage a Dell Chassis.
name
chassis_name
The name of the chassis.
datacenter
The datacenter in which the chassis is located
location
The location of the chassis.
password
Password for the chassis
mode
The management mode of the chassis. Viable options are:
@ -96,9 +241,10 @@ def chassis(name, location=None, mode=None, idrac_launch=None, slot_names=None,
.. code-block:: yaml
my-dell-chassis:
chassis.dell:
dellchassis.chassis:
- name: my-dell-chassis
- location: my-location
- datacenter: london
- mode: 2
- idrac_launch: 1
- slot_names:
@ -109,7 +255,7 @@ def chassis(name, location=None, mode=None, idrac_launch=None, slot_names=None,
- server-2: off
- server-3: powercycle
'''
ret = {'name': name,
ret = {'chassis_name': chassis_name,
'result': True,
'changes': {},
'comment': ''}
@ -119,12 +265,27 @@ def chassis(name, location=None, mode=None, idrac_launch=None, slot_names=None,
mode_cmd = 'cfgRacTuneChassisMgmtAtServer'
launch_cmd = 'cfgRacTuneIdracDNSLaunchEnable'
inventory = __salt__[chassis_cmd]('inventory')
if idrac_launch:
idrac_launch = str(idrac_launch)
current_name = __salt__[chassis_cmd]('get_chassis_name')
if name != current_name:
if chassis_name != current_name:
ret['changes'].update({'Name':
{'Old': current_name,
'New': name}})
'New': chassis_name}})
current_dc = __salt__[chassis_cmd]('get_chassis_datacenter')
if datacenter and datacenter != current_dc:
ret['changes'].update({'Datacenter':
{'Old': current_dc,
'New': datacenter}})
if password:
ret['changes'].update({'Password':
{'Old': '******',
'New': '******'}})
if location:
current_location = __salt__[chassis_cmd]('get_chassis_location')
if location != current_location:
@ -147,11 +308,16 @@ def chassis(name, location=None, mode=None, idrac_launch=None, slot_names=None,
if slot_names:
current_slot_names = __salt__[chassis_cmd]('list_slotnames')
for key, val in slot_names:
for s in slot_names:
key = s.keys()[0]
new_name = s[key]
if key.startswith('slot-'):
key = key[5:]
current_slot_name = current_slot_names.get(key).get('slotname')
if current_slot_name != val['name']:
if current_slot_name != new_name:
old = {key: current_slot_name}
new = {key: val}
new = {key: new_name}
if ret['changes'].get('Slot Names') is None:
ret['changes'].update({'Slot Names':
{'Old': {},
@ -159,23 +325,33 @@ def chassis(name, location=None, mode=None, idrac_launch=None, slot_names=None,
ret['changes']['Slot Names']['Old'].update(old)
ret['changes']['Slot Names']['New'].update(new)
# TODO: Refactor this and make DRY - can probable farm this out to a new funciton
current_power_states = {}
target_power_states = {}
if blade_power_states:
# TODO: Get the power state list working
current_power_states = 'get a list of current power states'
for key, val in blade_power_states:
# TODO: Get the correct state infos
current_power_state = current_power_states.get(key).get('state')
# TODO: Don't just compare values, check if True should be "on" or "off" etc
if current_power_state != val:
old = {key: current_power_state}
new = {key: val}
if ret['changes'].get('Blade Power States') is None:
ret['changes'].update({'Blade Power States':
{'Old': {},
'New': {}}})
ret['changes']['Blade Power States']['Old'].update(old)
ret['changes']['Blade Power States']['New'].update(new)
for b in blade_power_states:
key = b.keys()[0]
status = __salt__[chassis_cmd]('server_powerstatus', module=key)
current_power_states[key] = status.get('status', -1)
if b[key] == 'powerdown':
if current_power_states[key] != -1 and current_power_states[key]:
target_power_states[key] = 'powerdown'
if b[key] == 'powerup':
if current_power_states[key] != -1 and not current_power_states[key]:
target_power_states[key] = 'powerup'
if b[key] == 'powercycle':
if current_power_states[key] != -1 and not current_power_states[key]:
target_power_states[key] = 'powerup'
if current_power_states[key] != -1 and current_power_states[key]:
target_power_states[key] = 'powercycle'
for k, v in target_power_states.iteritems():
old = {k: current_power_states[k]}
new = {k: v}
if ret['changes'].get('Blade Power States') is None:
ret['changes'].update({'Blade Power States':
{'Old': {},
'New': {}}})
ret['changes']['Blade Power States']['Old'].update(old)
ret['changes']['Blade Power States']['New'].update(new)
if ret['changes'] == {}:
ret['comment'] = 'Dell chassis is already in the desired state.'
@ -190,21 +366,50 @@ def chassis(name, location=None, mode=None, idrac_launch=None, slot_names=None,
name = __salt__[chassis_cmd]('set_chassis_name', name)
if location:
location = __salt__[chassis_cmd]('set_chassis_location', location)
pw_result = True
if password:
pw_single = True
if __salt__[chassis_cmd]('change_password', username='root', uid=1,
password=password):
for blade in inventory['server'].keys():
pw_single = __salt__[chassis_cmd]('deploy_password',
username='root',
password=password,
module=blade)
if not pw_single:
pw_result = False
else:
pw_result = False
if datacenter:
datacenter_result = __salt__[chassis_cmd]('set_chassis_datacenter',
datacenter)
if mode:
mode = __salt__[chassis_cmd]('set_general', cfg_tuning, mode_cmd, mode)
if idrac_launch:
idrac_launch = __salt__[chassis_cmd]('set_general', cfg_tuning, launch_cmd, idrac_launch)
if slot_names:
if ret['changes'].get('Slot Names') is not None:
slot_rets = []
for key, val in slot_names.iteritems():
slot_name = val.get('slotname')
slot_rets.append(__salt__[chassis_cmd]('set_slotname', key, slot_name))
for s in slot_names:
key = s.keys()[0]
new_name = s[key]
if key.startswith('slot-'):
key = key[5:]
slot_rets.append(__salt__[chassis_cmd]('set_slotname', key, new_name))
if any(slot_rets) is False:
slot_names = False
else:
slot_names = True
if any([name, location, mode, idrac_launch, slot_names]) is False:
powerchange_all_ok = True
for k, v in target_power_states.iteritems():
powerchange_ok = __salt__[chassis_cmd]('server_power', v, module=k)
if not powerchange_ok:
powerchange_all_ok = False
if any([name, location, mode, idrac_launch,
slot_names, powerchange_all_ok]) is False:
ret['result'] = False
ret['comment'] = 'There was an error setting the Dell chassis.'
@ -212,7 +417,7 @@ def chassis(name, location=None, mode=None, idrac_launch=None, slot_names=None,
return ret
def dell_switch(name, ip=None, netmask=None, gateway=None, dhcp=None,
def switch(name, ip=None, netmask=None, gateway=None, dhcp=None,
password=None, snmp=None):
'''
Manage switches in a Dell Chassis.
@ -245,7 +450,7 @@ def dell_switch(name, ip=None, netmask=None, gateway=None, dhcp=None,
.. code-block:: yaml
my-dell-chassis:
chassis.dell_switch:
dellchassis.dell_switch:
- switch: switch-1
- ip: 192.168.1.1
- netmask: 255.255.255.0

View File

@ -2,6 +2,10 @@
'''
Send events through Salt's event system during state runs
'''
from __future__ import absolute_import
# import salt libs
import salt.utils
def send(name,
@ -86,5 +90,5 @@ def wait(name, sfun=None):
return {'name': name, 'changes': {}, 'result': True, 'comment': ''}
mod_watch = send
fire_master = send
mod_watch = salt.utils.alias_function(send, 'mod_watch')
fire_master = salt.utils.alias_function(send, 'fire_master')

View File

@ -2486,7 +2486,7 @@ def replace(name,
pattern,
repl,
count=0,
flags=0,
flags=8,
bufsize=1,
append_if_not_found=False,
prepend_if_not_found=False,
@ -2513,16 +2513,18 @@ def replace(name,
replaced, otherwise all occurrences will be replaced.
flags
A list of flags defined in the :ref:`re module documentation <contents-of-module-re>`.
Each list item should be a string that will correlate to the human-friendly flag name.
E.g., ``['IGNORECASE', 'MULTILINE']``. Note: multiline searches must specify ``file``
as the ``bufsize`` argument below. Defaults to 0 and can be a list or an int.
A list of flags defined in the :ref:`re module documentation
<contents-of-module-re>`. Each list item should be a string that will
correlate to the human-friendly flag name. E.g., ``['IGNORECASE',
'MULTILINE']``. Optionally, ``flags`` may be an int, with a value
corresponding to the XOR (``|``) of all the desired flags. Defaults to
8 (which supports 'MULTILINE').
bufsize
How much of the file to buffer into memory at once. The default value ``1`` processes
one line at a time. The special value ``file`` may be specified which will read the
entire file into memory before processing. Note: multiline searches must specify ``file``
buffering. Can be an int or a str.
How much of the file to buffer into memory at once. The default value
``1`` processes one line at a time. The special value ``file`` may be
specified which will read the entire file into memory before
processing.
append_if_not_found
If pattern is not found and set to ``True`` then, the content will be appended to the file.
@ -4353,6 +4355,8 @@ def serialize(name,
'result': False
}
contents += '\n'
if __opts__['test']:
ret['changes'] = __salt__['file.check_managed_changes'](
name=name,
@ -4622,10 +4626,18 @@ def mod_run_check_cmd(cmd, filename, **check_cmd_opts):
log.debug('running our check_cmd')
_cmd = '{0} {1}'.format(cmd, filename)
if __salt__['cmd.retcode'](_cmd, **check_cmd_opts) != 0:
return {'comment': 'check_cmd execution failed',
'skip_watch': True,
'result': False}
cret = __salt__['cmd.run_all'](_cmd, **check_cmd_opts)
if cret['retcode'] != 0:
ret = {'comment': 'check_cmd execution failed',
'skip_watch': True,
'result': False}
if cret.get('stdout'):
ret['comment'] += '\n' + cret['stdout']
if cret.get('stderr'):
ret['comment'] += '\n' + cret['stderr']
return ret
# No reason to stop, return True
return True

View File

@ -11,15 +11,16 @@ masquerading, and allows ports 22/tcp and 25/tcp.
.. code-block:: yaml
public:
- name: public
- block_icmp
- echo-reply
- echo-request
- default: False
- masquerade: True
- ports:
- 22/tcp
- 25/tcp
firewalld.present:
- name: public
- block_icmp:
- echo-reply
- echo-request
- default: False
- masquerade: True
- ports:
- 22/tcp
- 25/tcp
The following example applies changes to the public zone, enables
masquerading and configures port forwarding TCP traffic from port 22
@ -35,10 +36,14 @@ to 2222, and forwards TCP traffic from port 80 to 443 at 192.168.0.1.
- 22:2222:tcp
- 80:443:tcp:192.168.0.1
'''
from __future__ import absolute_import
# Import Python Libs
from __future__ import absolute_import
import logging
import salt.exceptions
# Import Salt Libs
from salt.exceptions import CommandExecutionError
import salt.utils
log = logging.getLogger(__name__)
@ -61,92 +66,119 @@ def present(name,
port_fwd=None,
services=None):
'''
Ensure a zone has specific attributes
Ensure a zone has specific attributes.
'''
ret = {'name': name,
'result': True,
'changes': {'icmp_blocks': [],
'ports': [],
'port_fwd': [],
'services': []},
'comment': {'icmp_blocks': [],
'ports': [],
'port_fwd': [],
'services': []}}
'result': False,
'changes': {},
'comment': ''}
if name not in __salt__['firewalld.get_zones']():
if __opts__['test']:
ret['comment'][name] = '`{0}` will be created'.format(name)
else:
__salt__['firewalld.new_zone'](name)
ret['changes'][name] = '`{0}` zone has been successfully created'.format(name)
else:
ret['comment'][name] = '`{0}` zone already exists'.format(name)
try:
zones = __salt__['firewalld.get_zones']()
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
if name not in zones:
if not __opts__['test']:
try:
__salt__['firewalld.new_zone'](name)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
ret['changes'].update({name:
{'old': zones,
'new': name}})
if block_icmp:
_valid_icmp_types = __salt__['firewalld.get_icmp_types']()
_current_icmp_blocks = __salt__['firewalld.list_icmp_block'](name)
new_icmp_types = []
try:
_valid_icmp_types = __salt__['firewalld.get_icmp_types']()
_current_icmp_blocks = __salt__['firewalld.list_icmp_block'](name)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
for icmp_type in set(block_icmp):
if icmp_type in _valid_icmp_types:
if icmp_type in _current_icmp_blocks:
ret['comment']['icmp_blocks'].append(
'`{0}` already exists'.format(icmp_type)
)
else:
if __opts__['test']:
ret['comment']['icmp_blocks'].append(
'`{0}` will be blocked'.format(icmp_type)
)
else:
__salt__['firewalld.block_icmp'](name, icmp_type)
ret['changes']['icmp_blocks'].append(
'`{0}` has been blocked'.format(icmp_type)
)
if icmp_type not in _current_icmp_blocks:
new_icmp_types.append(icmp_type)
if not __opts__['test']:
try:
__salt__['firewalld.block_icmp'](name, icmp_type)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
else:
log.error('{0} is an invalid ICMP type'.format(icmp_type))
if new_icmp_types:
ret['changes'].update({'icmp_blocks':
{'old': _current_icmp_blocks,
'new': new_icmp_types}})
if default:
if __salt__['firewalld.default_zone']() == name:
ret['comment']['default'] = '`{0}` is already the default zone'.format(name)
else:
if __opts__['test']:
ret['comment']['default'] = '`{0}` wll be set to the default zone'.format(name)
else:
__salt__['firewalld.set_default_zone'](name)
ret['changes']['default'] = '`{0}` has been set to the default zone'.format(name)
try:
default_zone = __salt__['firewalld.default_zone']()
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
if name != default_zone:
if not __opts__['test']:
try:
__salt__['firewalld.set_default_zone'](name)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
ret['changes'].update({'default':
{'old': default_zone,
'new': name}})
if masquerade:
if __salt__['firewalld.get_masquerade'](name):
ret['comment']['masquerade'] = 'masquerading is already enabed'
else:
if __opts__['test']:
ret['comment']['masquerade'] = 'masquerading will be enabled'
else:
__salt__['firewalld.add_masquerade'](name)
ret['changes']['masquerade'] = 'masquerading successfully set'
try:
masquerade_ret = __salt__['firewalld.get_masquerade'](name)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
if not masquerade_ret:
if not __opts__['test']:
try:
__salt__['firewalld.add_masquerade'](name)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
ret['changes'].update({'masquerade':
{'old': '',
'new': 'Masquerading successfully set.'}})
if ports:
_current_ports = __salt__['firewalld.list_ports'](name)
new_ports = []
try:
_current_ports = __salt__['firewalld.list_ports'](name)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
for port in ports:
if port in _current_ports:
ret['comment']['ports'].append(
'`{0}` already exists'.format(port)
)
else:
if __opts__['test']:
ret['comment']['ports'].append(
'{0} will be added'.format(port)
)
else:
__salt__['firewalld.add_port'](name, port)
ret['changes']['ports'].append(
'`{0}` has been added to the firewall'.format(port)
)
if port not in _current_ports:
new_ports.append(port)
if not __opts__['test']:
try:
__salt__['firewalld.add_port'](name, port)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
if new_ports:
ret['changes'].update({'ports':
{'old': _current_ports,
'new': new_ports}})
if port_fwd:
_current_port_fwd = __salt__['firewalld.list_port_fwd'](name)
new_port_fwds = []
try:
_current_port_fwd = __salt__['firewalld.list_port_fwd'](name)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
for port in port_fwd:
dstaddr = ''
@ -157,45 +189,55 @@ def present(name,
else:
(src, dest, protocol) = port.split(':')
for i in _current_port_fwd:
if (src == i['Source port'] and dest == i['Destination port'] and
protocol == i['Protocol'] and dstaddr == i['Destination address']):
for item in _current_port_fwd:
if (src == item['Source port'] and dest == item['Destination port'] and
protocol == item['Protocol'] and dstaddr == item['Destination address']):
rule_exists = True
if rule_exists:
ret['comment']['port_fwd'].append(
'`{0}` port forwarding already exists'.format(port)
)
else:
if __opts__['test']:
ret['comment']['port_fwd'].append(
'`{0}` port will be added'.format(port)
)
else:
__salt__['firewalld.add_port_fwd'](
name, src, dest, protocol, dstaddr
)
ret['changes']['port_fwd'].append(
'`{0}` port forwarding has been added'.format(port)
)
if rule_exists is False:
new_port_fwds.append(port)
if not __opts__['test']:
try:
__salt__['firewalld.add_port_fwd'](name, src, dest, protocol, dstaddr)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
if new_port_fwds:
ret['changes'].update({'port_fwd':
{'old': _current_port_fwd,
'new': new_port_fwds}})
if services:
_current_services = __salt__['firewalld.list_services'](name)
new_services = []
try:
_current_services = __salt__['firewalld.list_services'](name)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
for service in services:
if service in _current_services:
ret['comment']['services'].append(
'`{0}` service already exists'.format(service)
)
else:
if __opts__['test']:
ret['comment']['services'].append(
'`{0}` service will be added'.format(service)
)
else:
__salt__['firewalld.new_service'](service)
ret['changes']['services'].append(
'`{0}` has been successfully added'.format(service)
)
if service not in _current_services:
new_services.append(service)
if not __opts__['test']:
try:
__salt__['firewalld.add_service'](service, zone=name)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
if new_services:
ret['changes'].update({'services':
{'old': _current_services,
'new': new_services}})
ret['result'] = True
if ret['changes'] == {}:
ret['comment'] = '\'{0}\' is already in the desired state.'.format(name)
return ret
if __opts__['test']:
ret['result'] = None
ret['comment'] = 'Configuration for \'{0}\' will change.'.format(name)
return ret
ret['comment'] = '\'{0}\' was configured.'.format(name)
return ret

View File

@ -373,6 +373,7 @@ def append(name, table='filter', family='ipv4', **kwargs):
if ignore in kwargs:
del kwargs[ignore]
kwargs['name'] = name
kwargs['table'] = table
rule = __salt__['iptables.build_rule'](family=family, **kwargs)
command = __salt__['iptables.build_rule'](full='True', family=family, command='A', **kwargs)
if __salt__['iptables.check'](table,
@ -500,6 +501,7 @@ def insert(name, table='filter', family='ipv4', **kwargs):
if ignore in kwargs:
del kwargs[ignore]
kwargs['name'] = name
kwargs['table'] = table
rule = __salt__['iptables.build_rule'](family=family, **kwargs)
command = __salt__['iptables.build_rule'](full=True, family=family, command='I', **kwargs)
if __salt__['iptables.check'](table,
@ -622,6 +624,7 @@ def delete(name, table='filter', family='ipv4', **kwargs):
if ignore in kwargs:
del kwargs[ignore]
kwargs['name'] = name
kwargs['table'] = table
rule = __salt__['iptables.build_rule'](family=family, **kwargs)
command = __salt__['iptables.build_rule'](full=True, family=family, command='D', **kwargs)

View File

@ -127,7 +127,7 @@ def wait(name, **kwargs):
'comment': ''}
# Alias module.watch to module.wait
watch = wait
watch = salt.utils.alias_function(wait, 'watch')
def run(name, **kwargs):
@ -269,4 +269,4 @@ def run(name, **kwargs):
ret['result'] = False
return ret
mod_watch = run # pylint: disable=C0103
mod_watch = salt.utils.alias_function(run, 'mod_watch')

View File

@ -46,6 +46,9 @@ automatically
from __future__ import absolute_import, print_function
import os
# Import salt libs
import salt.utils
def built(
name,
@ -53,12 +56,13 @@ def built(
dest_dir,
spec,
sources,
template,
tgt,
template=None,
deps=None,
env=None,
results=None,
always=False,
force=False,
always=None,
saltenv='base'):
'''
Ensure that the named package is built and exists in the named directory
@ -78,12 +82,16 @@ def built(
sources
The list of package sources
template
Set to run the spec file through a templating engine
tgt
The target platform to run the build on
template
Run the spec file through a templating engine
.. versionchanged:: 2015.8.2
This argument is now optional, allowing for no templating engine to
be used if none is desired.
deps
Packages required to ensure that the named package is built
can be hosted on either the salt master server or on an HTTP
@ -112,9 +120,20 @@ def built(
results
The names of the expected rpms that will be built
force : False
If ``True``, packages will be built even if they already exist in the
``dest_dir``. This is useful when building a package for continuous or
nightly package builds.
.. versionadded:: 2015.8.2
always
Build with every run (good if the package is for continuous or
nightly package builds)
If ``True``, packages will be built even if they already exist in the
``dest_dir``. This is useful when building a package for continuous or
nightly package builds.
.. deprecated:: 2015.8.2
Use ``force`` instead.
saltenv
The saltenv to use for files downloaded from the salt filesever
@ -123,7 +142,16 @@ def built(
'changes': {},
'comment': '',
'result': True}
if not always:
if always is not None:
salt.utils.warn_until(
'Carbon',
'The \'always\' argument to the pkgbuild.built state has been '
'deprecated, please use \'force\' instead.'
)
force = always
if not force:
if isinstance(results, str):
results = results.split(',')
results = set(results)

View File

@ -2,10 +2,8 @@
'''
Management of PostgreSQL tablespace
===================================
The postgres_tablespace module is used to create and manage Postgres
tablespaces.
Tablespaces can be set as either absent or present.
A module used to create and manage PostgreSQL tablespaces.
.. code-block:: yaml
ssd-tablespace:

View File

@ -74,4 +74,4 @@ def joined(name, host, user='rabbit', ram_node=None, runas='root'):
# Alias join to preserve backward compat
join = joined
join = salt.utils.alias_function(joined, 'join')

View File

@ -12,11 +12,14 @@ Example:
some_plugin:
rabbitmq_plugin.enabled: []
'''
from __future__ import absolute_import
# Import python libs
# Import Python Libs
from __future__ import absolute_import
import logging
# Import Salt Libs
from salt.exceptions import CommandExecutionError
log = logging.getLogger(__name__)
@ -40,25 +43,33 @@ def enabled(name, runas=None):
'''
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
result = {}
if __salt__['rabbitmq.plugin_is_enabled'](name, runas=runas):
ret['comment'] = 'Plugin {0} is already enabled'.format(name)
try:
plugin_enabled = __salt__['rabbitmq.plugin_is_enabled'](name, runas=runas)
except CommandExecutionError as err:
ret['result'] = False
ret['comment'] = 'Error: {0}'.format(err)
return ret
if __opts__['test']:
if plugin_enabled:
ret['comment'] = 'Plugin \'{0}\' is already enabled.'.format(name)
return ret
if not __opts__['test']:
try:
__salt__['rabbitmq.enable_plugin'](name, runas=runas)
except CommandExecutionError as err:
ret['result'] = False
ret['comment'] = 'Error: {0}'.format(err)
return ret
ret['changes'].update({'old': '', 'new': name})
if __opts__['test'] and ret['changes']:
ret['result'] = None
ret['comment'] = 'Plugin {0} is set to be enabled'.format(name)
else:
result = __salt__['rabbitmq.enable_plugin'](name, runas=runas)
if 'Error' in result:
ret['result'] = False
ret['comment'] = result['Error']
elif 'Enabled' in result:
ret['comment'] = result['Enabled']
ret['changes'] = {'old': '', 'new': name}
ret['comment'] = 'Plugin \'{0}\' is set to be enabled.'.format(name)
return ret
ret['comment'] = 'Plugin \'{0}\' was enabled.'.format(name)
return ret
@ -73,23 +84,31 @@ def disabled(name, runas=None):
'''
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
result = {}
if not __salt__['rabbitmq.plugin_is_enabled'](name, runas=runas):
ret['comment'] = 'Plugin {0} is not enabled'.format(name)
try:
plugin_enabled = __salt__['rabbitmq.plugin_is_enabled'](name, runas=runas)
except CommandExecutionError as err:
ret['result'] = False
ret['comment'] = 'Error: {0}'.format(err)
return ret
if __opts__['test']:
if not plugin_enabled:
ret['comment'] = 'Plugin \'{0}\' is already disabled.'.format(name)
return ret
if not __opts__['test']:
try:
__salt__['rabbitmq.disable_plugin'](name, runas=runas)
except CommandExecutionError as err:
ret['result'] = False
ret['comment'] = 'Error: {0}'.format(err)
return ret
ret['changes'].update({'old': name, 'new': ''})
if __opts__['test'] and ret['changes']:
ret['result'] = None
ret['comment'] = 'Plugin {0} is set to be disabled'.format(name)
else:
result = __salt__['rabbitmq.disable_plugin'](name, runas=runas)
if 'Error' in result:
ret['result'] = False
ret['comment'] = result['Error']
elif 'Disabled' in result:
ret['comment'] = result['Disabled']
ret['changes'] = {'new': '', 'old': name}
ret['comment'] = 'Plugin \'{0}\' is set to be disabled.'.format(name)
return ret
ret['comment'] = 'Plugin \'{0}\' was disabled.'.format(name)
return ret

View File

@ -8,18 +8,18 @@ Example:
.. code-block:: yaml
rabbit_user:
rabbitmq_user.present:
- password: password
- force: True
- tags:
- monitoring
- user
- perms:
- '/':
- '.*'
- '.*'
- '.*'
- runas: rabbitmq
rabbitmq_user.present:
- password: password
- force: True
- tags:
- monitoring
- user
- perms:
- '/':
- '.*'
- '.*'
- '.*'
- runas: rabbitmq
'''
# Import python libs
@ -28,9 +28,8 @@ import logging
# Import salt libs
import salt.utils
# Import 3rd-party libs
import salt.ext.six as six
from salt.exceptions import CommandExecutionError
log = logging.getLogger(__name__)
@ -42,20 +41,25 @@ def __virtual__():
return salt.utils.which('rabbitmqctl') is not None
def _check_perms_changes(name, newperms, runas=None):
def _check_perms_changes(name, newperms, runas=None, existing=None):
'''
Whether Rabbitmq user's permissions need to be changed
Check whether Rabbitmq user's permissions need to be changed.
'''
if not newperms:
return False
existing_perms = __salt__['rabbitmq.list_user_permissions'](name, runas=runas)
if existing is None:
try:
existing = __salt__['rabbitmq.list_user_permissions'](name, runas=runas)
except CommandExecutionError as err:
log.error('Error: {0}'.format(err))
return False
perm_need_change = False
for vhost_perms in newperms:
for vhost, perms in vhost_perms.iteritems():
if vhost in existing_perms:
if perms != existing_perms[vhost]:
if vhost in existing:
if perms != existing[vhost]:
perm_need_change = True
else:
perm_need_change = True
@ -63,14 +67,19 @@ def _check_perms_changes(name, newperms, runas=None):
return perm_need_change
def _check_tags_changes(name, newtags, runas=None):
def _check_tags_changes(name, new_tags, runas=None):
'''
Whether Rabbitmq user's tags need to be changed
'''
if newtags:
if isinstance(newtags, str):
newtags = newtags.split()
return __salt__['rabbitmq.list_users'](runas=runas)[name] - set(newtags)
if new_tags:
if isinstance(new_tags, str):
new_tags = new_tags.split()
try:
users = __salt__['rabbitmq.list_users'](runas=runas)[name] - set(new_tags)
except CommandExecutionError as err:
log.error('Error: {0}'.format(err))
return []
return users
else:
return []
@ -97,97 +106,109 @@ def present(name,
runas
Name of the user to run the command
'''
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
result = {}
user_exists = __salt__['rabbitmq.user_exists'](name, runas=runas)
if user_exists and not any((force, perms, tags)):
log.debug('RabbitMQ user %s exists, '
'and force is not set.', name)
ret['comment'] = 'User {0} already presents'.format(name)
ret = {'name': name, 'result': False, 'comment': '', 'changes': {}}
try:
user = __salt__['rabbitmq.user_exists'](name, runas=runas)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
if user and not any((force, perms, tags)):
log.debug('RabbitMQ user \'{0}\' exists and force is not set.'.format(name))
ret['comment'] = 'User \'{0}\' is already present.'.format(name)
ret['result'] = True
return ret
if not user:
ret['changes'].update({'user':
{'old': '',
'new': name}})
if __opts__['test']:
ret['result'] = None
ret['comment'] = 'User \'{0}\' is set to be created.'.format(name)
return ret
log.debug('RabbitMQ user \'{0}\' doesn\'t exist - Creating.'.format(name))
try:
__salt__['rabbitmq.add_user'](name, password, runas=runas)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
else:
changes = {'old': '', 'new': ''}
if not user_exists:
if __opts__['test']:
ret['result'] = None
ret['comment'] = 'User {0} is set to be created'.format(name)
return ret
log.debug("RabbitMQ user %s doesn't exist - Creating", name)
result = __salt__['rabbitmq.add_user'](
name, password, runas=runas)
else:
log.debug('RabbitMQ user %s exists', name)
if force:
if __opts__['test']:
ret['result'] = None
if password is not None:
if __opts__['test']:
ret['comment'] = ('User {0}\'s password is '
'set to be updated'.format(name))
log.debug('RabbitMQ user \'{0}\' exists'.format(name))
if force:
if password is not None:
if not __opts__['test']:
try:
__salt__['rabbitmq.change_password'](name, password, runas=runas)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
result = __salt__['rabbitmq.change_password'](
name, password, runas=runas)
changes['new'] = 'Set password.\n'
else:
log.debug('Password for %s is not set - Clearing password',
name)
if __opts__['test']:
ret['comment'] = ('User {0}\'s password is '
'set to be removed'.format(name))
ret['changes'].update({'password':
{'old': '',
'new': 'Set password.'}})
else:
if not __opts__['test']:
log.debug('Password for {0} is not set - Clearing password.'.format(name))
try:
__salt__['rabbitmq.clear_password'](name, runas=runas)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
ret['changes'].update({'password':
{'old': 'Removed password.',
'new': ''}})
result = __salt__['rabbitmq.clear_password'](
name, runas=runas)
changes['old'] += 'Removed password.\n'
if _check_tags_changes(name, tags, runas=runas):
if __opts__['test']:
ret['result'] = None
ret['comment'] += ('Tags for user {0} '
'is set to be changed'.format(name))
new_tags = _check_tags_changes(name, tags, runas=runas)
if new_tags:
if not __opts__['test']:
try:
__salt__['rabbitmq.set_user_tags'](name, tags, runas=runas)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
result.update(__salt__['rabbitmq.set_user_tags'](
name, tags, runas=runas)
)
changes['new'] += 'Set tags: {0}\n'.format(tags)
if _check_perms_changes(name, perms, runas=runas):
if __opts__['test']:
ret['result'] = None
ret['comment'] += ('Permissions for user {0} '
'is set to be changed'.format(name))
return ret
for vhost_perm in perms:
for vhost, perm in six.iteritems(vhost_perm):
result.update(__salt__['rabbitmq.set_permissions'](
vhost, name, perm[0], perm[1], perm[2], runas=runas)
)
changes['new'] += (
'Set permissions {0} for vhost {1}'
).format(perm, vhost)
if 'Error' in result:
ret['result'] = False
ret['comment'] = result['Error']
elif 'Added' in result:
ret['comment'] = result['Added']
ret['changes'] = changes
elif 'Password Changed' in result:
ret['comment'] = result['Password Changed']
ret['changes'] = changes
elif 'Password Cleared' in result:
ret['comment'] = result['Password Cleared']
ret['changes'] = changes
ret['changes'].update({'tags':
{'old': tags,
'new': new_tags}})
try:
existing_perms = __salt__['rabbitmq.list_user_permissions'](name, runas=runas)[0]
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
if _check_perms_changes(name, perms, runas=runas, existing=existing_perms):
for vhost_perm in perms:
for vhost, perm in six.iteritems(vhost_perm):
if not __opts__['test']:
try:
__salt__['rabbitmq.set_permissions'](
vhost, name, perm[0], perm[1], perm[2], runas=runas
)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
new_perms = {vhost: perm}
if existing_perms != new_perms:
if ret['changes'].get('perms') is None:
ret['changes'].update({'perms':
{'old': {},
'new': {}}})
ret['changes']['perms']['old'].update(existing_perms)
ret['changes']['perms']['new'].update(new_perms)
ret['result'] = True
if ret['changes'] == {}:
ret['comment'] = '\'{0}\' is already in the desired state.'.format(name)
return ret
if __opts__['test']:
ret['result'] = None
ret['comment'] = 'Configuration for \'{0}\' will change.'.format(name)
return ret
ret['comment'] = '\'{0}\' was configured.'.format(name)
return ret
def absent(name,
runas=None):
@ -199,23 +220,34 @@ def absent(name,
runas
User to run the command
'''
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
ret = {'name': name, 'result': False, 'comment': '', 'changes': {}}
user_exists = __salt__['rabbitmq.user_exists'](name, runas=runas)
try:
user_exists = __salt__['rabbitmq.user_exists'](name, runas=runas)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
if not user_exists:
ret['comment'] = 'User {0} is not present'.format(name)
elif __opts__['test']:
ret['result'] = None
if user_exists:
ret['comment'] = 'Removing user {0}'.format(name)
if user_exists:
if not __opts__['test']:
try:
__salt__['rabbitmq.delete_user'](name, runas=runas)
except CommandExecutionError as err:
ret['comment'] = 'Error: {0}'.format(err)
return ret
ret['changes'].update({'name':
{'old': name,
'new': ''}})
else:
result = __salt__['rabbitmq.delete_user'](name, runas=runas)
if 'Error' in result:
ret['result'] = False
ret['comment'] = result['Error']
elif 'Deleted' in result:
ret['comment'] = 'Deleted'
ret['changes'] = {'new': '', 'old': name}
ret['result'] = True
ret['comment'] = 'The user \'{0}\' is not present.'.format(name)
return ret
if __opts__['test'] and ret['changes']:
ret['result'] = None
ret['comment'] = 'The user \'{0}\' will be removed.'.format(name)
return ret
ret['result'] = True
ret['comment'] = 'The user \'{0}\' was removed.'.format(name)
return ret

View File

@ -94,56 +94,65 @@ def _parse_key(key):
return hive, key
def present(name, value=None, vname=None, vdata=None, vtype='REG_SZ', reflection=True):
def present(name,
value=None,
vname=None,
vdata=None,
vtype='REG_SZ',
reflection=True,
use_32bit_registry=False):
'''
Ensure a registry key or value is present.
:param str name:
A string value representing the full path of the key to include the
HIVE, Key, and all Subkeys. For example:
:param str name: A string value representing the full path of the key to
include the HIVE, Key, and all Subkeys. For example:
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt``
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt``
Valid hive values include:
- HKEY_CURRENT_USER or HKCU
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_USERS or HKU
Valid hive values include:
- HKEY_CURRENT_USER or HKCU
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_USERS or HKU
:param str value:
Deprecated. Use vname and vdata instead. Included here for backwards
compatability.
:param str value: Deprecated. Use vname and vdata instead. Included here for
backwards compatability.
:param str vname:
The name of the value you'd like to create beneath the Key. If this
parameter is not passed it will assume you want to set the (Default)
value
:param str vname: The name of the value you'd like to create beneath the
Key. If this parameter is not passed it will assume you want to set the
(Default) value
:param str vdata:
The value you'd like to set for the Key. If a value name (vname) is
passed, this will be the data for that value name. If not, this will be
the (Default) value for the key.
:param str vdata: The value you'd like to set for the Key. If a value name
(vname) is passed, this will be the data for that value name. If not, this
will be the (Default) value for the key.
The type for the (Default) value is always REG_SZ and cannot be changed.
This parameter is optional. If not passed, the Key will be created with.
The type for the (Default) value is always REG_SZ and cannot be changed.
This parameter is optional. If not passed, the Key will be created with no
associated item/value pairs.
:param str vtype:
The value type for the data you wish to store in the registry. Valid
values are:
:param str vtype: The value type for the data you wish to store in the
registry. Valid values are:
- REG_BINARY
- REG_DWORD
- REG_EXPAND_SZ
- REG_MULTI_SZ
- REG_SZ (Default)
- REG_BINARY
- REG_DWORD
- REG_EXPAND_SZ
- REG_MULTI_SZ
- REG_SZ (Default)
:param bool reflection:
On 64 bit machines a duplicate value will be created in the
``Wow6432Node`` for 32bit programs. This only applies to the SOFTWARE
key. This option is ignored on 32bit operating systems. This value
defaults to True. Set it to False to disable reflection.
:param bool reflection: On 64 bit machines a duplicate value will be created
in the ``Wow6432Node`` for 32bit programs. This only applies to the SOFTWARE
key. This option is ignored on 32bit operating systems. This value defaults
to True. Set it to False to disable reflection.
:return:
Returns a dictionary showing the results of the registry operation.
.. deprecated:: 2015.8.2
Use `use_32bit_registry` instead.
The parameter seems to have no effect since Windows 7 / Windows 2008R2
removed support for reflection. The parameter will be removed in Boron.
:param bool use_32bit_registry: Use the 32bit portion of the registry.
Applies only to 64bit windows. 32bit Windows will ignore this parameter.
Default if False.
:return: Returns a dictionary showing the results of the registry operation.
:rtype: dict
The following example will set the ``(Default)`` value for the
@ -199,7 +208,10 @@ def present(name, value=None, vname=None, vdata=None, vtype='REG_SZ', reflection
hive, key = _parse_key(name)
# Determine what to do
reg_current = __salt__['reg.read_value'](hive, key, vname)
reg_current = __salt__['reg.read_value'](hive=hive,
key=key,
vname=vname,
use_32bit_registry=use_32bit_registry)
if vdata == reg_current['vdata'] and reg_current['success']:
ret['comment'] = '{0} in {1} is already configured'.\
@ -217,8 +229,12 @@ def present(name, value=None, vname=None, vdata=None, vtype='REG_SZ', reflection
return ret
# Configure the value
ret['result'] = __salt__['reg.set_value'](hive, key, vname, vdata, vtype,
reflection)
ret['result'] = __salt__['reg.set_value'](hive=hive,
key=key,
vname=vname,
vdata=vdata,
vtype=vtype,
use_32bit_registry=use_32bit_registry)
if not ret['result']:
ret['changes'] = {}
@ -230,11 +246,33 @@ def present(name, value=None, vname=None, vdata=None, vtype='REG_SZ', reflection
return ret
def absent(name, vname=None):
def absent(name, vname=None, use_32bit_registry=False):
'''
Ensure a registry value is removed. To remove a key use key_absent.
Example:
:param str name: A string value representing the full path of the key to
include the HIVE, Key, and all Subkeys. For example:
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt``
Valid hive values include:
- HKEY_CURRENT_USER or HKCU
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_USERS or HKU
:param str vname: The name of the value you'd like to create beneath the
Key. If this parameter is not passed it will assume you want to set the
(Default) value
:param bool use_32bit_registry: Use the 32bit portion of the registry.
Applies only to 64bit windows. 32bit Windows will ignore this parameter.
Default if False.
:return: Returns a dictionary showing the results of the registry operation.
:rtype: dict
CLI Example:
.. code-block:: yaml
@ -242,9 +280,11 @@ def absent(name, vname=None):
reg.absent
In the above example the path is interpreted as follows:
- ``HKEY_CURRENT_USER`` is the hive
- ``SOFTWARE\\Salt`` is the key
- ``version`` is the value name
So the value ``version`` will be deleted from the ``SOFTWARE\\Salt`` key in
the ``HKEY_CURRENT_USER`` hive.
'''
@ -256,11 +296,17 @@ def absent(name, vname=None):
hive, key = _parse_key(name)
# Determine what to do
reg_check = __salt__['reg.read_value'](hive, key, vname)
reg_check = __salt__['reg.read_value'](hive=hive,
key=key,
vname=vname,
use_32bit_registry=use_32bit_registry)
if not reg_check['success'] or reg_check['vdata'] == '(value not set)':
if not vname:
hive, key, vname = _parse_key_value(name)
reg_check = __salt__['reg.read_value'](hive, key, vname)
reg_check = __salt__['reg.read_value'](hive=hive,
key=key,
vname=vname,
use_32bit_registry=use_32bit_registry)
if not reg_check['success'] or reg_check['vdata'] == '(value not set)':
ret['comment'] = '{0} is already absent'.format(name)
return ret
@ -278,7 +324,10 @@ def absent(name, vname=None):
return ret
# Delete the value
ret['result'] = __salt__['reg.delete_value'](hive, key, vname)
ret['result'] = __salt__['reg.delete_value'](hive=hive,
key=key,
vname=vname,
use_32bit_registry=use_32bit_registry)
if not ret['result']:
ret['changes'] = {}
ret['comment'] = r'Failed to remove {0} from {1}'.format(key, hive)
@ -289,39 +338,40 @@ def absent(name, vname=None):
return ret
def key_absent(name, force=False):
def key_absent(name, force=False, use_32bit_registry=False):
r'''
.. versionadded:: 2015.5.4
Ensure a registry key is removed. This will remove a key and all value
entries it contains. It will fail if the key contains subkeys.
:param str name:
A string representing the full path to the key to be removed to include
the hive and the keypath. The hive can be any of the following:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:param str name: A string representing the full path to the key to be
removed to include the hive and the keypath. The hive can be any of the following:
:param bool force:
A boolean value indicating that all subkeys should be deleted with the
key. If force=False and subkeys exists beneath the key you want to
delete, key_absent will fail. Use with caution. The default is False.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:return:
Returns a dictionary showing the results of the registry operation.
:param bool force: A boolean value indicating that all subkeys should be
deleted with the key. If force=False and subkeys exists beneath the key you
want to delete, key_absent will fail. Use with caution. The default is False.
:return: Returns a dictionary showing the results of the registry operation.
:rtype: dict
The following example will delete the ``SOFTWARE\Salt`` key and all subkeys
under the ``HKEY_CURRENT_USER`` hive.
Example::
Example:
.. codeblock:: yaml
'HKEY_CURRENT_USER\SOFTWARE\Salt':
reg.key_absent:
- force: True
In the above example the path is interpreted as follows:
- ``HKEY_CURRENT_USER`` is the hive
- ``SOFTWARE\Salt`` is the key
'''
@ -333,7 +383,9 @@ def key_absent(name, force=False):
hive, key = _parse_key(name)
# Determine what to do
if not __salt__['reg.read_value'](hive, key)['success']:
if not __salt__['reg.read_value'](hive=hive,
key=key,
use_32bit_registry=use_32bit_registry)['success']:
ret['comment'] = '{0} is already absent'.format(name)
return ret
@ -348,8 +400,13 @@ def key_absent(name, force=False):
return ret
# Delete the value
__salt__['reg.delete_key'](hive, key, force=force)
if __salt__['reg.read_value'](hive, key)['success']:
__salt__['reg.delete_key'](hive=hive,
key=key,
force=force,
use_32bit_registry=use_32bit_registry)
if __salt__['reg.read_value'](hive=hive,
key=key,
use_32bit_registry=use_32bit_registry)['success']:
ret['result'] = False
ret['changes'] = {}
ret['comment'] = 'Failed to remove registry key {0}'.format(name)

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