diff --git a/doc/conf.py b/doc/conf.py index ef06527810..17c8d25d4d 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -46,6 +46,8 @@ class Mock(object): data = self.__mapping.get(name) elif name in ('__file__', '__path__'): data = '/dev/null' + elif name == '__qualname__': + raise AttributeError("'Mock' object has no attribute '__qualname__'") else: data = Mock(mapping=self.__mapping) return data diff --git a/doc/man/salt-api.1 b/doc/man/salt-api.1 index b4c78c6a8e..fe29c0fd45 100644 --- a/doc/man/salt-api.1 +++ b/doc/man/salt-api.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-API" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-API" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-api \- salt-api Command . diff --git a/doc/man/salt-call.1 b/doc/man/salt-call.1 index 8a3101e8cd..8386d3c11d 100644 --- a/doc/man/salt-call.1 +++ b/doc/man/salt-call.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-CALL" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-CALL" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-call \- salt-call Documentation . diff --git a/doc/man/salt-cloud.1 b/doc/man/salt-cloud.1 index 77313fe9a9..432cb8089b 100644 --- a/doc/man/salt-cloud.1 +++ b/doc/man/salt-cloud.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-CLOUD" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-CLOUD" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-cloud \- Salt Cloud Command . @@ -197,7 +197,7 @@ New in version 2014.7.0. .sp Display a list of configured profiles. Pass in a cloud provider to view -the provider\(aqs associated profiles, such as \fBdigital_ocean\fP, or pass in +the provider\(aqs associated profiles, such as \fBdigitalocean\fP, or pass in \fBall\fP to list all the configured profiles. .UNINDENT .SS Cloud Providers Listings diff --git a/doc/man/salt-cp.1 b/doc/man/salt-cp.1 index 88b2acaec6..28cf8617dd 100644 --- a/doc/man/salt-cp.1 +++ b/doc/man/salt-cp.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-CP" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-CP" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-cp \- salt-cp Documentation . diff --git a/doc/man/salt-key.1 b/doc/man/salt-key.1 index 998461d497..bf4e9bd425 100644 --- a/doc/man/salt-key.1 +++ b/doc/man/salt-key.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-KEY" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-KEY" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-key \- salt-key Documentation . diff --git a/doc/man/salt-master.1 b/doc/man/salt-master.1 index 7c108d2409..f2182c6389 100644 --- a/doc/man/salt-master.1 +++ b/doc/man/salt-master.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-MASTER" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-MASTER" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-master \- salt-master Documentation . diff --git a/doc/man/salt-minion.1 b/doc/man/salt-minion.1 index 6a21b15af0..3e150db372 100644 --- a/doc/man/salt-minion.1 +++ b/doc/man/salt-minion.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-MINION" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-MINION" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-minion \- salt-minion Documentation . diff --git a/doc/man/salt-proxy.1 b/doc/man/salt-proxy.1 index c26678d9ba..49b17a6e8b 100644 --- a/doc/man/salt-proxy.1 +++ b/doc/man/salt-proxy.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-PROXY" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-PROXY" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-proxy \- salt-proxy Documentation . diff --git a/doc/man/salt-run.1 b/doc/man/salt-run.1 index 044553e3b9..221a86f38e 100644 --- a/doc/man/salt-run.1 +++ b/doc/man/salt-run.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-RUN" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-RUN" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-run \- salt-run Documentation . diff --git a/doc/man/salt-ssh.1 b/doc/man/salt-ssh.1 index d1c95c8c8d..0abc8aefbd 100644 --- a/doc/man/salt-ssh.1 +++ b/doc/man/salt-ssh.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-SSH" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-SSH" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-ssh \- salt-ssh Documentation . diff --git a/doc/man/salt-syndic.1 b/doc/man/salt-syndic.1 index 095493ba93..9fb836270b 100644 --- a/doc/man/salt-syndic.1 +++ b/doc/man/salt-syndic.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-SYNDIC" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-SYNDIC" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-syndic \- salt-syndic Documentation . diff --git a/doc/man/salt-unity.1 b/doc/man/salt-unity.1 index 3e45edf4ad..aa6be8e5fd 100644 --- a/doc/man/salt-unity.1 +++ b/doc/man/salt-unity.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-UNITY" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT-UNITY" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt-unity \- salt-unity Command . diff --git a/doc/man/salt.1 b/doc/man/salt.1 index d6a0b4685d..57c417279f 100644 --- a/doc/man/salt.1 +++ b/doc/man/salt.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt \- salt . @@ -135,7 +135,7 @@ minions to execute on. .B \-a EAUTH, \-\-auth=EAUTH Pass in an external authentication medium to validate against. The credentials will be prompted for. The options are \fIauto\fP, -\fIkeystone\fP, \fIldap\fP, \fIpam\fP, and \fIstormpath\fP\&. Can be used with the \-T +\fIkeystone\fP, \fIldap\fP, and \fIpam\fP\&. Can be used with the \-T option. .UNINDENT .INDENT 0.0 diff --git a/doc/man/salt.7 b/doc/man/salt.7 index 7e3c7ae0e6..93c4b073cd 100644 --- a/doc/man/salt.7 +++ b/doc/man/salt.7 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT" "7" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SALT" "7" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME salt \- Salt Documentation . @@ -1469,11 +1469,31 @@ like to remove them. Clicking OK will remove the Salt binaries and related files but leave any existing config, cache, and PKI information. .SS Salt Minion Installation .sp +If the system is missing the appropriate version of the Visual C++ +Redistributable (vcredist) the user will be prompted to install it. Click \fBOK\fP +to install the vcredist. Click \fBCancel\fP to abort the installation without +making modifications to the system. +.sp +If Salt is already installed on the system the user will be prompted to remove +the previous installation. Click \fBOK\fP to uninstall Salt without removing the +configuration, PKI information, or cached files. Click \fBCancel\fP to abort the +installation before making any modifications to the system. +.sp After the Welcome and the License Agreement, the installer asks for two bits of information to configure the minion; the master hostname and the minion name. -The installer will update the minion config with these options. If the installer -finds an existing minion config file, these fields will be populated with values -from the existing config. +The installer will update the minion config with these options. +.sp +If the installer finds an existing minion config file, these fields will be +populated with values from the existing config, but they will be grayed out. +There will also be a checkbox to use the existing config. If you continue, the +existing config will be used. If the checkbox is unchecked, default values are +displayed and can be changed. If you continue, the existing config file in +\fBc:\esalt\econf\fP will be removed along with the +.nf +\(ga\(ga +.fi +c:saltconfminion.d\(ga +directory. The values entered will be used with the default config. .sp The final page allows you to start the minion service and optionally change its startup type. By default, the minion is set to \fBAutomatic\fP\&. You can change the @@ -1504,15 +1524,6 @@ net start salt\-minion .fi .UNINDENT .UNINDENT -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -If the minion won\(aqt start, you may need to install the Microsoft Visual C++ -2008 x64 SP1 redistributable. Allow all Windows updates to run salt\-minion -smoothly. -.UNINDENT -.UNINDENT .SS Installation Prerequisites .sp Most Salt functionality should work just fine right out of the box. A few Salt @@ -1535,17 +1546,22 @@ Description T} _ T{ -\fB/minion\-name=\fP +\fB/master=\fP T} T{ -A string value to set the minion name. Default is -\(aqhostname\(aq +A string value to set the IP address or hostname of +the master. Default value is \(aqsalt\(aq. You can pass a +single master or a comma\-separated list of masters. +Setting the master will cause the installer to use +the default config or a custom config if defined. T} _ T{ -\fB/master=\fP +\fB/minion\-name=\fP T} T{ -A string value to set the IP address or host name of -the master. Default value is \(aqsalt\(aq +A string value to set the minion name. Default value +is \(aqhostname\(aq. Setting the minion name causes the +installer to use the default config or a custom +config if defined. T} _ T{ @@ -1560,7 +1576,40 @@ T{ \fB/start\-minion\-delayed\fP T} T{ Set the minion start type to -\fBAutomatic (Delayed Start)\fP +\fBAutomatic (Delayed Start)\fP\&. +T} +_ +T{ +\fB/default\-config\fP +T} T{ +Overwrite the existing config if present with the +default config for salt. Default is to use the +existing config if present. If \fB/master\fP and/or +\fB/minion\-name\fP is passed, those values will be used +to update the new default config. +T} +_ +T{ +\fB/custom\-config=\fP +T} T{ +A string value specifying the name of a custom config +file in the same path as the installer of the full +path to a custom config file. If \fB/master\fP and/or +\fB/minion\-name\fP is passed, those values will be used +to update the new custom config. +T} +_ +T{ +\fB/S\fP +T} T{ +Runs the installation silently. Uses the above +settings or the defaults. +T} +_ +T{ +\fB/?\fP +T} T{ +Displays command line help. T} _ .TE @@ -1573,6 +1622,15 @@ expected for the time being. .UNINDENT .UNINDENT .sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fB/default\-config\fP and \fB/custom\-config=\fP will backup an existing config +if found. A timestamp and a \fB\&.bak\fP extension will be added. That includes +the \fBminion\fP file and the \fBminion.d\fP directory. +.UNINDENT +.UNINDENT +.sp Here are some examples of using the silent installer: .INDENT 0.0 .INDENT 3.5 @@ -1600,6 +1658,19 @@ Salt\-Minion\-2017.7.1\-Py3\-AMD64\-Setup.exe /S /master=yoursaltmaster /minion\ .fi .UNINDENT .UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Install the Salt Minion +# Configure the minion using a custom config and configuring multimaster + +Salt\-Minion\-2017.7.1\-Py3\-AMD64\-Setup.exe /S /custom\-config=windows_minion /master=prod_master1,prod_master2 +.ft P +.fi +.UNINDENT +.UNINDENT .SS Running the Salt Minion on Windows as an Unprivileged User .sp Notes: @@ -2682,7 +2753,7 @@ Gentoo \fBBSD\fP: .INDENT 0.0 .IP \(bu 2 -OpenBSD (\fBpip\fP installation) +OpenBSD .IP \(bu 2 FreeBSD 9/10/11 .UNINDENT @@ -2969,69 +3040,121 @@ Here\(aqs a summary of the command line options: .ft C $ sh bootstrap\-salt.sh \-h - Usage : bootstrap\-salt.sh [options] - Installation types: - \- stable (default) - \- stable [version] (ubuntu specific) - \- daily (ubuntu specific) - \- testing (redhat specific) - \- git + \- stable Install latest stable release. This is the default + install type + \- stable [branch] Install latest version on a branch. Only supported + for packages available at repo.saltstack.com + \- stable [version] Install a specific version. Only supported for + packages available at repo.saltstack.com + \- daily Ubuntu specific: configure SaltStack Daily PPA + \- testing RHEL\-family specific: configure EPEL testing repo + \- git Install from the head of the develop branch + \- git [ref] Install from any git ref (such as a branch, tag, or + commit) Examples: \- bootstrap\-salt.sh \- bootstrap\-salt.sh stable - \- bootstrap\-salt.sh stable 2014.7 + \- bootstrap\-salt.sh stable 2017.7 + \- bootstrap\-salt.sh stable 2017.7.2 \- bootstrap\-salt.sh daily \- bootstrap\-salt.sh testing \- bootstrap\-salt.sh git - \- bootstrap\-salt.sh git develop - \- bootstrap\-salt.sh git v0.17.0 - \- bootstrap\-salt.sh git 8c3fadf15ec183e5ce8c63739850d543617e4357 + \- bootstrap\-salt.sh git 2017.7 + \- bootstrap\-salt.sh git v2017.7.2 + \- bootstrap\-salt.sh git 06f249901a2e2f1ed310d58ea3921a129f214358 Options: - \-h Display this message - \-v Display script version - \-n No colours. - \-D Show debug output. - \-c Temporary configuration directory - \-g Salt repository URL. (default: git://github.com/saltstack/salt.git) - \-G Instead of cloning from git://github.com/saltstack/salt.git, clone from https://github.com/saltstack/salt.git (Usually necessary on systems which have the regular git protocol port blocked, where https usually is not) - \-k Temporary directory holding the minion keys which will pre\-seed - the master. - \-s Sleep time used when waiting for daemons to start, restart and when checking - for the services running. Default: 3 - \-M Also install salt\-master - \-S Also install salt\-syndic - \-N Do not install salt\-minion - \-X Do not start daemons after installation - \-C Only run the configuration function. This option automatically - bypasses any installation. - \-P Allow pip based installations. On some distributions the required salt - packages or its dependencies are not available as a package for that - distribution. Using this flag allows the script to use pip as a last - resort method. NOTE: This only works for functions which actually - implement pip based installations. - \-F Allow copied files to overwrite existing(config, init.d, etc) - \-U If set, fully upgrade the system prior to bootstrapping salt - \-K If set, keep the temporary files in the temporary directories specified - with \-c and \-k. - \-I If set, allow insecure connections while downloading any files. For - example, pass \(aq\-\-no\-check\-certificate\(aq to \(aqwget\(aq or \(aq\-\-insecure\(aq to \(aqcurl\(aq - \-A Pass the salt\-master DNS name or IP. This will be stored under - ${BS_SALT_ETC_DIR}/minion.d/99\-master\-address.conf - \-i Pass the salt\-minion id. This will be stored under - ${BS_SALT_ETC_DIR}/minion_id - \-L Install the Apache Libcloud package if possible(required for salt\-cloud) - \-p Extra\-package to install while installing salt dependencies. One package - per \-p flag. You\(aqre responsible for providing the proper package name. - \-d Disable check_service functions. Setting this flag disables the - \(aqinstall__check_services\(aq checks. You can also do this by - touching /tmp/disable_salt_checks on the target host. Defaults ${BS_FALSE} - \-H Use the specified http proxy for the installation - \-Z Enable external software source for newer ZeroMQ(Only available for RHEL/CentOS/Fedora/Ubuntu based distributions) - \-b Assume that dependencies are already installed and software sources are set up. - If git is selected, git tree is still checked out as dependency step. + \-h Display this message + \-v Display script version + \-n No colours + \-D Show debug output + \-c Temporary configuration directory + \-g Salt Git repository URL. Default: https://github.com/saltstack/salt.git + \-w Install packages from downstream package repository rather than + upstream, saltstack package repository. This is currently only + implemented for SUSE. + \-k Temporary directory holding the minion keys which will pre\-seed + the master. + \-s Sleep time used when waiting for daemons to start, restart and when + checking for the services running. Default: 3 + \-L Also install salt\-cloud and required python\-libcloud package + \-M Also install salt\-master + \-S Also install salt\-syndic + \-N Do not install salt\-minion + \-X Do not start daemons after installation + \-d Disables checking if Salt services are enabled to start on system boot. + You can also do this by touching /tmp/disable_salt_checks on the target + host. Default: ${BS_FALSE} + \-P Allow pip based installations. On some distributions the required salt + packages or its dependencies are not available as a package for that + distribution. Using this flag allows the script to use pip as a last + resort method. NOTE: This only works for functions which actually + implement pip based installations. + \-U If set, fully upgrade the system prior to bootstrapping Salt + \-I If set, allow insecure connections while downloading any files. For + example, pass \(aq\-\-no\-check\-certificate\(aq to \(aqwget\(aq or \(aq\-\-insecure\(aq to + \(aqcurl\(aq. On Debian and Ubuntu, using this option with \-U allows to obtain + GnuPG archive keys insecurely if distro has changed release signatures. + \-F Allow copied files to overwrite existing (config, init.d, etc) + \-K If set, keep the temporary files in the temporary directories specified + with \-c and \-k + \-C Only run the configuration function. Implies \-F (forced overwrite). + To overwrite Master or Syndic configs, \-M or \-S, respectively, must + also be specified. Salt installation will be ommitted, but some of the + dependencies could be installed to write configuration with \-j or \-J. + \-A Pass the salt\-master DNS name or IP. This will be stored under + ${BS_SALT_ETC_DIR}/minion.d/99\-master\-address.conf + \-i Pass the salt\-minion id. This will be stored under + ${BS_SALT_ETC_DIR}/minion_id + \-p Extra\-package to install while installing Salt dependencies. One package + per \-p flag. You\(aqre responsible for providing the proper package name. + \-H Use the specified HTTP proxy for all download URLs (including https://). + For example: http://myproxy.example.com:3128 + \-Z Enable additional package repository for newer ZeroMQ + (only available for RHEL/CentOS/Fedora/Ubuntu based distributions) + \-b Assume that dependencies are already installed and software sources are + set up. If git is selected, git tree is still checked out as dependency + step. + \-f Force shallow cloning for git installations. + This may result in an "n/a" in the version number. + \-l Disable ssl checks. When passed, switches "https" calls to "http" where + possible. + \-V Install Salt into virtualenv + (only available for Ubuntu based distributions) + \-a Pip install all Python pkg dependencies for Salt. Requires \-V to install + all pip pkgs into the virtualenv. + (Only available for Ubuntu based distributions) + \-r Disable all repository configuration performed by this script. This + option assumes all necessary repository configuration is already present + on the system. + \-R Specify a custom repository URL. Assumes the custom repository URL + points to a repository that mirrors Salt packages located at + repo.saltstack.com. The option passed with \-R replaces the + "repo.saltstack.com". If \-R is passed, \-r is also set. Currently only + works on CentOS/RHEL and Debian based distributions. + \-J Replace the Master config file with data passed in as a JSON string. If + a Master config file is found, a reasonable effort will be made to save + the file with a ".bak" extension. If used in conjunction with \-C or \-F, + no ".bak" file will be created as either of those options will force + a complete overwrite of the file. + \-j Replace the Minion config file with data passed in as a JSON string. If + a Minion config file is found, a reasonable effort will be made to save + the file with a ".bak" extension. If used in conjunction with \-C or \-F, + no ".bak" file will be created as either of those options will force + a complete overwrite of the file. + \-q Quiet salt installation from git (setup.py install \-q) + \-x Changes the python version used to install a git version of salt. Currently + this is considered experimental and has only been tested on Centos 6. This + only works for git installations. + \-y Installs a different python version on host. Currently this has only been + tested with Centos 6 and is considered experimental. This will install the + ius repo on the box if disable repo is false. This must be used in conjunction + with \-x . For example: + sh bootstrap.sh \-P \-y \-x python2.7 git v2016.11.3 + The above will install python27 and install the git version of salt using the + python2.7 executable. This only works for git and pip installations. .ft P .fi .UNINDENT @@ -4721,6 +4844,29 @@ user: root .fi .UNINDENT .UNINDENT +.SS \fBenable_ssh_minions\fP +.sp +Default: \fBFalse\fP +.sp +Tell the master to also use salt\-ssh when running commands against minions. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +enable_ssh_minions: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Cross\-minion communication is still not possible. The Salt mine and +publish.publish do not work between minion types. +.UNINDENT +.UNINDENT .SS \fBret_port\fP .sp Default: \fB4506\fP @@ -4775,7 +4921,8 @@ root_dir: / This directory is prepended to the following options: \fI\%pki_dir\fP, \fI\%cachedir\fP, \fI\%sock_dir\fP, \fI\%log_file\fP, \fI\%autosign_file\fP, -\fI\%autoreject_file\fP, \fI\%pidfile\fP\&. +\fI\%autoreject_file\fP, \fI\%pidfile\fP, +\fI\%autosign_grains_dir\fP\&. .UNINDENT .UNINDENT .SS \fBconf_file\fP @@ -4898,6 +5045,8 @@ clouds tops .IP \(bu 2 roster +.IP \(bu 2 +tokens .UNINDENT .UNINDENT .SS \fBmodule_dirs\fP @@ -5080,6 +5229,21 @@ color: False .fi .UNINDENT .UNINDENT +.SS \fBcolor_theme\fP +.sp +Default: \fB""\fP +.sp +Specifies a path to the color theme to use for colored command line output. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +color_theme: /etc/salt/color_theme +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBcli_summary\fP .sp Default: \fBFalse\fP @@ -5423,6 +5587,16 @@ appear to initially respond after a key is rotated. Note that ping_on_rotate may cause high load on the master immediately after the key rotation event as minions reconnect. Consider this carefully if this salt master is managing a large number of minions. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ping_on_rotate: False +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBmaster_job_cache\fP .sp New in version 2014.7.0. @@ -5586,6 +5760,21 @@ transport_opts: .fi .UNINDENT .UNINDENT +.SS \fBmaster_stats\fP +.sp +Default: False +.sp +Turning on the master stats enables runtime throughput and statistics events +to be fired from the master event bus. These events will report on what +functions have been run on the master and how long these runs have, on +average, taken over a given period of time. +.SS \fBmaster_stats_event_iter\fP +.sp +Default: 60 +.sp +The time in seconds to fire master_stats events. This will only fire in +conjunction with receiving a request to the master, idle masters will not +fire these events. .SS \fBsock_pool_size\fP .sp Default: 1 @@ -5727,11 +5916,26 @@ minion_data_cache_events: True .UNINDENT .UNINDENT .SS Salt\-SSH Configuration +.SS \fBroster\fP +.sp +Default: \fBflat\fP +.sp +Define the default salt\-ssh roster module to use +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +roster: cache +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBroster_file\fP .sp Default: \fB/etc/salt/roster\fP .sp -Pass in an alternative location for the salt\-ssh roster file. +Pass in an alternative location for the salt\-ssh \fIflat\fP roster file. .INDENT 0.0 .INDENT 3.5 .sp @@ -5742,6 +5946,27 @@ roster_file: /root/roster .fi .UNINDENT .UNINDENT +.SS \fBrosters\fP +.sp +Default: None +.sp +Define locations for \fIflat\fP roster files so they can be chosen when using Salt API. +An administrator can place roster files into these locations. +Then when calling Salt API, parameter \(aqroster_file\(aq should contain a relative path to these locations. +That is, "roster_file=/foo/roster" will be resolved as "/etc/salt/roster.d/foo/roster" etc. +This feature prevents passing insecure custom rosters through the Salt API. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +rosters: + \- /etc/salt/roster.d + \- /opt/salt/some/more/rosters +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBssh_passwd\fP .sp Default: \fB\(aq\(aq\fP @@ -6025,6 +6250,12 @@ will be automatically accepted. Matches will be searched for first by string comparison, then by globbing, then by full\-string regex matching. This should still be considered a less than secure option, due to the fact that trust is based on just the requesting minion id. +.sp +Changed in version 2018.3.0: For security reasons the file must be readonly except for it\(aqs owner. +If \fI\%permissive_pki_access\fP is \fBTrue\fP the owning group can also +have write access, but if Salt is running as \fBroot\fP it must be a member of that group. +A less strict requirement also existed in previous version. + .SS \fBautoreject_file\fP .sp New in version 2014.1.0. @@ -6036,6 +6267,35 @@ Works like \fI\%autosign_file\fP, but instead allows you to specify minion IDs for which keys will automatically be rejected. Will override both membership in the \fI\%autosign_file\fP and the \fI\%auto_accept\fP setting. +.SS \fBautosign_grains_dir\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fBnot defined\fP +.sp +If the \fBautosign_grains_dir\fP is specified, incoming keys from minions with +grain values that match those defined in files in the autosign_grains_dir +will be accepted automatically. Grain values that should be accepted automatically +can be defined by creating a file named like the corresponding grain in the +autosign_grains_dir and writing the values into that file, one value per line. +Lines starting with a \fB#\fP will be ignored. +Minion must be configured to send the corresponding grains on authentication. +This should still be considered a less than secure option, due to the fact +that trust is based on just the requesting minion. +.sp +Please see the Autoaccept Minions from Grains +documentation for more infomation. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +autosign_grains_dir: /etc/salt/autosign_grains +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBpermissive_pki_access\fP .sp Default: \fBFalse\fP @@ -6579,6 +6839,25 @@ runner_dirs: .fi .UNINDENT .UNINDENT +.SS \fButils_dirs\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB[]\fP +.sp +Set additional directories to search for util modules. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +utils_dirs: + \- /var/lib/salt/utils +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBcython_enable\fP .sp Default: \fBFalse\fP @@ -6602,7 +6881,8 @@ Default: \fBtop.sls\fP .sp The state system uses a "top" file to tell the minions what environment to use and what modules to use. The state_top file is defined relative to the -root of the base environment. +root of the base environment. The value of "state_top" is also used for the +pillar top file .INDENT 0.0 .INDENT 3.5 .sp @@ -6790,7 +7070,132 @@ userdata_template: jinja .fi .UNINDENT .UNINDENT +.SS \fBjinja_env\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB{}\fP +.sp +jinja_env overrides the default Jinja environment options for +\fBall templates except sls templates\fP\&. +To set the options for sls templates use \fI\%jinja_sls_env\fP\&. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +The \fI\%Jinja2 Environment documentation\fP is the official source for the default values. +Not all the options listed in the jinja documentation can be overridden using \fI\%jinja_env\fP or \fI\%jinja_sls_env\fP\&. +.UNINDENT +.UNINDENT +.sp +The default options are: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +jinja_env: + block_start_string: \(aq{%\(aq + block_end_string: \(aq%}\(aq + variable_start_string: \(aq{{\(aq + variable_end_string: \(aq}}\(aq + comment_start_string: \(aq{#\(aq + comment_end_string: \(aq#}\(aq + line_statement_prefix: + line_comment_prefix: + trim_blocks: False + lstrip_blocks: False + newline_sequence: \(aq\en\(aq + keep_trailing_newline: False +.ft P +.fi +.UNINDENT +.UNINDENT +.SS \fBjinja_sls_env\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB{}\fP +.sp +jinja_sls_env sets the Jinja environment options for \fBsls templates\fP\&. +The defaults and accepted options are exactly the same as they are +for \fI\%jinja_env\fP\&. +.sp +The default options are: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +jinja_sls_env: + block_start_string: \(aq{%\(aq + block_end_string: \(aq%}\(aq + variable_start_string: \(aq{{\(aq + variable_end_string: \(aq}}\(aq + comment_start_string: \(aq{#\(aq + comment_end_string: \(aq#}\(aq + line_statement_prefix: + line_comment_prefix: + trim_blocks: False + lstrip_blocks: False + newline_sequence: \(aq\en\(aq + keep_trailing_newline: False +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Example using line statements and line comments to increase ease of use: +.sp +If your configuration options are +.sp +With these options jinja will interpret anything after a \fB%\fP at the start of a line (ignoreing whitespace) +as a jinja statement and will interpret anything after a \fB##\fP as a comment. +.sp +This allows the following more convenient syntax to be used: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +## (this comment will not stay once rendered) +# (this comment remains in the rendered template) +## ensure all the formula services are running +% for service in formula_services: +enable_service_{{ serivce }}: + service.running: + name: {{ service }} +% endfor +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The following less convenient but equivalent syntax would have to +be used if you had not set the line_statement and line_comment options: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{# (this comment will not stay once rendered) #} +# (this comment remains in the rendered template) +{# ensure all the formula services are running #} +{% for service in formula_services %} +enable_service_{{ service }}: + service.running: + name: {{ service }} +{% endfor %} +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBjinja_trim_blocks\fP +.sp +Deprecated since version 2018.3.0: Replaced by \fI\%jinja_env\fP and \fI\%jinja_sls_env\fP + .sp New in version 2014.1.0. @@ -6811,6 +7216,9 @@ jinja_trim_blocks: False .UNINDENT .UNINDENT .SS \fBjinja_lstrip_blocks\fP +.sp +Deprecated since version 2018.3.0: Replaced by \fI\%jinja_env\fP and \fI\%jinja_sls_env\fP + .sp New in version 2014.1.0. @@ -6867,11 +7275,18 @@ state_verbose: False .sp Default: \fBfull\fP .sp -The state_output setting changes if the output is the full multi line -output for each changed state if set to \(aqfull\(aq, but if set to \(aqterse\(aq -the output will be shortened to a single line. If set to \(aqmixed\(aq, the output -will be terse unless a state failed, in which case that output will be full. -If set to \(aqchanges\(aq, the output will be full unless the state didn\(aqt change. +The state_output setting controls which results will be output full multi line: +.INDENT 0.0 +.IP \(bu 2 +\fBfull\fP, \fBterse\fP \- each state will be full/terse +.IP \(bu 2 +\fBmixed\fP \- only states with errors will be full +.IP \(bu 2 +\fBchanges\fP \- states with changes and errors will be full +.UNINDENT +.sp +\fBfull_id\fP, \fBmixed_id\fP, \fBchanges_id\fP and \fBterse_id\fP are also allowed; +when set, the state ID will be used as name in the output. .INDENT 0.0 .INDENT 3.5 .sp @@ -6995,7 +7410,7 @@ Example: .ft C fileserver_backend: \- roots - \- git + \- gitfs .ft P .fi .UNINDENT @@ -7216,6 +7631,22 @@ fileserver, it is good practice to include \fB\(aq\e*.swp\(aq\fP in the \fI\%file_ignore_glob\fP\&. .UNINDENT .UNINDENT +.SS \fBmaster_roots\fP +.sp +Default: \fB/srv/salt\-master\fP +.sp +A master\-only copy of the \fI\%file_roots\fP dictionary, used by the +state compiler. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +master_roots: /srv/salt\-master +.ft P +.fi +.UNINDENT +.UNINDENT .SS roots: Master\(aqs Local File Server .SS \fBfile_roots\fP .sp @@ -7268,22 +7699,34 @@ For masterless Salt, this parameter must be specified in the minion config file. .UNINDENT .UNINDENT -.SS \fBmaster_roots\fP +.SS \fBroots_update_interval\fP .sp -Default: \fB/srv/salt\-master\fP +New in version 2018.3.0. + .sp -A master\-only copy of the file_roots dictionary, used by the state compiler. +Default: \fB60\fP +.sp +This option defines the update interval (in seconds) for +\fI\%file_roots\fP\&. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Since \fBfile_roots\fP consists of files local to the minion, the update +process for this fileserver backend just reaps the cache for this backend. +.UNINDENT +.UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -master_roots: /srv/salt\-master +roots_update_interval: 120 .ft P .fi .UNINDENT .UNINDENT -.SS git: Git Remote File Server Backend +.SS gitfs: Git Remote File Server Backend .SS \fBgitfs_remotes\fP .sp Default: \fB[]\fP @@ -7474,10 +7917,82 @@ gitfs_saltenv: .fi .UNINDENT .UNINDENT -.SS \fBgitfs_env_whitelist\fP +.SS \fBgitfs_disable_saltenv_mapping\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fBFalse\fP +.sp +When set to \fBTrue\fP, all saltenv mapping logic is disregarded (aside from +which branch/tag is mapped to the \fBbase\fP saltenv). To use any other +environments, they must then be defined using per\-saltenv configuration +parameters\&. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +gitfs_disable_saltenv_mapping: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +This is is a global configuration option, see here for examples of configuring it for individual +repositories. +.UNINDENT +.UNINDENT +.SS \fBgitfs_ref_types\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB[\(aqbranch\(aq, \(aqtag\(aq, \(aqsha\(aq]\fP +.sp +This option defines what types of refs are mapped to fileserver environments +(i.e. saltenvs). It also sets the order of preference when there are +ambiguously\-named refs (i.e. when a branch and tag both have the same name). +The below example disables mapping of both tags and SHAs, so that only branches +are mapped as saltenvs: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +gitfs_ref_types: + \- branch +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +This is is a global configuration option, see here for examples of configuring it for individual +repositories. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fBsha\fP is special in that it will not show up when listing saltenvs (e.g. +with the \fBfileserver.envs\fP runner), +but works within states and with \fBcp.cache_file\fP to retrieve a file from a specific git SHA. +.UNINDENT +.UNINDENT +.SS \fBgitfs_saltenv_whitelist\fP .sp New in version 2014.7.0. +.sp +Changed in version 2018.3.0: Renamed from \fBgitfs_env_whitelist\fP to \fBgitfs_saltenv_whitelist\fP + .sp Default: \fB[]\fP .sp @@ -7489,7 +8004,7 @@ information can be found in the GitFS Walkthrough\&. .sp .nf .ft C -gitfs_env_whitelist: +gitfs_saltenv_whitelist: \- base \- v1.* \- \(aqmybranch\ed+\(aq @@ -7497,10 +8012,13 @@ gitfs_env_whitelist: .fi .UNINDENT .UNINDENT -.SS \fBgitfs_env_blacklist\fP +.SS \fBgitfs_saltenv_blacklist\fP .sp New in version 2014.7.0. +.sp +Changed in version 2018.3.0: Renamed from \fBgitfs_env_blacklist\fP to \fBgitfs_saltenv_blacklist\fP + .sp Default: \fB[]\fP .sp @@ -7512,7 +8030,7 @@ information can be found in the GitFS Walkthrough\&. .sp .nf .ft C -gitfs_env_blacklist: +gitfs_saltenv_blacklist: \- base \- v1.* \- \(aqmybranch\ed+\(aq @@ -7551,6 +8069,26 @@ gitfs_global_lock: False .fi .UNINDENT .UNINDENT +.SS \fBgitfs_update_interval\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB60\fP +.sp +This option defines the default update interval (in seconds) for gitfs remotes. +The update interval can also be set for a single repository via a +per\-remote config option +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +gitfs_update_interval: 120 +.ft P +.fi +.UNINDENT +.UNINDENT .SS GitFS Authentication Options .sp These parameters only currently apply to the pygit2 gitfs provider. Examples of @@ -7744,7 +8282,7 @@ gitfs_refspecs: .fi .UNINDENT .UNINDENT -.SS hg: Mercurial Remote File Server Backend +.SS hgfs: Mercurial Remote File Server Backend .SS \fBhgfs_remotes\fP .sp New in version 0.17.0. @@ -7915,10 +8453,13 @@ hgfs_base: salt .fi .UNINDENT .UNINDENT -.SS \fBhgfs_env_whitelist\fP +.SS \fBhgfs_saltenv_whitelist\fP .sp New in version 2014.7.0. +.sp +Changed in version 2018.3.0: Renamed from \fBhgfs_env_whitelist\fP to \fBhgfs_saltenv_whitelist\fP + .sp Default: \fB[]\fP .sp @@ -7930,7 +8471,7 @@ expression must match the entire minion ID. If used, only branches/bookmarks/tags which match one of the specified expressions will be exposed as fileserver environments. .sp -If used in conjunction with \fI\%hgfs_env_blacklist\fP, then the subset +If used in conjunction with \fI\%hgfs_saltenv_blacklist\fP, then the subset of branches/bookmarks/tags which match the whitelist but do \fInot\fP match the blacklist will be exposed as fileserver environments. .INDENT 0.0 @@ -7938,7 +8479,7 @@ blacklist will be exposed as fileserver environments. .sp .nf .ft C -hgfs_env_whitelist: +hgfs_saltenv_whitelist: \- base \- v1.* \- \(aqmybranch\ed+\(aq @@ -7946,10 +8487,13 @@ hgfs_env_whitelist: .fi .UNINDENT .UNINDENT -.SS \fBhgfs_env_blacklist\fP +.SS \fBhgfs_saltenv_blacklist\fP .sp New in version 2014.7.0. +.sp +Changed in version 2018.3.0: Renamed from \fBhgfs_env_blacklist\fP to \fBhgfs_saltenv_blacklist\fP + .sp Default: \fB[]\fP .sp @@ -7961,7 +8505,7 @@ expression must match the entire minion ID. If used, branches/bookmarks/tags which match one of the specified expressions will \fInot\fP be exposed as fileserver environments. .sp -If used in conjunction with \fI\%hgfs_env_whitelist\fP, then the subset +If used in conjunction with \fI\%hgfs_saltenv_whitelist\fP, then the subset of branches/bookmarks/tags which match the whitelist but do \fInot\fP match the blacklist will be exposed as fileserver environments. .INDENT 0.0 @@ -7969,7 +8513,7 @@ blacklist will be exposed as fileserver environments. .sp .nf .ft C -hgfs_env_blacklist: +hgfs_saltenv_blacklist: \- base \- v1.* \- \(aqmybranch\ed+\(aq @@ -7977,7 +8521,26 @@ hgfs_env_blacklist: .fi .UNINDENT .UNINDENT -.SS svn: Subversion Remote File Server Backend +.SS \fBhgfs_update_interval\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB60\fP +.sp +This option defines the update interval (in seconds) for +\fI\%hgfs_remotes\fP\&. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +hgfs_update_interval: 120 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS svnfs: Subversion Remote File Server Backend .SS \fBsvnfs_remotes\fP .sp New in version 0.17.0. @@ -8158,10 +8721,13 @@ svnfs_tags: tags .fi .UNINDENT .UNINDENT -.SS \fBsvnfs_env_whitelist\fP +.SS \fBsvnfs_saltenv_whitelist\fP .sp New in version 2014.7.0. +.sp +Changed in version 2018.3.0: Renamed from \fBsvnfs_env_whitelist\fP to \fBsvnfs_saltenv_whitelist\fP + .sp Default: \fB[]\fP .sp @@ -8173,7 +8739,7 @@ must match the entire minion ID. If used, only branches/tags which match one of the specified expressions will be exposed as fileserver environments. .sp -If used in conjunction with \fI\%svnfs_env_blacklist\fP, then the subset +If used in conjunction with \fI\%svnfs_saltenv_blacklist\fP, then the subset of branches/tags which match the whitelist but do \fInot\fP match the blacklist will be exposed as fileserver environments. .INDENT 0.0 @@ -8181,7 +8747,7 @@ will be exposed as fileserver environments. .sp .nf .ft C -svnfs_env_whitelist: +svnfs_saltenv_whitelist: \- base \- v1.* \- \(aqmybranch\ed+\(aq @@ -8189,10 +8755,13 @@ svnfs_env_whitelist: .fi .UNINDENT .UNINDENT -.SS \fBsvnfs_env_blacklist\fP +.SS \fBsvnfs_saltenv_blacklist\fP .sp New in version 2014.7.0. +.sp +Changed in version 2018.3.0: Renamed from \fBsvnfs_env_blacklist\fP to \fBsvnfs_saltenv_blacklist\fP + .sp Default: \fB[]\fP .sp @@ -8204,7 +8773,7 @@ expression must match the entire minion ID. If used, branches/tags which match one of the specified expressions will \fInot\fP be exposed as fileserver environments. .sp -If used in conjunction with \fI\%svnfs_env_whitelist\fP, then the subset +If used in conjunction with \fI\%svnfs_saltenv_whitelist\fP, then the subset of branches/tags which match the whitelist but do \fInot\fP match the blacklist will be exposed as fileserver environments. .INDENT 0.0 @@ -8212,7 +8781,7 @@ will be exposed as fileserver environments. .sp .nf .ft C -svnfs_env_blacklist: +svnfs_saltenv_blacklist: \- base \- v1.* \- \(aqmybranch\ed+\(aq @@ -8220,7 +8789,26 @@ svnfs_env_blacklist: .fi .UNINDENT .UNINDENT -.SS minion: MinionFS Remote File Server Backend +.SS \fBsvnfs_update_interval\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB60\fP +.sp +This option defines the update interval (in seconds) for +\fI\%svnfs_remotes\fP\&. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +svnfs_update_interval: 120 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS minionfs: MinionFS Remote File Server Backend .SS \fBminionfs_env\fP .sp New in version 2014.7.0. @@ -8323,6 +8911,82 @@ minionfs_blacklist: .fi .UNINDENT .UNINDENT +.SS \fBminionfs_update_interval\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB60\fP +.sp +This option defines the update interval (in seconds) for MinionFS\&. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Since MinionFS consists of files local to the +master, the update process for this fileserver backend just reaps the cache +for this backend. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +minionfs_update_interval: 120 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS azurefs: Azure File Server Backend +.sp +New in version 2015.8.0. + +.sp +See the \fBazurefs documentation\fP for usage +examples. +.SS \fBazurefs_update_interval\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB60\fP +.sp +This option defines the update interval (in seconds) for azurefs. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +azurefs_update_interval: 120 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS s3fs: S3 File Server Backend +.sp +New in version 0.16.0. + +.sp +See the \fBs3fs documentation\fP for usage examples. +.SS \fBs3fs_update_interval\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB60\fP +.sp +This option defines the update interval (in seconds) for s3fs. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +s3fs_update_interval: 120 +.ft P +.fi +.UNINDENT +.UNINDENT .SS Pillar Configuration .SS \fBpillar_roots\fP .sp @@ -9355,6 +10019,16 @@ reactor_refresh_interval: 60 Default: \fB10\fP .sp The number of workers for the runner/wheel in the reactor. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +reactor_worker_threads: 10 +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBreactor_worker_hwm\fP .sp Default: \fB10000\fP @@ -10657,6 +11331,26 @@ master_uri_format: ip_only .fi .UNINDENT .UNINDENT +.SS \fBmaster_tops_first\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fBFalse\fP +.sp +SLS targets defined using the Master Tops system +are normally executed \fIafter\fP any matches defined in the Top File\&. Set this option to \fBTrue\fP to have the minion execute the +Master Tops states first. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +master_tops_first: True +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBmaster_type\fP .sp New in version 2014.7.0. @@ -10876,6 +11570,162 @@ publish_port: 4505 .fi .UNINDENT .UNINDENT +.SS \fBsource_interface_name\fP +.sp +New in version 2018.3.0. + +.sp +The name of the interface to use when establishing the connection to the Master. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +If multiple IP addresses are configured on the named interface, +the first one will be selected. In that case, for a better selection, +consider using the \fI\%source_address\fP option. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +To use an IPv6 address from the named interface, make sure the option +\fI\%ipv6\fP is enabled, i.e., \fBipv6: true\fP\&. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +If the interface is down, it will avoid using it, and the Minion +will bind to \fB0.0.0.0\fP (all interfaces). +.UNINDENT +.UNINDENT +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +This option requires modern version of the underlying libraries used by +the selected transport: +.INDENT 0.0 +.IP \(bu 2 +\fBzeromq\fP requires \fBpyzmq\fP >= 16.0.1 and \fBlibzmq\fP >= 4.1.6 +.IP \(bu 2 +\fBtcp\fP requires \fBtornado\fP >= 4.5 +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Configuration example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +source_interface_name: bond0.1234 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS \fBsource_address\fP +.sp +New in version 2018.3.0. + +.sp +The source IP address or the domain name to be used when connecting the Minion +to the Master. +See \fI\%ipv6\fP for IPv6 connections to the Master. +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +This option requires modern version of the underlying libraries used by +the selected transport: +.INDENT 0.0 +.IP \(bu 2 +\fBzeromq\fP requires \fBpyzmq\fP >= 16.0.1 and \fBlibzmq\fP >= 4.1.6 +.IP \(bu 2 +\fBtcp\fP requires \fBtornado\fP >= 4.5 +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Configuration example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +source_address: if\-bond0\-1234.sjc.us\-west.internal +.ft P +.fi +.UNINDENT +.UNINDENT +.SS \fBsource_ret_port\fP +.sp +New in version 2018.3.0. + +.sp +The source port to be used when connecting the Minion to the Master ret server. +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +This option requires modern version of the underlying libraries used by +the selected transport: +.INDENT 0.0 +.IP \(bu 2 +\fBzeromq\fP requires \fBpyzmq\fP >= 16.0.1 and \fBlibzmq\fP >= 4.1.6 +.IP \(bu 2 +\fBtcp\fP requires \fBtornado\fP >= 4.5 +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Configuration example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +source_ret_port: 49017 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS \fBsource_publish_port\fP +.sp +New in version 2018.3.0. + +.sp +The source port to be used when connecting the Minion to the Master publish +server. +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +This option requires modern version of the underlying libraries used by +the selected transport: +.INDENT 0.0 +.IP \(bu 2 +\fBzeromq\fP requires \fBpyzmq\fP >= 16.0.1 and \fBlibzmq\fP >= 4.1.6 +.IP \(bu 2 +\fBtcp\fP requires \fBtornado\fP >= 4.5 +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Configuration example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +source_publish_port: 49018 +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBuser\fP .sp Default: \fBroot\fP @@ -11047,6 +11897,22 @@ append_domain: foo.org .fi .UNINDENT .UNINDENT +.SS \fBminion_id_lowercase\fP +.sp +Default: \fBFalse\fP +.sp +Convert minion id to lowercase when it is being generated. Helpful when some hosts +get the minion id in uppercase. Cached ids will remain the same and not converted. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +minion_id_lowercase: True +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBcachedir\fP .sp Default: \fB/var/cache/salt/minion\fP @@ -11064,6 +11930,21 @@ cachedir: /var/cache/salt/minion .fi .UNINDENT .UNINDENT +.SS \fBcolor_theme\fP +.sp +Default: \fB""\fP +.sp +Specifies a path to the color theme to use for colored command line output. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +color_theme: /etc/salt/color_theme +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBappend_minionid_config_dirs\fP .sp Default: \fB[]\fP (the empty list) for regular minions, \fB[\(aqcachedir\(aq]\fP for proxy minions. @@ -11877,14 +12758,55 @@ proxy_password: obolus .fi .UNINDENT .UNINDENT -.SS Minion Module Management +.SS \fBdocker.compare_container_networks\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB{\(aqstatic\(aq: [\(aqAliases\(aq, \(aqLinks\(aq, \(aqIPAMConfig\(aq], \(aqautomatic\(aq: [\(aqIPAddress\(aq, \(aqGateway\(aq, \(aqGlobalIPv6Address\(aq, \(aqIPv6Gateway\(aq]}\fP +.sp +Specifies which keys are examined by +\fBdocker.compare_container_networks\fP\&. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +This should not need to be modified unless new features added to Docker +result in new keys added to the network configuration which must be +compared to determine if two containers have different network configs. +This config option exists solely as a way to allow users to continue using +Salt to manage their containers after an API change, without waiting for a +new Salt release to catch up to the changes in the Docker API. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +docker.compare_container_networks: + static: + \- Aliases + \- Links + \- IPAMConfig + automatic: + \- IPAddress + \- Gateway + \- GlobalIPv6Address + \- IPv6Gateway +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Minion Execution Module Management .SS \fBdisable_modules\fP .sp -Default: \fB[]\fP (all modules are enabled by default) +Default: \fB[]\fP (all execution modules are enabled by default) .sp The event may occur in which the administrator desires that a minion should not -be able to execute a certain module. The \fBsys\fP module is built into the minion -and cannot be disabled. +be able to execute a certain module. +.sp +However, the \fBsys\fP module is built into the minion and cannot be disabled. .sp This setting can also tune the minion. Because all modules are loaded into system memory, disabling modules will lower the minion\(aqs memory footprint. @@ -11926,7 +12848,8 @@ Default: \fB[]\fP (Module whitelisting is disabled. Adding anything to the conf will cause only the listed modules to be enabled. Modules not in the list will not be loaded.) .sp -This option is the reverse of disable_modules. +This option is the reverse of disable_modules. If enabled, only execution modules in this +list will be loaded and executed on the minion. .sp Note that this is a very large hammer and it can be quite difficult to keep the minion working the way you think it should since Salt uses many modules internally itself. At a bare minimum @@ -12426,9 +13349,18 @@ state_verbose: True .sp Default: \fBfull\fP .sp -The state_output setting changes if the output is the full multi line -output for each changed state if set to \(aqfull\(aq, but if set to \(aqterse\(aq -the output will be shortened to a single line. +The state_output setting controls which results will be output full multi line: +.INDENT 0.0 +.IP \(bu 2 +\fBfull\fP, \fBterse\fP \- each state will be full/terse +.IP \(bu 2 +\fBmixed\fP \- only states with errors will be full +.IP \(bu 2 +\fBchanges\fP \- states with changes and errors will be full +.UNINDENT +.sp +\fBfull_id\fP, \fBmixed_id\fP, \fBchanges_id\fP and \fBterse_id\fP are also allowed; +when set, the state ID will be used as name in the output. .INDENT 0.0 .INDENT 3.5 .sp @@ -12497,7 +13429,12 @@ clean_dynamic_modules: True If \fBextmod_whitelist\fP is specified, modules which are not whitelisted will also be cleaned here. .UNINDENT .UNINDENT -.SS \fBenvironment\fP +.SS \fBsaltenv\fP +.sp +Changed in version 2018.3.0: Renamed from \fBenvironment\fP to \fBsaltenv\fP\&. If \fBenvironment\fP is used, +\fBsaltenv\fP will take its value. If both are used, \fBenvironment\fP will be +ignored and \fBsaltenv\fP will be used. + .sp Normally the minion is not isolated to any single environment on the master when running states, but the environment can be isolated on the minion side @@ -12508,7 +13445,28 @@ environments is to isolate via the top file. .sp .nf .ft C -environment: dev +saltenv: dev +.ft P +.fi +.UNINDENT +.UNINDENT +.SS \fBlock_saltenv\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fBFalse\fP +.sp +For purposes of running states, this option prevents using the \fBsaltenv\fP +argument to manually set the environment. This is useful to keep a minion which +has the \fI\%saltenv\fP option set to \fBdev\fP from running states from +an environment other than \fBdev\fP\&. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lock_saltenv: True .ft P .fi .UNINDENT @@ -12945,6 +13903,49 @@ file_recv_max_size: 100 .fi .UNINDENT .UNINDENT +.SS \fBpass_to_ext_pillars\fP +.sp +Specify a list of configuration keys whose values are to be passed to +external pillar functions. +.sp +Suboptions can be specified using the \(aq:\(aq notation (i.e. \fBoption:suboption\fP) +.sp +The values are merged and included in the \fBextra_minion_data\fP optional +parameter of the external pillar function. The \fBextra_minion_data\fP parameter +is passed only to the external pillar functions that have it explicitly +specified in their definition. +.sp +If the config contains +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +opt1: value1 +opt2: + subopt1: value2 + subopt2: value3 + +pass_to_ext_pillars: + \- opt1 + \- opt2: subopt1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +the \fBextra_minion_data\fP parameter will be +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{\(aqopt1\(aq: \(aqvalue1\(aq, + \(aqopt2\(aq: {\(aqsubopt1\(aq: \(aqvalue2\(aq}} +.ft P +.fi +.UNINDENT +.UNINDENT .SS Security Settings .SS \fBopen_mode\fP .sp @@ -13056,6 +14057,30 @@ master_sign_key_name: .fi .UNINDENT .UNINDENT +.SS \fBautosign_grains\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fBnot defined\fP +.sp +The grains that should be sent to the master on authentication to decide if +the minion\(aqs key should be accepted automatically. +.sp +Please see the Autoaccept Minions from Grains +documentation for more infomation. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +autosign_grains: + \- uuid + \- server_id +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBalways_verify_signature\fP .sp Default: \fBFalse\fP @@ -13204,6 +14229,16 @@ reactor_refresh_interval: 60 Default: \fB10\fP .sp The number of workers for the runner/wheel in the reactor. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +reactor_worker_threads: 10 +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBreactor_worker_hwm\fP .sp Default: \fB10000\fP @@ -13238,6 +14273,27 @@ multiprocessing: True .fi .UNINDENT .UNINDENT +.SS \fBprocess_count_max\fP +.sp +New in version 2018.3.0. + +.sp +Default: \fB\-1\fP +.sp +Limit the maximum amount of processes or threads created by \fBsalt\-minion\fP\&. +This is useful to avoid resource exhaustion in case the minion receives more +publications than it is able to handle, as it limits the number of spawned +processes or threads. \fB\-1\fP is the default and disables the limit. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +process_count_max: \-1 +.ft P +.fi +.UNINDENT +.UNINDENT .SS Minion Logging Settings .SS \fBlog_file\fP .sp @@ -14053,7 +15109,7 @@ and \fBmine_functions\fP\&. # The root directory prepended to these options: pki_dir, cachedir, # sock_dir, log_file, autosign_file, autoreject_file, extension_modules, -# key_logfile, pidfile: +# key_logfile, pidfile, autosign_grains_dir: #root_dir: / # The path to the master\(aqs configuration file. @@ -14305,9 +15361,39 @@ and \fBmine_functions\fP\&. # a value for you. Default is disabled. # ipc_write_buffer: \(aqdynamic\(aq +# These two batch settings, batch_safe_limit and batch_safe_size, are used to +# automatically switch to a batch mode execution. If a command would have been +# sent to more than minions, then run the command in +# batches of . If no batch_safe_size is specified, a default +# of 8 will be used. If no batch_safe_limit is specified, then no automatic +# batching will occur. +#batch_safe_limit: 100 +#batch_safe_size: 8 + +# Master stats enables stats events to be fired from the master at close +# to the defined interval +#master_stats: False +#master_stats_event_iter: 60 + ##### Security settings ##### ########################################## +# Enable passphrase protection of Master private key. Although a string value +# is acceptable; passwords should be stored in an external vaulting mechanism +# and retrieved via sdb. See https://docs.saltstack.com/en/latest/topics/sdb/. +# Passphrase protection is off by default but an example of an sdb profile and +# query is as follows. +# masterkeyring: +# driver: keyring +# service: system +# +# key_pass: sdb://masterkeyring/key_pass + +# Enable passphrase protection of the Master signing_key. This only applies if +# master_sign_pubkey is set to True. This is disabled by default. +# master_sign_pubkey: True +# signing_key_pass: sdb://masterkeyring/signing_pass + # Enable "open mode", this mode still maintains encryption, but turns off # authentication, this is only intended for highly secure environments or for # the situation where your keys end up in a bad state. If you run in open mode @@ -14329,7 +15415,8 @@ and \fBmine_functions\fP\&. # If the autosign_file is specified, incoming keys specified in the # autosign_file will be automatically accepted. This is insecure. Regular -# expressions as well as globing lines are supported. +# expressions as well as globing lines are supported. The file must be readonly +# except for the owner. Use permissive_pki_access to allow the group write access. #autosign_file: /etc/salt/autosign.conf # Works like autosign_file, but instead allows you to specify minion IDs for @@ -14337,6 +15424,11 @@ and \fBmine_functions\fP\&. # the autosign_file and the auto_accept setting. #autoreject_file: /etc/salt/autoreject.conf +# If the autosign_grains_dir is specified, incoming keys from minons with grain +# values matching those defined in files in this directory will be accepted +# automatically. This is insecure. Minions need to be configured to send the grains. +#autosign_grains_dir: /etc/salt/autosign_grains + # Enable permissive access to the salt keys. This allows you to run the # master or minion as root, but have a non\-root group be given access to # your pki_dir. To make the access explicit, root must belong to the group @@ -14456,11 +15548,13 @@ and \fBmine_functions\fP\&. ##### Salt\-SSH Configuration ##### ########################################## +# Define the default salt\-ssh roster module to use +#roster: flat -# Pass in an alternative location for the salt\-ssh roster file +# Pass in an alternative location for the salt\-ssh \(gaflat\(ga roster file #roster_file: /etc/salt/roster -# Define locations for roster files so they can be chosen when using Salt API. +# Define locations for \(gaflat\(ga roster files so they can be chosen when using Salt API. # An administrator can place roster files into these locations. Then when # calling Salt API, parameter \(aqroster_file\(aq should contain a relative path to # these locations. That is, "roster_file=/foo/roster" will be resolved as @@ -14524,6 +15618,9 @@ and \fBmine_functions\fP\&. # Add any additional locations to look for master runners: #runner_dirs: [] +# Add any additional locations to look for master utils: +#utils_dirs: [] + # Enable Cython for master side modules: #cython_enable: False @@ -14555,18 +15652,35 @@ and \fBmine_functions\fP\&. # The renderer to use on the minions to render the state data #renderer: yaml_jinja -# The Jinja renderer can strip extra carriage returns and whitespace -# See http://jinja.pocoo.org/docs/api/#high\-level\-api -# -# If this is set to True the first newline after a Jinja block is removed -# (block, not variable tag!). Defaults to False, corresponds to the Jinja -# environment init variable "trim_blocks". -#jinja_trim_blocks: False -# -# If this is set to True leading spaces and tabs are stripped from the start -# of a line to a block. Defaults to False, corresponds to the Jinja -# environment init variable "lstrip_blocks". -#jinja_lstrip_blocks: False +# Default Jinja environment options for all templates except sls templates +#jinja_env: +# block_start_string: \(aq{%\(aq +# block_end_string: \(aq%}\(aq +# variable_start_string: \(aq{{\(aq +# variable_end_string: \(aq}}\(aq +# comment_start_string: \(aq{#\(aq +# comment_end_string: \(aq#}\(aq +# line_statement_prefix: +# line_comment_prefix: +# trim_blocks: False +# lstrip_blocks: False +# newline_sequence: \(aq\en\(aq +# keep_trailing_newline: False + +# Jinja environment options for sls templates +#jinja_sls_env: +# block_start_string: \(aq{%\(aq +# block_end_string: \(aq%}\(aq +# variable_start_string: \(aq{{\(aq +# variable_end_string: \(aq}}\(aq +# comment_start_string: \(aq{#\(aq +# comment_end_string: \(aq#}\(aq +# line_statement_prefix: +# line_comment_prefix: +# trim_blocks: False +# lstrip_blocks: False +# newline_sequence: \(aq\en\(aq +# keep_trailing_newline: False # The failhard option tells the minions to stop immediately after the first # failure detected in the state execution, defaults to False @@ -14578,11 +15692,12 @@ and \fBmine_functions\fP\&. # all data that has a result of True and no changes will be suppressed. #state_verbose: True -# The state_output setting changes if the output is the full multi line -# output for each changed state if set to \(aqfull\(aq, but if set to \(aqterse\(aq -# the output will be shortened to a single line. If set to \(aqmixed\(aq, the output -# will be terse unless a state failed, in which case that output will be full. -# If set to \(aqchanges\(aq, the output will be full unless the state didn\(aqt change. +# The state_output setting controls which results will be output full multi line +# full, terse \- each state will be full/terse +# mixed \- only states with errors will be full +# changes \- states with changes and errors will be full +# full_id, mixed_id, changes_id and terse_id are also allowed; +# when set, the state ID will be used as name in the output #state_output: full # The state_output_diff setting changes whether or not the output from @@ -14959,7 +16074,7 @@ and \fBmine_functions\fP\&. #pillar_cache_ttl: 3600 # If and only if a master has set \(gapillar_cache: True\(ga, one of several storage providers -# can be utililzed. +# can be utilized. # # \(gadisk\(ga: The default storage backend. This caches rendered pillars to the master cache. # Rendered pillars are serialized and deserialized as msgpack structures for speed. @@ -15261,7 +16376,6 @@ and \fBmine_functions\fP\&. # /proc/sys/net/ipv4/tcp_keepalive_intvl. #tcp_keepalive_intvl: \-1 - .ft P .fi .UNINDENT @@ -15909,9 +17023,12 @@ and \fBmine_functions\fP\&. # all data that has a result of True and no changes will be suppressed. #state_verbose: True -# The state_output setting changes if the output is the full multi line -# output for each changed state if set to \(aqfull\(aq, but if set to \(aqterse\(aq -# the output will be shortened to a single line. +# The state_output setting controls which results will be output full multi line +# full, terse \- each state will be full/terse +# mixed \- only states with errors will be full +# changes \- states with changes and errors will be full +# full_id, mixed_id, changes_id and terse_id are also allowed; +# when set, the state ID will be used as name in the output #state_output: full # The state_output_diff setting changes whether or not the output from @@ -15937,6 +17054,12 @@ and \fBmine_functions\fP\&. # certfile: # ssl_version: PROTOCOL_TLSv1_2 +# Grains to be sent to the master on authentication to check if the minion\(aqs key +# will be accepted automatically. Needs to be configured on the master. +#autosign_grains: +# \- uuid +# \- server_id + ###### Reactor Settings ##### ########################################### @@ -15963,6 +17086,12 @@ and \fBmine_functions\fP\&. # for a full explanation. #multiprocessing: True +# Limit the maximum amount of processes or threads created by salt\-minion. +# This is useful to avoid resource exhaustion in case the minion receives more +# publications than it is able to handle, as it limits the number of spawned +# processes or threads. \-1 is the default and disables the limit. +#process_count_max: \-1 + ##### Logging settings ##### ########################################## @@ -16646,9 +17775,12 @@ and \fBmine_functions\fP\&. # all data that has a result of True and no changes will be suppressed. #state_verbose: True -# The state_output setting changes if the output is the full multi line -# output for each changed state if set to \(aqfull\(aq, but if set to \(aqterse\(aq -# the output will be shortened to a single line. +# The state_output setting controls which results will be output full multi line +# full, terse \- each state will be full/terse +# mixed \- only states with errors will be full +# changes \- states with changes and errors will be full +# full_id, mixed_id, changes_id and terse_id are also allowed; +# when set, the state ID will be used as name in the output #state_output: full # The state_output_diff setting changes whether or not the output from @@ -17105,6 +18237,38 @@ external_auth: .fi .UNINDENT .UNINDENT +.sp +By user, by runner/wheel: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +external_auth: + : + : + <@runner or @wheel>: + \- +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +By user, by runner+wheel module: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +external_auth: + : + : + <@module_name>: + \- +.ft P +.fi +.UNINDENT +.UNINDENT .SS Groups .sp To apply permissions to a group of users in an external authentication system, @@ -17145,6 +18309,14 @@ external_auth: kwargs: \(aqkwa\(aq: \(aqkwa.*\(aq \(aqkwb\(aq: \(aqkwb\(aq + \- \(aq@runner\(aq: + \- \(aqrunner_mod.*\(aq: + args: + \- \(aqa.*\(aq + \- \(aqb.*\(aq + kwargs: + \(aqkwa\(aq: \(aqkwa.*\(aq + \(aqkwb\(aq: \(aqkwb\(aq .ft P .fi .UNINDENT @@ -17987,6 +19159,40 @@ Monday, Wednesday and Friday, and 3:00 PM on Tuesday and Thursday. .sp .nf .ft C +schedule: + job1: + function: state.sls + args: + \- httpd + kwargs: + test: True + when: + \- \(aqtea time\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +whens: + tea time: 1:40pm + deployment time: Friday 5:00pm +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The Salt scheduler also allows custom phrases to be used for the \fIwhen\fP +parameter. These \fIwhens\fP can be stored as either pillar values or +grain values. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C schedule: job1: function: state.sls @@ -19763,19 +20969,27 @@ To use the gitfs backend, only two configuration changes are required on the master: .INDENT 0.0 .IP 1. 3 -Include \fBgit\fP in the \fBfileserver_backend\fP list in the master -config file: +Include \fBgitfs\fP in the \fBfileserver_backend\fP list in the +master config file: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C fileserver_backend: - \- git + \- gitfs .ft P .fi .UNINDENT .UNINDENT +.sp +\fBNOTE:\fP +.INDENT 3.0 +.INDENT 3.5 +\fBgit\fP also works here. Prior to the 2018.3.0 release, \fIonly\fP \fBgit\fP +would work. +.UNINDENT +.UNINDENT .IP 2. 3 Specify one or more \fBgit://\fP, \fBhttps://\fP, \fBfile://\fP, or \fBssh://\fP URLs in \fBgitfs_remotes\fP to configure which repositories to @@ -19932,6 +21146,12 @@ configured gitfs remotes): \fBgitfs_passphrase\fP (\fBpygit2 only\fP, new in 2014.7.0) .IP \(bu 2 \fBgitfs_refspecs\fP (new in 2017.7.0) +.IP \(bu 2 +\fBgitfs_disable_saltenv_mapping\fP (new in 2018.3.0) +.IP \(bu 2 +\fBgitfs_ref_types\fP (new in 2018.3.0) +.IP \(bu 2 +\fBgitfs_update_interval\fP (new in 2018.3.0) .UNINDENT .sp \fBNOTE:\fP @@ -19959,16 +21179,25 @@ gitfs_remotes: \- mountpoint: salt://bar \- base: salt\-base \- ssl_verify: False + \- update_interval: 120 \- https://foo.com/bar.git: \- name: second_bar_repo \- root: other/salt \- mountpoint: salt://other/bar \- base: salt\-base + \- ref_types: + \- branch \- http://foo.com/baz.git: \- root: salt/states \- user: joe \- password: mysupersecretpassword \- insecure_auth: True + \- disable_saltenv_mapping: True + \- saltenv: + \- foo: + \- ref: foo + \- http://foo.com/quux.git: + \- all_saltenvs: master .ft P .fi .UNINDENT @@ -19986,9 +21215,11 @@ with a colon. .IP 2. 3 Per\-remote configuration parameters are named like the global versions, with the \fBgitfs_\fP removed from the beginning. The exception being the -\fBname\fP and \fBsaltenv\fP parameters, which are only available to -per\-remote configurations. +\fBname\fP, \fBsaltenv\fP, and \fBall_saltenvs\fP parameters, which are only +available to per\-remote configurations. .UNINDENT +.sp +The \fBall_saltenvs\fP parameter is new in the 2018.3.0 release. .UNINDENT .UNINDENT .sp @@ -20006,16 +21237,37 @@ subdirectories). The third remote will only server files from the will only serve files from the \fBsalt/states\fP directory (and its subdirectories). .IP 3. 3 +The third remote will only serve files from branches, and not from tags or +SHAs. +.IP 4. 3 +The fourth remote will only have two saltenvs available: \fBbase\fP (pointed +at \fBdevelop\fP), and \fBfoo\fP (pointed at \fBfoo\fP). +.IP 5. 3 The first and fourth remotes will have files located under the root of the Salt fileserver namespace (\fBsalt://\fP). The files from the second remote will be located under \fBsalt://bar\fP, while the files from the third remote will be located under \fBsalt://other/bar\fP\&. -.IP 4. 3 +.IP 6. 3 The second and third remotes reference the same repository and unique names need to be declared for duplicate gitfs remotes. -.IP 5. 3 +.IP 7. 3 The fourth remote overrides the default behavior of \fI\%not authenticating to insecure (non\-HTTPS) remotes\fP\&. +.IP 8. 3 +Because \fBall_saltenvs\fP is configured for the fifth remote, files from the +branch/tag \fBmaster\fP will appear in every fileserver environment. +.sp +\fBNOTE:\fP +.INDENT 3.0 +.INDENT 3.5 +The use of \fBhttp://\fP (instead of \fBhttps://\fP) is permitted here +\fIonly\fP because authentication is not being used. Otherwise, the +\fBinsecure_auth\fP parameter must be used (as in the fourth remote) to +force Salt to authenticate to an \fBhttp://\fP remote. +.UNINDENT +.UNINDENT +.IP 9. 3 +The first remote will wait 120 seconds between updates instead of 60. .UNINDENT .SS Per\-Saltenv Configuration Parameters .sp @@ -20142,6 +21394,63 @@ gitfs_remotes: .fi .UNINDENT .UNINDENT +.SS Global Remotes +.sp +New in version 2018.3.0. + +.sp +The \fBall_saltenvs\fP per\-remote configuration parameter overrides the logic +Salt uses to map branches/tags to fileserver environments (i.e. saltenvs). This +allows a single branch/tag to appear in \fIall\fP saltenvs. +.sp +This is very useful in particular when working with salt formulas\&. Prior to the addition of this feature, it was necessary +to push a branch/tag to the remote repo for each saltenv in which that formula +was to be used. If the formula needed to be updated, this update would need to +be reflected in all of the other branches/tags. This is both inconvenient and +not scalable. +.sp +With \fBall_saltenvs\fP, it is now possible to define your formula once, in a +single branch. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +gitfs_remotes: + \- http://foo.com/quux.git: + \- all_saltenvs: anything +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Update Intervals +.sp +Prior to the 2018.3.0 release, GitFS would update its fileserver backends as part +of a dedicated "maintenance" process, in which various routine maintenance +tasks were performed. This tied the update interval to the +\fBloop_interval\fP config option, and also forced all fileservers to +update at the same interval. +.sp +Now it is possible to make GitFS update at its own interval, using +\fBgitfs_update_interval\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +gitfs_update_interval: 180 + +gitfs_remotes: + \- https://foo.com/foo.git + \- https://foo.com/bar.git: + \- update_interval: 120 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Using the above configuration, the first remote would update every three +minutes, while the second remote would update every two minutes. .SS Configuration Order of Precedence .sp The order of precedence for GitFS configuration is as follows (each level @@ -20206,6 +21515,21 @@ gitfs_mountpoint: salt://bar .UNINDENT .UNINDENT .UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +The one exception to the above is when \fI\%all_saltenvs\fP is used. This value overrides all logic for mapping +branches/tags to fileserver environments. So, even if +\fBgitfs_saltenv\fP is used to globally override the mapping for a +given saltenv, \fI\%all_saltenvs\fP would take +precedence for any remote which uses it. +.sp +It\(aqs important to note however that any \fBroot\fP and \fBmountpoint\fP values +configured in \fBgitfs_saltenv\fP (or \fI\%per\-saltenv +configuration\fP) would be unaffected by this. +.UNINDENT +.UNINDENT .SS Serving from a Subdirectory .sp The \fBgitfs_root\fP parameter allows files to be served from a @@ -20358,18 +21682,18 @@ The base can also be configured on a \fI\%per\-remote basis\fP\&. New in version 2014.7.0. .sp -The \fBgitfs_env_whitelist\fP and \fBgitfs_env_blacklist\fP -parameters allow for greater control over which branches/tags are exposed as -fileserver environments. Exact matches, globs, and regular expressions are -supported, and are evaluated in that order. If using a regular expression, -\fB^\fP and \fB$\fP must be omitted, and the expression must match the entire -branch/tag. +The \fBgitfs_saltenv_whitelist\fP and +\fBgitfs_saltenv_blacklist\fP parameters allow for greater control +over which branches/tags are exposed as fileserver environments. Exact matches, +globs, and regular expressions are supported, and are evaluated in that order. +If using a regular expression, \fB^\fP and \fB$\fP must be omitted, and the +expression must match the entire branch/tag. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -gitfs_env_whitelist: +gitfs_saltenv_whitelist: \- base \- v1.* \- \(aqmybranch\ed+\(aq @@ -20391,11 +21715,12 @@ The behavior of the blacklist/whitelist will differ depending on which combination of the two options is used: .INDENT 0.0 .IP \(bu 2 -If only \fBgitfs_env_whitelist\fP is used, then \fBonly\fP branches/tags -which match the whitelist will be available as environments +If only \fBgitfs_saltenv_whitelist\fP is used, then \fBonly\fP +branches/tags which match the whitelist will be available as environments .IP \(bu 2 -If only \fBgitfs_env_blacklist\fP is used, then the branches/tags -which match the blacklist will \fBnot\fP be available as environments +If only \fBgitfs_saltenv_blacklist\fP is used, then the +branches/tags which match the blacklist will \fBnot\fP be available as +environments .IP \(bu 2 If both are used, then the branches/tags which match the whitelist, but do \fBnot\fP match the blacklist, will be available as environments. @@ -20828,13 +22153,7 @@ match the user under which the minion is running. The git external pillar (a.k.a. git_pillar) has been rewritten for the 2015.8.0 release. This rewrite brings with it \fI\%pygit2\fP support (allowing for access to authenticated repositories), as well as more granular support for per\-remote -configuration. -.sp -To make use of the new features, changes to the git ext_pillar configuration -must be made. The new configuration schema is detailed here\&. -.sp -For Salt releases before 2015.8.0, click here -for documentation. +configuration. This configuration schema is detailed here\&. .SS Why aren\(aqt my custom modules/states/etc. syncing to my Minions? .sp In versions 0.16.3 and older, when using the \fBgit fileserver backend\fP, certain versions of GitPython may generate errors @@ -20926,7 +22245,7 @@ the Salt fileserver, and provides an easy mechanism to restrict which minions\(a pushed files are made available. .SS Simple Configuration .sp -To use the \fBminionfs\fP backend, add \fBminion\fP +To use the \fBminionfs\fP backend, add \fBminionfs\fP to the list of backends in the \fBfileserver_backend\fP configuration option on the master: .INDENT 0.0 @@ -20938,7 +22257,7 @@ file_recv: True fileserver_backend: \- roots - \- minion + \- minionfs .ft P .fi .UNINDENT @@ -20947,7 +22266,10 @@ fileserver_backend: \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -As described earlier, \fBfile_recv: True\fP is also needed to enable the +\fBminion\fP also works here. Prior to the 2018.3.0 release, \fIonly\fP +\fBminion\fP would work. +.sp +Also, as described earlier, \fBfile_recv: True\fP is needed to enable the master to receive files pushed from minions. As always, changes to the master configuration require a restart of the \fBsalt\-master\fP service. .UNINDENT @@ -20995,7 +22317,7 @@ file_recv: True fileserver_backend: \- roots - \- minion + \- minionfs minionfs_mountpoint: salt://minionfs @@ -21267,6 +22589,19 @@ my_repo: .UNINDENT .sp For HTTP/HTTPS Basic authorization you can define credentials: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my_repo: + url: https://spm.example.com/ + username: user + password: pass +.ft P +.fi +.UNINDENT +.UNINDENT .sp Beware of unauthorized access to this file, please set at least 0640 permissions for this configuration file: .sp @@ -21636,6 +22971,19 @@ states are evaluated before \fBtgt\fP states. .sp Each of these sections needs to be evaluated as text, rather than as YAML. Consider the following block: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pre_local_state: > + echo test > /tmp/spmtest: + cmd: + \- run +.ft P +.fi +.UNINDENT +.UNINDENT .sp Note that this declaration uses \fB>\fP after \fBpre_local_state\fP\&. This is a YAML marker that marks the next multi\-line block as text, including newlines. It is @@ -21651,6 +22999,19 @@ a minion. \fBlocal\fP states do not require any special arguments, but they must still use the \fB>\fP marker to denote that the state is evaluated as text, not a data structure. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pre_local_state: > + echo test > /tmp/spmtest: + cmd: + \- run +.ft P +.fi +.UNINDENT +.UNINDENT .SS tgt States .sp \fBtgt\fP states are issued against a remote target. This is analogous to issuing @@ -21659,6 +23020,21 @@ the \fBspm\fP command is running on is a master. .sp Because \fBtgt\fP states require that a target be specified, their code blocks are a little different. Consider the following state: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pre_tgt_state: + tgt: \(aq*\(aq + data: > + echo test > /tmp/spmtest: + cmd: + \- run +.ft P +.fi +.UNINDENT +.UNINDENT .sp With \fBtgt\fP states, the state data is placed under a \fBdata\fP section, inside the \fB*_tgt_state\fP code block. The target is of course specified as a \fBtgt\fP @@ -21675,6 +23051,21 @@ engine, as it would be with a standard state run. This means that you can use Jinja or any other supported renderer inside of Salt. All formula variables are available to the renderer, so you can reference \fBFORMULA\fP data inside your state if you need to: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pre_tgt_state: + tgt: \(aq*\(aq + data: > + echo {{ name }} > /tmp/spmtest: + cmd: + \- run +.ft P +.fi +.UNINDENT +.UNINDENT .sp You may also declare your own variables inside the \fBFORMULA\fP\&. If SPM doesn\(aqt recognize them then it will ignore them, so there are no restrictions on @@ -22013,7 +23404,7 @@ This function will not generally be more complex than: .nf .ft C def hash_file(path, hashobj, conn=None): - with salt.utils.fopen(path, \(aqr\(aq) as f: + with salt.utils.files.fopen(path, \(aqr\(aq) as f: hashobj.update(f.read()) return hashobj.hexdigest() .ft P @@ -22692,6 +24083,9 @@ actual message that we are sending. With this flexible wire protocol we can implement any message semantics that we\(aqd like\-\- including multiplexed message passing on a single socket. .SS TLS Support +.sp +New in version 2016.11.1. + .sp The TCP transport allows for the master/minion communication to be optionally wrapped in a TLS connection. Enabling this is simple, the master and minion need @@ -23058,7 +24452,7 @@ minion .INDENT 3.5 If a master_tops module returns top file data for a given minion, it will be added to the states configured in the top file. It -will \fInot\fP replace it altogether. The Oxygen release adds additional +will \fInot\fP replace it altogether. The 2018.3.0 release adds additional functionality allowing a minion to treat master_tops as the single source of truth, irrespective of the top file. .UNINDENT @@ -23121,6 +24515,11 @@ In this scenario all three returners will be called and the data from the test.ping command will be sent out to the three named returners. .SS Writing a Returner .sp +Returners are Salt modules that allow the redirection of results data to targets other than the Salt Master. +.SS Returners Are Easy To Write! +.sp +Writing a Salt returner is straightforward. +.sp A returner is a Python module containing at minimum a \fBreturner\fP function. Other optional functions can be included to add support for \fBmaster_job_cache\fP, external\-job\-cache, and \fI\%Event Returners\fP\&. @@ -23149,7 +24548,7 @@ salt\-call \-\-local \-\-metadata test.ping \-\-out=pprint .nf .ft C import redis -import json +import salt.utils.json def returner(ret): \(aq\(aq\(aq @@ -23161,7 +24560,7 @@ def returner(ret): port=6379, db=\(aq0\(aq) serv.sadd("%(id)s:jobs" % ret, ret[\(aqjid\(aq]) - serv.set("%(jid)s:%(id)s" % ret, json.dumps(ret[\(aqreturn\(aq])) + serv.set("%(jid)s:%(id)s" % ret, salt.utils.json.dumps(ret[\(aqreturn\(aq])) serv.sadd(\(aqjobs\(aq, ret[\(aqjid\(aq]) serv.sadd(ret[\(aqjid\(aq], ret[\(aqid\(aq]) .ft P @@ -23171,6 +24570,52 @@ def returner(ret): .sp The above example of a returner set to send the data to a Redis server serializes the data as JSON and sets it in redis. +.SS Using Custom Returner Modules +.sp +Place custom returners in a \fB_returners/\fP directory within the +\fBfile_roots\fP specified by the master config file. +.sp +Custom returners are distributed when any of the following are called: +.INDENT 0.0 +.IP \(bu 2 +\fBstate.apply\fP +.IP \(bu 2 +\fBsaltutil.sync_returners\fP +.IP \(bu 2 +\fBsaltutil.sync_all\fP +.UNINDENT +.sp +Any custom returners which have been synced to a minion that are named the +same as one of Salt\(aqs default set of returners will take the place of the +default returner with the same name. +.SS Naming the Returner +.sp +Note that a returner\(aqs default name is its filename (i.e. \fBfoo.py\fP becomes +returner \fBfoo\fP), but that its name can be overridden by using a +__virtual__ function\&. A good example of this can be +found in the \fI\%redis\fP returner, which is named \fBredis_return.py\fP but is +loaded as simply \fBredis\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +try: + import redis + HAS_REDIS = True +except ImportError: + HAS_REDIS = False + +__virtualname__ = \(aqredis\(aq + +def __virtual__(): + if not HAS_REDIS: + return False + return __virtualname__ +.ft P +.fi +.UNINDENT +.UNINDENT .SS Master Job Cache Support .sp \fBmaster_job_cache\fP, external\-job\-cache, and \fI\%Event Returners\fP\&. @@ -23222,6 +24667,8 @@ the load as a JSON string in the salt.jids table. .sp .nf .ft C +import salt.utils.json + def save_load(jid, load): \(aq\(aq\(aq Save the load to the specified jid id @@ -23230,7 +24677,7 @@ def save_load(jid, load): jid, load ) VALUES ( \(aq{0}\(aq, \(aq{1}\(aq - );\(aq\(aq\(aq.format(jid, json.dumps(load)) + );\(aq\(aq\(aq.format(jid, salt.utils.json.dumps(load)) # cassandra_cql.cql_query may raise a CommandExecutionError try: @@ -23239,8 +24686,9 @@ def save_load(jid, load): log.critical(\(aqCould not save load in jids table.\(aq) raise except Exception as e: - log.critical(\(aq\(aq\(aqUnexpected error while inserting into - jids: {0}\(aq\(aq\(aq.format(str(e))) + log.critical( + \(aqUnexpected error while inserting into jids: {0}\(aq.format(e) + ) raise .ft P .fi @@ -23409,6 +24857,8 @@ contains the jid and therefore is guaranteed to be unique. .sp .nf .ft C +import salt.utils.json + def event_return(events): \(aq\(aq\(aq Return event to mysql server @@ -23422,53 +24872,7 @@ def event_return(events): data = event.get(\(aqdata\(aq, \(aq\(aq) sql = \(aq\(aq\(aqINSERT INTO \(gasalt_events\(ga (\(gatag\(ga, \(gadata\(ga, \(gamaster_id\(ga ) VALUES (%s, %s, %s)\(aq\(aq\(aq - cur.execute(sql, (tag, json.dumps(data), __opts__[\(aqid\(aq])) -.ft P -.fi -.UNINDENT -.UNINDENT -.SS Custom Returners -.sp -Place custom returners in a \fB_returners\fP directory within the -\fBfile_roots\fP specified by the master config file. -.sp -Custom returners are distributed when any of the following are called: -.INDENT 0.0 -.IP \(bu 2 -\fBstate.apply\fP -.IP \(bu 2 -\fBsaltutil.sync_returners\fP -.IP \(bu 2 -\fBsaltutil.sync_all\fP -.UNINDENT -.sp -Any custom returners which have been synced to a minion that are named the -same as one of Salt\(aqs default set of returners will take the place of the -default returner with the same name. -.SS Naming the Returner -.sp -Note that a returner\(aqs default name is its filename (i.e. \fBfoo.py\fP becomes -returner \fBfoo\fP), but that its name can be overridden by using a -__virtual__ function\&. A good example of this can be -found in the \fI\%redis\fP returner, which is named \fBredis_return.py\fP but is -loaded as simply \fBredis\fP: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -try: - import redis - HAS_REDIS = True -except ImportError: - HAS_REDIS = False - -__virtualname__ = \(aqredis\(aq - -def __virtual__(): - if not HAS_REDIS: - return False - return __virtualname__ + cur.execute(sql, (tag, salt.utils.json.dumps(data), __opts__[\(aqid\(aq])) .ft P .fi .UNINDENT @@ -23745,6 +25149,12 @@ Return data to the host operating system\(aqs syslog facility T} _ T{ +\fBtelegram_return\fP +T} T{ +Return salt data via Telegram. +T} +_ +T{ \fBxmpp_return\fP T} T{ Return salt data via xmpp @@ -26516,13 +27926,18 @@ either exclude these options or set them to None. .sp .nf .ft C -returner.pgjsonb.ssl_ca: None -returner.pgjsonb.ssl_cert: None -returner.pgjsonb.ssl_key: None +returner.pgjsonb.sslmode: None +returner.pgjsonb.sslcert: None +returner.pgjsonb.sslkey: None +returner.pgjsonb.sslrootcert: None +returner.pgjsonb.sslcrl: None .ft P .fi .UNINDENT .UNINDENT +.sp +New in version 2017.5.0. + .sp Alternative configuration values can be used by prefacing the configuration with \fIalternative.\fP\&. Any values not found in the alternative configuration will @@ -27255,8 +28670,8 @@ noise, so you may wish to configure batch processing and/or configure the to restrict the events that are written. .INDENT 0.0 .TP -.B salt.returners.rawfile_json.event_return(event) -Write event return data to a file on the master. +.B salt.returners.rawfile_json.event_return(events) +Write event data (return data and non\-return data) to file on the master. .UNINDENT .INDENT 0.0 .TP @@ -27283,6 +28698,8 @@ redis.port: 6379 .UNINDENT .UNINDENT .sp +Cluster Mode Example: +.sp Alternative configuration values can be used by prefacing the configuration. Any values not found in the alternative configuration will be pulled from the default location: @@ -27340,6 +28757,28 @@ salt \(aq*\(aq test.ping \-\-return redis \-\-return_kwargs \(aq{"db": "another\ .fi .UNINDENT .UNINDENT +.sp +Redis Cluster Mode Options: +.INDENT 0.0 +.TP +.B cluster_mode: \fBFalse\fP +Whether cluster_mode is enabled or not +.TP +.B cluster.startup_nodes: +A list of host, port dictionaries pointing to cluster members. At least one is required +but multiple nodes are better +.TP +.B cluster.skip_full_coverage_check: \fBFalse\fP +Some cluster providers restrict certain redis commands such as CONFIG for enhanced security. +Set this option to true to skip checks that required advanced privileges. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Most cloud hosted redis clusters will require this to be set to \fBTrue\fP +.UNINDENT +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.returners.redis_return.clean_old_jobs() @@ -28169,6 +29608,61 @@ Do any work necessary to prepare a JID, including sending a custom id .B salt.returners.syslog_return.returner(ret) Return data to the local syslog .UNINDENT +.SS salt.returners.telegram_return +.sp +Return salt data via Telegram. +.sp +The following fields can be set in the minion conf file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +telegram.chat_id (required) +telegram.token (required) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Telegram settings may also be configured as: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +telegram: + chat_id: 000000000 + token: 000000000:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To use the Telegram return, append \(aq\-\-return telegram\(aq to the salt command. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq test.ping \-\-return telegram +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.returners.telegram_return.returner(ret) +Send a Telegram message with the data. +.INDENT 7.0 +.TP +.B Parameters +\fBret\fP \-\- The data to be sent. +.TP +.B Returns +Boolean if message was sent successfully. +.UNINDENT +.UNINDENT .SS salt.returners.xmpp_return .sp Return salt data via xmpp @@ -28486,15 +29980,14 @@ Here is a simple YAML renderer example: .sp .nf .ft C -import yaml +import salt.utils.yaml from salt.utils.yamlloader import SaltYamlSafeLoader +from salt.ext import six + def render(yaml_data, saltenv=\(aq\(aq, sls=\(aq\(aq, **kws): - if not isinstance(yaml_data, basestring): + if not isinstance(yaml_data, six.string_types): yaml_data = yaml_data.read() - data = yaml.load( - yaml_data, - Loader=SaltYamlSafeLoader - ) + data = salt.utils.yaml.safe_load(yaml_data) return data if data else {} .ft P .fi @@ -28617,7 +30110,7 @@ _ Cheetah Renderer for Salt .INDENT 0.0 .TP -.B salt.renderers.cheetah.render(cheetah_data, saltenv=\(aqbase\(aq, sls=\(aq\(aq, method=\(aqxml\(aq, **kws) +.B salt.renderers.cheetah.render(cheetah_data, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, method=u\(aqxml\(aq, **kws) Render a Cheetah template. .INDENT 7.0 .TP @@ -28635,7 +30128,7 @@ spec can be found \fI\%here\fP\&. This renderer requires \fI\%Dogeon\fP (installable via pip) .INDENT 0.0 .TP -.B salt.renderers.dson.render(dson_input, saltenv=\(aqbase\(aq, sls=\(aq\(aq, **kwargs) +.B salt.renderers.dson.render(dson_input, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, **kwargs) Accepts DSON data as a string or as a file object and runs it through the JSON parser. .INDENT 7.0 @@ -28649,7 +30142,7 @@ A Python data structure Genshi Renderer for Salt .INDENT 0.0 .TP -.B salt.renderers.genshi.render(genshi_data, saltenv=\(aqbase\(aq, sls=\(aq\(aq, method=\(aqxml\(aq, **kws) +.B salt.renderers.genshi.render(genshi_data, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, method=u\(aqxml\(aq, **kws) Render a Genshi template. A method should be passed in as part of the kwargs. If no method is passed in, xml is assumed. Valid methods are: .sp @@ -28944,7 +30437,7 @@ salt myminion state.sls secretstuff pillar_enc=gpg pillar="$ciphertext" .UNINDENT .INDENT 0.0 .TP -.B salt.renderers.gpg.render(gpg_data, saltenv=\(aqbase\(aq, sls=\(aq\(aq, argline=\(aq\(aq, **kwargs) +.B salt.renderers.gpg.render(gpg_data, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, argline=u\(aq\(aq, **kwargs) Create a gpg object given a gpg_keydir, and then use it to try to decrypt the data to be rendered. .UNINDENT @@ -28954,7 +30447,7 @@ Hjson Renderer for Salt \fI\%http://laktak.github.io/hjson/\fP .INDENT 0.0 .TP -.B salt.renderers.hjson.render(hjson_data, saltenv=\(aqbase\(aq, sls=\(aq\(aq, **kws) +.B salt.renderers.hjson.render(hjson_data, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, **kws) Accepts HJSON as a string or as a file object and runs it through the HJSON parser. .INDENT 7.0 @@ -28970,7 +30463,7 @@ Jinja loading utils to enable a more powerful backend for jinja templates For Jinja usage information see Understanding Jinja\&. .INDENT 0.0 .TP -.B salt.renderers.jinja.render(template_file, saltenv=\(aqbase\(aq, sls=\(aq\(aq, argline=\(aq\(aq, context=None, tmplpath=None, **kws) +.B salt.renderers.jinja.render(template_file, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, argline=u\(aq\(aq, context=None, tmplpath=None, **kws) Render the template_file, passing the functions and grains into the Jinja rendering system. .INDENT 7.0 @@ -29010,6 +30503,7 @@ data = { yaml = {{ data|yaml }} json = {{ data|json }} python = {{ data|python }} +xml = {{ {\(aqroot_node\(aq: data}|xml }} .ft P .fi .UNINDENT @@ -29024,6 +30518,12 @@ will be rendered as: yaml = {bar: 42, baz: [1, 2, 3], foo: true, qux: 2.0} json = {"baz": [1, 2, 3], "foo": true, "bar": 42, "qux": 2.0} python = {\(aqbar\(aq: 42, \(aqbaz\(aq: [1, 2, 3], \(aqfoo\(aq: True, \(aqqux\(aq: 2.0} +xml = """< + + 1 + 2 + 3 + """ .ft P .fi .UNINDENT @@ -29250,7 +30750,7 @@ unique = [\(aqfoo\(aq, \(aqbar\(aq] JSON Renderer for Salt .INDENT 0.0 .TP -.B salt.renderers.json.render(json_data, saltenv=\(aqbase\(aq, sls=\(aq\(aq, **kws) +.B salt.renderers.json.render(json_data, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, **kws) Accepts JSON as a string or as a file object and runs it through the JSON parser. .INDENT 7.0 @@ -29272,7 +30772,7 @@ information. This renderer requires the \fI\%json5 python bindings\fP, installable via pip. .INDENT 0.0 .TP -.B salt.renderers.json5.render(json_data, saltenv=\(aqbase\(aq, sls=\(aq\(aq, **kws) +.B salt.renderers.json5.render(json_data, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, **kws) Accepts JSON as a string or as a file object and runs it through the JSON parser. .INDENT 7.0 @@ -29286,7 +30786,7 @@ A Python data structure Mako Renderer for Salt .INDENT 0.0 .TP -.B salt.renderers.mako.render(template_file, saltenv=\(aqbase\(aq, sls=\(aq\(aq, context=None, tmplpath=None, **kws) +.B salt.renderers.mako.render(template_file, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, context=None, tmplpath=None, **kws) Render the template_file, passing the functions and grains into the Mako rendering system. .INDENT 7.0 @@ -29298,7 +30798,7 @@ string .SS salt.renderers.msgpack .INDENT 0.0 .TP -.B salt.renderers.msgpack.render(msgpack_data, saltenv=\(aqbase\(aq, sls=\(aq\(aq, **kws) +.B salt.renderers.msgpack.render(msgpack_data, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, **kws) Accepts a message pack string or a file object, renders said data back to a python dict. .INDENT 7.0 @@ -29442,7 +30942,7 @@ pkg.installed .UNINDENT .INDENT 0.0 .TP -.B salt.renderers.pass.render(pass_info, saltenv=\(aqbase\(aq, sls=\(aq\(aq, argline=\(aq\(aq, **kwargs) +.B salt.renderers.pass.render(pass_info, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, argline=u\(aq\(aq, **kwargs) Fetch secret from pass based on pass_path .UNINDENT .SS salt.renderers.py @@ -29593,7 +31093,7 @@ if data[\(aqid\(aq] == \(aqmysql1\(aq: .UNINDENT .INDENT 0.0 .TP -.B salt.renderers.py.render(template, saltenv=\(aqbase\(aq, sls=\(aq\(aq, tmplpath=None, **kws) +.B salt.renderers.py.render(template, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, tmplpath=None, **kws) Render the python module\(aqs components .INDENT 7.0 .TP @@ -29934,7 +31434,7 @@ extend(A) __pydsl__.set(ordered=True) for i in range(10): - i = str(i) + i = six.text_type(i) state(i).cmd.run(\(aqecho \(aq+i, cwd=\(aq/\(aq) state(\(aq1\(aq).cmd.run(\(aqecho one\(aq) state(\(aq2\(aq).cmd.run(name=\(aqecho two\(aq) @@ -30772,7 +32272,7 @@ then there\(aqs no way to reliably rewrite such reference. .SS salt.renderers.wempy .INDENT 0.0 .TP -.B salt.renderers.wempy.render(template_file, saltenv=\(aqbase\(aq, sls=\(aq\(aq, argline=\(aq\(aq, context=None, **kws) +.B salt.renderers.wempy.render(template_file, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, argline=u\(aq\(aq, context=None, **kws) Render the data passing the functions and grains into the rendering system .INDENT 7.0 .TP @@ -30894,7 +32394,7 @@ Return the ordered dict yaml loader .UNINDENT .INDENT 0.0 .TP -.B salt.renderers.yaml.render(yaml_data, saltenv=\(aqbase\(aq, sls=\(aq\(aq, argline=\(aq\(aq, **kws) +.B salt.renderers.yaml.render(yaml_data, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, argline=u\(aq\(aq, **kws) Accepts YAML as a string or as a file object and runs it through the YAML parser. .INDENT 7.0 @@ -30954,7 +32454,7 @@ qux: [my custom data] .SS Reference .INDENT 0.0 .TP -.B salt.renderers.yamlex.render(sls_data, saltenv=\(aqbase\(aq, sls=\(aq\(aq, **kws) +.B salt.renderers.yamlex.render(sls_data, saltenv=u\(aqbase\(aq, sls=u\(aq\(aq, **kws) Accepts YAML_EX as a string or as a file object and runs it through the YAML_EX parser. .INDENT 7.0 @@ -31093,57 +32593,21 @@ the following configuration: .sp .nf .ft C -\(aqnode_type:webserver\(aq: +\(aqroles:webserver\(aq: \- match: grain - \- webserver + \- state0 -\(aqnode_type:postgres\(aq: +\(aqroles:memcache\(aq: \- match: grain - \- postgres - -\(aqnode_type:redis\(aq: - \- match: grain - \- redis - -\(aqnode_type:lb\(aq: - \- match: grain - \- lb + \- state1 + \- state2 .ft P .fi .UNINDENT .UNINDENT .sp For this example to work, you would need to have defined the grain -\fBnode_type\fP for the minions you wish to match. This simple example is nice, -but too much of the code is similar. To go one step further, Jinja templating -can be used to simplify the top file\&. -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set the_node_type = salt[\(aqgrains.get\(aq](\(aqnode_type\(aq, \(aq\(aq) %} - -{% if the_node_type %} - \(aqnode_type:{{ the_node_type }}\(aq: - \- match: grain - \- {{ the_node_type }} -{% endif %} -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -Using Jinja templating, only one match entry needs to be defined. -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -The example above uses the \fBgrains.get\fP -function to account for minions which do not have the \fBnode_type\fP grain -set. -.UNINDENT -.UNINDENT +\fBrole\fP for the minions you wish to match. .SS Writing Grains .sp The grains are derived by executing all of the "public" functions (i.e. those @@ -34632,6 +36096,32 @@ breaks, using \fI\%whitespace control\fP\&. .sp \fI\%Template inheritance\fP works fine from state files and files. The search path starts at the root of the state tree or pillar. +.SS Errors +.sp +Saltstack allows to raise custom errors using the \fBraise\fP jinja function. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{{ raise(\(aqCustom Error\(aq) }} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +When rendering the template containing the above statement, a \fBTemplateError\fP +exception is raised, causing the rendering to fail with the following message: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +TemplateError: Custom Error +.ft P +.fi +.UNINDENT +.UNINDENT .SS Filters .sp Saltstack extends \fI\%builtin filters\fP with these custom filters: @@ -35024,9 +36514,9 @@ Returns: New in version 2017.7.0. .sp -To pass a SIGUSR1 to the master, first make sure the master is running in the -foreground. Stop the service if it is running as a daemon, and start it in the -foreground like so: +Returns the maximum value from a list. +.sp +Example: .INDENT 0.0 .INDENT 3.5 .sp @@ -35483,10 +36973,13 @@ Returns: .fi .UNINDENT .UNINDENT -.SS \fBstr_to_num\fP +.SS \fBto_num\fP .sp New in version 2017.7.0. +.sp +New in version 2018.3.0: Renamed from \fBstr_to_num\fP to \fBto_num\fP\&. + .sp Converts a string to its numerical value. .sp @@ -35496,7 +36989,7 @@ Example: .sp .nf .ft C -{{ \(aq5\(aq | str_to_num }} +{{ \(aq5\(aq | to_num }} .ft P .fi .UNINDENT @@ -35535,19 +37028,25 @@ Example: \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -This option may have adverse effects when using the default renderer, \fByaml_jinja\fP\&. -This is due to the fact that YAML requires proper handling in regard to special -characters. Please see the section on YAML ASCII support -in the YAML Idiosyncracies documentation for more -information. +This option may have adverse effects when using the default renderer, +\fByaml_jinja\fP\&. This is due to the fact that YAML requires proper handling +in regard to special characters. Please see the section on YAML ASCII +support in the YAML Idiosyncracies documentation for more information. .UNINDENT .UNINDENT -.SS \fBjson_decode_list\fP +.SS \fBjson_encode_list\fP .sp New in version 2017.7.0. .sp -JSON decodes as unicode, Jinja needs bytes. +New in version 2018.3.0: Renamed from \fBjson_decode_list\fP to \fBjson_encode_list\fP\&. When you encode +something you get bytes, and when you decode, you get your locale\(aqs +encoding (usually a \fBunicode\fP type). This filter was incorrectly\-named +when it was added. \fBjson_decode_list\fP will be supported until the Neon +release. + +.sp +Recursively encodes all string elements of the list to bytes. .sp Example: .INDENT 0.0 @@ -35555,7 +37054,7 @@ Example: .sp .nf .ft C -{{ [1, 2, 3] | json_decode_list }} +{{ [1, 2, 3] | json_encode_list }} .ft P .fi .UNINDENT @@ -35572,20 +37071,30 @@ Returns: .fi .UNINDENT .UNINDENT -.SS \fBjson_decode_dict\fP +.SS \fBjson_encode_dict\fP .sp New in version 2017.7.0. .sp -JSON decodes as unicode, Jinja needs bytes. +New in version 2018.3.0: Renamed from \fBjson_decode_dict\fP to \fBjson_encode_dict\fP\&. When you encode +something you get bytes, and when you decode, you get your locale\(aqs +encoding (usually a \fBunicode\fP type). This filter was incorrectly\-named +when it was added. \fBjson_decode_dict\fP will be supported until the Neon +release. + +.sp +Recursively encodes all string items in the dictionary to bytes. .sp Example: +.sp +Assuming that \fBpillar[\(aqfoo\(aq]\fP contains \fB{u\(aqa\(aq: u\(aq\eu0414\(aq}\fP, and your locale +is \fBen_US.UTF\-8\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -{{ {\(aqa\(aq: \(aqb\(aq} | json_decode_dict }} +{{ pillar[\(aqfoo\(aq] | json_encode_dict }} .ft P .fi .UNINDENT @@ -35597,18 +37106,19 @@ Returns: .sp .nf .ft C -{\(aqa\(aq: \(aqb\(aq} +{\(aqa\(aq: \(aq\exd0\ex94\(aq} .ft P .fi .UNINDENT .UNINDENT -.SS \fBrand_str\fP +.SS \fBrandom_hash\fP .sp New in version 2017.7.0. .sp -New in version Oxygen: Renamed from \fBrand_str\fP to \fBrandom_hash\fP to more accurately describe -what the filter does. +New in version 2018.3.0: Renamed from \fBrand_str\fP to \fBrandom_hash\fP to more accurately describe +what the filter does. \fBrand_str\fP will be supported until the Neon +release. .sp Generates a random number between 1 and the number passed to the filter, and @@ -35623,8 +37133,8 @@ Example: .nf .ft C {% set num_range = 99999999 %} -{{ num_range | rand_str }} -{{ num_range | rand_str(\(aqsha512\(aq) }} +{{ num_range | random_hash }} +{{ num_range | random_hash(\(aqsha512\(aq) }} .ft P .fi .UNINDENT @@ -36433,6 +37943,97 @@ Returns: .fi .UNINDENT .UNINDENT +.SS Tests +.sp +Saltstack extends \fI\%builtin tests\fP with these custom tests: +.SS \fBequalto\fP +.sp +Tests the equality between two values. +.sp +Can be used in an \fBif\fP statement directly: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{% if 1 is equalto(1) %} + < statements > +{% endif %} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If clause evaluates to \fBTrue\fP +.sp +or with the \fBselectattr\fP filter: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{{ [{\(aqvalue\(aq: 1}, {\(aqvalue\(aq: 2} , {\(aqvalue\(aq: 3}] | selectattr(\(aqvalue\(aq, \(aqequalto\(aq, 3) | list }} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Returns: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +[{\(aqvalue\(aq: 3}] +.ft P +.fi +.UNINDENT +.UNINDENT +.SS \fBmatch\fP +.sp +Tests that a string matches the regex passed as an argument. +.sp +Can be used in a \fBif\fP statement directly: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{% if \(aqa\(aq is match(\(aq[a\-b]\(aq) %} + < statements > +{% endif %} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If clause evaluates to \fBTrue\fP +.sp +or with the \fBselectattr\fP filter: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{{ [{\(aqvalue\(aq: \(aqa\(aq}, {\(aqvalue\(aq: \(aqb\(aq}, {\(aqvalue\(aq: \(aqc\(aq}] | selectattr(\(aqvalue\(aq, \(aqmatch\(aq, \(aq[b\-e]\(aq) | list }} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Returns: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +[{\(aqvalue\(aq: \(aqb\(aq}, {\(aqvalue\(aq: \(aqc\(aq}] +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Test supports additional optional arguments: \fBignorecase\fP, \fBmultiline\fP .SS Escape filters .SS \fBregex_escape\fP .sp @@ -36648,7 +38249,7 @@ New in version 2014.7.0. .sp .nf .ft C -Context is: {{ show_full_context() }} +Context is: {{ show_full_context()|yaml(False) }} .ft P .fi .UNINDENT @@ -36682,6 +38283,31 @@ Will insert the following message in the minion logs: .fi .UNINDENT .UNINDENT +.SS Python Methods +.sp +A powerful feature of jinja that is only hinted at in the official jinja +documentation is that you can use the native python methods of the +variable type. Here is the python documentation for \fI\%string methods\fP\&. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{% set hostname,domain = grains.id.partition(\(aq.\(aq)[::2] %}{{ hostname }} +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{% set strings = grains.id.split(\(aq\-\(aq) %}{{ strings[0] }} +.ft P +.fi +.UNINDENT +.UNINDENT .SS Custom Execution Modules .sp Custom execution modules can be used to supplement or replace complex Jinja. Many @@ -36833,8 +38459,6 @@ States tutorial, part 4 .IP \(bu 2 How to Convert Jinja Logic to an Execution Module .IP \(bu 2 -Using Salt with Stormpath -.IP \(bu 2 Syslog\-ng usage .IP \(bu 2 The macOS (Maverick) Developer Step By Step Guide To Salt Installation @@ -36843,9 +38467,13 @@ SaltStack Walk\-through .IP \(bu 2 Writing Salt Tests .IP \(bu 2 +Multi\-cloud orchestration with Apache Libcloud +.IP \(bu 2 Running Salt States and Commands in Docker Containers .IP \(bu 2 Preseed Minion with Accepted Key +.IP \(bu 2 +Autoaccept Minions from Grains .UNINDENT .SS Troubleshooting .sp @@ -37024,7 +38652,7 @@ If the master seems to be unresponsive, a SIGUSR1 can be passed to the salt\-master threads to display what piece of code is executing. This debug information can be invaluable in tracking down bugs. .sp -To pass a SIGUSR1 to the master, first make sure the minion is running in the +To pass a SIGUSR1 to the master, first make sure the master is running in the foreground. Stop the service if it is running as a daemon, and start it in the foreground like so: .INDENT 0.0 @@ -38435,7 +40063,7 @@ The following example works on UNIX\-like operating systems: .sp .nf .ft C -{%\- if grains[\(aqos\(aq] != \(aqWindows\(aq % +{%\- if grains[\(aqos\(aq] != \(aqWindows\(aq %} Restart Salt Minion: cmd.run: \- name: \(aqsalt\-call \-\-local service.restart salt\-minion\(aq @@ -39683,7 +41311,7 @@ Writing Salt execution modules is straightforward. .sp A Salt execution module is a Python or \fI\%Cython\fP module placed in a directory called \fB_modules/\fP at the root of the Salt fileserver. When using the default -fileserver backend (i.e. \fBroots =0.2.1\fP\&. +.sp +For versions greater than \fI0.2.1\fP, \fBwinrm_verify_ssl\fP needs to be set to +\fIFalse\fP if the certificate is self signed and not verifiable. .SS Firewall Settings .sp Because Salt Cloud makes use of \fIsmbclient\fP and \fIwinexe\fP, port 445 must be open @@ -52281,7 +54930,8 @@ The default Windows user is \fIAdministrator\fP, and the default Windows passwor is blank. .sp If WinRM is to be used \fBuse_winrm\fP needs to be set to \fITrue\fP\&. \fBwinrm_port\fP -can be used to specify a custom port (must be HTTPS listener). +can be used to specify a custom port (must be HTTPS listener). And +\fBwinrm_verify_ssl\fP can be set to \fIFalse\fP to use a self signed certificate. .SS Auto\-Generated Passwords on EC2 .sp On EC2, when the \fIwin_password\fP is set to \fIauto\fP, Salt Cloud will query EC2 for @@ -54190,18 +56840,14 @@ New in version 2016.11.0. .sp Azure is a cloud service by Microsoft providing virtual machines, SQL services, media services, and more. Azure ARM (aka, the Azure Resource Manager) is a next -generatiom version of the Azure portal and API. This document describes how to +generation version of the Azure portal and API. This document describes how to use Salt Cloud to create a virtual machine on Azure ARM, with Salt installed. .sp More information about Azure is located at \fI\%http://www.windowsazure.com/\fP\&. .SS Dependencies .INDENT 0.0 .IP \(bu 2 -\fI\%Microsoft Azure SDK for Python\fP >= 2.0rc6 -.IP \(bu 2 -\fI\%Microsoft Azure Storage SDK for Python\fP >= 0.32 -.IP \(bu 2 -The python\-requests library, for Python < 2.7.9. +Azure Cli \fB\(gapip install \(aqazure\-cli>=2.0.12\(aq\(ga\fP .IP \(bu 2 A Microsoft Azure account .IP \(bu 2 @@ -54452,10 +57098,40 @@ Required. The virtual network that the VM will be spun up in. .sp Optional. The subnet inside the virtual network that the VM will be spun up in. Default is \fBdefault\fP\&. +.SS load_balancer +.sp +Optional. The load\-balancer for the VM\(aqs network interface to join. If +specified the backend_pool option need to be set. +.SS backend_pool +.sp +Optional. Required if the load_balancer option is set. The load\-balancer\(aqs +Backend Pool the VM\(aqs network interface will join. .SS iface_name .sp Optional. The name to apply to the VM\(aqs network interface. If not supplied, the value will be set to \fB\-iface0\fP\&. +.SS dns_servers +.sp +Optional. A \fBlist\fP of the DNS servers to configure for the network interface +(will be set on the VM by the DHCP of the VNET). +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my\-azurearm\-profile: + provider: azurearm\-provider + network: mynetwork + dns_servers: + \- 10.1.1.4 + \- 10.1.1.5 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS availability_set +.sp +Optional. If set, the VM will be added to the specified availability set. .SS cleanup_disks .sp Optional. Default is \fBFalse\fP\&. If set to \fBTrue\fP, disks will be cleaned up @@ -54814,7 +57490,7 @@ under the "SSH Keys" section. # /etc/salt/cloud.providers.d/ directory. my\-digitalocean\-config: - driver: digital_ocean + driver: digitalocean personal_access_token: xxx ssh_key_file: /path/to/ssh/key/file ssh_key_names: my\-key\-name,my\-key\-name\-2 @@ -54857,6 +57533,10 @@ digitalocean\-ubuntu: ipv6: True create_dns_record: True userdata_file: /etc/salt/cloud.userdata.d/setup + tags: + \- tag1 + \- tag2 + \- tag3 .ft P .fi .UNINDENT @@ -54872,7 +57552,7 @@ command: # salt\-cloud \-\-list\-locations my\-digitalocean\-config my\-digitalocean\-config: \-\-\-\-\-\-\-\-\-\- - digital_ocean: + digitalocean: \-\-\-\-\-\-\-\-\-\- Amsterdam 1: \-\-\-\-\-\-\-\-\-\- @@ -54902,7 +57582,7 @@ command: # salt\-cloud \-\-list\-sizes my\-digitalocean\-config my\-digitalocean\-config: \-\-\-\-\-\-\-\-\-\- - digital_ocean: + digitalocean: \-\-\-\-\-\-\-\-\-\- 512MB: \-\-\-\-\-\-\-\-\-\- @@ -54938,7 +57618,7 @@ command: # salt\-cloud \-\-list\-images my\-digitalocean\-config my\-digitalocean\-config: \-\-\-\-\-\-\-\-\-\- - digital_ocean: + digitalocean: \-\-\-\-\-\-\-\-\-\- 10.1: \-\-\-\-\-\-\-\-\-\- @@ -54962,7 +57642,7 @@ my\-digitalocean\-config: .SS Profile Specifics: .SS ssh_username .sp -If using a FreeBSD image from Digital Ocean, you\(aqll need to set the \fBssh_username\fP +If using a FreeBSD image from DigitalOcean, you\(aqll need to set the \fBssh_username\fP setting to \fBfreebsd\fP in your profile configuration. .INDENT 0.0 .INDENT 3.5 @@ -55372,7 +58052,7 @@ my\-ec2\-southeast\-public\-ips: id: \(aquse\-instance\-role\-credentials\(aq key: \(aquse\-instance\-role\-credentials\(aq - # Make sure this key is owned by root with permissions 0400. + # Make sure this key is owned by corresponding user (default \(aqsalt\(aq) with permissions 0400. # private_key: /etc/salt/my_test_key.pem keyname: my_test_key @@ -55869,7 +58549,7 @@ my\-ec2\-config: By default, the spot instance type is set to \(aqone\-time\(aq, meaning it will be launched and, if it\(aqs ever terminated for whatever reason, it will not be recreated. If you would like your spot instances to be relaunched after -a termination (by your or AWS), set the \fBtype\fP to \(aqpersistent\(aq. +a termination (by you or AWS), set the \fBtype\fP to \(aqpersistent\(aq. .sp NOTE: Spot instances are a great way to save a bit of money, but you do run the risk of losing your spot instances if the current price for the @@ -56061,7 +58741,7 @@ just instances: .ft C salt\-cloud \-f get_tags my_ec2 resource_id=af5467ba salt\-cloud \-f set_tags my_ec2 resource_id=af5467ba tag1=somestuff -salt\-cloud \-f del_tags my_ec2 resource_id=af5467ba tag1,tag2,tag3 +salt\-cloud \-f del_tags my_ec2 resource_id=af5467ba tags=tag1,tag2,tag3 .ft P .fi .UNINDENT @@ -58112,11 +60792,16 @@ of Linux (and other OSes). This driver Salt cloud provider is currently geared t libvirt with qemu\-kvm. .sp \fI\%http://www.libvirt.org/\fP -.SS Dependencies +.SS Host Dependencies .INDENT 0.0 .IP \(bu 2 libvirt >= 1.2.18 (older might work) .UNINDENT +.SS Salt\-Cloud Dependencies +.INDENT 0.0 +.IP \(bu 2 +libvirt\-python +.UNINDENT .SS Provider Configuration .sp For every KVM host a provider needs to be set up. The provider currently maps to one libvirt daemon (e.g. one KVM host). @@ -58137,6 +60822,8 @@ kvm\-via\-ssh: local\-kvm: driver: libvirt url: qemu:///system + # work around flag for XML validation errors while cloning + validate_xml: no .ft P .fi .UNINDENT @@ -58858,6 +61545,183 @@ Image listing (LXC templates) .IP \(bu 2 Running container information (IP addresses, etc.) .UNINDENT +.SS Getting Started With 1and1 +.sp +1&1 is one of the world’s leading Web hosting providers. 1&1 currently offers +a wide range of Web hosting products, including email solutions and high\-end +servers in 10 different countries including Germany, Spain, Great Britain +and the United States. From domains to 1&1 MyWebsite to eBusiness solutions +like Cloud Hosting and Web servers for complex tasks, 1&1 is well placed to deliver +a high quality service to its customers. All 1&1 products are hosted in +1&1‘s high\-performance, green data centers in the USA and Europe. +.SS Dependencies +.INDENT 0.0 +.IP \(bu 2 +1and1 >= 1.2.0 +.UNINDENT +.SS Configuration +.INDENT 0.0 +.IP \(bu 2 +Using the new format, set up the cloud configuration at +\fB/etc/salt/cloud.providers\fP or +\fB/etc/salt/cloud.providers.d/oneandone.conf\fP: +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my\-oneandone\-config: + driver: oneandone + + # Set the location of the salt\-master + # + minion: + master: saltmaster.example.com + + # Configure oneandone authentication credentials + # + api_token: + ssh_private_key: /path/to/id_rsa + ssh_public_key: /path/to/id_rsa.pub +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Authentication +.sp +The \fBapi_key\fP is used for API authorization. This token can be obtained +from the CloudPanel in the Management section below Users. +.SS Profiles +.sp +Here is an example of a profile: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +oneandone_fixed_size: + provider: my\-oneandone\-config + description: Small instance size server + fixed_instance_size: S + appliance_id: 8E3BAA98E3DFD37857810E0288DD8FBA + +oneandone_custom_size: + provider: my\-oneandone\-config + description: Custom size server + vcore: 2 + cores_per_processor: 2 + ram: 8 + appliance_id: 8E3BAA98E3DFD37857810E0288DD8FBA + hdds: + \- + is_main: true + size: 20 + \- + is_main: false + size: 20 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The following list explains some of the important properties. +.INDENT 0.0 +.TP +.B fixed_instance_size_id +When creating a server, either \fBfixed_instance_size_id\fP or custom hardware params +containing \fBvcore\fP, \fBcores_per_processor\fP, \fBram\fP, and \fBhdds\fP must be provided. +Can be one of the IDs listed among the output of the following command: +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-sizes oneandone +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B vcore +Total amount of processors. +.TP +.B cores_per_processor +Number of cores per processor. +.TP +.B ram +RAM memory size in GB. +.TP +.B hdds +Hard disks. +.TP +.B appliance_id +ID of the image that will be installed on server. +Can be one of the IDs listed in the output of the following command: +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-images oneandone +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B datacenter_id +ID of the datacenter where the server will be created. +Can be one of the IDs listed in the output of the following command: +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-locations oneandone +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B description +Description of the server. +.TP +.B password +Password of the server. Password must contain more than 8 characters +using uppercase letters, numbers and other special symbols. +.TP +.B power_on +Power on server after creation. Default is set to true. +.TP +.B firewall_policy_id +Firewall policy ID. If it is not provided, the server will assign +the best firewall policy, creating a new one if necessary. If the parameter +is sent with a 0 value, the server will be created with all ports blocked. +.TP +.B ip_id +IP address ID. +.TP +.B load_balancer_id +Load balancer ID. +.TP +.B monitoring_policy_id +Monitoring policy ID. +.TP +.B deploy +Set to False if Salt should not be installed on the node. +.TP +.B wait_for_timeout +The timeout to wait in seconds for provisioning resources such as servers. +The default wait_for_timeout is 15 minutes. +.UNINDENT +.sp +For more information concerning cloud profiles, see here\&. .SS Getting Started with OpenNebula .sp OpenNebula is an open\-source solution for the comprehensive management of virtualized data centers to enable the mixed @@ -59170,225 +62034,6 @@ my\-opennebula\-provider: .fi .UNINDENT .UNINDENT -.SS Getting Started With OpenStack -.sp -OpenStack is one the most popular cloud projects. It\(aqs an open source project -to build public and/or private clouds. You can use Salt Cloud to launch -OpenStack instances. -.SS Dependencies -.INDENT 0.0 -.IP \(bu 2 -Libcloud >= 0.13.2 -.UNINDENT -.SS Configuration -.INDENT 0.0 -.IP \(bu 2 -Using the new format, set up the cloud configuration at -\fB/etc/salt/cloud.providers\fP or -\fB/etc/salt/cloud.providers.d/openstack.conf\fP: -.UNINDENT -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-config: - # Set the location of the salt\-master - # - minion: - master: saltmaster.example.com - - # Configure the OpenStack driver - # - identity_url: http://identity.youopenstack.com/v2.0/tokens - compute_name: nova - protocol: ipv4 - - compute_region: RegionOne - - # Configure Openstack authentication credentials - # - user: myname - password: 123456 - # tenant is the project name - tenant: myproject - - driver: openstack - - # skip SSL certificate validation (default false) - insecure: false -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -Changed in version 2015.8.0. - -.sp -The \fBprovider\fP parameter in cloud provider definitions was renamed to \fBdriver\fP\&. This -change was made to avoid confusion with the \fBprovider\fP parameter that is used in cloud profile -definitions. Cloud provider definitions now use \fBdriver\fP to refer to the Salt cloud module that -provides the underlying functionality to connect to a cloud host, while cloud profiles continue -to use \fBprovider\fP to refer to provider configurations that you define. -.UNINDENT -.UNINDENT -.SS Using nova client to get information from OpenStack -.sp -One of the best ways to get information about OpenStack is using the novaclient -python package (available in pypi as python\-novaclient). The client -configuration is a set of environment variables that you can get from the -Dashboard. Log in and then go to Project \-> Access & security \-> API Access and -download the "OpenStack RC file". Then: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -source /path/to/your/rcfile -nova credentials -nova endpoints -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -In the \fBnova endpoints\fP output you can see the information about -\fBcompute_region\fP and \fBcompute_name\fP\&. -.SS Compute Region -.sp -It depends on the OpenStack cluster that you are using. Please, have a look at -the previous sections. -.SS Authentication -.sp -The \fBuser\fP and \fBpassword\fP is the same user as is used to log into the -OpenStack Dashboard. -.SS Profiles -.sp -Here is an example of a profile: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -openstack_512: - provider: my\-openstack\-config - size: m1.tiny - image: cirros\-0.3.1\-x86_64\-uec - ssh_key_file: /tmp/test.pem - ssh_key_name: test - ssh_interface: private_ips -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -The following list explains some of the important properties. -.INDENT 0.0 -.TP -.B size -can be one of the options listed in the output of \fBnova flavor\-list\fP\&. -.TP -.B image -can be one of the options listed in the output of \fBnova image\-list\fP\&. -.TP -.B ssh_key_file -The SSH private key that the salt\-cloud uses to SSH into the VM after its -first booted in order to execute a command or script. This private key\(aqs -\fIpublic key\fP must be the openstack public key inserted into the -authorized_key\(aqs file of the VM\(aqs root user account. -.TP -.B ssh_key_name -The name of the openstack SSH public key that is inserted into the -authorized_keys file of the VM\(aqs root user account. Prior to using this -public key, you must use openstack commands or the horizon web UI to load -that key into the tenant\(aqs account. Note that this openstack tenant must be -the one you defined in the cloud provider. -.TP -.B ssh_interface -This option allows you to create a VM without a public IP. If this option -is omitted and the VM does not have a public IP, then the salt\-cloud waits -for a certain period of time and then destroys the VM. With the nova drive, -private cloud networks can be defined here. -.UNINDENT -.sp -For more information concerning cloud profiles, see here\&. -.SS change_password -.sp -If no ssh_key_file is provided, and the server already exists, change_password -will use the api to change the root password of the server so that it can be -bootstrapped. -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -change_password: True -.ft P -.fi -.UNINDENT -.UNINDENT -.SS userdata_file -.sp -Use \fIuserdata_file\fP to specify the userdata file to upload for use with -cloud\-init if available. -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-config: - # Pass userdata to the instance to be created - userdata_file: /etc/salt/cloud\-init/packages.yml -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -As of the 2016.11.4 release, this file can be templated. To use templating, -simply specify a \fBuserdata_template\fP option in the cloud profile: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-config: - # Pass userdata to the instance to be created - userdata_file: /etc/salt/cloud\-init/packages.yml - userdata_template: jinja -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -If no \fBuserdata_template\fP is set in the cloud profile, then the master -configuration will be checked for a \fBuserdata_template\fP value. -If this is not set, then no templating will be performed on the -userdata_file. -.sp -To disable templating in a cloud profile when a -\fBuserdata_template\fP has been set in the master configuration -file, simply set \fBuserdata_template\fP to \fBFalse\fP in the cloud profile: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-config: - # Pass userdata to the instance to be created - userdata_file: /etc/salt/cloud\-init/packages.yml - userdata_template: False -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT .SS Getting Started With Parallels .sp Parallels Cloud Server is a product by Parallels that delivers a cloud hosting @@ -59630,8 +62275,8 @@ my\-profitbricks\-config: # username: user@domain.com password: 123456 - # datacenter is the UUID of a pre\-existing virtual data center. - datacenter: 9e6709a0\-6bf9\-4bd6\-8692\-60349c70ce0e + # datacenter_id is the UUID of a pre\-existing virtual data center. + datacenter_id: 9e6709a0\-6bf9\-4bd6\-8692\-60349c70ce0e # Connect to public LAN ID 1. public_lan: 1 ssh_public_key: /path/to/id_rsa.pub @@ -60526,14 +63171,14 @@ Additional documentation about Scaleway can be found at \fI\%https://www.scalewa .UNINDENT .SS Getting Started With Saltify .sp -The Saltify driver is a new, experimental driver for installing Salt on existing +The Saltify driver is a driver for installing Salt on existing machines (virtual or bare metal). .SS Dependencies .sp The Saltify driver has no external dependencies. .SS Configuration .sp -Because the Saltify driver does not use an actual cloud provider host, it has a +Because the Saltify driver does not use an actual cloud provider host, it can have a simple provider configuration. The only thing that is required to be set is the driver name, and any other potentially useful information, like the location of the salt\-master: @@ -60548,18 +63193,34 @@ the salt\-master: my\-saltify\-config: minion: master: 111.222.333.444 - provider: saltify + driver: saltify .ft P .fi .UNINDENT .UNINDENT +.sp +However, if you wish to use the more advanced capabilities of salt\-cloud, such as +rebooting, listing, and disconnecting machines, then the salt master must fill +the role usually performed by a vendor\(aqs cloud management system. The salt master +must be running on the salt\-cloud machine, and created nodes must be connected to the +master. +.sp +Additional information about which configuration options apply to which actions +can be studied in the +Saltify Module documentation +and the +Miscellaneous Salt Cloud Options +document. .SS Profiles .sp -Saltify requires a profile to be configured for each machine that needs Salt -installed. The initial profile can be set up at \fB/etc/salt/cloud.profiles\fP +Saltify requires a separate profile to be configured for each machine that +needs Salt installed [1]\&. The initial profile can be set up at +\fB/etc/salt/cloud.profiles\fP or in the \fB/etc/salt/cloud.profiles.d/\fP directory. Each profile requires both an \fBssh_host\fP and an \fBssh_username\fP key parameter as well as either an \fBkey_filename\fP or a \fBpassword\fP\&. +.IP [1] 5 +Unless you are using a map file to provide the unique parameters. .sp Profile configuration example: .INDENT 0.0 @@ -60594,7 +63255,7 @@ salt\-cloud \-p salt\-this\-machine my\-machine This will install salt on the machine specified by the cloud profile, \fBsalt\-this\-machine\fP, and will give the machine the minion id of \fBmy\-machine\fP\&. If the command was executed on the salt\-master, its Salt -key will automatically be signed on the master. +key will automatically be accepted by the master. .sp Once a salt\-minion has been successfully installed on the instance, connectivity to it can be verified with Salt: @@ -60603,7 +63264,78 @@ to it can be verified with Salt: .sp .nf .ft C -salt my\-machine test.ping +salt my\-machine test.version +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Destroy Options +.sp +New in version 2018.3.0. + +.sp +For obvious reasons, the \fBdestroy\fP action does not actually vaporize hardware. +If the salt master is connected, it can tear down parts of the client machines. +It will remove the client\(aqs key from the salt master, +and can execute the following options: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +\- remove_config_on_destroy: true + # default: true + # Deactivate salt\-minion on reboot and + # delete the minion config and key files from its "/etc/salt" directory, + # NOTE: If deactivation was unsuccessful (older Ubuntu machines) then when + # salt\-minion restarts it will automatically create a new, unwanted, set + # of key files. Use the "force_minion_config" option to replace them. + +\- shutdown_on_destroy: false + # default: false + # last of all, send a "shutdown" command to the client. +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Wake On LAN +.sp +New in version 2018.3.0. + +.sp +In addition to connecting a hardware machine to a Salt master, +you have the option of sending a wake\-on\-LAN +\fI\%magic packet\fP +to start that machine running. +.sp +The "magic packet" must be sent by an existing salt minion which is on +the same network segment as the target machine. (Or your router +must be set up especially to route WoL packets.) Your target machine +must be set up to listen for WoL and to respond appropriatly. +.sp +You must provide the Salt node id of the machine which will send +the WoL packet (parameter \fBwol_sender_node\fP), and +the hardware MAC address of the machine you intend to wake, +(parameter \fBwake_on_lan_mac\fP). If both parameters are defined, +the WoL will be sent. The cloud master will then sleep a while +(parameter \fBwol_boot_wait\fP) to give the target machine time to +boot up before we start probing its SSH port to begin deploying +Salt to it. The default sleep time is 30 seconds. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# /etc/salt/cloud.profiles.d/saltify.conf + +salt\-this\-machine: + ssh_host: 12.34.56.78 + ssh_username: root + key_filename: \(aq/etc/salt/mysshkey.pem\(aq + provider: my\-saltify\-config + wake_on_lan_mac: \(aq00:e0:4c:70:2a:b2\(aq # found with ifconfig + wol_sender_node: bevymaster # its on this network segment + wol_boot_wait: 45 # seconds to sleep .ft P .fi .UNINDENT @@ -60700,13 +63432,6 @@ deployment. \fBNone\fP: Credential verification was not attempted. .UNINDENT .UNINDENT -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -This feature is not available for Windows targets. -.UNINDENT -.UNINDENT .SS Getting Started With SoftLayer .sp SoftLayer is a public cloud host, and baremetal hardware hosting service. @@ -60816,6 +63541,8 @@ base_softlayer_ubuntu: private_vlan: 396 private_network: True private_ssh: True + # Use a dedicated host instead of cloud + dedicated_host_id: 1234 # May be used _instead_of_ image global_identifier: 320d8be5\-46c0\-dead\-cafe\-13e3c51 .ft P @@ -61108,7 +63835,18 @@ it can be verified with Salt: .fi .UNINDENT .UNINDENT -.SS Cloud Profiles +.SS Dedicated Host +.sp +Soflayer allows the creation of new VMs in a dedicated host. This means that +you can order and pay a fixed amount for a bare metal dedicated host and use +it to provision as many VMs as you can fit in there. If you want your VMs to +be launched in a dedicated host, instead of Sofltayer\(aqs cloud, set the +\fBdedicated_host_id\fP parameter in your profile. +.SS dedicated_host_id +.sp +The id of the dedicated host where the VMs should be created. If not set, VMs +will be created in Softlayer\(aqs cloud instead. +.SS Bare metal Profiles .sp Set up an initial profile at \fB/etc/salt/cloud.profiles\fP: .INDENT 0.0 @@ -61498,6 +64236,340 @@ here: .IP \(bu 2 408: 1000Mbps Hardware Firewall .UNINDENT +.SS Getting Started With Vagrant +.sp +The Vagrant driver is a new, experimental driver for spinning up a VagrantBox +virtual machine, and installing Salt on it. +.SS Dependencies +.sp +The Vagrant driver itself has no external dependencies. +.sp +The machine which will host the VagrantBox must be an already existing minion +of the cloud server\(aqs Salt master. +It must have \fI\%Vagrant\fP installed, and a Vagrant\-compatible virtual machine engine, +such as \fI\%VirtualBox\fP\&. +(Note: The Vagrant driver does not depend on the salt\-cloud VirtualBox driver in any way.) +.sp +[Caution: The version of Vagrant packaged for \fBapt install\fP in Ubuntu 16.04 will not connect a bridged +network adapter correctly. Use a version downloaded directly from the web site.] +.sp +Include the Vagrant guest editions plugin: +\fBvagrant plugin install vagrant\-vbguest\fP\&. +.SS Configuration +.sp +Configuration of the client virtual machine (using VirtualBox, VMware, etc) +will be done by Vagrant as specified in the Vagrantfile on the host machine. +.sp +Salt\-cloud will push the commands to install and provision a salt minion on +the virtual machine, so you need not (perhaps \fBshould\fP not) provision salt +in your Vagrantfile, in most cases. +.sp +If, however, your cloud master cannot open an SSH connection to the child VM, +you may \fBneed\fP to let Vagrant provision the VM with Salt, and use some other +method (such as passing a pillar dictionary to the VM) to pass the master\(aqs +IP address to the VM. The VM can then attempt to reach the salt master in the +usual way for non\-cloud minions. Specify the profile configuration argument +as \fBdeploy: False\fP to prevent the cloud master from trying. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Note: This example is for /etc/salt/cloud.providers file or any file in +# the /etc/salt/cloud.providers.d/ directory. + +my\-vagrant\-config: + minion: + master: 111.222.333.444 + provider: vagrant +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Because the Vagrant driver needs a place to store the mapping between the +node name you use for Salt commands and the Vagrantfile which controls the VM, +you must configure your salt minion as a Salt smb server. +(See \fI\%host provisioning example\fP below.) +.SS Profiles +.sp +Vagrant requires a profile to be configured for each machine that needs Salt +installed. The initial profile can be set up at \fB/etc/salt/cloud.profiles\fP +or in the \fB/etc/salt/cloud.profiles.d/\fP directory. +.sp +Each profile requires a \fBvagrantfile\fP parameter. If the Vagrantfile has +definitions for \fI\%multiple machines\fP then you need a \fBmachine\fP parameter, +.sp +Salt\-cloud uses SSH to provision the minion. There must be a routable path +from the cloud master to the VM. Usually, you will want to use +a bridged network adapter for SSH. The address may not be known until +DHCP assigns it. If \fBssh_host\fP is not defined, and \fBtarget_network\fP +is defined, the driver will attempt to read the address from the output +of an \fBifconfig\fP command. Lacking either setting, +the driver will try to use the value Vagrant returns as its \fBssh_host\fP, +which will work only if the cloud master is running somewhere on the same host. +.sp +The \fBtarget_network\fP setting should be used +to identify the IP network your bridged adapter is expected to appear on. +Use CIDR notation, like \fBtarget_network: \(aq2001:DB8::/32\(aq\fP +or \fBtarget_network: \(aq192.0.2.0/24\(aq\fP\&. +.sp +Profile configuration example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# /etc/salt/cloud.profiles.d/vagrant.conf + +vagrant\-machine: + host: my\-vhost # the Salt id of the virtual machine\(aqs host computer. + provider: my\-vagrant\-config + cwd: /srv/machines # the path to your Virtualbox file. + vagrant_runas: my\-username # the username who defined the Vagrantbox on the host + # vagrant_up_timeout: 300 # (seconds) timeout for cmd.run of the "vagrant up" command + # vagrant_provider: \(aq\(aq # option for "vagrant up" like: "\-\-provider vmware_fusion" + # ssh_host: None # "None" means try to find the routable IP address from "ifconfig" + # ssh_username: \(aq\(aq # also required when ssh_host is used. + # target_network: None # Expected CIDR address range of your bridged network + # force_minion_config: false # Set "true" to re\-purpose an existing VM +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The machine can now be created and configured with the following command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-p vagrant\-machine my\-id +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This will create the machine specified by the cloud profile +\fBvagrant\-machine\fP, and will give the machine the minion id of +\fBmy\-id\fP\&. If the cloud master is also the salt\-master, its Salt +key will automatically be accepted on the master. +.sp +Once a salt\-minion has been successfully installed on the instance, connectivity +to it can be verified with Salt: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt my\-id test.ping +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Provisioning a Vagrant cloud host (example) +.sp +In order to query or control minions it created, each host +minion needs to track the Salt node names associated with +any guest virtual machines on it. +It does that using a Salt sdb database. +.sp +The Salt sdb is not configured by default. The following example shows a +simple installation. +.sp +This example assumes: +.INDENT 0.0 +.IP \(bu 2 +you are on a large network using the 10.x.x.x IP address space +.IP \(bu 2 +your Salt master\(aqs Salt id is "bevymaster" +.IP \(bu 2 +it will also be your salt\-cloud controller +.IP \(bu 2 +it is at hardware address 10.124.30.7 +.IP \(bu 2 +it is running a recent Debian family Linux (raspbian) +.IP \(bu 2 +your workstation is a Salt minion of bevymaster +.IP \(bu 2 +your workstation\(aqs minion id is "my_laptop" +.IP \(bu 2 +VirtualBox has been installed on "my_laptop" (apt install is okay) +.IP \(bu 2 +Vagrant was installed from vagrantup.com. (not the 16.04 Ubuntu apt) +.IP \(bu 2 +"my_laptop" has done "vagrant plugin install vagrant\-vbguest" +.IP \(bu 2 +the VM you want to start is on "my_laptop" at "/home/my_username/Vagrantfile" +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# file /etc/salt/minion.d/vagrant_sdb.conf on host computer "my_laptop" +# \-\- this sdb database is required by the Vagrant module \-\- +vagrant_sdb_data: # The sdb database must have this name. + driver: sqlite3 # Let\(aqs use SQLite to store the data ... + database: /var/cache/salt/vagrant.sqlite # ... in this file ... + table: sdb # ... using this table name. + create_table: True # if not present +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Remember to re\-start your minion after changing its configuration files... +.INDENT 0.0 +.INDENT 3.5 +\fBsudo systemctl restart salt\-minion\fP +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# \-*\- mode: ruby \-*\- +# file /home/my_username/Vagrantfile on host computer "my_laptop" +BEVY = "bevy1" +DOMAIN = BEVY + ".test" # .test is an ICANN reserved non\-public TLD + +# must supply a list of names to avoid Vagrant asking for interactive input +def get_good_ifc() # try to find a working Ubuntu network adapter name + addr_infos = Socket.getifaddrs + addr_infos.each do |info| + a = info.addr + if a and a.ip? and not a.ip_address.start_with?("127.") + return info.name + end + end + return "eth0" # fall back to an old reliable name +end + +Vagrant.configure(2) do |config| + config.ssh.forward_agent = true # so you can use git ssh://... + + # add a bridged network interface. (try to detect name, then guess MacOS names, too) + interface_guesses = [get_good_ifc(), \(aqen0: Ethernet\(aq, \(aqen1: Wi\-Fi (AirPort)\(aq] + config.vm.network "public_network", bridge: interface_guesses + if ARGV[0] == "up" + puts "Trying bridge network using interfaces: #{interface_guesses}" + end + config.vm.provision "shell", inline: "ip address", run: "always" # make user feel good + + # . . . . . . . . . . . . Define machine QUAIL1 . . . . . . . . . . . . . . + config.vm.define "quail1", primary: true do |quail_config| + quail_config.vm.box = "boxesio/xenial64\-standard" # a public VMware & Virtualbox box + quail_config.vm.hostname = "quail1." + DOMAIN # supply a name in our bevy + quail_config.vm.provider "virtualbox" do |v| + v.memory = 1024 # limit memory for the virtual box + v.cpus = 1 + v.linked_clone = true # make a soft copy of the base Vagrant box + v.customize ["modifyvm", :id, "\-\-natnet1", "192.168.128.0/24"] # do not use 10.x network for NAT + end + end +end +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# file /etc/salt/cloud.profiles.d/my_vagrant_profiles.conf on bevymaster +q1: + host: my_laptop # the Salt id of your virtual machine host + machine: quail1 # a machine name in the Vagrantfile (if not primary) + vagrant_runas: my_username # owner of Vagrant box files on "my_laptop" + cwd: \(aq/home/my_username\(aq # the path (on "my_laptop") of the Vagrantfile + provider: my_vagrant_provider # name of entry in provider.conf file + target_network: \(aq10.0.0.0/8\(aq # VM external address will be somewhere here +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# file /etc/salt/cloud.providers.d/vagrant_provider.conf on bevymaster +my_vagrant_provider: + driver: vagrant + minion: + master: 10.124.30.7 # the hard address of the master +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Create and use your new Salt minion +.INDENT 0.0 +.IP \(bu 2 +Typing on the Salt master computer \fBbevymaster\fP, tell it to create a new minion named \fBv1\fP using profile \fBq1\fP\&... +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +sudo salt\-cloud \-p q1 v1 +sudo salt v1 network.ip_addrs + [ you get a list of IP addresses, including the bridged one ] +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +logged in to your laptop (or some other computer known to GitHub)... +.INDENT 2.0 +.INDENT 3.5 +[NOTE:] if you are using MacOS, you need to type \fBssh\-add \-K\fP after each boot, +unless you use one of the methods in \fI\%this gist\fP\&. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ssh \-A vagrant@< the bridged network address > + # [ or, if you are at /home/my_username/ on my_laptop ] +vagrant ssh quail1 +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +then typing on your new node "v1" (a.k.a. quail1.bevy1.test)... +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +password: vagrant + # [ stuff types out ... ] + +ls \-al /vagrant + # [ should be shared /home/my_username from my_laptop ] + +# you can access other network facilities using the ssh authorization +# as recorded in your ~.ssh/ directory on my_laptop ... + +sudo apt update +sudo apt install git +git clone ssh://git@github.com/yourID/your_project +# etc... +.ft P +.fi +.UNINDENT +.UNINDENT .SS Getting Started with VEXXHOST .sp \fI\%VEXXHOST\fP is a cloud computing host which provides @@ -61937,6 +65009,7 @@ vmware\-centos6.5: guestinfo.foo: bar guestinfo.domain: foobar.com guestinfo.customVariable: customValue + annotation: Created by Salt\-Cloud deploy: True customization: True @@ -62044,6 +65117,11 @@ Enter the size of disk in GB Specifies whether the disk should be thin provisioned or not. Default is \fBthin_provision: False\fP\&. .. versionadded:: 2016.3.0 .TP +.B eagerly_scrub +Specifies whether the disk should be rewrite with zeros during thick provisioning or not. +Default is \fBeagerly_scrub: False\fP\&. +.. versionadded:: 2018.3.0 +.TP .B controller Specify the SCSI controller label to which this disk should be attached. This should be specified only when creating both the specified SCSI @@ -62268,6 +65346,11 @@ describes a set of modifications to the additional options. If the key is alread present, it will be reset with the new value provided. Otherwise, a new option is added. Keys with empty values will be removed. .TP +.B \fBannotation\fP +User\-provided description of the virtual machine. This will store a message in the +vSphere interface, under the annotations section in the Summary view of the virtual +machine. +.TP .B \fBdeploy\fP Specifies if salt should be installed on the newly created VM. Default is \fBTrue\fP so salt will be installed using the bootstrap script. If \fBtemplate: True\fP or @@ -62622,6 +65705,249 @@ my\-vm: .fi .UNINDENT .UNINDENT +.SS Getting Started With Xen +.sp +The Xen cloud driver works with Citrix XenServer. +.sp +It can be used with a single XenServer or a XenServer resource pool. +.SS Setup Dependencies +.sp +This driver requires a copy of the freely available \fBXenAPI.py\fP Python module. +.sp +Information about the Xen API Python module in the XenServer SDK +can be found at \fI\%https://xenserver.org/partners/developing\-products\-for\-xenserver.html\fP +.sp +Place a copy of this module on your system. For example, it can +be placed in the \fIsite packages\fP location on your system. +.sp +The location of \fIsite packages\fP can be determined by running: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +python \-m site \-\-user\-site +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Provider Configuration +.sp +Xen requires login credentials to a XenServer. +.sp +Set up the provider cloud configuration file at \fB/etc/salt/cloud.providers\fP or +\fB/etc/salt/cloud.providers.d/*.conf\fP\&. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# /etc/salt/cloud.providers.d/myxen.conf +myxen: + driver: xen + url: https://10.0.0.120 + user: root + password: p@ssw0rd +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B url: +The \fBurl\fP option supports both \fBhttp\fP and \fBhttps\fP uri prefixes. +.TP +.B user: +A valid user id to login to the XenServer host. +.TP +.B password: +The associated password for the user. +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Changed in version 2015.8.0. + +.sp +The \fBprovider\fP parameter in cloud provider definitions was renamed to \fBdriver\fP\&. This +change was made to avoid confusion with the \fBprovider\fP parameter that is used in cloud profile +definitions. Cloud provider definitions now use \fBdriver\fP to refer to the Salt cloud module that +provides the underlying functionality to connect to a cloud host, while cloud profiles continue +to use \fBprovider\fP to refer to provider configurations that you define. +.UNINDENT +.UNINDENT +.SS Profile Configuration +.sp +Xen profiles require a \fBprovider\fP and \fBimage\fP\&. +.INDENT 0.0 +.TP +.B provider: +This will be the name of your defined provider. +.TP +.B image: +The name of the VM template used to clone or copy. +.TP +.B clone: +The default behavior is to clone a template or VM. This is very fast, +but requires the source template or VM to be in the same storage +repository of the new target system. If the source and target are in +different storage repositories then you must copy the source and not +clone it by setting \fBclone: False\fP\&. +.TP +.B deploy: +The provisioning process will attempt to install the Salt minion +service on the new target system by default. This will require login +credentials for Salt cloud to login via ssh to it. The \fBuser\fP and +\fBpassword\fP options are required. If \fBdeploy\fP is set to \fBFalse\fP +then these options are not needed. +.TP +.B resource_pool: +The name of the resource pool used for this profile. +.TP +.B storage_repo: +The name of the storage repository for the target system. +.TP +.B ipv4_cidr: +If template is Windows, and running guest tools then a static +ip address can be set. +.TP +.B ipv4_gw: +If template is Windows, and running guest tools then a gateway +can be set. +.UNINDENT +.sp +Set up an initial profile +at \fB/etc/salt/cloud.profiles\fP or in the \fB/etc/salt/cloud.profiles.d/\fP directory: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# file: /etc/salt/cloud.profiles.d/xenprofiles.conf +sles: + provider: myxen + deploy: False + image: sles12sp2\-template + +suse: + user: root + password: p@ssw0rd + provider: myxen + image: opensuseleap42_2\-template + storage_repo: \(aqLocal storage\(aq + clone: False + minion: + master: 10.0.0.20 + +w2k12: + provider: myxen + image: w2k12svr\-template + clone: True + userdata_file: /srv/salt/win/files/windows\-firewall.ps1 + win_installer: /srv/salt/win/files/Salt\-Minion\-2016.11.3\-AMD64\-Setup.exe + win_username: Administrator + win_password: p@ssw0rd + use_winrm: False + ipv4_cidr: 10.0.0.215/24 + ipv4_gw: 10.0.0.1 + minion: + master: 10.0.0.21 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The first example will create a clone of the sles12sp2\-template in the +same storage repository without deploying the Salt minion. +.sp +The second example will make a copy of the image and deploy a new +suse VM with the Salt minion installed. +.sp +The third example will create a clone of the Windows 2012 template +and deploy the Salt minion. +.sp +The profile can be used with a salt command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-p suse xenvm02 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This will create an salt minion instance named \fBxenvm02\fP in Xen. If the command was +executed on the salt\-master, its Salt key will automatically be signed on the master. +.sp +Once the instance has been created with a salt\-minion installed, connectivity to +it can be verified with Salt: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt xenvm02 test.ping +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Listing Sizes +.sp +Sizes can be obtained using the \fB\-\-list\-sizes\fP option for the \fBsalt\-cloud\fP +command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# salt\-cloud \-\-list\-sizes myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Since size information is build in a template this command +is not implemented. +.UNINDENT +.UNINDENT +.SS Listing Images +.sp +Images can be obtained using the \fB\-\-list\-images\fP option for the \fBsalt\-cloud\fP +command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# salt\-cloud \-\-list\-images myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This command will return a list of templates with details. +.SS Listing Locations +.sp +Locations can be obtained using the \fB\-\-list\-locations\fP option for the \fBsalt\-cloud\fP +command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# salt\-cloud \-\-list\-locations myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Returns a list of resource pools. .SS Miscellaneous Options .SS Miscellaneous Salt Cloud Options .sp @@ -63054,6 +66380,55 @@ ubuntu14: .fi .UNINDENT .UNINDENT +.SS Running Pre\-Flight Commands +.sp +New in version 2018.3.0. + +.sp +To execute specified preflight shell commands on a VM before the deploy script is +run, use the \fBpreflight_cmds\fP option. These must be defined as a list in a cloud +configuration file. For example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my\-cloud\-profile: + provider: linode\-config + image: Ubuntu 16.04 LTS + size: Linode 2048 + preflight_cmds: + \- whoami + \- echo \(aqhello world!\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +These commands will run in sequence \fBbefore\fP the bootstrap script is executed. +.SS Force Minion Config +.sp +New in version 2018.3.0. + +.sp +The \fBforce_minion_config\fP option requests the bootstrap process to overwrite +an existing minion configuration file and public/private key files. +Default: False +.sp +This might be important for drivers (such as \fBsaltify\fP) which are expected to +take over a connection from a former salt master. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my_saltify_provider: + driver: saltify + force_minion_config: true +.ft P +.fi +.UNINDENT +.UNINDENT .SS Troubleshooting Steps .SS Troubleshooting Salt Cloud .sp @@ -63400,7 +66775,7 @@ library. The following two lines set up the imports: .nf .ft C from salt.cloud.libcloudfuncs import * # pylint: disable=W0614,W0401 -from salt.utils import namespaced_function +import salt.utils.functools .ft P .fi .UNINDENT @@ -63413,17 +66788,17 @@ within the cloud module. .sp .nf .ft C -get_size = namespaced_function(get_size, globals()) -get_image = namespaced_function(get_image, globals()) -avail_locations = namespaced_function(avail_locations, globals()) -avail_images = namespaced_function(avail_images, globals()) -avail_sizes = namespaced_function(avail_sizes, globals()) -script = namespaced_function(script, globals()) -destroy = namespaced_function(destroy, globals()) -list_nodes = namespaced_function(list_nodes, globals()) -list_nodes_full = namespaced_function(list_nodes_full, globals()) -list_nodes_select = namespaced_function(list_nodes_select, globals()) -show_instance = namespaced_function(show_instance, globals()) +get_size = salt.utils.functools.namespaced_function(get_size, globals()) +get_image = salt.utils.functools.namespaced_function(get_image, globals()) +avail_locations = salt.utils.functools.namespaced_function(avail_locations, globals()) +avail_images = salt.utils.functools.namespaced_function(avail_images, globals()) +avail_sizes = salt.utils.functools.namespaced_function(avail_sizes, globals()) +script = salt.utils.functools.namespaced_function(script, globals()) +destroy = salt.utils.functools.namespaced_function(destroy, globals()) +list_nodes = salt.utils.functools.namespaced_function(list_nodes, globals()) +list_nodes_full = salt.utils.functools.namespaced_function(list_nodes_full, globals()) +list_nodes_select = salt.utils.functools.namespaced_function(list_nodes_select, globals()) +show_instance = salt.utils.functools.namespaced_function(show_instance, globals()) .ft P .fi .UNINDENT @@ -63445,7 +66820,7 @@ imports should be absent from the Salt Cloud module. .sp A good example of a non\-libcloud driver is the DigitalOcean driver: .sp -\fI\%https://github.com/saltstack/salt/tree/develop/salt/cloud/clouds/digital_ocean.py\fP +\fI\%https://github.com/saltstack/salt/tree/develop/salt/cloud/clouds/digitalocean.py\fP .SS The \fBcreate()\fP Function .sp The \fBcreate()\fP function must be created as described in the libcloud\-based @@ -63869,7 +67244,7 @@ the Jinja template. A good, well commented example of this process is the Fedora deployment script: .sp -\fI\%https://github.com/saltstack/salt\-cloud/blob/master/saltcloud/deploy/Fedora.sh\fP +\fI\%https://github.com/saltstack/salt/blob/develop/salt/cloud/deploy/Fedora.sh\fP .sp A number of legacy deploy scripts are included with the release tarball. None of them are as functional or complete as Salt Bootstrap, and are still included @@ -64539,7 +67914,7 @@ properly listed here, pull requests to fix them is appreciated. These are features that are available for almost every cloud host. .TS center; -|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|. +|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|. _ T{ T} T{ @@ -64568,6 +67943,8 @@ Rackspace T} T{ Saltify T} T{ +Vagrant +T} T{ Softlayer T} T{ Softlayer @@ -64599,6 +67976,9 @@ Yes T} T{ Yes T} T{ +[1] +T} T{ +[1] T} T{ Yes T} T{ @@ -64630,6 +68010,9 @@ Yes T} T{ Yes T} T{ +[1] +T} T{ +[1] T} T{ Yes T} T{ @@ -64661,6 +68044,9 @@ Yes T} T{ Yes T} T{ +[1] +T} T{ +[1] T} T{ Yes T} T{ @@ -64692,6 +68078,9 @@ Yes T} T{ Yes T} T{ +[2] +T} T{ +[2] T} T{ Yes T} T{ @@ -64723,6 +68112,9 @@ Yes T} T{ Yes T} T{ +Yes +T} T{ +Yes T} T{ Yes T} T{ @@ -64754,6 +68146,9 @@ Yes T} T{ Yes T} T{ +[2] +T} T{ +[2] T} T{ Yes T} T{ @@ -64787,6 +68182,8 @@ Yes T} T{ Yes T} T{ +[1] +T} T{ Yes T} T{ Yes @@ -64817,6 +68214,9 @@ Yes T} T{ Yes T} T{ +[1] +T} T{ +[1] T} T{ Yes T} T{ @@ -64826,6 +68226,10 @@ Yes T} _ .TE +.sp +[1] Yes, if salt\-api is enabled. +.sp +[2] Always returns \fI{}\fP\&. .SS Actions .sp These are features that are performed on a specific instance, and require an @@ -64870,7 +68274,11 @@ T} T{ Rackspace (Legacy) T} T{ -Saltify +.INDENT 0.0 +.TP +.B Saltify& +Vagrant +.UNINDENT T} T{ Softlayer T} T{ @@ -65290,7 +68698,11 @@ T} T{ Rackspace (Legacy) T} T{ -Saltify +.INDENT 0.0 +.TP +.B Saltify& +Vagrant +.UNINDENT T} T{ Softlayer T} T{ @@ -65915,6 +69327,7 @@ T} T{ T} T{ T} T{ T} T{ +[1] T} T{ T} T{ T} T{ @@ -66061,6 +69474,8 @@ Yes T} _ .TE +.sp +[1] Yes, if salt\-api is enabled. .SS Tutorials .SS Salt Cloud Quickstart .sp @@ -66648,7 +70063,7 @@ def __virtual__(): Only work on proxy \(aq\(aq\(aq try: - if salt.utils.is_proxy() and \e + if salt.utils.platform.is_proxy() and \e __opts__[\(aqproxy\(aq][\(aqproxytype\(aq] == \(aqssh_sample\(aq: return __virtualname__ except KeyError: @@ -66721,18 +70136,22 @@ will need to be restarted to pick up any changes. A corresponding utility funct \fBsaltutil.sync_proxymodules\fP, has been added to sync these modules to minions. .sp In addition, a salt.utils helper function called \fIis_proxy()\fP was added to make -it easier to tell when the running minion is a proxy minion. +it easier to tell when the running minion is a proxy minion. \fBNOTE: This +function was renamed to salt.utils.platform.is_proxy() for the 2018.3.0 +release\fP .SS New in 2015.8 .sp -Starting with the 2015.8 release of Salt, proxy processes are no longer forked off from a controlling minion. -Instead, they have their own script \fBsalt\-proxy\fP which takes mostly the same arguments that the -standard Salt minion does with the addition of \fB\-\-proxyid\fP\&. This is the id that the salt\-proxy will -use to identify itself to the master. Proxy configurations are still best kept in Pillar and their format -has not changed. +Starting with the 2015.8 release of Salt, proxy processes are no longer forked +off from a controlling minion. Instead, they have their own script +\fBsalt\-proxy\fP which takes mostly the same arguments that the standard Salt +minion does with the addition of \fB\-\-proxyid\fP\&. This is the id that the +salt\-proxy will use to identify itself to the master. Proxy configurations are +still best kept in Pillar and their format has not changed. .sp -This change allows for better process control and logging. Proxy processes can now be listed with standard -process management utilities (\fBps\fP from the command line). Also, a full Salt minion is no longer -required (though it is still strongly recommended) on machines hosting proxies. +This change allows for better process control and logging. Proxy processes can +now be listed with standard process management utilities (\fBps\fP from the +command line). Also, a full Salt minion is no longer required (though it is +still strongly recommended) on machines hosting proxies. .SS Getting Started .sp The following diagram may be helpful in understanding the structure of a Salt @@ -67219,9 +70638,10 @@ in the proxymodule itself. This might be useful if a proxymodule author wants t all the code for the proxy interface in the same place instead of splitting it between the proxy and grains directories. .sp -This function will only be called automatically if the configuration variable \fBproxy_merge_grains_in_module\fP -is set to True in the proxy configuration file (default \fB/etc/salt/proxy\fP). This -variable defaults to \fBTrue\fP in the release code\-named \fI2017.7.0\fP\&. +This function will only be called automatically if the configuration variable +\fBproxy_merge_grains_in_module\fP is set to True in the proxy configuration file +(default \fB/etc/salt/proxy\fP). This variable defaults to \fBTrue\fP in the +release code\-named \fI2017.7.0\fP\&. .SS The __proxyenabled__ directive .sp In previous versions of Salt the \fB__proxyenabled__\fP directive controlled @@ -67252,7 +70672,7 @@ __virtualname__ = \(aqrest_sample\(aq def __virtual__(): try: - if salt.utils.is_proxy() and __opts__[\(aqproxy\(aq][\(aqproxytype\(aq] == \(aqrest_sample\(aq: + if salt.utils.platform.is_proxy() and __opts__[\(aqproxy\(aq][\(aqproxytype\(aq] == \(aqrest_sample\(aq: return __virtualname__ except KeyError: pass @@ -67456,7 +70876,7 @@ an api over HTTP and doesn\(aqt have the python stack to run a minion. from __future__ import absolute_import # Import python libs -import json +import salt.utils.json import logging # Import Salt\(aqs libs @@ -67524,7 +70944,7 @@ def parse(out): jsonret.append(ln_) if \(aq}\(aq in ln_: in_json = False - return json.loads(\(aq\en\(aq.join(jsonret)) + return salt.utils.json.loads(\(aq\en\(aq.join(jsonret)) def package_list(): @@ -68541,6 +71961,879 @@ Salt Proxy Minion End\-to\-End Example .IP \(bu 2 \fBvSphere Execution Module\fP .UNINDENT +.SH NETWORK AUTOMATION +.sp +Network automation is a continuous process of automating the configuration, +management and operations of a computer network. Although the abstraction +could be compared with the operations on the server side, there are many particular +challenges, the most important being that a network device is traditionally +closed hardware able to run proprietary software only. In other words, +the user is not able to install the salt\-minion package directly on a +traditional network device. For these reasons, most network devices can be +controlled only remotely via proxy minions or +using the Salt SSH\&. However, there are also vendors producing +whitebox equipment (e.g. Arista, Cumulus) or others that have moved the +operating system in the container (e.g. Cisco NX\-OS, Cisco IOS\-XR), +allowing the salt\-minion to be installed directly on the platform. +.SS New in Carbon (2016.11) +.sp +The methodologies for network automation have been introduced in +Carbon based on proxy +minions: +.INDENT 0.0 +.IP \(bu 2 +\fBNAPALM proxy\fP +.IP \(bu 2 +\fBJunos proxy\fP +.IP \(bu 2 +\fBCisco NXOS\fP +.IP \(bu 2 +\fBCisco NOS\fP +.UNINDENT +.SS NAPALM +.sp +NAPALM (Network Automation and Programmability Abstraction Layer with +Multivendor support) is an opensourced Python library that implements a set of +functions to interact with different router vendor devices using a unified API. +Begin vendor\-agnostic simplifies the operations, as the configuration +and the interaction with the network device does not rely on a particular vendor. +[image] +.sp +Beginning with 2017.7.0, the NAPALM modules have been transformed so they can +run in both proxy and regular minions. That means, if the operating system +allows, the salt\-minion package can be installed directly on the network gear. +The interface between the network operating system and Salt in that case would +be the corresponding NAPALM sub\-package. +.sp +For example, if the user installs the +salt\-minion on a Arista switch, the only requirement is +\fI\%napalm\-eos\fP\&. +.sp +The following modules are available in 2017.7.0: +.INDENT 0.0 +.IP \(bu 2 +\fBNAPALM grains\fP +.IP \(bu 2 +\fBNET execution module\fP \- Networking basic +features +.IP \(bu 2 +\fBNTP execution module\fP +.IP \(bu 2 +\fBBGP execution module\fP +.IP \(bu 2 +\fBRoutes execution module\fP +.IP \(bu 2 +\fBSNMP execution module\fP +.IP \(bu 2 +\fBUsers execution module\fP +.IP \(bu 2 +\fBProbes execution module\fP +.IP \(bu 2 +\fBNTP peers management state\fP +.IP \(bu 2 +\fBSNMP configuration management state\fP +.IP \(bu 2 +\fBUsers management state\fP +.IP \(bu 2 +\fBNetconfig state module\fP \- Manage the configuration +of network devices using arbitrary templates and the Salt\-specific +advanced templating methodologies. +.IP \(bu 2 +\fBNetwork ACL execution module\fP \- Generate and +load ACL (firewall) configuration on network devices. +.IP \(bu 2 +\fBNetwork ACL state\fP \- Manage the firewall +configuration. It only requires writing the pillar structure correctly! +.IP \(bu 2 +\fBNAPALM YANG execution module\fP \- Parse, +generate and load native device configuration in a standard way, +using the OpenConfig/IETF models. This module contains also helpers for +the states. +.IP \(bu 2 +\fBNAPALM YANG state module\fP \- Manage the +network device configuration according to the YANG models (OpenConfig or IETF). +.IP \(bu 2 +\fBNET finder\fP \- Runner to find details easily and +fast. It\(aqs smart enough to know what you are looking for. It will search +in the details of the network interfaces, IP addresses, MAC address tables, +ARP tables and LLDP neighbors. +.IP \(bu 2 +\fBBGP finder\fP \- Runner to search BGP neighbors details. +.IP \(bu 2 +\fBNAPALM syslog\fP \- Engine to import events +from the napalm\-logs library into the Salt event bus. The events are based +on the syslog messages from the network devices and structured following +the OpenConfig/IETF YANG models. +.IP \(bu 2 +\fBNAPALM Helpers\fP \- Generic helpers for +NAPALM\-related operations. For example, the +\fBCompliance report\fP function +can be used inside the state modules to compare the expected and the +existing configuration. +.UNINDENT +.SS Getting started +.sp +Install NAPALM \- follow the \fI\%notes\fP and check the platform\-specific \fI\%dependencies\fP\&. +.sp +Salt\(aqs Pillar system is ideally suited for configuring proxy\-minions +(though they can be configured in /etc/salt/proxy as well). Proxies +can either be designated via a pillar file in \fBpillar_roots\fP, +or through an external pillar. +External pillars afford the opportunity for interfacing with +a configuration management system, database, or other knowledgeable system +that may already contain all the details of proxy targets. To use static files +in \fBpillar_roots\fP, pattern your files after the following examples: +.sp +\fB/etc/salt/pillar/top.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +base: + router1: + \- router1 + router2: + \- router2 + switch1: + \- swtich1 + swtich2: + \- switch2 + cpe1: + \- cpe1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fB/etc/salt/pillar/router1.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +proxy: + proxytype: napalm + driver: junos + host: r1.bbone.as1234.net + username: my_username + password: my_password +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fB/etc/salt/pillar/router2.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +proxy: + proxytype: napalm + driver: iosxr + host: r2.bbone.as1234.net + username: my_username + password: my_password + optional_args: + port: 22022 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fB/etc/salt/pillar/switch1.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +proxy: + proxytype: napalm + driver: eos + host: sw1.bbone.as1234.net + username: my_username + password: my_password + optional_args: + enable_password: my_secret +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fB/etc/salt/pillar/switch2.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +proxy: + proxytype: napalm + driver: nxos + host: sw2.bbone.as1234.net + username: my_username + password: my_password +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fB/etc/salt/pillar/cpe1.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +proxy: + proxytype: napalm + driver: ios + host: cpe1.edge.as1234.net + username: \(aq\(aq + password: \(aq\(aq + optional_args: + use_keys: True + auto_rollback_on_error: True +.ft P +.fi +.UNINDENT +.UNINDENT +.SS CLI examples +.sp +Display the complete running configuration on \fBrouter1\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aqrouter1\(aq net.config source=\(aqrunning\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Retrieve the NTP servers configured on all devices: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aq*\(aq ntp.servers +router1: + \-\-\-\-\-\-\-\-\-\- + comment: + out: + \- 1.2.3.4 + result: + True +cpe1: + \-\-\-\-\-\-\-\-\-\- + comment: + out: + \- 1.2.3.4 + result: + True +switch2: + \-\-\-\-\-\-\-\-\-\- + comment: + out: + \- 1.2.3.4 + result: + True +router2: + \-\-\-\-\-\-\-\-\-\- + comment: + out: + \- 1.2.3.4 + result: + True +switch1: + \-\-\-\-\-\-\-\-\-\- + comment: + out: + \- 1.2.3.4 + result: + True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Display the ARP tables on all Cisco devices running IOS\-XR 5.3.3: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \-G \(aqos:iosxr and version:5.3.3\(aq net.arp +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Return operational details for interfaces from Arista switches: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \-C \(aqsw* and os:eos\(aq net.interfaces +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Execute traceroute from the edge of the network: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aqrouter*\(aq net.traceroute 8.8.8.8 vrf=\(aqCUSTOMER1\-VRF\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Verbatim display from the CLI of Juniper routers: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \-C \(aqrouter* and G@os:junos\(aq net.cli \(aqshow version and haiku\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Retrieve the results of the RPM probes configured on Juniper MX960 routers: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \-C \(aqrouter* and G@os:junos and G@model:MX960\(aq probes.results +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Return the list of configured users on the CPEs: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aqcpe*\(aq users.config +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Using the \fBBGP finder\fP, return the list of BGP neighbors +that are down: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt\-run bgp.neighbors up=False +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Using the \fBNET finder\fP, determine the devices containing +the pattern "PX\-1234\-LHR" in their interface description: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt\-run net.find PX\-1234\-LHR +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Cross\-platform configuration management example: NTP +.sp +Assuming that the user adds the following two lines under +\fBfile_roots\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +file_roots: + base: + \- /etc/salt/pillar/ + \- /etc/salt/templates/ + \- /etc/salt/states/ +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Define the list of NTP peers and servers wanted: +.sp +\fB/etc/salt/pillar/ntp.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ntp.servers: + \- 1.2.3.4 + \- 5.6.7.8 +ntp.peers: + \- 10.11.12.13 + \- 14.15.16.17 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Include the new file: for example, if we want to have the same NTP servers on all +network devices, we can add the following line inside the \fBtop.sls\fP file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +\(aq*\(aq: + \- ntp +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fB/etc/salt/pillar/top.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +base: + \(aq*\(aq: + \- ntp + router1: + \- router1 + router2: + \- router2 + switch1: + \- swtich1 + swtich2: + \- switch2 + cpe1: + \- cpe1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Or include only where needed: +.sp +\fB/etc/salt/pillar/top.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +base: + router1: + \- router1 + \- ntp + router2: + \- router2 + \- ntp + switch1: + \- swtich1 + swtich2: + \- switch2 + cpe1: + \- cpe1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Define the cross\-vendor template: +.sp +\fB/etc/salt/templates/ntp.jinja\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{%\- if grains.vendor|lower == \(aqcisco\(aq %} + no ntp + {%\- for server in servers %} + ntp server {{ server }} + {%\- endfor %} + {%\- for peer in peers %} + ntp peer {{ peer }} + {%\- endfor %} +{%\- elif grains.os|lower == \(aqjunos\(aq %} + system { + replace: + ntp { + {%\- for server in servers %} + server {{ server }}; + {%\- endfor %} + {%\- for peer in peers %} + peer {{ peer }}; + {%\- endfor %} + } + } +{%\- endif %} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Define the SLS state file, making use of the +\fBNetconfig state module\fP: +.sp +\fB/etc/salt/states/router/ntp.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ntp_config_example: + netconfig.managed: + \- template_name: salt://ntp.jinja + \- peers: {{ pillar.get(\(aqntp.peers\(aq, []) | json }} + \- servers: {{ pillar.get(\(aqntp.servers\(aq, []) | json }} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Run the state and assure NTP configuration consistency across your +multi\-vendor network: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aqrouter*\(aq state.sls router.ntp +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Besides CLI, the state can be scheduled or executed when triggered by a certain +event. +.SS JUNOS +.sp +Juniper has developed a Junos specific proxy infrastructure which allows +remote execution and configuration management of Junos devices without +having to install SaltStack on the device. The infrastructure includes: +.INDENT 0.0 +.IP \(bu 2 +\fBJunos proxy\fP +.IP \(bu 2 +\fBJunos execution module\fP +.IP \(bu 2 +\fBJunos state module\fP +.IP \(bu 2 +\fBJunos syslog engine\fP +.UNINDENT +.sp +The execution and state modules are implemented using junos\-eznc (PyEZ). +Junos PyEZ is a microframework for Python that enables you to remotely manage +and automate devices running the Junos operating system. +.SS Getting started +.sp +Install PyEZ on the system which will run the Junos proxy minion. +It is required to run Junos specific modules. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pip install junos\-eznc +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Next, set the master of the proxy minions. +.sp +\fB/etc/salt/proxy\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +master: +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Add the details of the Junos device. Device details are usually stored in +salt pillars. If the you do not wish to store credentials in the pillar, +one can setup passwordless ssh. +.sp +\fB/srv/pillar/vmx_details.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +proxy: + proxytype: junos + host: + username: user + passwd: secret123 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Map the pillar file to the proxy minion. This is done in the top file. +.sp +\fB/srv/pillar/top.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +base: + vmx: + \- vmx_details +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Before starting the Junos proxy make sure that netconf is enabled on the +Junos device. This can be done by adding the following configuration on +the Junos device. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +set system services netconf ssh +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Start the salt master. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-master \-l debug +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Then start the salt proxy. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-proxy \-\-proxyid=vmx \-l debug +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Once the master and junos proxy minion have started, we can run execution +and state modules on the proxy minion. Below are few examples. +.SS CLI examples +.sp +For detailed documentation of all the junos execution modules refer: +\fBJunos execution module\fP +.sp +Display device facts. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aqvmx\(aq junos.facts +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Refresh the Junos facts. This function will also refresh the facts which are +stored in salt grains. (Junos proxy stores Junos facts in the salt grains) +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aqvmx\(aq junos.facts_refresh +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Call an RPC. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aqvmx\(aq junos.rpc \(aqget\-interface\-information\(aq \(aq/var/log/interface\-info.txt\(aq terse=True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Install config on the device. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aqvmx\(aq junos.install_config \(aqsalt://my_config.set\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Shutdown the junos device. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ sudo salt \(aqvmx\(aq junos.shutdown shutdown=True in_min=10 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS State file examples +.sp +For detailed documentation of all the junos state modules refer: +\fBJunos state module\fP +.sp +Executing an RPC on Junos device and storing the output in a file. +.sp +\fB/srv/salt/rpc.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +get\-interface\-information: + junos: + \- rpc + \- dest: /home/user/rpc.log + \- interface_name: lo0 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Lock the junos device, load the configuration, commit it and unlock +the device. +.sp +\fB/srv/salt/load.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lock the config: + junos.lock + +salt://configs/my_config.set: + junos: + \- install_config + \- timeout: 100 + \- diffs_file: \(aqvar/log/diff\(aq + +commit the changes: + junos: + \- commit + +unlock the config: + junos.unlock +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +According to the device personality install appropriate image on the device. +.sp +\fB/srv/salt/image_install.sls\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{% if grains[\(aqjunos_facts\(aq][\(aqpersonality\(aq] == MX %} +salt://images/mx_junos_image.tgz: + junos: + \- install_os + \- timeout: 100 + \- reboot: True +{% elif grains[\(aqjunos_facts\(aq][\(aqpersonality\(aq] == EX %} +salt://images/ex_junos_image.tgz: + junos: + \- install_os + \- timeout: 150 +{% elif grains[\(aqjunos_facts\(aq][\(aqpersonality\(aq] == SRX %} +salt://images/srx_junos_image.tgz: + junos: + \- install_os + \- timeout: 150 +{% endif %} +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Junos Syslog Engine +.sp +\fBJunos Syslog Engine\fP is a Salt engine +which receives data from various Junos devices, extracts event information and +forwards it on the master/minion event bus. To start the engine on the salt +master, add the following configuration in the master config file. +The engine can also run on the salt minion. +.sp +\fB/etc/salt/master\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +engines: + \- junos_syslog: + port: xxx +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +For junos_syslog engine to receive events, syslog must be set on the Junos device. +This can be done via following configuration: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +set system syslog host port xxx any any +.ft P +.fi +.UNINDENT +.UNINDENT .SH SALT VIRT .sp The Salt Virt cloud controller capability was initially added to Salt in @@ -69593,7 +73886,7 @@ minions to execute on. .B \-a EAUTH, \-\-auth=EAUTH Pass in an external authentication medium to validate against. The credentials will be prompted for. The options are \fIauto\fP, -\fIkeystone\fP, \fIldap\fP, \fIpam\fP, and \fIstormpath\fP\&. Can be used with the \-T +\fIkeystone\fP, \fIldap\fP, and \fIpam\fP\&. Can be used with the \-T option. .UNINDENT .INDENT 0.0 @@ -71379,12 +75672,6 @@ Provide authentication using configured shared secret T} _ T{ -\fBstormpath\fP -T} T{ -Provide authentication using Stormpath. -T} -_ -T{ \fByubico\fP T} T{ Provide authentication using YubiKey. @@ -71946,37 +76233,6 @@ New in version Beryllium. .B salt.auth.sharedsecret.auth(username, sharedsecret, **kwargs) Shared secret authentication .UNINDENT -.SS salt.auth.stormpath -.sp -Provide authentication using Stormpath. -.sp -This driver requires some extra configuration beyond that which Stormpath -normally requires. -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -stormpath: - apiid: 1234567890 - apikey: 1234567890/ABCDEF - # Can use an application ID - application: 6789012345 - # Or can use a directory ID - directory: 3456789012 - # But not both -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -New in version 2015.8.0. - -.INDENT 0.0 -.TP -.B salt.auth.stormpath.auth(username, password) -Authenticate using a Stormpath directory or application -.UNINDENT .SS salt.auth.yubico .sp Provide authentication using YubiKey. @@ -72112,6 +76368,12 @@ Beacon to monitor memory usage. T} _ T{ +\fBnapalm_beacon\fP +T} T{ +NAPALM functions +T} +_ +T{ \fBnetwork_info\fP T} T{ Beacon to monitor statistics from ethernet adapters @@ -72138,7 +76400,7 @@ _ T{ \fBps\fP T} T{ -Send events covering service status +Send events covering process status T} _ T{ @@ -72222,6 +76484,11 @@ beacons: .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.adb.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.avahi_announce module .sp Beacon to announce via avahi (zeroconf) @@ -72306,18 +76573,23 @@ Example Config .ft C beacons: avahi_announce: - run_once: True - servicetype: _demo._tcp - port: 1234 - txt: - ProdName: grains.productname - SerialNo: grains.serialnumber - Comments: \(aqthis is a test\(aq + \- run_once: True + \- servicetype: _demo._tcp + \- port: 1234 + \- txt: + ProdName: grains.productname + SerialNo: grains.serialnumber + Comments: \(aqthis is a test\(aq .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.avahi_announce.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.bonjour_announce module .sp Beacon to announce via Bonjour (zeroconf) @@ -72392,18 +76664,23 @@ Example Config .ft C beacons: bonjour_announce: - run_once: True - servicetype: _demo._tcp - port: 1234 - txt: - ProdName: grains.productname - SerialNo: grains.serialnumber - Comments: \(aqthis is a test\(aq + \- run_once: True + \- servicetype: _demo._tcp + \- port: 1234 + \- txt: + ProdName: grains.productname + SerialNo: grains.serialnumber + Comments: \(aqthis is a test\(aq .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.bonjour_announce.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.btmp .sp Beacon to fire events at failed login of users @@ -72413,7 +76690,7 @@ Beacon to fire events at failed login of users .nf .ft C beacons: - btmp: {} + btmp: [] .ft P .fi .UNINDENT @@ -72428,12 +76705,38 @@ Read the last btmp file and return information on the failed logins .nf .ft C beacons: - btmp: {} + btmp: [] + +beacons: + btmp: + \- users: + gareth: + \- defaults: + time_range: + start: \(aq8am\(aq + end: \(aq4pm\(aq + +beacons: + btmp: + \- users: + gareth: + time_range: + start: \(aq8am\(aq + end: \(aq4pm\(aq + \- defaults: + time_range: + start: \(aq8am\(aq + end: \(aq4pm\(aq .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.btmp.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.diskusage .sp Beacon to monitor disk usage. @@ -72504,6 +76807,11 @@ Note that if a regular expression are evaluated after static mount points, which means that if a regular expression matches an other defined mount point, it will override the previously defined threshold. .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.diskusage.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.glxinfo module .sp Beacon to emit when a display is available to a linux machine @@ -72515,7 +76823,8 @@ New in version 2016.3.0. .B salt.beacons.glxinfo.beacon(config) Emit the status of a connected display to the minion .sp -Mainly this is used to detect when the display fails to connect for whatever reason. +Mainly this is used to detect when the display fails to connect +for whatever reason. .INDENT 7.0 .INDENT 3.5 .sp @@ -72523,13 +76832,18 @@ Mainly this is used to detect when the display fails to connect for whatever rea .ft C beacons: glxinfo: - user: frank - screen_event: True + \- user: frank + \- screen_event: True .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.glxinfo.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.haproxy module .sp Watch current connections of haproxy server backends. @@ -72549,17 +76863,23 @@ is over a defined threshold. .ft C beacons: haproxy: - \- www\-backend: - threshold: 45 - servers: - \- web1 - \- web2 + \- backends: + www\-backend: + threshold: 45 + servers: + \- web1 + \- web2 \- interval: 120 .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.haproxy.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.inotify .sp Watch files and translate the changes into salt events @@ -72579,8 +76899,8 @@ setting the \fIdisable_during_state_run\fP flag to \fITrue\fP in the beacon configuration. .TP .B note -The \fIinotify\fP beacon only works on OSes that have \fIinotify\fP kernel support. -Currently this excludes FreeBSD, macOS, and Windows. +The \fIinotify\fP beacon only works on OSes that have \fIinotify\fP +kernel support. Currently this excludes FreeBSD, macOS, and Windows. .UNINDENT .INDENT 0.0 .TP @@ -72595,19 +76915,20 @@ Example Config .ft C beacons: inotify: - /path/to/file/or/dir: - mask: - \- open - \- create - \- close_write - recurse: True - auto_add: True - exclude: - \- /path/to/file/or/dir/exclude1 - \- /path/to/file/or/dir/exclude2 - \- /path/to/file/or/dir/regex[a\-m]*$: - regex: True - coalesce: True + \- files: + /path/to/file/or/dir: + mask: + \- open + \- create + \- close_write + recurse: True + auto_add: True + exclude: + \- /path/to/file/or/dir/exclude1 + \- /path/to/file/or/dir/exclude2 + \- /path/to/file/or/dir/regex[a\-m]*$: + regex: True + \- coalesce: True .ft P .fi .UNINDENT @@ -72676,6 +76997,11 @@ affects all paths that are being watched. This is due to this option being at the Notifier level in pyinotify. .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.inotify.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.journald .sp A simple beacon to watch journald for specific entries @@ -72693,14 +77019,20 @@ This beacons config will return all sshd jornal entries .ft C beacons: journald: - sshd: - SYSLOG_IDENTIFIER: sshd - PRIORITY: 6 + \- services: + sshd: + SYSLOG_IDENTIFIER: sshd + PRIORITY: 6 .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.journald.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.load .sp Beacon to emit system load averages @@ -72729,22 +77061,28 @@ The default is True. .ft C beacons: load: - 1m: - \- 0.0 - \- 2.0 - 5m: - \- 0.0 - \- 1.5 - 15m: - \- 0.1 - \- 1.0 - emitatstartup: True - onchangeonly: False + \- averages: + 1m: + \- 0.0 + \- 2.0 + 5m: + \- 0.0 + \- 1.5 + 15m: + \- 0.1 + \- 1.0 + \- emitatstartup: True + \- onchangeonly: False .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.load.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.log module .sp Beacon to fire events at specific log messages. @@ -72762,14 +77100,20 @@ Read the log file and return match whole string .ft C beacons: log: - file: - : - regex: + \- file: + \- tags: + : + regex: .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.log.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.memusage module .sp Beacon to monitor memory usage. @@ -72786,7 +77130,8 @@ python\-psutil .B salt.beacons.memusage.beacon(config) Monitor the memory usage of the minion .sp -Specify thresholds for percent used and only emit a beacon if it is exceeded. +Specify thresholds for percent used and only emit a beacon +if it is exceeded. .INDENT 7.0 .INDENT 3.5 .sp @@ -72800,6 +77145,229 @@ beacons: .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.memusage.validate(config) +Validate the beacon configuration +.UNINDENT +.SS salt.beacons.napalm_beacon +.SS NAPALM functions +.sp +New in version 2018.3.0. + +.sp +Watch NAPALM functions and fire events on specific triggers. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +The \fBNAPALM\fP beacon only works only when running under +a regular Minion or a Proxy Minion, managed via +.nf +NAPALM_ +.fi +\&. +Check the documentation for the +\fBNAPALM proxy module\fP\&. +.sp +_NAPALM: \fI\%http://napalm.readthedocs.io/en/latest/index.html\fP +.UNINDENT +.UNINDENT +.sp +The configuration accepts a list of Salt functions to be +invoked, and the corresponding output hierarchy that should +be matched against. To invoke a function with certain +arguments, they can be specified using the \fB_args\fP key, or +\fB_kwargs\fP for more specific key\-value arguments. +.sp +The match structure follows the output hierarchy of the NAPALM +functions, under the \fBout\fP key. +.sp +For example, the following is normal structure returned by the +\fBntp.stats\fP execution function: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{ + "comment": "", + "result": true, + "out": [ + { + "referenceid": ".GPSs.", + "remote": "172.17.17.1", + "synchronized": true, + "reachability": 377, + "offset": 0.461, + "when": "860", + "delay": 143.606, + "hostpoll": 1024, + "stratum": 1, + "jitter": 0.027, + "type": "\-" + }, + { + "referenceid": ".INIT.", + "remote": "172.17.17.2", + "synchronized": false, + "reachability": 0, + "offset": 0.0, + "when": "\-", + "delay": 0.0, + "hostpoll": 1024, + "stratum": 16, + "jitter": 4000.0, + "type": "\-" + } + ] +} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +In order to fire events when the synchronization is lost with +one of the NTP peers, e.g., \fB172.17.17.2\fP, we can match it explicitly as: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ntp.stats: + remote: 172.17.17.2 + synchronized: false +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +There is one single nesting level, as the output of \fBntp.stats\fP is +just a list of dictionaries, and this beacon will compare each dictionary +from the list with the structure examplified above. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +When we want to match on any element at a certain level, we can +configure \fB*\fP to match anything. +.UNINDENT +.UNINDENT +.sp +Considering a more complex structure consisting on multiple nested levels, +e.g., the output of the \fBbgp.neighbors\fP +execution function, to check when any neighbor from the \fBglobal\fP +routing table is down, the match structure would have the format: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +bgp.neighbors: + global: + \(aq*\(aq: + up: false +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The match structure above will match any BGP neighbor, with +any network (\fB*\fP matches any AS number), under the \fBglobal\fP VRF. +In other words, this beacon will push an event on the Salt bus +when there\(aqs a BGP neighbor down. +.sp +The right operand can also accept mathematical operations +(i.e., \fB<\fP, \fB<=\fP, \fB!=\fP, \fB>\fP, \fB>=\fP etc.) when comparing +numerical values. +.sp +Configuration Example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + napalm: + \- net.interfaces: + # fire events when any interfaces is down + \(aq*\(aq: + is_up: false + \- net.interfaces: + # fire events only when the xe\-0/0/0 interface is down + \(aqxe\-0/0/0\(aq: + is_up: false + \- ntp.stats: + # fire when there\(aqs any NTP peer unsynchornized + synchronized: false + \- ntp.stats: + # fire only when the synchronization + # with with the 172.17.17.2 NTP server is lost + _args: + \- 172.17.17.2 + synchronized: false + \- ntp.stats: + # fire only when there\(aqs a NTP peer with + # synchronization stratum > 5 + stratum: \(aq> 5\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Event structure example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt/beacon/edge01.bjm01/napalm/junos/ntp.stats { + "_stamp": "2017\-09\-05T09:51:09.377202", + "args": [], + "data": { + "comment": "", + "out": [ + { + "delay": 0.0, + "hostpoll": 1024, + "jitter": 4000.0, + "offset": 0.0, + "reachability": 0, + "referenceid": ".INIT.", + "remote": "172.17.17.1", + "stratum": 16, + "synchronized": false, + "type": "\-", + "when": "\-" + } + ], + "result": true + }, + "fun": "ntp.stats", + "id": "edge01.bjm01", + "kwargs": {}, + "match": { + "stratum": "> 5" + } +} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The event examplified above has been fired when the device +identified by the Minion id \fBedge01.bjm01\fP has been synchronized +with a NTP server at a stratum level greater than 5. +.INDENT 0.0 +.TP +.B salt.beacons.napalm_beacon.beacon(config) +Watch napalm function and fire events. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.napalm_beacon.validate(config) +Validate the beacon configuration. +.UNINDENT .SS salt.beacons.network_info .sp Beacon to monitor statistics from ethernet adapters @@ -72824,16 +77392,17 @@ configured values. .ft C beacons: network_info: - eth0: - \- type: equal - \- bytes_sent: 100000 - \- bytes_recv: 100000 - \- packets_sent: 100000 - \- packets_recv: 100000 - \- errin: 100 - \- errout: 100 - \- dropin: 100 - \- dropout: 100 + \- interfaces: + eth0: + type: equal + bytes_sent: 100000 + bytes_recv: 100000 + packets_sent: 100000 + packets_recv: 100000 + errin: 100 + errout: 100 + dropin: 100 + dropout: 100 .ft P .fi .UNINDENT @@ -72848,21 +77417,27 @@ than configured values. .ft C beacons: network_info: - eth0: - \- type: greater - \- bytes_sent: 100000 - \- bytes_recv: 100000 - \- packets_sent: 100000 - \- packets_recv: 100000 - \- errin: 100 - \- errout: 100 - \- dropin: 100 - \- dropout: 100 + \- interfaces: + eth0: + type: greater + bytes_sent: 100000 + bytes_recv: 100000 + packets_sent: 100000 + packets_recv: 100000 + errin: 100 + errout: 100 + dropin: 100 + dropout: 100 .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.network_info.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.network_settings .sp Beacon to monitor network adapter setting changes on Linux @@ -72881,8 +77456,8 @@ Watch for changes on network settings .sp By default, the beacon will emit when there is a value change on one of the settings on watch. The config also support the onvalue parameter for each -setting, which instruct the beacon to only emit if the setting changed to the -value defined. +setting, which instruct the beacon to only emit if the setting changed to +the value defined. .sp Example Config .INDENT 7.0 @@ -72892,12 +77467,13 @@ Example Config .ft C beacons: network_settings: - eth0: - ipaddr: - promiscuity: - onvalue: 1 - eth1: - linkmode: + \- interfaces: + \- eth0: + ipaddr: + promiscuity: + onvalue: 1 + \- eth1: + linkmode: .ft P .fi .UNINDENT @@ -72918,15 +77494,21 @@ The example below shows how to trigger coalesced results: .ft C beacons: network_settings: - coalesce: True - eth0: - ipaddr: - promiscuity: + \- coalesce: True + \- interfaces: + \- eth0: + ipaddr: + promiscuity: .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.network_settings.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.pkg .sp Watch for pkgs that have upgrades, then fire an event. @@ -72954,6 +77536,11 @@ beacons: .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.pkg.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.proxy_example module .sp Example beacon to use with salt\-proxy @@ -72981,15 +77568,20 @@ Called several times each second .ft C beacons: proxy_example: - endpoint: beacon + \- endpoint: beacon .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.proxy_example.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.ps module .sp -Send events covering service status +Send events covering process status .INDENT 0.0 .TP .B salt.beacons.ps.beacon(config) @@ -73003,8 +77595,9 @@ Example Config .ft C beacons: ps: - salt\-master: running - mysql: stopped + \- processes: + salt\-master: running + mysql: stopped .ft P .fi .UNINDENT @@ -73013,6 +77606,11 @@ beacons: The config above sets up beacons to check that processes are running or stopped. .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.ps.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.salt_proxy module .sp Beacon to manage and report the status of @@ -73022,7 +77620,7 @@ New in version 2015.8.3. .INDENT 0.0 .TP -.B salt.beacons.salt_proxy.beacon(proxies) +.B salt.beacons.salt_proxy.beacon(config) Handle configured proxies .INDENT 7.0 .INDENT 3.5 @@ -73031,13 +77629,19 @@ Handle configured proxies .ft C beacons: salt_proxy: - \- p8000: {} - \- p8001: {} + \- proxies: + p8000: {} + p8001: {} .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.salt_proxy.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.sensehat module .sp Beacon to monitor temperature, humidity and pressure using the SenseHat @@ -73077,15 +77681,21 @@ Units: .ft C beacons: sensehat: - humidity: 70% - temperature: [20, 40] - temperature_from_pressure: 40 - pressure: 1500 + \- sensors: + humidity: 70% + temperature: [20, 40] + temperature_from_pressure: 40 + pressure: 1500 .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.sensehat.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.service .sp Send events covering service status @@ -73102,8 +77712,9 @@ Example Config .ft C beacons: service: - salt\-master: - mysql: + \- services: + salt\-master: + mysql: .ft P .fi .UNINDENT @@ -73118,6 +77729,10 @@ The config also supports two other parameters for each service: events only when the service status changes. Otherwise, it will fire an event at each beacon interval. The default is False. .sp +\fIdelay\fP: when \fIdelay\fP is greater than 0 the beacon will fire events only +after the service status changes, and the delay (in seconds) has passed. +Applicable only when \fIonchangeonly\fP is True. The default is 0. +.sp \fIemitatstartup\fP: when \fIemitatstartup\fP is False the beacon will not fire event when the minion is reload. Applicable only when \fIonchangeonly\fP is True. The default is True. @@ -73138,7 +77753,7 @@ file is observed as removed when kill \-9 is sent to the nginx master process). The \(aquncleanshutdown\(aq option might not be of much use there, unless the unit file is modified. .sp -Here is an example that will fire an event whenever the state of nginx +Here is an example that will fire an event 30 seconds after the state of nginx changes and report an uncleanshutdown. This example is for Arch, which places nginx\(aqs pid file in \fI/run\fP\&. .INDENT 7.0 @@ -73148,14 +77763,21 @@ places nginx\(aqs pid file in \fI/run\fP\&. .ft C beacons: service: - nginx: - onchangeonly: True - uncleanshutdown: /run/nginx.pid + \- services: + nginx: + onchangeonly: True + delay: 30 + uncleanshutdown: /run/nginx.pid .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.service.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.sh .sp Watch the shell commands being executed actively. This beacon requires strace. @@ -73169,12 +77791,17 @@ Scan the shell execve routines. This beacon will convert all login shells .nf .ft C beacons: - sh: {} + sh: [] .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.sh.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.status module .sp The status beacon is intended to send a basic health check event up to the @@ -73195,7 +77822,7 @@ the minion config: .nf .ft C beacons: - status: {} + status: [] .ft P .fi .UNINDENT @@ -73320,9 +77947,16 @@ to check the minion log for errors after configuring this beacon. .B salt.beacons.status.beacon(config) Return status for requested information .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.status.validate(config) +Validate the the config is a dict +.UNINDENT .SS salt.beacons.telegram_bot_msg .sp Beacon to emit Telegram messages +.sp +Requires the python\-telegram\-bot library .INDENT 0.0 .TP .B salt.beacons.telegram_bot_msg.beacon(config) @@ -73335,15 +77969,20 @@ sent to the configured bot by one of the allowed usernames. .ft C beacons: telegram_bot_msg: - token: "" - accept_from: + \- token: "" + \- accept_from: \- "" - interval: 10 + \- interval: 10 .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.telegram_bot_msg.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.twilio_txt_msg .sp Beacon to emit Twilio text messages @@ -73359,15 +77998,20 @@ of texts. .ft C beacons: twilio_txt_msg: - account_sid: "" - auth_token: "" - twilio_number: "+15555555555" - interval: 10 + \- account_sid: "" + \- auth_token: "" + \- twilio_number: "+15555555555" + \- interval: 10 .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.twilio_txt_msg.validate(config) +Validate the beacon configuration +.UNINDENT .SS salt.beacons.wtmp .sp Beacon to fire events at login of users as registered in the wtmp file @@ -73377,7 +78021,7 @@ Beacon to fire events at login of users as registered in the wtmp file .nf .ft C beacons: - wtmp: {} + wtmp: [] .ft P .fi .UNINDENT @@ -73392,12 +78036,38 @@ Read the last wtmp file and return information on the logins .nf .ft C beacons: - wtmp: {} + wtmp: [] + +beacons: + wtmp: + \- users: + gareth: + \- defaults: + time_range: + start: \(aq8am\(aq + end: \(aq4pm\(aq + +beacons: + wtmp: + \- users: + gareth: + time_range: + start: \(aq8am\(aq + end: \(aq4pm\(aq + \- defaults: + time_range: + start: \(aq8am\(aq + end: \(aq4pm\(aq .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.beacons.wtmp.validate(config) +Validate the beacon configuration +.UNINDENT .SS cache modules .TS center; @@ -73627,6 +78297,24 @@ The hostname of the Redis server. .B port: \fB6379\fP The Redis server port. .TP +.B cluster_mode: \fBFalse\fP +Whether cluster_mode is enabled or not +.TP +.B cluster.startup_nodes: +A list of host, port dictionaries pointing to cluster members. At least one is required +but multiple nodes are better +.TP +.B cluster.skip_full_coverage_check: \fBFalse\fP +Some cluster providers restrict certain redis commands such as CONFIG for enhanced security. +Set this option to true to skip checks that required advanced privileges. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Most cloud hosted redis clusters will require this to be set to \fBTrue\fP +.UNINDENT +.UNINDENT +.TP .B db: \fB\(aq0\(aq\fP The database index. .sp @@ -73642,6 +78330,8 @@ Redis connection password. .UNINDENT .sp Configuration Example: +.sp +Cluster Configuration Example: .INDENT 0.0 .TP .B salt.cache.redis_cache.contains(bank, key) @@ -73711,7 +78401,7 @@ CloudStack Cloud Module T} _ T{ -\fBdigital_ocean\fP +\fBdigitalocean\fP T} T{ DigitalOcean Cloud Module T} @@ -73779,7 +78469,7 @@ _ T{ \fBopenstack\fP T} T{ -OpenStack Cloud Module +Openstack Cloud Driver T} _ T{ @@ -73815,7 +78505,6 @@ _ T{ \fBsaltify\fP T} T{ -Saltify Module T} _ T{ @@ -73837,6 +78526,12 @@ SoftLayer HW Cloud Module T} _ T{ +\fBvagrant\fP +T} T{ +Vagrant Cloud Driver +T} +_ +T{ \fBvirtualbox\fP T} T{ A salt cloud provider that lets you use virtualbox on your machine and act as a cloud. @@ -73854,6 +78549,12 @@ T} T{ Vultr Cloud Module using python\-vultr bindings T} _ +T{ +\fBxen\fP +T} T{ +XenServer Cloud Driver +T} +_ .TE .SS salt.cloud.clouds.aliyun .SS AliYun ECS Cloud Module @@ -74128,6 +78829,8 @@ The Azure cloud module is used to control access to Microsoft Azure \fI\%Microsoft Azure SDK for Python\fP >= 2.0rc5 .IP \(bu 2 \fI\%Microsoft Azure Storage SDK for Python\fP >= 0.32 +.IP \(bu 2 +\fIMicrosoft Azure CLI \fP >= 2.0.12 .UNINDENT .TP .B configuration @@ -74290,7 +78993,7 @@ List virtual networks .INDENT 0.0 .TP .B salt.cloud.clouds.azurearm.list_nodes(conn=None, call=None) -List VMs on this Azure account +List VMs on this Azure Active Provider .UNINDENT .INDENT 0.0 .TP @@ -74546,7 +79249,7 @@ Return the script deployment object .B salt.cloud.clouds.cloudstack.show_instance(name, call=None) Show the details from the provider concerning an instance .UNINDENT -.SS salt.cloud.clouds.digital_ocean +.SS salt.cloud.clouds.digitalocean .SS DigitalOcean Cloud Module .sp The DigitalOcean cloud module is used to control access to the DigitalOcean VPS system. @@ -74568,7 +79271,7 @@ my\-digital\-ocean\-config: personal_access_token: xxx ssh_key_file: /path/to/ssh/key/file ssh_key_names: my\-key\-name,my\-key\-name\-2 - driver: digital_ocean + driver: digitalocean .ft P .fi .UNINDENT @@ -74580,91 +79283,100 @@ requests .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.assign_floating_ip(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.assign_floating_ip(kwargs=None, call=None) Assign a floating IP .sp New in version 2016.3.0. .sp CLI Examples: -.sp -\&... code\-block:: bash .INDENT 7.0 .INDENT 3.5 +.sp +.nf +.ft C salt\-cloud \-f assign_floating_ip my\-digitalocean\-config droplet_id=1234567 floating_ip=\(aq45.55.96.47\(aq +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.avail_images(call=None) +.B salt.cloud.clouds.digitalocean.avail_images(call=None) Return a list of the images that are on the provider .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.avail_locations(call=None) +.B salt.cloud.clouds.digitalocean.avail_locations(call=None) Return a dict of all available VM locations on the cloud provider with relevant data .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.avail_sizes(call=None) +.B salt.cloud.clouds.digitalocean.avail_sizes(call=None) Return a list of the image sizes that are on the provider .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.create(vm_) +.B salt.cloud.clouds.digitalocean.create(vm_) Create a single VM from a data dict .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.create_floating_ip(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.create_floating_ip(kwargs=None, call=None) Create a new floating IP .sp New in version 2016.3.0. .sp CLI Examples: -.sp -\&... code\-block:: bash .INDENT 7.0 .INDENT 3.5 -salt\-cloud \-f create_floating_ip my\-digitalocean\-config region=\(aqNYC2\(aq .sp +.nf +.ft C +salt\-cloud \-f create_floating_ip my\-digitalocean\-config region=\(aqNYC2\(aq + salt\-cloud \-f create_floating_ip my\-digitalocean\-config droplet_id=\(aq1234567\(aq +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.create_key(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.create_key(kwargs=None, call=None) Upload a public key .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.create_node(args) +.B salt.cloud.clouds.digitalocean.create_node(args) Create a node .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.delete_floating_ip(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.delete_floating_ip(kwargs=None, call=None) Delete a floating IP .sp New in version 2016.3.0. .sp CLI Examples: -.sp -\&... code\-block:: bash .INDENT 7.0 .INDENT 3.5 +.sp +.nf +.ft C salt\-cloud \-f delete_floating_ip my\-digitalocean\-config floating_ip=\(aq45.55.96.47\(aq +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.destroy(name, call=None) +.B salt.cloud.clouds.digitalocean.destroy(name, call=None) Destroy a node. Will check termination protection and warn if enabled. .sp CLI Example: @@ -74681,42 +79393,42 @@ salt\-cloud \-\-destroy mymachine .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.destroy_dns_records(fqdn) +.B salt.cloud.clouds.digitalocean.destroy_dns_records(fqdn) Deletes DNS records for the given hostname if the domain is managed with DO. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.get_configured_provider() +.B salt.cloud.clouds.digitalocean.get_configured_provider() Return the first configured instance. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.get_dependencies() +.B salt.cloud.clouds.digitalocean.get_dependencies() Warn if dependencies aren\(aqt met. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.get_image(vm_) +.B salt.cloud.clouds.digitalocean.get_image(vm_) Return the image object to use .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.get_keyid(keyname) +.B salt.cloud.clouds.digitalocean.get_keyid(keyname) Return the ID of the keyname .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.get_location(vm_) +.B salt.cloud.clouds.digitalocean.get_location(vm_) Return the VM\(aqs location .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.get_size(vm_) +.B salt.cloud.clouds.digitalocean.get_size(vm_) Return the VM\(aqs size. Used by create_node(). .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.import_keypair(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.import_keypair(kwargs=None, call=None) Upload public key to cloud provider. Similar to EC2 import_keypair. .sp @@ -74731,55 +79443,58 @@ keyname(mandatory): public key name in the provider .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.list_floating_ips(call=None) +.B salt.cloud.clouds.digitalocean.list_floating_ips(call=None) Return a list of the floating ips that are on the provider .sp New in version 2016.3.0. .sp CLI Examples: -.sp -\&... code\-block:: bash .INDENT 7.0 .INDENT 3.5 +.sp +.nf +.ft C salt\-cloud \-f list_floating_ips my\-digitalocean\-config +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.list_keypairs(call=None) +.B salt.cloud.clouds.digitalocean.list_keypairs(call=None) Return a dict of all available VM locations on the cloud provider with relevant data .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.list_nodes(call=None) +.B salt.cloud.clouds.digitalocean.list_nodes(call=None) Return a list of the VMs that are on the provider .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.list_nodes_full(call=None, for_output=True) +.B salt.cloud.clouds.digitalocean.list_nodes_full(call=None, for_output=True) Return a list of the VMs that are on the provider .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.list_nodes_select(call=None) +.B salt.cloud.clouds.digitalocean.list_nodes_select(call=None) Return a list of the VMs that are on the provider, with select fields .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.post_dns_record(**kwargs) +.B salt.cloud.clouds.digitalocean.post_dns_record(**kwargs) Creates a DNS record for the given name if the domain is managed with DO. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.query(method=\(aqdroplets\(aq, droplet_id=None, command=None, args=None, http_method=\(aqget\(aq) +.B salt.cloud.clouds.digitalocean.query(method=u\(aqdroplets\(aq, droplet_id=None, command=None, args=None, http_method=u\(aqget\(aq) Make a web call to DigitalOcean .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.reboot(name, call=None) +.B salt.cloud.clouds.digitalocean.reboot(name, call=None) Reboot a droplet in DigitalOcean. .sp New in version 2015.8.8. @@ -74804,44 +79519,47 @@ salt\-cloud \-a reboot droplet_name .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.remove_key(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.remove_key(kwargs=None, call=None) Delete public key .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.script(vm_) +.B salt.cloud.clouds.digitalocean.script(vm_) Return the script deployment object .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.show_floating_ip(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.show_floating_ip(kwargs=None, call=None) Show the details of a floating IP .sp New in version 2016.3.0. .sp CLI Examples: -.sp -\&... code\-block:: bash .INDENT 7.0 .INDENT 3.5 +.sp +.nf +.ft C salt\-cloud \-f show_floating_ip my\-digitalocean\-config floating_ip=\(aq45.55.96.47\(aq +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.show_instance(name, call=None) +.B salt.cloud.clouds.digitalocean.show_instance(name, call=None) Show the details from DigitalOcean concerning a droplet .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.show_keypair(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.show_keypair(kwargs=None, call=None) Show the details of an SSH keypair .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.show_pricing(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.show_pricing(kwargs=None, call=None) Show pricing for a particular profile. This is only an estimate, based on unofficial pricing sources. .sp @@ -74862,7 +79580,7 @@ salt\-cloud \-f show_pricing my\-digitalocean\-config profile=my\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.start(name, call=None) +.B salt.cloud.clouds.digitalocean.start(name, call=None) Start a droplet in DigitalOcean. .sp New in version 2015.8.8. @@ -74887,7 +79605,7 @@ salt\-cloud \-a start droplet_name .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.stop(name, call=None) +.B salt.cloud.clouds.digitalocean.stop(name, call=None) Stop a droplet in DigitalOcean. .sp New in version 2015.8.8. @@ -74912,18 +79630,21 @@ salt\-cloud \-a stop droplet_name .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.digital_ocean.unassign_floating_ip(kwargs=None, call=None) +.B salt.cloud.clouds.digitalocean.unassign_floating_ip(kwargs=None, call=None) Unassign a floating IP .sp New in version 2016.3.0. .sp CLI Examples: -.sp -\&... code\-block:: bash .INDENT 7.0 .INDENT 3.5 +.sp +.nf +.ft C salt\-cloud \-f unassign_floating_ip my\-digitalocean\-config floating_ip=\(aq45.55.96.47\(aq +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT @@ -75453,20 +80174,17 @@ Detach a volume from an instance .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.ec2.disable_term_protect(name, call=None) -Disable termination protection on a node +.B salt.cloud.clouds.ec2.disable_detailed_monitoring(name, call=None) +Enable/disable detailed monitoring on a node .sp CLI Example: -.INDENT 7.0 -.INDENT 3.5 +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.ec2.enable_detailed_monitoring(name, call=None) +Enable/disable detailed monitoring on a node .sp -.nf -.ft C -salt\-cloud \-a disable_term_protect mymachine -.ft P -.fi -.UNINDENT -.UNINDENT +CLI Example: .UNINDENT .INDENT 0.0 .TP @@ -75818,6 +80536,11 @@ salt\-cloud \-a show_delvol_on_destroy mymachine .UNINDENT .INDENT 0.0 .TP +.B salt.cloud.clouds.ec2.show_detailed_monitoring(name=None, instance_id=None, call=None, quiet=False) +Show the details from EC2 regarding cloudwatch detailed monitoring. +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.ec2.show_image(kwargs, call=None) Show the details from EC2 concerning an AMI .UNINDENT @@ -75894,7 +80617,7 @@ New in version 2015.8.0. .INDENT 0.0 .TP .B salt.cloud.clouds.ec2.show_term_protect(name=None, instance_id=None, call=None, quiet=False) -Show the details from EC2 concerning an AMI +Show the details from EC2 concerning an instance\(aqs termination protection state .UNINDENT .INDENT 0.0 .TP @@ -76146,6 +80869,12 @@ is a list of maps, where each map contains: \(aqtype\(aq: The disk type, either pd\-standard or pd\-ssd. Optional, defaults to pd\-standard. \(aqimage\(aq: An image to use for this new disk. Optional. \(aqsnapshot\(aq: A snapshot to use for this new disk. Optional. +\(aqauto_delete\(aq: An option(bool) to keep or remove the disk upon +.INDENT 7.0 +.INDENT 3.5 +instance deletion. Optional, defaults to False. +.UNINDENT +.UNINDENT .sp Volumes are attached in the order in which they are given, thus on a new node the first volume will be /dev/sdb, the second /dev/sdc, and so on. @@ -77104,7 +81833,7 @@ Can use a custom URL for images. Default is: .sp .nf .ft C -image_url: images.joyent.com/image +image_url: images.joyent.com/images .ft P .fi .UNINDENT @@ -77230,7 +81959,7 @@ Cloud profile setting .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.joyent.get_location_path(location=\(aqus\-east\-1\(aq, api_host_suffix=\(aq.api.joyentcloud.com\(aq) +.B salt.cloud.clouds.joyent.get_location_path(location=u\(aqus\-east\-1\(aq, api_host_suffix=u\(aq.api.joyentcloud.com\(aq) create url from location variable :param location: joyent data center location :return: url @@ -77336,7 +82065,7 @@ Return a list of the VMs that are on the provider, with select fields .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.joyent.query(action=None, command=None, args=None, method=\(aqGET\(aq, location=None, data=None) +.B salt.cloud.clouds.joyent.query(action=None, command=None, args=None, method=u\(aqGET\(aq, location=None, data=None) Make a web call to Joyent .UNINDENT .INDENT 0.0 @@ -77456,7 +82185,7 @@ salt\-cloud \-a stop vm_name .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.joyent.take_action(name=None, call=None, command=None, data=None, method=\(aqGET\(aq, location=\(aqus\-east\-1\(aq) +.B salt.cloud.clouds.joyent.take_action(name=None, call=None, command=None, data=None, method=u\(aqGET\(aq, location=u\(aqus\-east\-1\(aq) take action call used by start,stop, reboot :param name: name given to the machine :param call: call value in this case is \(aqaction\(aq @@ -79511,7 +84240,7 @@ Required if the blob has an active lease. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.msazure.query(path, method=\(aqGET\(aq, data=None, params=None, header_dict=None, decode=True) +.B salt.cloud.clouds.msazure.query(path, method=u\(aqGET\(aq, data=None, params=None, header_dict=None, decode=True) Perform a query directly against the Azure REST API .UNINDENT .INDENT 0.0 @@ -80062,7 +84791,7 @@ salt\-cloud \-f update_disk my\-azure name=my_disk new_name=another_disk .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.msazure.update_input_endpoint(kwargs=None, conn=None, call=None, activity=\(aqupdate\(aq) +.B salt.cloud.clouds.msazure.update_input_endpoint(kwargs=None, conn=None, call=None, activity=u\(aqupdate\(aq) New in version 2015.8.0. .sp @@ -80355,7 +85084,7 @@ Note: For rackconnect v3, rackconnectv3 needs to be specified with the rackconnect v3 cloud network as its variable. .INDENT 0.0 .TP -.B salt.cloud.clouds.nova.attach_volume(name, server_name, device=\(aq/dev/xvdb\(aq, **kwargs) +.B salt.cloud.clouds.nova.attach_volume(name, server_name, device=u\(aq/dev/xvdb\(aq, **kwargs) Attach block volume .UNINDENT .INDENT 0.0 @@ -80571,7 +85300,7 @@ Create private networks .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.nova.volume_attach(name, server_name, device=\(aq/dev/xvdb\(aq, **kwargs) +.B salt.cloud.clouds.nova.volume_attach(name, server_name, device=u\(aq/dev/xvdb\(aq, **kwargs) Attach block volume .UNINDENT .INDENT 0.0 @@ -80975,7 +85704,7 @@ salt\-cloud \-f get_template_id opennebula name=my\-template\-name .B salt.cloud.clouds.opennebula.get_template_image(kwargs=None, call=None) Returns a template\(aqs image from the given template name. .sp -New in version oxygen. +New in version 2018.3.0. .INDENT 7.0 .INDENT 3.5 @@ -82957,215 +87686,404 @@ salt\-cloud \-f vn_reserve opennebula vn_name=my\-vn data="SIZE=10 AR_ID=8 NETWO .UNINDENT .UNINDENT .SS salt.cloud.clouds.openstack -.SS OpenStack Cloud Module -.sp -OpenStack is an open source project that is in use by a number a cloud -providers, each of which have their own ways of using it. +.SS Openstack Cloud Driver .INDENT 0.0 .TP .B depends -libcloud >= 0.13.2 +\fI\%shade\fP .UNINDENT .sp -OpenStack provides a number of ways to authenticate. This module uses password\- -based authentication, using auth v2.0. It is likely to start supporting other -methods of authentication provided by OpenStack in the future. +OpenStack is an open source project that is in use by a number a cloud +providers, each of which have their own ways of using it. .sp -Note that there is currently a dependency upon netaddr. This can be installed -on Debian\-based systems by means of the python\-netaddr package. +This OpenStack driver uses a the shade python module which is managed by the +OpenStack Infra team. This module is written to handle all the different +versions of different OpenStack tools for salt, so most commands are just passed +over to the module to handle everything. +.SS Provider .sp -This module has been tested to work with HP Cloud and Rackspace. See the -documentation for specific options for either of these providers. Some -examples, using the old cloud configuration syntax, are provided below: -.sp -Set up in the cloud configuration at \fB/etc/salt/cloud.providers\fP or -\fB/etc/salt/cloud.providers.d/openstack.conf\fP: +There are two ways to configure providers for this driver. The first one is to +just let shade handle everything, and configure using \fI\%os\-client\-config\fP and +setting up \fI/etc/openstack/clouds.yml\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -my\-openstack\-config: - # The OpenStack identity service url - identity_url: https://region\-b.geo\-1.identity.hpcloudsvc.com:35357/v2.0/tokens - # The OpenStack Identity Version (default: 2) - auth_version: 2 - # The OpenStack compute region - compute_region: region\-b.geo\-1 - # The OpenStack compute service name - compute_name: Compute - # The OpenStack tenant name (not tenant ID) - tenant: myuser\-tenant1 - # The OpenStack user name - user: myuser - # The OpenStack keypair name +clouds: + democloud: + region_name: RegionOne + auth: + username: \(aqdemo\(aq + password: secret + project_name: \(aqdemo\(aq + auth_url: \(aqhttp://openstack/identity\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +And then this can be referenced in the salt provider based on the \fIdemocloud\fP +name. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +myopenstack: + driver: openstack + cloud: democloud + region_name: RegionOne +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This allows for just using one configuration for salt\-cloud and for any other +openstack tools which are all using \fI/etc/openstack/clouds.yml\fP +.sp +The other method allows for specifying everything in the provider config, +instead of using the extra configuration file. This will allow for passing +salt\-cloud configs only through pillars for minions without having to write a +clouds.yml file on each minion.abs +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +myopenstack: + driver: openstack + region_name: RegionOne + auth: + username: \(aqdemo\(aq + password: secret + project_name: \(aqdemo\(aq + auth_url: \(aqhttp://openstack/identity\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Or if you need to use a profile to setup some extra stuff, it can be passed as a +\fIprofile\fP to use any of the \fI\%vendor\fP config options. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +myrackspace: + driver: openstack + profile: rackspace + auth: + username: rackusername + api_key: myapikey + region_name: ORD +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +And this will pull in the profile for rackspace and setup all the correct +options for the auth_url and different api versions for services. +.SS Profile +.sp +Most of the options for building servers are just passed on to the +\fI\%create_server\fP function from shade. +.sp +The salt specific ones are: +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +ssh_key_file: The path to the ssh key that should be used to login to the machine to bootstrap it +.IP \(bu 2 +ssh_key_file: The name of the keypair in openstack +.IP \(bu 2 +userdata_template: The renderer to use if the userdata is a file that is templated. Default: False +.IP \(bu 2 +ssh_interface: The interface to use to login for bootstrapping: public_ips, private_ips, floating_ips, fixed_ips +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +centos: + provider: myopenstack + image: CentOS 7 + size: ds1G ssh_key_name: mykey - # Skip SSL certificate validation - insecure: false - # The ssh key file - ssh_key_file: /path/to/keyfile/test.pem - # The OpenStack network UUIDs - networks: - \- fixed: - \- 4402cd51\-37ee\-435e\-a966\-8245956dc0e6 - \- floating: - \- Ext\-Net - files: - /path/to/dest.txt: - /local/path/to/src.txt - # Skips the service catalog API endpoint, and uses the following - base_url: http://192.168.1.101:3000/v2/12345 - driver: openstack - userdata_file: /tmp/userdata.txt - # config_drive is required for userdata at rackspace - config_drive: True + ssh_key_file: /root/.ssh/id_rsa .ft P .fi .UNINDENT .UNINDENT .sp -For in\-house Openstack Essex installation, libcloud needs the service_type : +This is the minimum setup required. +.sp +Anything else from the \fI\%create_server\fP docs can be passed through here. .INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-config: - identity_url: \(aqhttp://control.openstack.example.org:5000/v2.0/\(aq - compute_name : Compute Service - service_type : compute -.ft P -.fi +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBimage\fP: Image dict, name or ID to boot with. image is required +unless boot_volume is given. .UNINDENT +.IP \(bu 2 +\fBflavor\fP: Flavor dict, name or ID to boot onto. +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBauto_ip\fP: Whether to take actions to find a routable IP for +the server. (defaults to True) .UNINDENT -.sp -To use identity v3 for authentication, specify the \fIdomain\fP and \fIauth_version\fP -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-config: - identity_url: \(aqhttp://control.openstack.example.org:5000/v3/auth/tokens\(aq - auth_version: 3 - compute_name : Compute Service - compute_region: East - service_type : compute - tenant: tenant - domain: testing - user: daniel - password: securepassword - driver: openstack -.ft P -.fi +.IP \(bu 2 +\fBips\fP: List of IPs to attach to the server (defaults to None) +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBip_pool\fP: Name of the network or floating IP pool to get an +address from. (defaults to None) .UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBroot_volume\fP: Name or ID of a volume to boot from +(defaults to None \- deprecated, use boot_volume) .UNINDENT -.sp -Either a password or an API key must also be specified: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-password\-or\-api\-config: - # The OpenStack password - password: letmein - # The OpenStack API key - apikey: 901d3f579h23c8v73q9 -.ft P -.fi +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBboot_volume\fP: Name or ID of a volume to boot from +(defaults to None) .UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBterminate_volume\fP: If booting from a volume, whether it should +be deleted when the server is destroyed. +(defaults to False) .UNINDENT -.sp -Optionally, if you don\(aqt want to save plain\-text password in your configuration file, you can use keyring: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-keyring\-config: - # The OpenStack password is stored in keyring - # don\(aqt forget to set the password by running something like: - # salt\-cloud \-\-set\-password=myuser my\-openstack\-keyring\-config - password: USE_KEYRING -.ft P -.fi +.IP \(bu 2 +\fBvolumes\fP: (optional) A list of volumes to attach to the server +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBmeta\fP: (optional) A dict of arbitrary key/value metadata to +store for this server. Both keys and values must be +<=255 characters. .UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBfiles\fP: (optional, deprecated) A dict of files to overwrite +on the server upon boot. Keys are file names (i.e. +\fB/etc/passwd\fP) and values +are the file contents (either as a string or as a +file\-like object). A maximum of five entries is allowed, +and each file must be 10k or less. .UNINDENT -.sp -For local installations that only use private IP address ranges, the -following option may be useful. Using the old syntax: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-config: - # Ignore IP addresses on this network for bootstrap - ignore_cidr: 192.168.50.0/24 -.ft P -.fi +.IP \(bu 2 +\fBreservation_id\fP: a UUID for the set of servers being requested. +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBmin_count\fP: (optional extension) The minimum number of +servers to launch. .UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBmax_count\fP: (optional extension) The maximum number of +servers to launch. .UNINDENT -.sp -It is possible to upload a small set of files (no more than 5, and nothing too -large) to the remote server. Generally this should not be needed, as salt -itself can upload to the server after it is spun up, with nowhere near the -same restrictions. -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-config: - files: - /path/to/dest.txt: - /local/path/to/src.txt -.ft P -.fi +.IP \(bu 2 +\fBsecurity_groups\fP: A list of security group names +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBuserdata\fP: user data to pass to be exposed by the metadata +server this can be a file type object as well or a +string. .UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBkey_name\fP: (optional extension) name of previously created +keypair to inject into the instance. .UNINDENT -.sp -Alternatively, one could use the private IP to connect by specifying: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my\-openstack\-config: - ssh_interface: private_ips -.ft P -.fi +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBavailability_zone\fP: Name of the availability zone for instance +placement. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBblock_device_mapping\fP: (optional) A dict of block +device mappings for this server. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBblock_device_mapping_v2\fP: (optional) A dict of block +device mappings for this server. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBnics\fP: (optional extension) an ordered list of nics to be +added to this server, with information about +connected networks, fixed IPs, port etc. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBscheduler_hints\fP: (optional extension) arbitrary key\-value pairs +specified by the client to help boot an instance +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBconfig_drive\fP: (optional extension) value for config drive +either boolean, or volume\-id +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBdisk_config\fP: (optional extension) control how the disk is +partitioned when the server is created. possible +values are \(aqAUTO\(aq or \(aqMANUAL\(aq. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBadmin_pass\fP: (optional extension) add a user supplied admin +password. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBtimeout\fP: (optional) Seconds to wait, defaults to 60. +See the \fBwait\fP parameter. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBreuse_ips\fP: (optional) Whether to attempt to reuse pre\-existing +floating ips should a floating IP be +needed (defaults to True) +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBnetwork\fP: (optional) Network dict or name or ID to attach the +server to. Mutually exclusive with the nics parameter. +Can also be be a list of network names or IDs or +network dicts. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBboot_from_volume\fP: Whether to boot from volume. \(aqboot_volume\(aq +implies True, but boot_from_volume=True with +no boot_volume is valid and will create a +volume from the image and use that. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBvolume_size\fP: When booting an image from volume, how big should +the created volume be? Defaults to 50. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBnat_destination\fP: Which network should a created floating IP +be attached to, if it\(aqs not possible to +infer from the cloud\(aqs configuration. +(Optional, defaults to None) +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBgroup\fP: ServerGroup dict, name or id to boot the server in. +If a group is provided in both scheduler_hints and in +the group param, the group param will win. +(Optional, defaults to None) .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -When using floating ips from networks, if the OpenStack driver is unable to -allocate a new ip address for the server, it will check that for -unassociated ip addresses in the floating ip pool. If SaltCloud is running -in parallel mode, it is possible that more than one server will attempt to -use the same ip address. +If there is anything added, that is not in this list, it can be added to an \fIextras\fP +dictionary for the profile, and that will be to the create_server function. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B salt.cloud.clouds.openstack.avail_images(conn=None, call=None) -Return a dict of all available VM images on the cloud provider with -relevant data +List available images for OpenStack +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f avail_images myopenstack +salt\-cloud \-\-list\-images myopenstack +.ft P +.fi +.UNINDENT .UNINDENT -.INDENT 0.0 -.TP -.B salt.cloud.clouds.openstack.avail_locations(conn=None, call=None) -Return a dict of all available VM locations on the cloud provider with -relevant data .UNINDENT .INDENT 0.0 .TP .B salt.cloud.clouds.openstack.avail_sizes(conn=None, call=None) -Return a dict of all available VM images on the cloud provider with -relevant data +List available sizes for OpenStack +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f avail_sizes myopenstack +salt\-cloud \-\-list\-sizes myopenstack +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.openstack.call(conn=None, call=None, kwargs=None) +Call function from shade. +.sp +func +.INDENT 7.0 +.INDENT 3.5 +function to call from shade.openstackcloud library +.UNINDENT +.UNINDENT +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f call myopenstack func=list_images +t sujksalt\-cloud \-f call myopenstack func=create_network name=mysubnet +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -83194,44 +88112,98 @@ Warn if dependencies aren\(aqt met. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.openstack.get_image(conn, vm_) -Return the image object to use +.B salt.cloud.clouds.openstack.list_networks(conn=None, call=None) +List networks for OpenStack +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f list_networks myopenstack +.ft P +.fi .UNINDENT -.INDENT 0.0 -.TP -.B salt.cloud.clouds.openstack.get_node(conn, name) -Return a libcloud node for the named VM .UNINDENT -.INDENT 0.0 -.TP -.B salt.cloud.clouds.openstack.get_size(conn, vm_) -Return the VM\(aqs size object -.UNINDENT -.INDENT 0.0 -.TP -.B salt.cloud.clouds.openstack.ignore_cidr(vm_, ip) -Return True if we are to ignore the specified IP. Compatible with IPv4. .UNINDENT .INDENT 0.0 .TP .B salt.cloud.clouds.openstack.list_nodes(conn=None, call=None) -Return a list of the VMs that are on the provider +Return a list of VMs +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f list_nodes myopenstack +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP .B salt.cloud.clouds.openstack.list_nodes_full(conn=None, call=None) -Return a list of the VMs that are on the provider, with all fields +Return a list of VMs with all the information about them +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f list_nodes_full myopenstack +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.openstack.list_nodes_min(conn=None, call=None) +Return a list of VMs with minimal information +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f list_nodes_min myopenstack +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP .B salt.cloud.clouds.openstack.list_nodes_select(conn=None, call=None) -Return a list of the VMs that are on the provider, with select fields +Return a list of VMs with the fields from \fIquery.selection\fP +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f list_nodes_full myopenstack +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.openstack.managedcloud(vm_) -Determine if we should wait for the managed cloud automation before -running. Either \(aqFalse\(aq (default) or \(aqTrue\(aq. +.B salt.cloud.clouds.openstack.list_subnets(conn=None, call=None, kwargs=None) +List subnets in a virtual network +.INDENT 7.0 +.TP +.B network +network to list subnets of +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -83240,32 +88212,32 @@ Return the preferred Internet protocol. Either \(aqipv4\(aq (default) or \(aqipv .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.openstack.rackconnect(vm_) -Determine if we should wait for rackconnect automation before running. -Either \(aqFalse\(aq (default) or \(aqTrue\(aq. +.B salt.cloud.clouds.openstack.request_instance(vm_, conn=None, call=None) +Request an instance to be built .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.openstack.reboot(name, conn=None) -Reboot a single VM -.UNINDENT -.INDENT 0.0 -.TP -.B salt.cloud.clouds.openstack.request_instance(vm_=None, call=None) -Put together all of the information necessary to request an instance on Openstack -and then fire off the request the instance. +.B salt.cloud.clouds.openstack.show_instance(name, conn=None, call=None) +Get VM on this OpenStack account .sp -Returns data about the instance +name +.INDENT 7.0 +.INDENT 3.5 +name of the instance +.UNINDENT +.UNINDENT +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a show_instance myserver +.ft P +.fi .UNINDENT -.INDENT 0.0 -.TP -.B salt.cloud.clouds.openstack.script(vm_) -Return the script deployment object .UNINDENT -.INDENT 0.0 -.TP -.B salt.cloud.clouds.openstack.show_instance(name, call=None) -Show the details from the provider concerning an instance .UNINDENT .INDENT 0.0 .TP @@ -83357,7 +88329,7 @@ Return a list of the VMs that are on the provider, with select fields .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.parallels.query(action=None, command=None, args=None, method=\(aqGET\(aq, data=None) +.B salt.cloud.clouds.parallels.query(action=None, command=None, args=None, method=u\(aqGET\(aq, data=None) Make a web call to a Parallels provider .UNINDENT .INDENT 0.0 @@ -83422,7 +88394,7 @@ be automatically deployed and bootstraped with Salt. .INDENT 0.0 .TP .B depends -profitbrick >= 3.0.0 +profitbrick >= 3.1.0 .UNINDENT .sp The module requires ProfitBricks credentials to be supplied along with @@ -83821,7 +88793,7 @@ IPy >= 0.81 .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.proxmox.avail_images(call=None, location=\(aqlocal\(aq) +.B salt.cloud.clouds.proxmox.avail_images(call=None, location=u\(aqlocal\(aq) Return a list of the images that are on the provider .sp CLI Example: @@ -83942,7 +88914,7 @@ Get the status for a VM, either via the ID or the hostname .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.proxmox.get_vmconfig(vmid, node=None, node_type=\(aqopenvz\(aq) +.B salt.cloud.clouds.proxmox.get_vmconfig(vmid, node=None, node_type=u\(aqopenvz\(aq) Get VM configuration .UNINDENT .INDENT 0.0 @@ -84407,14 +89379,156 @@ salt\-cloud \-a stop i\-2f733r5n force=True 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. +.sp +Changed in version 2018.3.0: The wake_on_lan capability, and actions destroy, reboot, and query functions were added. + .sp Use of this module requires some configuration in cloud profile and provider files as described in the Gettting Started with Saltify documentation. .INDENT 0.0 .TP +.B salt.cloud.clouds.saltify.avail_images(call=None) +This function returns a list of images available for this cloud provider. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-images saltify +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +returns a list of available profiles. +.sp +\&..versionadded:: 2018.3.0 +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.saltify.avail_locations(call=None) +This function returns a list of locations available. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-locations my\-cloud\-provider +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +[ saltify will always return an empty dictionary ] +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.saltify.avail_sizes(call=None) +This function returns a list of sizes available for this cloud provider. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-sizes saltify +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +[ saltify always returns an empty dictionary ] +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.saltify.create(vm_) -Provision a single machine +if configuration parameter \fBdeploy\fP is \fBTrue\fP, +.INDENT 7.0 +.INDENT 3.5 +Provision a single machine, adding its keys to the salt master +.UNINDENT +.UNINDENT +.sp +else, +.INDENT 7.0 +.INDENT 3.5 +Test ssh connections to the machine +.UNINDENT +.UNINDENT +.sp +Configuration parameters: +.INDENT 7.0 +.IP \(bu 2 +deploy: (see above) +.IP \(bu 2 +provider: name of entry in \fBsalt/cloud.providers.d/???\fP file +.IP \(bu 2 +ssh_host: IP address or DNS name of the new machine +.IP \(bu 2 +ssh_username: name used to log in to the new machine +.IP \(bu 2 +ssh_password: password to log in (unless key_filename is used) +.IP \(bu 2 +key_filename: (optional) SSH private key for passwordless login +.IP \(bu 2 +ssh_port: (default=22) TCP port for SSH connection +.IP \(bu 2 +wake_on_lan_mac: (optional) hardware (MAC) address for wake on lan +.IP \(bu 2 +wol_sender_node: (optional) salt minion to send wake on lan command +.IP \(bu 2 +wol_boot_wait: (default=30) seconds to delay while client boots +.IP \(bu 2 +force_minion_config: (optional) replace the minion configuration files on the new machine +.UNINDENT +.sp +See also +Miscellaneous Salt Cloud Options +and +Getting Started with Saltify +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-p mymachine my_new_id +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.saltify.destroy(name, call=None) +Destroy a node. +.sp +New in version 2018.3.0. + +.sp +Disconnect a minion from the master, and remove its keys. +.INDENT 7.0 +.TP +.B Optionally, (if \fBremove_config_on_destroy\fP is \fBTrue\fP), +disables salt\-minion from running on the minion, and +erases the Salt configuration files from it. +.TP +.B Optionally, (if \fBshutdown_on_destroy\fP is \fBTrue\fP), +orders the minion to halt. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-destroy mymachine +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -84423,21 +89537,78 @@ Return the first configured instance. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.saltify.list_nodes() -Because this module is not specific to any cloud providers, there will be -no nodes to list. +.B salt.cloud.clouds.saltify.list_nodes(call=None) +List the nodes which have salt\-cloud:driver:saltify grains. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-Q +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +returns a list of dictionaries of defined standard fields. +.sp +\&..versionadded:: 2018.3.0 .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.saltify.list_nodes_full() -Because this module is not specific to any cloud providers, there will be -no nodes to list. +.B salt.cloud.clouds.saltify.list_nodes_full(call=None) +Lists complete information for all nodes. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-F +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +returns a list of dictionaries. +.sp +for \(aqsaltify\(aq minions, returns dict of grains (enhanced). +.sp +\&..versionadded:: 2018.3.0 .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.saltify.list_nodes_select() -Because this module is not specific to any cloud providers, there will be -no nodes to list. +.B salt.cloud.clouds.saltify.list_nodes_select(call=None) +Return a list of the minions that have salt\-cloud grains, with +select fields. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.saltify.reboot(name, call=None) +Reboot a saltify minion. +.sp +\&..versionadded:: 2018.3.0 +.INDENT 7.0 +.TP +.B name +The name of the VM to reboot. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a reboot vm_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.saltify.show_instance(name, call=None) +List the a single node, return dict of grains. .UNINDENT .SS salt.cloud.clouds.scaleway .SS Scaleway Cloud Module @@ -84531,7 +89702,7 @@ select fields. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.scaleway.query(method=\(aqservers\(aq, server_id=None, command=None, args=None, http_method=\(aqget\(aq) +.B salt.cloud.clouds.scaleway.query(method=u\(aqservers\(aq, server_id=None, command=None, args=None, http_method=u\(aqget\(aq) Make a call to the Scaleway API. .UNINDENT .INDENT 0.0 @@ -84621,7 +89792,7 @@ Return the first configured instance. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.softlayer.get_conn(service=\(aqSoftLayer_Virtual_Guest\(aq) +.B salt.cloud.clouds.softlayer.get_conn(service=u\(aqSoftLayer_Virtual_Guest\(aq) Return a conn object for the passed VM data .UNINDENT .INDENT 0.0 @@ -84657,7 +89828,7 @@ Return a list of the VMs that are on the provider .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.softlayer.list_nodes_full(mask=\(aqmask[id]\(aq, call=None) +.B salt.cloud.clouds.softlayer.list_nodes_full(mask=u\(aqmask[id]\(aq, call=None) Return a list of the VMs that are on the provider .UNINDENT .INDENT 0.0 @@ -84757,7 +89928,7 @@ Return the first configured instance. .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.softlayer_hw.get_conn(service=\(aqSoftLayer_Hardware\(aq) +.B salt.cloud.clouds.softlayer_hw.get_conn(service=u\(aqSoftLayer_Hardware\(aq) Return a conn object for the passed VM data .UNINDENT .INDENT 0.0 @@ -84788,7 +89959,7 @@ Return a list of the VMs that are on the provider .UNINDENT .INDENT 0.0 .TP -.B salt.cloud.clouds.softlayer_hw.list_nodes_full(mask=\(aqmask[id, hostname, primaryIpAddress, primaryBackendIpAddress, processorPhysicalCoreAmount, memoryCount]\(aq, call=None) +.B salt.cloud.clouds.softlayer_hw.list_nodes_full(mask=u\(aqmask[id, hostname, primaryIpAddress, primaryBackendIpAddress, processorPhysicalCoreAmount, memoryCount]\(aq, call=None) Return a list of the VMs that are on the provider .UNINDENT .INDENT 0.0 @@ -84858,6 +90029,169 @@ salt\-cloud \-f update_pricing .sp New in version 2015.8.0. +.UNINDENT +.SS salt.cloud.clouds.vagrant +.SS Vagrant Cloud Driver +.sp +The Vagrant cloud is designed to "vagrant up" a virtual machine as a +Salt minion. +.sp +Use of this module requires some configuration in cloud profile and provider +files as described in the +Getting Started with Vagrant documentation. +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.avail_images(call=None) +This function returns a list of images available for this cloud provider. +vagrant will return a list of profiles. +salt\-cloud \-\-list\-images my\-cloud\-provider +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.avail_locations(call=None) +This function returns a list of locations available. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-locations my\-cloud\-provider + +# \e[ vagrant will always returns an empty dictionary \e] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.avail_sizes(call=None) +This function returns a list of sizes available for this cloud provider. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-sizes my\-cloud\-provider + +# \e[ vagrant always returns an empty dictionary \e] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.create(vm_) +Provision a single machine +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-p my_profile new_node_1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.destroy(name, call=None) +Destroy a node. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-destroy mymachine +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.get_configured_provider() +Return the first configured instance. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.list_nodes(call=None) +List the nodes which have salt\-cloud:driver:vagrant grains. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-Q +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.list_nodes_full(call=None) +List the nodes, ask all \(aqvagrant\(aq minions, return dict of grains (enhanced). +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-F +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.list_nodes_select(call=None) +Return a list of the minions that have salt\-cloud grains, with +select fields. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.reboot(name, call=None) +Reboot a vagrant minion. +.INDENT 7.0 +.TP +.B name +The name of the VM to reboot. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a reboot vm_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.vagrant.show_instance(name, call=None) +List the a single node, return dict of grains. .UNINDENT .SS salt.cloud.clouds.virtualbox .sp @@ -84953,6 +90287,16 @@ No other fields should be returned in this function, and all of these fields sho The private_ips and public_ips fields should always be of a list type, even if empty, and the other fields should always be of a str type. This function is normally called with the \-Q option: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-Q +.ft P +.fi +.UNINDENT +.UNINDENT .sp @param kwargs: @type kwargs: @@ -84970,6 +90314,16 @@ even if they would not normally be provided by the cloud provider. .sp This is because some functions both within Salt and 3rd party will break if an expected field is not present. This function is normally called with the \-F option: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-F +.ft P +.fi +.UNINDENT +.UNINDENT .sp @param kwargs: @type kwargs: @@ -85303,6 +90657,23 @@ salt\-cloud \-f connect_host my\-vmware\-config host="myHostSystemName" .UNINDENT .INDENT 0.0 .TP +.B salt.cloud.clouds.vmware.convert_to_template(name, kwargs=None, call=None) +Convert the specified virtual machine to template. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a convert_to_template vmname +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.vmware.create(vm_) To create a single VM in the VMware environment. .sp @@ -86147,6 +91518,24 @@ salt\-cloud \-f remove_host my\-vmware\-config host="myHostSystemName" .UNINDENT .INDENT 0.0 .TP +.B salt.cloud.clouds.vmware.remove_snapshot(name, kwargs=None, call=None) +Remove a snapshot of the specified virtual machine in this VMware environment +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a remove_snapshot vmname snapshot_name="mySnapshot" +salt\-cloud \-a remove_snapshot vmname snapshot_name="mySnapshot" [remove_children="True"] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.vmware.rescan_hba(kwargs=None, call=None) To rescan a specified HBA or all the HBAs on the Host System .sp @@ -86500,6 +91889,560 @@ Execute a "start" action on a VM .B salt.cloud.clouds.vultrpy.stop(*args, **kwargs) Execute a "stop" action on a VM .UNINDENT +.SS salt.cloud.clouds.xen +.SS XenServer Cloud Driver +.sp +The XenServer driver is designed to work with a Citrix XenServer. +.sp +Requires XenServer SDK +(can be downloaded from \fI\%https://www.citrix.com/downloads/xenserver/product\-software/\fP ) +.sp +Place a copy of the XenAPI.py in the Python site\-packages folder. +.INDENT 0.0 +.TP +.B depends +XenAPI +.UNINDENT +.sp +Example provider configuration: +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# /etc/salt/cloud.providers.d/myxen.conf +myxen: + driver: xen + url: http://10.0.0.120 + user: root + password: p@ssw0rd +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Example profile configuration: +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# /etc/salt/cloud.profiles.d/myxen.conf +suse: + provider: myxen + user: root + password: p@ssw0rd + image: opensuseleap42_2\-template + storage_repo: \(aqLocal storage\(aq + resource_pool: default_pool + clone: True + minion: + master: 10.0.0.18 +sles: + provider: myxen + user: root + clone: False + image: sles12sp2\-template + deploy: False +w2k12: + provider: myxen + image: w2k12svr\-template + clone: True + userdata_file: /srv/salt/win/files/windows\-firewall.ps1 + win_installer: /srv/salt/win/files/Salt\-Minion\-2016.11.3\-AMD64\-Setup.exe + win_username: Administrator + win_password: p@ssw0rd + use_winrm: False + ipv4_cidr: 10.0.0.215/24 + ipv4_gw: 10.0.0.1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.avail_images(call=None) +Get a list of images from Xen +.sp +If called with the \fI\-\-list\-images\fP then it returns +images with all details. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-images myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.avail_locations(session=None, call=None) +Return available Xen locations (not implemented) +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-locations myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.avail_sizes(session=None, call=None) +Return a list of Xen templat definitions +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-sizes myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.create(vm_) +Create a VM in Xen +.sp +The configuration for this function is read from the profile settings. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-p some_profile xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.destroy(name=None, call=None) +Destroy Xen VM or template instance +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-d xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.destroy_template(name=None, call=None, kwargs=None) +Destroy Xen VM or template instance +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f destroy_template myxen name=testvm2 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.destroy_vm_vdis(name=None, session=None, call=None) +Get virtual block devices on VM +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a destroy_vm_vdis xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.get_configured_provider() +Return the first configured instance. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.get_vm_ip(name=None, session=None, call=None) +Get the IP address of the VM +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a get_vm_ip xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Requires xen guest tools to be installed in VM +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.host_list(call=None) +Get a list of Xen Servers +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f host_list myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.list_nodes() +List virtual machines +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-Q +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.list_nodes_full(session=None) +List full virtual machines +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-F +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.list_nodes_select(call=None) +Perform a select query on Xen VM instances +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-S +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.pause(name, call=None, session=None) +Pause a vm +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a pause xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.pif_list(call=None) +Get a list of Resource Pools +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f pool_list myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.pool_list(call=None) +Get a list of Resource Pools +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f pool_list myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.reboot(name, call=None, session=None) +Reboot a vm +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a reboot xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.resume(name, call=None, session=None) +Resume a vm from disk +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a resume xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.set_vm_ip(name=None, ipv4_cidr=None, ipv4_gw=None, session=None, call=None) +Set the IP address on a virtual interface (vif) +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.show_instance(name, session=None, call=None) +Show information about a specific VM or template +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a show_instance xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +memory is memory_dynamic_max +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.shutdown(name, call=None, session=None) +Shutdown a vm +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a shutdown xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.sr_list(call=None) +Geta list of storage repositories +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f sr_list myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.start(name, call=None, session=None) +Start a vm +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a start xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.stop(name, call=None, session=None) +Stop a vm +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a stop xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.suspend(name, call=None, session=None) +Suspend a vm to disk +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a suspend xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.template_list(call=None) +Return available Xen template information. +.sp +This returns the details of +each template to show number cores, memory sizes, etc.. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f template_list myxen +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.unpause(name, call=None, session=None) +UnPause a vm +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a unpause xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.vbd_list(name=None, call=None) +Get a list of VBDs on a VM +.sp +\fBrequires\fP: the name of the vm with the vbd definition +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a vbd_list xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.vdi_list(call=None, kwargs=None) +Return available Xen VDI images +.sp +If this function is called with the \fB\-f\fP or \fB\-\-function\fP then +it can return a list with minimal deatil using the \fBterse=True\fP keyword +argument. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f vdi_list myxen terse=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.xen.vif_list(name, call=None, kwargs=None) +Get a list of virtual network interfaces on a VM +.sp +\fBrequires\fP: the name of the vm with the vbd definition +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a vif_list xenvm01 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS engine modules .TS center; @@ -86568,7 +92511,7 @@ _ T{ \fBslack\fP T} T{ -An engine that reads messages from Slack and sends them to the Salt event bus. +An engine that reads messages from Slack and can act on them. T} _ T{ @@ -86608,7 +92551,7 @@ Send events from Docker events :Depends: Docker API >= 1.22 .INDENT 0.0 .TP -.B salt.engines.docker_events.start(docker_url=\(aqunix://var/run/docker.sock\(aq, timeout=60, tag=\(aqsalt/engines/docker_events\(aq) +.B salt.engines.docker_events.start(docker_url=u\(aqunix://var/run/docker.sock\(aq, timeout=60, tag=u\(aqsalt/engines/docker_events\(aq) Scan for Docker events and fire events .sp Example Config @@ -86675,7 +92618,7 @@ engines: .UNINDENT .INDENT 0.0 .TP -.B salt.engines.hipchat.start(token, room=\(aqsalt\(aq, aliases=None, valid_users=None, valid_commands=None, control=False, trigger=\(aq!\(aq, tag=\(aqsalt/engines/hipchat/incoming\(aq, api_key=None, api_url=None, max_rooms=None, wait_time=None, output_type=\(aqfile\(aq, outputter=\(aqnested\(aq) +.B salt.engines.hipchat.start(token, room=u\(aqsalt\(aq, aliases=None, valid_users=None, valid_commands=None, control=False, trigger=u\(aq!\(aq, tag=u\(aqsalt/engines/hipchat/incoming\(aq, api_key=None, api_url=None, max_rooms=None, wait_time=None, output_type=u\(aqfile\(aq, outputter=u\(aqnested\(aq) Listen to Hipchat messages and forward them to Salt. .INDENT 7.0 .TP @@ -86765,6 +92708,19 @@ HipChat Example: .sp An engine that reads messages from the salt event bus and pushes them onto a logstash endpoint via HTTP requests. +.sp +Changed in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +By default, this engine take everything from the Salt bus and exports into +Logstash. +For a better selection of the events that you want to publish, you can use +the \fBtags\fP and \fBfuns\fP options. +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B configuration @@ -86791,7 +92747,25 @@ engines: .INDENT 0.0 .TP .B salt.engines.http_logstash.start(url, funs=None, tags=None) -Listen to salt events and forward them to logstash via HTTP. +Listen to salt events and forward them to logstash. +.INDENT 7.0 +.TP +.B url +The Logstash endpoint. +.TP +.B funs: \fBNone\fP +A list of functions to be compared against, looking into the \fBfun\fP +field from the event data. This option helps to select the events +generated by one or more functions. +If an event does not have the \fBfun\fP field in the data section, it +will be published. For a better selection, consider using the \fBtags\fP +option. +By default, this option accepts any event to be submitted to Logstash. +.TP +.B tags: \fBNone\fP +A list of pattern to compare the event tag against. +By default, this option accepts any event to be submitted to Logstash. +.UNINDENT .UNINDENT .SS salt.engines.ircbot .sp @@ -86844,6 +92818,31 @@ list of everything else sent in the message .sp Example of usage .INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +08:33:57 @gtmanfred > !ping +08:33:57 gtmanbot > gtmanfred: pong +08:34:02 @gtmanfred > !echo ping +08:34:02 gtmanbot > ping +08:34:17 @gtmanfred > !event test/tag/ircbot irc is usefull +08:34:17 gtmanbot > gtmanfred: TaDa! +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +[DEBUG ] Sending event: tag = salt/engines/ircbot/test/tag/ircbot; data = {\(aq_stamp\(aq: \(aq2016\-11\-28T14:34:16.633623\(aq, \(aqdata\(aq: [\(aqirc\(aq, \(aqis\(aq, \(aquseful\(aq]} +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 .TP .B class salt.engines.ircbot.Event(source, code, line) .INDENT 7.0 @@ -86908,7 +92907,7 @@ Alias for field number 2 .UNINDENT .INDENT 0.0 .TP -.B salt.engines.ircbot.start(nick, host, port=6667, username=None, password=None, channels=None, use_ssl=False, use_sasl=False, char=\(aq!\(aq, allow_hosts=False, allow_nicks=False, disable_query=True) +.B salt.engines.ircbot.start(nick, host, port=6667, username=None, password=None, channels=None, use_ssl=False, use_sasl=False, char=u\(aq!\(aq, allow_hosts=False, allow_nicks=False, disable_query=True) IRC Bot for interacting with salt. .INDENT 7.0 .TP @@ -87192,7 +93191,7 @@ salt \(aq*\(aq test.ping cmd.run uptime .UNINDENT .INDENT 0.0 .TP -.B salt.engines.logentries.start(endpoint=\(aqdata.logentries.com\(aq, port=10000, token=None, tag=\(aqsalt/engines/logentries\(aq) +.B salt.engines.logentries.start(endpoint=u\(aqdata.logentries.com\(aq, port=10000, token=None, tag=u\(aqsalt/engines/logentries\(aq) Listen to salt events and forward them to Logentries .UNINDENT .SS salt.engines.logstash @@ -87223,7 +93222,7 @@ logstash .UNINDENT .INDENT 0.0 .TP -.B salt.engines.logstash.start(host, port=5959, tag=\(aqsalt/engine/logstash\(aq, proto=\(aqudp\(aq) +.B salt.engines.logstash.start(host, port=5959, tag=u\(aqsalt/engine/logstash\(aq, proto=u\(aqudp\(aq) Listen to salt events and forward them to logstash .UNINDENT .SS salt.engines.napalm_syslog @@ -87442,7 +93441,7 @@ can process the object from \fBopenconfig_structure\fP and define the bussiness logic as required. .INDENT 0.0 .TP -.B salt.engines.napalm_syslog.start(transport=\(aqzmq\(aq, address=\(aq0.0.0.0\(aq, port=49017, auth_address=\(aq0.0.0.0\(aq, auth_port=49018, disable_security=False, certificate=None, os_whitelist=None, os_blacklist=None, error_whitelist=None, error_blacklist=None, host_whitelist=None, host_blacklist=None) +.B salt.engines.napalm_syslog.start(transport=u\(aqzmq\(aq, address=u\(aq0.0.0.0\(aq, port=49017, auth_address=u\(aq0.0.0.0\(aq, auth_port=49018, disable_security=False, certificate=None, os_whitelist=None, os_blacklist=None, error_whitelist=None, error_blacklist=None, host_whitelist=None, host_blacklist=None) Listen to napalm\-logs and publish events into the Salt event bus. .INDENT 7.0 .TP @@ -87551,52 +93550,117 @@ redis .UNINDENT .SS salt.engines.slack module .sp -An engine that reads messages from Slack and sends them to the Salt -event bus. Alternatively Salt commands can be sent to the Salt master -via Slack by setting the control parameter to \fBTrue\fP and using command -prefaced with a \fB!\fP\&. +An engine that reads messages from Slack and can act on them. +.sp +It has two major uses. +.INDENT 0.0 +.IP 1. 3 +When the \fBcontrol\fP parameter is set to \fBTrue\fP and a message is prefaced +with the \fBtrigger\fP (which defaults to \fB!\fP) then the engine will +validate that the user has permission, and if so will run the command +.IP 2. 3 +In addition, when the parameter \fBfire_all\fP is set (defaults to False), +all other messages (the messages that aren\(aqt control messages) will be +fired off to the salt event bus with the tag prefixed by the string +provided by the \fBtag\fP config option (defaults to \fBsalt/engines/slack\fP). +.UNINDENT +.sp +This allows for configuration to be gotten from either the engine config, or from +the saltmaster\(aqs minion pillar. .INDENT 0.0 .TP .B configuration -Example configuration -.INDENT 7.0 +Example configuration using only a \(aqdefault\(aq group. The default group is not special. +.UNINDENT +.sp +In addition, other groups are being loaded from pillars. +.INDENT 0.0 .INDENT 3.5 .sp .nf .ft C engines: - \- slack: - token: \(aqxoxb\-xxxxxxxxxx\-xxxxxxxxxxxxxxxxxxxxxxxx\(aq - control: True - valid_users: - \- garethgreenaway - valid_commands: - \- test.ping - \- cmd.run - \- list_jobs - \- list_commands + \- slack: + token: \(aqxoxb\-xxxxxxxxxx\-xxxxxxxxxxxxxxxxxxxxxxxx\(aq + control: True + fire_all: False + groups_pillar_name: \(aqslack_engine:groups_pillar\(aq + groups: + default: + users: + \- * + commands: + \- test.ping + \- cmd.run + \- list_jobs + \- list_commands aliases: - list_jobs: - cmd: jobs.list_jobs - list_commands: - cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster tgt_type=list + list_jobs: + cmd: jobs.list_jobs + list_commands: + cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster tgt_type=list + default_target: + target: saltmaster + tgt_type: glob + targets: + test.ping: + target: \(aq*\(aq + tgt_type: glob + cmd.run: + target: saltmaster + tgt_type: list .ft P .fi .UNINDENT .UNINDENT -.INDENT 7.0 +.INDENT 0.0 .TP .B configuration -Example configuration using groups +Example configuration using the \(aqdefault\(aq group and a non\-default group and a pillar that will be merged in +If the user is \(aq*\(aq (without the quotes) then the group\(aqs users or commands will match all users as appropriate .UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +engines: + \- slack: + groups_pillar: slack_engine_pillar + token: \(aqxoxb\-xxxxxxxxxx\-xxxxxxxxxxxxxxxxxxxxxxxx\(aq + control: True + fire_all: True + tag: salt/engines/slack + groups_pillar_name: \(aqslack_engine:groups_pillar\(aq + groups: + default: + valid_users: + \- * + valid_commands: + \- test.ping + aliases: + list_jobs: + cmd: jobs.list_jobs + list_commands: + cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster tgt_type=list + gods: + users: + \- garethgreenaway + commands: + \- * +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 .TP .B depends slackclient .UNINDENT .INDENT 0.0 .TP -.B salt.engines.slack.start(token, aliases=None, valid_users=None, valid_commands=None, control=False, trigger=\(aq!\(aq, groups=None, tag=\(aqsalt/engines/slack\(aq) -Listen to Slack events and forward them to Salt +.B salt.engines.slack.start(token, control=False, trigger=u\(aq!\(aq, groups=None, groups_pillar_name=None, fire_all=False, tag=u\(aqsalt/engines/slack\(aq) +Listen to slack events and forward them to salt, new version .UNINDENT .SS salt.engines.sqs_events .sp @@ -87718,7 +93782,7 @@ engines: .UNINDENT .INDENT 0.0 .TP -.B salt.engines.sqs_events.start(queue, profile=None, tag=\(aqsalt/engine/sqs\(aq, owner_acct_id=None) +.B salt.engines.sqs_events.start(queue, profile=None, tag=u\(aqsalt/engine/sqs\(aq, owner_acct_id=None) Listen to sqs and fire message on event bus .UNINDENT .SS salt.engines.stalekey module @@ -87823,6 +93887,133 @@ engines: .UNINDENT .UNINDENT .UNINDENT +.SS executors modules +.TS +center; +|l|l|. +_ +T{ +\fBdirect_call\fP +T} T{ +Direct call executor module +T} +_ +T{ +\fBsplay\fP +T} T{ +Splay function calls across targeted minions +T} +_ +T{ +\fBsudo\fP +T} T{ +Sudo executor module +T} +_ +.TE +.SS salt.executors.direct_call module +.sp +Direct call executor module +.INDENT 0.0 +.TP +.B salt.executors.direct_call.execute(opts, data, func, args, kwargs) +Directly calls the given function with arguments +.UNINDENT +.SS salt.executors.splay module +.sp +Splay function calls across targeted minions +.INDENT 0.0 +.TP +.B salt.executors.splay.execute(opts, data, func, args, kwargs) +Splay a salt function call execution time across minions over +a number of seconds (default: 300) +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +You \fIprobably\fP want to use \-\-async here and look up the job results later. +If you\(aqre dead set on getting the output from the CLI command, then make +sure to set the timeout (with the \-t flag) to something greater than the +splaytime (max splaytime + time to execute job). +Otherwise, it\(aqs very likely that the cli will time out before the job returns. +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# With default splaytime +salt \-\-async \-\-module\-executors=\(aq[splay, direct_call]\(aq \(aq*\(aq pkg.install cowsay version=3.03\-8.el6 +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# With specified splaytime (5 minutes) and timeout with 10 second buffer +salt \-t 310 \-\-module\-executors=\(aq[slpay, direct_call]\(aq \-\-executor\-opts=\(aq{splaytime: 300}\(aq \(aq*\(aq pkg.version cowsay +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.SS salt.executors.sudo module +.sp +Sudo executor module +.INDENT 0.0 +.TP +.B salt.executors.sudo.execute(opts, data, func, args, kwargs) +Allow for the calling of execution modules via sudo. +.sp +This module is invoked by the minion if the \fBsudo_user\fP minion config is +present. +.sp +Example minion config: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +sudo_user: saltdev +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Once this setting is made, any execution module call done by the minion will be +run under \fBsudo \-u salt\-call\fP\&. For example, with the above +minion config, +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt sudo_minion cmd.run \(aqcat /etc/sudoers\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +is equivalent to +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +sudo \-u saltdev salt\-call cmd.run \(aqcat /etc/sudoers\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +being run on \fBsudo_minion\fP\&. +.UNINDENT .SS fileserver modules .TS center; @@ -87831,7 +94022,6 @@ _ T{ \fBazurefs\fP T} T{ -The backend for serving files from the Azure blob storage service. T} _ T{ @@ -87871,44 +94061,6 @@ Subversion Fileserver Backend T} _ .TE -.SS salt.fileserver.azurefs -.sp -The backend for serving files from the Azure blob storage service. -.sp -To enable, add \fBazurefs\fP to the \fBfileserver_backend\fP option in -the Master config file. -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -fileserver_backend: - \- azurefs -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -Each environment is configured as a storage container. The name of the container -must match the name of the environment. The \fBstorage_account\fP is the name of -the storage account inside Azure where the container lives, and the -\fBstorage_key\fP is the access key used for that storage account: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -azurefs_envs: - base: - storage_account: my_storage - storage_key: frehgfw34fWGegG07fwsfw343tGFDSDGDFGD== -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -With this configuration, multiple storage accounts can be used with a single -salt instrastructure. .SS salt.fileserver.gitfs .sp Git Fileserver Backend @@ -87916,7 +94068,7 @@ Git Fileserver Backend With this backend, branches and tags in a remote git repository are exposed to salt as different environments. .sp -To enable, add \fBgit\fP to the \fBfileserver_backend\fP option in the +To enable, add \fBgitfs\fP to the \fBfileserver_backend\fP option in the Master config file. .INDENT 0.0 .INDENT 3.5 @@ -87924,12 +94076,20 @@ Master config file. .nf .ft C fileserver_backend: - \- git + \- gitfs .ft P .fi .UNINDENT .UNINDENT .sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fBgit\fP also works here. Prior to the 2018.3.0 release, \fIonly\fP \fBgit\fP +would work. +.UNINDENT +.UNINDENT +.sp The Git fileserver backend supports both \fI\%pygit2\fP and \fI\%GitPython\fP, to provide the Python interface to git. If both are present, the order of preference for which one will be chosen is the same as the order in which they were listed: pygit2, @@ -87964,7 +94124,7 @@ To clear stale refs the git CLI utility must also be installed. .sp Mercurial Fileserver Backend .sp -To enable, add \fBhg\fP to the \fBfileserver_backend\fP option in the +To enable, add \fBhgfs\fP to the \fBfileserver_backend\fP option in the Master config file. .INDENT 0.0 .INDENT 3.5 @@ -87972,12 +94132,20 @@ Master config file. .nf .ft C fileserver_backend: - \- hg + \- hgfs .ft P .fi .UNINDENT .UNINDENT .sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fBhg\fP also works here. Prior to the 2018.3.0 release, \fIonly\fP \fBhg\fP would +work. +.UNINDENT +.UNINDENT +.sp After enabling this backend, branches, bookmarks, and tags in a remote mercurial repository are exposed to salt as different environments. This feature is managed by the \fBfileserver_backend\fP option in the salt @@ -88011,22 +94179,30 @@ The \fBcp.push\fP function allows Minions to push files up to the Master. Using this backend, these pushed files are exposed to other Minions via the Salt fileserver. .sp -To enable minionfs, \fBfile_recv\fP needs to be set to \fBTrue\fP in -the master config file (otherwise \fBcp.push\fP will -not be allowed to push files to the Master), and \fBminion\fP must be added to -the \fBfileserver_backends\fP list. +To enable minionfs, \fBfile_recv\fP needs to be set to \fBTrue\fP in the +master config file (otherwise \fBcp.push\fP will not be +allowed to push files to the Master), and \fBminionfs\fP must be added to the +\fBfileserver_backends\fP list. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C fileserver_backend: - \- minion + \- minionfs .ft P .fi .UNINDENT .UNINDENT .sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fBminion\fP also works here. Prior to the 2018.3.0 release, \fIonly\fP +\fBminion\fP would work. +.UNINDENT +.UNINDENT +.sp Other minionfs settings include: \fBminionfs_whitelist\fP, \fBminionfs_blacklist\fP, \fBminionfs_mountpoint\fP, and \fBminionfs_env\fP\&. @@ -88062,6 +94238,9 @@ configuration option. .SS salt.fileserver.s3fs .sp Amazon S3 Fileserver Backend +.sp +New in version 0.16.0. + .sp This backend exposes directories in S3 buckets as Salt environments. To enable this backend, add \fBs3fs\fP to the \fBfileserver_backend\fP option in the @@ -88161,7 +94340,7 @@ Subversion Fileserver Backend .sp After enabling this backend, branches and tags in a remote subversion repository are exposed to salt as different environments. To enable this -backend, add \fBsvn\fP to the \fBfileserver_backend\fP option in the +backend, add \fBsvnfs\fP to the \fBfileserver_backend\fP option in the Master config file. .INDENT 0.0 .INDENT 3.5 @@ -88169,12 +94348,20 @@ Master config file. .nf .ft C fileserver_backend: - \- svn + \- svnfs .ft P .fi .UNINDENT .UNINDENT .sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fBsvn\fP also works here. Prior to the 2018.3.0 release, \fIonly\fP \fBsvn\fP +would work. +.UNINDENT +.UNINDENT +.sp This backend assumes a standard svn layout with directories for \fBbranches\fP, \fBtags\fP, and \fBtrunk\fP, at the repository root. .INDENT 0.0 @@ -88307,6 +94494,29 @@ Return append_domain if set .UNINDENT .INDENT 0.0 .TP +.B salt.grains.core.default_gateway() +Populates grains which describe whether a server has a default gateway +configured or not. Uses \fIip \-4 route show\fP and \fIip \-6 route show\fP and greps +for a \fIdefault\fP at the beginning of any line. Assuming the standard +\fIdefault via \fP format for default gateways, it will also parse out the +ip address of the default gateway, and put it in ip4_gw or ip6_gw. +.sp +If the \fIip\fP command is unavailable, no grains will be populated. +.sp +Currently does not support multiple default gateways. The grains will be +set to the first default gateway found. +.sp +List of grains: +.INDENT 7.0 +.INDENT 3.5 +ip4_gw: True # ip/True/False if default ipv4 gateway +ip6_gw: True # ip/True/False if default ipv6 gateway +ip_gw: True # True if either of the above is True, False otherwise +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.grains.core.dns() Parse the resolver configuration file .INDENT 7.0 @@ -88318,6 +94528,11 @@ New in version 2016.3.0. .UNINDENT .INDENT 0.0 .TP +.B salt.grains.core.fc_wwn() +Return list of fiber channel HBA WWNs +.UNINDENT +.INDENT 0.0 +.TP .B salt.grains.core.get_machine_id() Provide the machine\-id .UNINDENT @@ -88375,6 +94590,11 @@ The addresses will be passed as a list for each interface .UNINDENT .INDENT 0.0 .TP +.B salt.grains.core.iscsi_iqn() +Return iSCSI IQN +.UNINDENT +.INDENT 0.0 +.TP .B salt.grains.core.locale_info() .INDENT 7.0 .TP @@ -89023,6 +95243,34 @@ Windows T} _ .TE +.SS salt.modules.kernelpkg +.sp +\fBkernelpkg\fP is a virtual module that is fulfilled by one of the following modules: +.TS +center; +|l|l|. +_ +T{ +Execution Module +T} T{ +Used for +T} +_ +T{ +\fBkernelpkg_linux_apt\fP +T} T{ +Debian/Ubuntu\-based distros which use +\fBapt\-get\fP for package management +T} +_ +T{ +\fBkernelpkg_linux_yum\fP +T} T{ +RedHat\-based distros and derivatives +using \fByum\fP or \fBdnf\fP +T} +_ +.TE .SS salt.modules.pkg .sp \fBpkg\fP is a virtual module that is fulfilled by one of the following modules: @@ -89298,12 +95546,6 @@ An execution module which can manipulate an f5 bigip via iControl REST T} _ T{ -\fBblockdev\fP -T} T{ -Module for managing block devices -T} -_ -T{ \fBbluez\fP T} T{ Support for Bluetooth (using BlueZ in Linux). @@ -89340,6 +95582,12 @@ Connection module for Amazon Cloud Formation T} _ T{ +\fBboto_cloudfront\fP +T} T{ +Connection module for Amazon CloudFront +T} +_ +T{ \fBboto_cloudtrail\fP T} T{ Connection module for Amazon CloudTrail @@ -89657,6 +95905,12 @@ Manage a local persistent data structure that can hold any arbitrary data T} _ T{ +\fBdatadog_api\fP +T} T{ +An execution module that interacts with the Datadog API +T} +_ +T{ \fBddns\fP T} T{ Support for RFC 2136 dynamic DNS updates. @@ -89689,7 +95943,7 @@ _ T{ \fBdebian_ip\fP T} T{ -The networking module for Debian based distros +The networking module for Debian\-based distros T} _ T{ @@ -89701,6 +95955,7 @@ _ T{ \fBdefaults\fP T} T{ +Module to work with salt formula defaults files T} _ T{ @@ -90084,7 +96339,7 @@ _ T{ \fBinfoblox\fP T} T{ -Module for managing Infoblox +This module have been tested on infoblox API v1.2.1, other versions of the API are likly workable. T} _ T{ @@ -90221,6 +96476,18 @@ Manage Kerberos KDC T} _ T{ +\fBkernelpkg_linux_apt\fP +T} T{ +Manage Linux kernel packages on APT\-based systems +T} +_ +T{ +\fBkernelpkg_linux_yum\fP +T} T{ +Manage Linux kernel packages on YUM\-based systems +T} +_ +T{ \fBkey\fP T} T{ Functions to view the minion\(aqs public key information @@ -90275,6 +96542,30 @@ Salt interface to LDAP commands T} _ T{ +\fBlibcloud_compute\fP +T} T{ +Apache Libcloud Compute Management +T} +_ +T{ +\fBlibcloud_dns\fP +T} T{ +Apache Libcloud DNS Management +T} +_ +T{ +\fBlibcloud_loadbalancer\fP +T} T{ +Apache Libcloud Load Balancer Management +T} +_ +T{ +\fBlibcloud_storage\fP +T} T{ +Apache Libcloud Storage Management +T} +_ +T{ \fBlinux_acl\fP T} T{ Support for Linux File Access Control Lists @@ -90409,7 +96700,7 @@ _ T{ \fBmac_shadow\fP T} T{ -New in version 2016.3.0. +Manage macOS local directory passwords and policies T} _ T{ @@ -90427,7 +96718,7 @@ _ T{ \fBmac_system\fP T} T{ -New in version 2016.3.0. +System module for sleeping, restarting, and shutting down the system on Mac OS X T} _ T{ @@ -90455,6 +96746,12 @@ Support for modifying make.conf under Gentoo T} _ T{ +\fBmandrill\fP +T} T{ +Mandrill +T} +_ +T{ \fBmarathon\fP T} T{ Module providing a simple management interface to a marathon cluster. @@ -90583,31 +96880,31 @@ _ T{ \fBnamecheap_dns\fP T} T{ -Namecheap management +Namecheap dns management T} _ T{ \fBnamecheap_domains\fP T} T{ -Namecheap management +Namecheap domains management T} _ T{ \fBnamecheap_ns\fP T} T{ -Namecheap management +Namecheap nameservers management T} _ T{ \fBnamecheap_ssl\fP T} T{ -Namecheap management +Namecheap ssl management T} _ T{ \fBnamecheap_users\fP T} T{ -Namecheap management +Namecheap users management T} _ T{ @@ -90793,6 +97090,7 @@ _ T{ \fBopenscap\fP T} T{ +Module for OpenSCAP Management T} _ T{ @@ -90820,6 +97118,12 @@ Support for Opkg T} _ T{ +\fBopsgenie\fP +T} T{ +Module for sending data to OpsGenie +T} +_ +T{ \fBoracle\fP T} T{ Oracle DataBase connection module @@ -90832,6 +97136,12 @@ Support for OSQuery \- \fI\%https://osquery.io\fP\&. T} _ T{ +\fBout\fP +T} T{ +Output Module +T} +_ +T{ \fBpacman\fP T} T{ A module to wrap pacman calls, since Arch is the best @@ -90982,6 +97292,12 @@ Execute puppet routines T} _ T{ +\fBpurefa\fP +T} T{ +Management of Pure Storage FlashArray +T} +_ +T{ \fBpushbullet\fP T} T{ Module for sending messages to Pushbullet (\fI\%https://www.pushbullet.com\fP) @@ -91080,6 +97396,7 @@ _ T{ \fBreg\fP T} T{ +Manage the Windows registry T} _ T{ @@ -91425,12 +97742,6 @@ StatusPage T} _ T{ -\fBstormpath\fP -T} T{ -Support for Stormpath -T} -_ -T{ \fBsupervisord\fP T} T{ Provide the service module for system supervisord or supervisord in a @@ -91449,6 +97760,12 @@ Subversion SCM T} _ T{ +\fBswarm\fP +T} T{ +Docker Swarm Module using Docker\(aqs Python SDK +T} +_ +T{ \fBswift\fP T} T{ Module for handling OpenStack Swift calls @@ -91487,7 +97804,7 @@ _ T{ \fBsystem\fP T} T{ -Support for reboot, shutdown, etc +Support for reboot, shutdown, etc on POSIX\-like systems. T} _ T{ @@ -91503,6 +97820,12 @@ Provides the service module for systemd T} _ T{ +\fBtelegram\fP +T} T{ +Module for sending messages via Telegram. +T} +_ +T{ \fBtelemetry\fP T} T{ Connection module for Telemetry @@ -91533,6 +97856,12 @@ Module for running arbitrary tests with a __virtual__ function T} _ T{ +\fBtextfsm_mod\fP +T} T{ +TextFSM +T} +_ +T{ \fBtimezone\fP T} T{ Module for managing timezone on POSIX\-like systems. @@ -91605,6 +97934,12 @@ uWSGI stats server \fI\%https://uwsgi\-docs.readthedocs.io/en/latest/StatsServer T} _ T{ +\fBvagrant\fP +T} T{ +Work with virtual machines managed by Vagrant. +T} +_ +T{ \fBvarnish\fP T} T{ Support for Varnish @@ -91613,11 +97948,7 @@ _ T{ \fBvault\fP T} T{ -.INDENT 0.0 -.TP -.B maintainer -SaltStack -.UNINDENT +Functions to interact with Hashicorp Vault. T} _ T{ @@ -91695,7 +98026,7 @@ _ T{ \fBwin_dsc\fP T} T{ -This module is Alpha +Module for working with Windows PowerShell DSC (Desired State Configuration) T} _ T{ @@ -91791,7 +98122,7 @@ _ T{ \fBwin_servermanager\fP T} T{ -Manage Windows features via the ServerManager powershell module +Manage Windows features via the ServerManager powershell module. T} _ T{ @@ -91985,7 +98316,7 @@ Be sure to set at least accept\-tos = True in cli.ini! Most parameters will fall back to cli.ini defaults if None is given. .INDENT 0.0 .TP -.B salt.modules.acme.cert(name, aliases=None, email=None, webroot=None, test_cert=False, renew=None, keysize=None, server=None, owner=\(aqroot\(aq, group=\(aqroot\(aq, certname=None) +.B salt.modules.acme.cert(name, aliases=None, email=None, webroot=None, test_cert=False, renew=None, keysize=None, server=None, owner=u\(aqroot\(aq, group=u\(aqroot\(aq, certname=None) Obtain/renew a certificate from an ACME CA, probably Let\(aqs Encrypt. .INDENT 7.0 .TP @@ -92691,7 +99022,7 @@ salt \(aq*\(aq apache.modules .UNINDENT .INDENT 0.0 .TP -.B salt.modules.apache.server_status(profile=\(aqdefault\(aq) +.B salt.modules.apache.server_status(profile=u\(aqdefault\(aq) Get Information from the Apache server\-status handler .sp \fBNOTE:\fP @@ -92772,7 +99103,7 @@ salt \(aq*\(aq apache.signal restart .UNINDENT .INDENT 0.0 .TP -.B salt.modules.apache.useradd(pwfile, user, password, opts=\(aq\(aq) +.B salt.modules.apache.useradd(pwfile, user, password, opts=u\(aq\(aq) Add HTTP user using the \fBhtpasswd\fP command. If the \fBhtpasswd\fP file does not exist, it will be created. Valid options that can be passed are: .INDENT 7.0 @@ -93433,7 +99764,7 @@ For repository management, the \fBpython\-apt\fP package must be installed. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.aptpkg.add_repo_key(path=None, text=None, keyserver=None, keyid=None, saltenv=\(aqbase\(aq) +.B salt.modules.aptpkg.add_repo_key(path=None, text=None, keyserver=None, keyid=None, saltenv=u\(aqbase\(aq) New in version 2017.7.0. .sp @@ -93793,7 +100124,7 @@ salt \(aq*\(aq pkg.info_installed failhard=false .UNINDENT .INDENT 0.0 .TP -.B salt.modules.aptpkg.install(name=None, refresh=False, fromrepo=None, skip_verify=False, debconf=None, pkgs=None, sources=None, reinstall=False, **kwargs) +.B salt.modules.aptpkg.install(name=None, refresh=False, fromrepo=None, skip_verify=False, debconf=None, pkgs=None, sources=None, reinstall=False, ignore_epoch=False, **kwargs) Changed in version 2015.8.12,2016.3.3,2016.11.0: On minions running systemd>=205, \fI\%systemd\-run(1)\fP is now used to isolate commands which modify installed packages from the \fBsalt\-minion\fP daemon\(aqs control group. This is done to keep systemd @@ -93861,6 +100192,10 @@ installation. .B version Install a specific version of the package, e.g. 1.2.3~0ubuntu0. Ignored if "pkgs" or "sources" is passed. +.sp +Changed in version 2018.3.0: version can now contain comparison operators (e.g. \fB>1.2.3\fP, +\fB<=2.0\fP, etc.) + .TP .B reinstall False @@ -93874,6 +100209,16 @@ matches the requested version. .sp New in version 2015.8.0. +.TP +.B ignore_epoch +False +Only used when the version of a package is specified using a comparison +operator (e.g. \fB>4.1\fP). If set to \fBTrue\fP, then the epoch will be +ignored when comparing the currently\-installed version to the desired +version. +.sp +New in version 2018.3.0. + .UNINDENT .sp Multiple Package Installation Options: @@ -94155,7 +100500,7 @@ salt \(aq*\(aq pkg.list_upgrades .UNINDENT .INDENT 0.0 .TP -.B salt.modules.aptpkg.mod_repo(repo, saltenv=\(aqbase\(aq, **kwargs) +.B salt.modules.aptpkg.mod_repo(repo, saltenv=u\(aqbase\(aq, **kwargs) Modify one or more values for a repo. If the repo does not exist, it will be created, so long as the definition is well formed. For Ubuntu the \fBppa:/repo\fP format is acceptable. \fBppa:\fP format can only be @@ -94163,34 +100508,36 @@ used to create a new repository. .sp The following options are available to modify a repo definition: .INDENT 7.0 -.INDENT 3.5 -.INDENT 0.0 .TP .B architectures -a comma separated list of supported architectures, e.g. \fBamd64\fP -If this option is not set, all architectures (configured in the -system) will be used. +A comma\-separated list of supported architectures, e.g. \fBamd64\fP If +this option is not set, all architectures (configured in the system) +will be used. .TP .B comps -a comma separated list of components for the repo, e.g. \fBmain\fP +A comma separated list of components for the repo, e.g. \fBmain\fP .TP .B file -a file name to be used +A file name to be used .TP .B keyserver -keyserver to get gpg key from +Keyserver to get gpg key from .TP .B keyid -key id to load with the keyserver argument +Key ID to load with the \fBkeyserver\fP argument .TP .B key_url URL to a GPG key to add to the APT GPG keyring .TP .B key_text GPG key in string form to add to the APT GPG keyring +.sp +New in version 2018.3.0. + .TP .B consolidate -if \fBTrue\fP, will attempt to de\-dup and consolidate sources +False +If \fBTrue\fP, will attempt to de\-duplicate and consolidate sources .TP .B comments Sometimes you want to supply additional information, but not as @@ -94203,14 +100550,11 @@ New in version 2015.8.9. .UNINDENT .sp \fBNOTE:\fP -.INDENT 0.0 +.INDENT 7.0 .INDENT 3.5 -Due to the way keys are stored for APT, there is a known issue -where the key won\(aqt be updated unless another change is made -at the same time. Keys should be properly added on initial -configuration. -.UNINDENT -.UNINDENT +Due to the way keys are stored for APT, there is a known issue where +the key won\(aqt be updated unless another change is made at the same +time. Keys should be properly added on initial configuration. .UNINDENT .UNINDENT .sp @@ -94399,7 +100743,7 @@ salt \(aq*\(aq pkg.remove pkgs=\(aq["foo", "bar"]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.aptpkg.set_selections(path=None, selection=None, clear=False, saltenv=\(aqbase\(aq) +.B salt.modules.aptpkg.set_selections(path=None, selection=None, clear=False, saltenv=u\(aqbase\(aq) Change package state in the dpkg database. .sp The state can be any one of, documented in \fBdpkg(1)\fP: @@ -94545,6 +100889,12 @@ Skip refreshing the package database if refresh has already occurred within .UNINDENT .UNINDENT .INDENT 7.0 +.TP +.B download_only +Only donwload the packages, don\(aqt unpack or install them +.sp +New in version 2018.3.0. + .TP .B force_conf_new Always install the new version of any configuration files. @@ -94905,7 +101255,7 @@ salt \(aq*\(aq archive.gzip /tmp/sourcefile.txt options=\(aq\-9 \-\-verbose\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.archive.is_encrypted(name, clean=False, saltenv=\(aqbase\(aq) +.B salt.modules.archive.is_encrypted(name, clean=False, saltenv=u\(aqbase\(aq, source_hash=None) New in version 2016.11.0. .sp @@ -94929,6 +101279,21 @@ If there is an error listing the archive\(aqs contents, the cached file will not be removed, to allow for troubleshooting. .UNINDENT .UNINDENT +.TP +.B saltenv +base +Specifies the fileserver environment from which to retrieve +\fBarchive\fP\&. This is only applicable when \fBarchive\fP is a file from +the \fBsalt://\fP fileserver. +.TP +.B source_hash +If \fBname\fP is an http(s)/ftp URL and the file exists in the minion\(aqs +file cache, this option can be passed to keep the minion from +re\-downloading the archive if the cached copy matches the specified +hash. +.sp +New in version 2018.3.0. + .UNINDENT .sp CLI Examples: @@ -94941,6 +101306,7 @@ salt \(aq*\(aq archive.is_encrypted /path/to/myfile.zip salt \(aq*\(aq archive.is_encrypted salt://foo.zip salt \(aq*\(aq archive.is_encrypted salt://foo.zip saltenv=dev salt \(aq*\(aq archive.is_encrypted https://domain.tld/myfile.zip clean=True +salt \(aq*\(aq archive.is_encrypted https://domain.tld/myfile.zip source_hash=f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 salt \(aq*\(aq archive.is_encrypted ftp://10.1.2.3/foo.zip .ft P .fi @@ -94949,7 +101315,7 @@ salt \(aq*\(aq archive.is_encrypted ftp://10.1.2.3/foo.zip .UNINDENT .INDENT 0.0 .TP -.B salt.modules.archive.list(name, archive_format=None, options=None, strip_components=None, clean=False, verbose=False, saltenv=\(aqbase\(aq) +.B salt.modules.archive.list(name, archive_format=None, options=None, strip_components=None, clean=False, verbose=False, saltenv=u\(aqbase\(aq, source_hash=None) New in version 2016.11.0. .sp @@ -95065,6 +101431,15 @@ base Specifies the fileserver environment from which to retrieve \fBarchive\fP\&. This is only applicable when \fBarchive\fP is a file from the \fBsalt://\fP fileserver. +.TP +.B source_hash +If \fBname\fP is an http(s)/ftp URL and the file exists in the minion\(aqs +file cache, this option can be passed to keep the minion from +re\-downloading the archive if the cached copy matches the specified +hash. +.sp +New in version 2018.3.0. + .UNINDENT .sp CLI Examples: @@ -95077,6 +101452,7 @@ salt \(aq*\(aq archive.list /path/to/myfile.tar.gz salt \(aq*\(aq archive.list /path/to/myfile.tar.gz strip_components=1 salt \(aq*\(aq archive.list salt://foo.tar.gz salt \(aq*\(aq archive.list https://domain.tld/myfile.zip +salt \(aq*\(aq archive.list https://domain.tld/myfile.zip source_hash=f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 salt \(aq*\(aq archive.list ftp://10.1.2.3/foo.rar .ft P .fi @@ -95461,7 +101837,7 @@ salt \(aq*\(aq archive.zip /tmp/zipfile.zip \(aq/tmp/sourcefile*\(aq Module for fetching artifacts from Artifactory .INDENT 0.0 .TP -.B salt.modules.artifactory.get_latest_release(artifactory_url, repository, group_id, artifact_id, packaging, target_dir=\(aq/tmp\(aq, target_file=None, classifier=None, username=None, password=None) +.B salt.modules.artifactory.get_latest_release(artifactory_url, repository, group_id, artifact_id, packaging, target_dir=u\(aq/tmp\(aq, target_file=None, classifier=None, username=None, password=None, use_literal_group_id=False) Gets the latest release of the artifact .INDENT 7.0 .TP @@ -95498,7 +101874,7 @@ Artifactory password. Optional parameter. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.artifactory.get_latest_snapshot(artifactory_url, repository, group_id, artifact_id, packaging, target_dir=\(aq/tmp\(aq, target_file=None, classifier=None, username=None, password=None) +.B salt.modules.artifactory.get_latest_snapshot(artifactory_url, repository, group_id, artifact_id, packaging, target_dir=u\(aq/tmp\(aq, target_file=None, classifier=None, username=None, password=None, use_literal_group_id=False) Gets latest snapshot of the given artifact .INDENT 7.0 .TP @@ -95535,7 +101911,7 @@ Artifactory password. Optional parameter. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.artifactory.get_release(artifactory_url, repository, group_id, artifact_id, packaging, version, target_dir=\(aq/tmp\(aq, target_file=None, classifier=None, username=None, password=None) +.B salt.modules.artifactory.get_release(artifactory_url, repository, group_id, artifact_id, packaging, version, target_dir=u\(aq/tmp\(aq, target_file=None, classifier=None, username=None, password=None, use_literal_group_id=False) Gets the specified release of the artifact .INDENT 7.0 .TP @@ -95575,7 +101951,7 @@ Artifactory password. Optional parameter. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.artifactory.get_snapshot(artifactory_url, repository, group_id, artifact_id, packaging, version, snapshot_version=None, target_dir=\(aq/tmp\(aq, target_file=None, classifier=None, username=None, password=None) +.B salt.modules.artifactory.get_snapshot(artifactory_url, repository, group_id, artifact_id, packaging, version, snapshot_version=None, target_dir=u\(aq/tmp\(aq, target_file=None, classifier=None, username=None, password=None, use_literal_group_id=False) Gets snapshot of the desired version of the artifact .INDENT 7.0 .TP @@ -95927,7 +102303,7 @@ in AUGEAS_LENS_LIB. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.augeas_cfg.get(path, value=\(aq\(aq, load_path=None) +.B salt.modules.augeas_cfg.get(path, value=u\(aq\(aq, load_path=None) Get a value for a specific augeas path .sp CLI Example: @@ -95994,7 +102370,7 @@ in AUGEAS_LENS_LIB. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.augeas_cfg.match(path, value=\(aq\(aq, load_path=None) +.B salt.modules.augeas_cfg.match(path, value=u\(aq\(aq, load_path=None) Get matches for path expression .sp CLI Example: @@ -96359,7 +102735,7 @@ New in version 2015.8.0. Requires a \fBsubdomain\fP and an \fBapikey\fP in \fB/etc/salt/minion\fP: .INDENT 0.0 .TP -.B salt.modules.bamboohr.list_employees(order_by=\(aqid\(aq) +.B salt.modules.bamboohr.list_employees(order_by=u\(aqid\(aq) Show all employees for this company. .sp CLI Example: @@ -96399,7 +102775,7 @@ salt myminion bamboohr.list_meta_fields .UNINDENT .INDENT 0.0 .TP -.B salt.modules.bamboohr.list_users(order_by=\(aqid\(aq) +.B salt.modules.bamboohr.list_users(order_by=u\(aqid\(aq) Show all users for this company. .sp CLI Example: @@ -96542,7 +102918,7 @@ bool or None if nuttin\(aq happened .UNINDENT .INDENT 0.0 .TP -.B salt.modules.bcache.back_make(dev, cache_mode=\(aqwriteback\(aq, force=False, attach=True, bucket_size=None) +.B salt.modules.bcache.back_make(dev, cache_mode=u\(aqwriteback\(aq, force=False, attach=True, bucket_size=None) Create a backing device for attachment to a set. Because the block size must be the same, a cache set already needs to exist. .sp @@ -96840,7 +103216,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq beacons.add ps "{\(aqsalt\-master\(aq: \(aqstopped\(aq, \(aqapache2\(aq: \(aqstopped\(aq}" +salt \(aq*\(aq beacons.add ps "[{\(aqsalt\-master\(aq: \(aqstopped\(aq, \(aqapache2\(aq: \(aqstopped\(aq}]" .ft P .fi .UNINDENT @@ -97051,7 +103427,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq beacons.modify ps "{\(aqsalt\-master\(aq: \(aqstopped\(aq, \(aqapache2\(aq: \(aqstopped\(aq}" +salt \(aq*\(aq beacons.modify ps "[{\(aqsalt\-master\(aq: \(aqstopped\(aq, \(aqapache2\(aq: \(aqstopped\(aq}]" .ft P .fi .UNINDENT @@ -97706,7 +104082,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq bigip.delete_node bigip admin admin my\-pool 10.2.2.2:80 +salt \(aq*\(aq bigip.delete_pool_member bigip admin admin my\-pool 10.2.2.2:80 .ft P .fi .UNINDENT @@ -98588,99 +104964,6 @@ salt \(aq*\(aq bigip.start_transaction bigip admin admin my_transaction .UNINDENT .UNINDENT .UNINDENT -.SS salt.modules.blockdev -.sp -Module for managing block devices -.sp -New in version 2014.7.0. - -.sp -Deprecated since version 2016.11.0: Merged to \fIdisk\fP module - -.INDENT 0.0 -.TP -.B salt.modules.blockdev.format(device, fs_type=\(aqext4\(aq, inode_size=None, lazy_itable_init=None, force=False) -Format a filesystem onto a block device -.sp -New in version 2015.8.2. - -.sp -Deprecated since version 2016.11.0. - -.INDENT 7.0 -.TP -.B device -The block device in which to create the new filesystem -.TP -.B fs_type -The type of filesystem to create -.TP -.B inode_size -Size of the inodes -.sp -This option is only enabled for ext and xfs filesystems -.TP -.B 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. -.sp -This option is only enabled for ext filesystems -.TP -.B force -Force mke2fs to create a filesystem, even if the specified device is -not a partition on a block special device. This option is only enabled -for ext and xfs filesystems -.sp -This option is dangerous, use it with caution. -.sp -New in version 2016.11.0. - -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq blockdev.format /dev/sdX1 -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.blockdev.fstype(device) -Return the filesystem name of a block device -.sp -New in version 2015.8.2. - -.sp -Deprecated since version 2016.11.0. - -.INDENT 7.0 -.TP -.B device -The name of the block device -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq blockdev.fstype /dev/sdX1 -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT .SS salt.modules.bluez .sp Support for Bluetooth (using BlueZ in Linux). @@ -99151,7 +105434,7 @@ Example: .sp .nf .ft C -salt myminion boto3_elasticache.create_cache_subnet_group name=my\-subnet\-group CacheSubnetGroupDescription="description" subnets=\(aq[myVPCSubnet1,myVPCSubnet2]\(aq +salt myminion boto3_elasticache.create_cache_subnet_group name=my\-subnet\-group CacheSubnetGroupDescription="description" subnets=\(aq[myVPCSubnet1,myVPCSubnet2]\(aq .ft P .fi .UNINDENT @@ -99760,7 +106043,7 @@ salt myminion boto3_route53.change_resource_record_sets DomainName=example.org. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto3_route53.create_hosted_zone(Name, VPCId=None, VPCName=None, VPCRegion=None, CallerReference=None, Comment=\(aq\(aq, PrivateZone=False, DelegationSetId=None, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto3_route53.create_hosted_zone(Name, VPCId=None, VPCName=None, VPCRegion=None, CallerReference=None, Comment=u\(aq\(aq, PrivateZone=False, DelegationSetId=None, region=None, key=None, keyid=None, profile=None) Create a new Route53 Hosted Zone. Returns a Python data structure with information about the newly created Hosted Zone. .INDENT 7.0 @@ -100120,6 +106403,9 @@ salt myminion boto3_route53.update_hosted_zone_comment Name=example.org. .SS salt.modules.boto_apigateway module .sp Connection module for Amazon APIGateway +.sp +New in version 2016.11.0. + .INDENT 0.0 .TP .B configuration @@ -100365,7 +106651,7 @@ salt myminion boto_apigateway.create_api myapi_name api_description .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_apigateway.create_api_deployment(restApiId, stageName, stageDescription=\(aq\(aq, description=\(aq\(aq, cacheClusterEnabled=False, cacheClusterSize=\(aq0.5\(aq, variables=None, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_apigateway.create_api_deployment(restApiId, stageName, stageDescription=u\(aq\(aq, description=u\(aq\(aq, cacheClusterEnabled=False, cacheClusterSize=u\(aq0.5\(aq, variables=None, region=None, key=None, keyid=None, profile=None) Creates a new API deployment. .sp CLI Example: @@ -100489,7 +106775,7 @@ salt myminion boto_apigateway.create_api_method_response restApiId resourcePath .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_apigateway.create_api_model(restApiId, modelName, modelDescription, schema, contentType=\(aqapplication/json\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_apigateway.create_api_model(restApiId, modelName, modelDescription, schema, contentType=u\(aqapplication/json\(aq, region=None, key=None, keyid=None, profile=None) Create a new model in a given API with a given schema, currently only contentType supported is \(aqapplication/json\(aq .sp @@ -100525,7 +106811,7 @@ salt myminion boto_apigateway.create_api_resources myapi_id resource_path .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_apigateway.create_api_stage(restApiId, stageName, deploymentId, description=\(aq\(aq, cacheClusterEnabled=False, cacheClusterSize=\(aq0.5\(aq, variables=None, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_apigateway.create_api_stage(restApiId, stageName, deploymentId, description=u\(aq\(aq, cacheClusterEnabled=False, cacheClusterSize=u\(aq0.5\(aq, variables=None, region=None, key=None, keyid=None, profile=None) Creates a new API stage for a given restApiId and deploymentId. .sp CLI Example: @@ -101389,7 +107675,7 @@ salt myminion boto_asg.create myasg mylc \(aq["us\-east\-1a", "us\-east\-1e"]\(a .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_asg.create_launch_configuration(name, image_id, key_name=None, vpc_id=None, vpc_name=None, security_groups=None, user_data=None, instance_type=\(aqm1.small\(aq, kernel_id=None, ramdisk_id=None, block_device_mappings=None, instance_monitoring=False, spot_price=None, instance_profile_name=None, ebs_optimized=False, associate_public_ip_address=None, volume_type=None, delete_on_termination=True, iops=None, use_block_device_types=False, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_asg.create_launch_configuration(name, image_id, key_name=None, vpc_id=None, vpc_name=None, security_groups=None, user_data=None, instance_type=u\(aqm1.small\(aq, kernel_id=None, ramdisk_id=None, block_device_mappings=None, instance_monitoring=False, spot_price=None, instance_profile_name=None, ebs_optimized=False, associate_public_ip_address=None, volume_type=None, delete_on_termination=True, iops=None, use_block_device_types=False, region=None, key=None, keyid=None, profile=None) Create a launch configuration. .sp CLI example: @@ -101587,7 +107873,7 @@ salt myminion boto_asg.get_config myasg region=us\-east\-1 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_asg.get_instances(name, lifecycle_state=\(aqInService\(aq, health_status=\(aqHealthy\(aq, attribute=\(aqprivate_ip_address\(aq, attributes=None, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_asg.get_instances(name, lifecycle_state=u\(aqInService\(aq, health_status=u\(aqHealthy\(aq, attribute=u\(aqprivate_ip_address\(aq, attributes=None, region=None, key=None, keyid=None, profile=None) return attribute of all instances in the named autoscale group. .sp CLI example: @@ -101751,7 +108037,7 @@ boto .B salt.modules.boto_cfn.create(name, template_body=None, template_url=None, parameters=None, notification_arns=None, disable_rollback=None, timeout_in_minutes=None, capabilities=None, tags=None, on_failure=None, stack_policy_body=None, stack_policy_url=None, region=None, key=None, keyid=None, profile=None) Create a CFN stack. .sp -CLI example to create a stack: +CLI Example: .INDENT 7.0 .INDENT 3.5 .sp @@ -101768,7 +108054,7 @@ salt myminion boto_cfn.create mystack template_url=\(aqhttps://s3.amazonaws.com/ .B salt.modules.boto_cfn.delete(name, region=None, key=None, keyid=None, profile=None) Delete a CFN stack. .sp -CLI example to delete a stack: +CLI Example: .INDENT 7.0 .INDENT 3.5 .sp @@ -101788,7 +108074,7 @@ Describe a stack. New in version 2015.8.0. .sp -CLI example: +CLI Example: .INDENT 7.0 .INDENT 3.5 .sp @@ -101805,7 +108091,7 @@ salt myminion boto_cfn.describe mystack region=us\-east\-1 .B salt.modules.boto_cfn.exists(name, region=None, key=None, keyid=None, profile=None) Check to see if a stack exists. .sp -CLI example: +CLI Example: .INDENT 7.0 .INDENT 3.5 .sp @@ -101822,7 +108108,7 @@ salt myminion boto_cfn.exists mystack region=us\-east\-1 .B salt.modules.boto_cfn.get_template(name, region=None, key=None, keyid=None, profile=None) Check to see if attributes are set on a CFN stack. .sp -CLI example: +CLI Example: .INDENT 7.0 .INDENT 3.5 .sp @@ -101842,7 +108128,7 @@ Update a CFN stack. New in version 2015.8.0. .sp -CLI example to update a stack: +CLI Example: .INDENT 7.0 .INDENT 3.5 .sp @@ -101862,7 +108148,7 @@ Validate cloudformation template New in version 2015.8.0. .sp -CLI example: +CLI Example: .INDENT 7.0 .INDENT 3.5 .sp @@ -101874,6 +108160,218 @@ salt myminion boto_cfn.validate_template mystack\-template .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.boto_cloudfront +.sp +Connection module for Amazon CloudFront +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B depends +boto3 +.TP +.B configuration +This module accepts explicit AWS credentials but can also +utilize IAM roles assigned to the instance through Instance Profiles or +it can read them from the ~/.aws/credentials file or from these +environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY. +Dynamic credentials are then automatically obtained from AWS API and no +further configuration is necessary. More information available at: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ + iam\-roles\-for\-amazon\-ec2.html + +http://boto3.readthedocs.io/en/latest/guide/ + configuration.html#guide\-configuration +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If IAM roles are not used you need to specify them either in a pillar or +in the minion\(aqs config file: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +cloudfront.keyid: GKTADJGHEIQSXMKKRBJ08H +cloudfront.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +A region may also be specified in the configuration: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +cloudfront.region: us\-east\-1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If a region is not specified, the default is us\-east\-1. +.sp +It\(aqs also possible to specify key, keyid and region via a profile, either +as a passed in dict, or as a string to pull from pillars or minion config: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +myprofile: + keyid: GKTADJGHEIQSXMKKRBJ08H + key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs + region: us\-east\-1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_cloudfront.create_distribution(name, config, tags=None, region=None, key=None, keyid=None, profile=None) +Create a CloudFront distribution with the given name, config, and (optionally) tags. +.INDENT 7.0 +.TP +.B name +Name for the CloudFront distribution +.TP +.B config +Configuration for the distribution +.TP +.B tags +Tags to associate with the distribution +.TP +.B region +Region to connect to +.TP +.B key +Secret key to use +.TP +.B keyid +Access key to use +.TP +.B profile +A dict with region, key, and keyid, +or a pillar key (string) that contains such a dict. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_cloudfront.create_distribution name=mydistribution profile=awsprofile config=\(aq{"Comment":"partial configuration","Enabled":true}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_cloudfront.export_distributions(region=None, key=None, keyid=None, profile=None) +Get details of all CloudFront distributions. +Produces results that can be used to create an SLS file. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call boto_cloudfront.export_distributions \-\-out=txt | sed "s/local: //" > cloudfront_distributions.sls +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_cloudfront.get_distribution(name, region=None, key=None, keyid=None, profile=None) +Get information about a CloudFront distribution (configuration, tags) with a given name. +.INDENT 7.0 +.TP +.B name +Name of the CloudFront distribution +.TP +.B region +Region to connect to +.TP +.B key +Secret key to use +.TP +.B keyid +Access key to use +.TP +.B profile +A dict with region, key, and keyid, +or a pillar key (string) that contains such a dict. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_cloudfront.get_distribution name=mydistribution profile=awsprofile +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_cloudfront.update_distribution(name, config, tags=None, region=None, key=None, keyid=None, profile=None) +Update the config (and optionally tags) for the CloudFront distribution with the given name. +.INDENT 7.0 +.TP +.B name +Name of the CloudFront distribution +.TP +.B config +Configuration for the distribution +.TP +.B tags +Tags to associate with the distribution +.TP +.B region +Region to connect to +.TP +.B key +Secret key to use +.TP +.B keyid +Access key to use +.TP +.B profile +A dict with region, key, and keyid, +or a pillar key (string) that contains such a dict. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_cloudfront.update_distribution name=mydistribution profile=awsprofile config=\(aq{"Comment":"partial configuration","Enabled":true}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.boto_cloudtrail module .sp Connection module for Amazon CloudTrail @@ -102295,7 +108793,7 @@ salt \(aq*\(aq convert_to_arn \(aqscaling_policy:\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_cloudwatch.create_or_update_alarm(connection=None, name=None, metric=None, namespace=None, statistic=None, comparison=None, threshold=None, period=None, evaluation_periods=None, unit=None, description=\(aq\(aq, dimensions=None, alarm_actions=None, insufficient_data_actions=None, ok_actions=None, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_cloudwatch.create_or_update_alarm(connection=None, name=None, metric=None, namespace=None, statistic=None, comparison=None, threshold=None, period=None, evaluation_periods=None, unit=None, description=u\(aq\(aq, dimensions=None, alarm_actions=None, insufficient_data_actions=None, ok_actions=None, region=None, key=None, keyid=None, profile=None) Create or update a cloudwatch alarm. .INDENT 7.0 .TP @@ -102939,7 +109437,7 @@ salt myminion boto_datapipeline.activate_pipeline my_pipeline_id .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_datapipeline.create_pipeline(name, unique_id, description=\(aq\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_datapipeline.create_pipeline(name, unique_id, description=u\(aq\(aq, region=None, key=None, keyid=None, profile=None) Create a new, empty pipeline. This function is idempotent. .sp CLI example: @@ -102990,7 +109488,7 @@ salt myminion boto_datapipeline.describe_pipelines [\(aqmy_pipeline_id\(aq] .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_datapipeline.get_pipeline_definition(pipeline_id, version=\(aqlatest\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_datapipeline.get_pipeline_definition(pipeline_id, version=u\(aqlatest\(aq, region=None, key=None, keyid=None, profile=None) Get the definition of the specified pipeline. .sp CLI example: @@ -103476,6 +109974,38 @@ salt myminion boto_ec2.attach_network_interface my_eni instance_name=salt\-maste .UNINDENT .INDENT 0.0 .TP +.B salt.modules.boto_ec2.attach_volume(volume_id, instance_id, device, region=None, key=None, keyid=None, profile=None) +Attach an EBS volume to an EC2 instance. +.. +.INDENT 7.0 +.TP +.B volume_id +(string) – The ID of the EBS volume to be attached. +.TP +.B instance_id +(string) – The ID of the EC2 instance to attach the volume to. +.TP +.B device +(string) – The device on the instance through which the volume is exposed (e.g. /dev/sdh) +.TP +.B returns +(bool) \- True on success, False on failure. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call boto_ec2.attach_volume vol\-12345678 i\-87654321 /dev/sdh +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.boto_ec2.create_image(ami_name, instance_id=None, instance_name=None, tags=None, region=None, key=None, keyid=None, profile=None, description=None, no_reboot=False, dry_run=False, filters=None) Given instance properties that define exactly one instance, create AMI and return AMI\-id. .sp @@ -103563,6 +110093,67 @@ salt\-call boto_ec2.create_tags vol\-12345678 \(aq{"Name": "myVolume01"}\(aq .UNINDENT .INDENT 0.0 .TP +.B salt.modules.boto_ec2.create_volume(zone_name, size=None, snapshot_id=None, volume_type=None, iops=None, encrypted=False, kms_key_id=None, wait_for_creation=False, region=None, key=None, keyid=None, profile=None) +Create an EBS volume to an availability zone. +.INDENT 7.0 +.TP +.B zone_name +(string) – The Availability zone name of the EBS volume to be created. +.TP +.B size +.INDENT 7.0 +.TP +.B (int) – The size of the new volume, in GiB. If you\(aqre creating the +volume from a snapshot and don\(aqt specify a volume size, the +default is the snapshot size. +.UNINDENT +.TP +.B snapshot_id +(string) – The snapshot ID from which the new volume will be created. +.TP +.B volume_type +.INDENT 7.0 +.TP +.B (string) \- The type of the volume. Valid volume types for AWS can be found here: +\fI\%http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html\fP +.UNINDENT +.TP +.B iops +(int) \- The provisioned IOPS you want to associate with this volume. +.TP +.B encrypted +(bool) \- Specifies whether the volume should be encrypted. +.TP +.B kms_key_id +.INDENT 7.0 +.TP +.B (string) \- If encrypted is True, this KMS Key ID may be specified to +encrypt volume with this key +e.g.: arn:aws:kms:us\-east\-1:012345678910:key/abcd1234\-a123\-456a\-a12b\-a123b4cd56ef +.UNINDENT +.TP +.B wait_for_creation +(bool) \- Whether or not to wait for volume creation to complete. +.TP +.B returns +(string) \- created volume id on success, error message on failure. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call boto_ec2.create_volume us\-east\-1a size=10 +salt\-call boto_ec2.create_volume us\-east\-1a snapshot_id=snap\-0123abcd +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.boto_ec2.delete_key(key_name, region=None, key=None, keyid=None, profile=None) Deletes a key. Always returns True .sp @@ -103689,7 +110280,7 @@ salt myminion boto_ec2.detach_network_interface my_eni .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_ec2.detach_volume(volume_id, instance_id=None, device=None, force=False, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_ec2.detach_volume(volume_id, instance_id=None, device=None, force=False, wait_for_detachement=False, region=None, key=None, keyid=None, profile=None) Detach an EBS volume from an EC2 instance. .sp New in version 2016.11.0. @@ -103715,6 +110306,9 @@ will not have an opportunity to flush file system caches nor file system meta da If you use this option, you must perform file system check and repair procedures. .UNINDENT .TP +.B wait_for_detachement +(bool) \- Whether or not to wait for volume detachement to complete. +.TP .B returns (bool) \- True on success, False on failure. .UNINDENT @@ -103767,9 +110361,9 @@ New in version 2016.3.0. .INDENT 0.0 .TP .B salt.modules.boto_ec2.exists(instance_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None, in_states=None, filters=None) -Given a instance id, check to see if the given instance id exists. +Given an instance id, check to see if the given instance id exists. .sp -Returns True if the given an instance with the given id, name, or tags +Returns True if the given instance with the given id, name, or tags exists; otherwise, False is returned. .sp CLI Example: @@ -103853,6 +110447,34 @@ salt\-call boto_ec2.get_all_eip_addresses .sp New in version 2016.3.0. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_ec2.get_all_tags(filters=None, region=None, key=None, keyid=None, profile=None) +Describe all tags matching the filter criteria, or all tags in the account otherwise. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B filters +(dict) \- Additional constraints on which volumes to return. Note that valid filters vary +extensively depending on the resource type. When in doubt, search first without a filter +and then use the returned data to help fine\-tune your search. You can generally garner the +resource type from its ID (e.g. \fIvol\-XXXXX\fP is a volume, \fIi\-XXXXX\fP is an instance, etc. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call boto_ec2.get_all_tags \(aq{"tag:Name": myInstanceNameTag, resource\-type: instance}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -104098,12 +110720,34 @@ salt myminion boto_ec2.get_network_interface_id name=my_eni .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_ec2.get_unassociated_eip_address(domain=\(aqstandard\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_ec2.get_tags(instance_id=None, keyid=None, key=None, profile=None, region=None) +Given an instance_id, return a list of tags associated with that instance. +.INDENT 7.0 +.TP +.B returns +(list) \- list of tags as key/value pairs +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_ec2.get_tags instance_id +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_ec2.get_unassociated_eip_address(domain=u\(aqstandard\(aq, region=None, key=None, keyid=None, profile=None) Return the first unassociated EIP .INDENT 7.0 .TP .B domain -Indicates whether the address is a EC2 address or a VPC address +Indicates whether the address is an EC2 address or a VPC address (standard|vpc). .UNINDENT .sp @@ -104216,7 +110860,7 @@ New in version 2016.3.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_ec2.run(image_id, name=None, tags=None, key_name=None, security_groups=None, user_data=None, instance_type=\(aqm1.small\(aq, placement=None, kernel_id=None, ramdisk_id=None, monitoring_enabled=None, vpc_id=None, vpc_name=None, subnet_id=None, subnet_name=None, private_ip_address=None, block_device_map=None, disable_api_termination=None, instance_initiated_shutdown_behavior=None, placement_group=None, client_token=None, security_group_ids=None, security_group_names=None, additional_info=None, tenancy=None, instance_profile_arn=None, instance_profile_name=None, ebs_optimized=None, network_interface_id=None, network_interface_name=None, region=None, key=None, keyid=None, profile=None, network_interfaces=None) +.B salt.modules.boto_ec2.run(image_id, name=None, tags=None, key_name=None, security_groups=None, user_data=None, instance_type=u\(aqm1.small\(aq, placement=None, kernel_id=None, ramdisk_id=None, monitoring_enabled=None, vpc_id=None, vpc_name=None, subnet_id=None, subnet_name=None, private_ip_address=None, block_device_map=None, disable_api_termination=None, instance_initiated_shutdown_behavior=None, placement_group=None, client_token=None, security_group_ids=None, security_group_names=None, additional_info=None, tenancy=None, instance_profile_arn=None, instance_profile_name=None, ebs_optimized=None, network_interface_id=None, network_interface_name=None, region=None, key=None, keyid=None, profile=None, network_interfaces=None) Create and start an EC2 instance. .sp Returns True if the instance was created; otherwise False. @@ -104452,6 +111096,36 @@ The default set of states is (\(aqpending\(aq, \(aqrebooting\(aq, \(aqrunning\(a .sp YAML example fragment: .INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +\- filters: + attachment.instance_id: i\-abcdef12 + tags: + Name: dev\-int\-abcdef12.aws\-foo.com +\- filters: + attachment.device: /dev/sdf + tags: + ManagedSnapshots: true + BillingGroup: bubba.hotep@aws\-foo.com + in_states: + \- stopped + \- terminated +\- filters: + instance_name: prd\-foo\-01.aws\-foo.com + tags: + Name: prd\-foo\-01.aws\-foo.com + BillingGroup: infra\-team@aws\-foo.com +\- filters: + volume_ids: [ vol\-12345689, vol\-abcdef12 ] + tags: + BillingGroup: infra\-team@aws\-foo.com +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 .TP .B authoritative (bool) If true, any existing tags on the matched volumes, and not explicitly requested here, will @@ -104462,7 +111136,7 @@ If true, don\(aqt change anything, just return a dictionary describing any chang would have been applied. .TP .B returns (dict) -A dict dsecribing status and any changes. +A dict describing status and any changes. .UNINDENT .UNINDENT .INDENT 0.0 @@ -104596,7 +111270,7 @@ boto3 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_efs.create_file_system(name, performance_mode=\(aqgeneralPurpose\(aq, keyid=None, key=None, profile=None, region=None, **kwargs) +.B salt.modules.boto_efs.create_file_system(name, performance_mode=u\(aqgeneralPurpose\(aq, keyid=None, key=None, profile=None, region=None, creation_token=None, **kwargs) Creates a new, empty file system. .INDENT 7.0 .TP @@ -104607,11 +111281,25 @@ Creates a new, empty file system. (string) \- The PerformanceMode of the file system. Can be either generalPurpose or maxIO .TP +.B creation_token +(string) \- A unique name to be used as reference when creating an EFS. +This will ensure idempotency. Set to name if not specified otherwise +.TP .B returns (dict) \- A dict of the data for the elastic file system .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.create_file_system efs\-name generalPurpose +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -104655,6 +111343,16 @@ These must be for the same VPC as subnet specified. .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.create_mount_target filesystemid subnetid +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -104673,6 +111371,16 @@ its value with the value provided in the request. .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.create_tags +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -104689,6 +111397,16 @@ you must first delete them. .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.delete_file_system filesystemid +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -104711,6 +111429,16 @@ You can mount an EC2 instance in your VPC via another mount target. .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.delete_mount_target mounttargetid +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -104726,10 +111454,20 @@ Deletes the specified tags from a file system. .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.delete_tags +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_efs.get_file_systems(filesystemid=None, keyid=None, key=None, profile=None, region=None, **kwargs) +.B salt.modules.boto_efs.get_file_systems(filesystemid=None, keyid=None, key=None, profile=None, region=None, creation_token=None, **kwargs) Get all EFS properties or a specific instance property if filesystemid is specified .INDENT 7.0 @@ -104737,11 +111475,27 @@ if filesystemid is specified .B filesystemid (string) \- ID of the file system to retrieve properties .TP +.B creation_token +(string) \- A unique token that identifies an EFS. +If fileysystem created via create_file_system this would +either be explictitly passed in or set to name. +You can limit your search with this. +.TP .B returns (list[dict]) \- list of all elastic file system properties .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.get_file_systems efs\-id +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -104770,6 +111524,16 @@ Must be specified if filesystemid is not .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.get_mount_targets +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -104785,6 +111549,16 @@ Return the tags associated with an EFS instance. .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.get_tags efs\-id +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -104800,6 +111574,16 @@ Modifies the set of security groups in effect for a mount target .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq boto_efs.set_security_groups my\-mount\-target\-id my\-sec\-group +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .SS salt.modules.boto_elasticache .sp @@ -105653,7 +112437,7 @@ salt myminion boto_elb.attach_subnets myelb \(aq["mysubnet"]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_elb.create(name, availability_zones, listeners, subnets=None, security_groups=None, scheme=\(aqinternet\-facing\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_elb.create(name, availability_zones, listeners, subnets=None, security_groups=None, scheme=u\(aqinternet\-facing\(aq, region=None, key=None, keyid=None, profile=None) Create an ELB .sp CLI example to create an ELB: @@ -106244,6 +113028,94 @@ myprofile: .fi .UNINDENT .UNINDENT +.TP +.B depends +boto3 +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_elbv2.create_target_group(name, protocol, port, vpc_id, region=None, key=None, keyid=None, profile=None, health_check_protocol=u\(aqHTTP\(aq, health_check_port=u\(aqtraffic\-port\(aq, health_check_path=u\(aq/\(aq, health_check_interval_seconds=30, health_check_timeout_seconds=5, healthy_threshold_count=5, unhealthy_threshold_count=2) +Create target group if not present. +.INDENT 7.0 +.TP +.B name +(string) \- The name of the target group. +.TP +.B protocol +(string) \- The protocol to use for routing traffic to the targets +.TP +.B port +(int) \- The port on which the targets receive traffic. This port is used unless +you specify a port override when registering the traffic. +.TP +.B vpc_id +(string) \- The identifier of the virtual private cloud (VPC). +.TP +.B health_check_protocol +(string) \- The protocol the load balancer uses when performing health check on +targets. The default is the HTTP protocol. +.TP +.B health_check_port +(string) \- The port the load balancer uses when performing health checks on +targets. The default is \(aqtraffic\-port\(aq, which indicates the port on which each +target receives traffic from the load balancer. +.TP +.B health_check_path +(string) \- The ping path that is the destination on the targets for health +checks. The default is /. +.TP +.B health_check_interval_seconds +(integer) \- The approximate amount of time, in seconds, between health checks +of an individual target. The default is 30 seconds. +.TP +.B health_check_timeout_seconds +(integer) \- The amount of time, in seconds, during which no response from a +target means a failed health check. The default is 5 seconds. +.TP +.B healthy_threshold_count +(integer) \- The number of consecutive health checks successes required before +considering an unhealthy target healthy. The default is 5. +.TP +.B unhealthy_threshold_count +(integer) \- The number of consecutive health check failures required before +considering a target unhealthy. The default is 2. +.TP +.B returns +(bool) \- True on success, False on failure. +.UNINDENT +.sp +CLI example: +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +salt myminion boto_elbv2.create_target_group learn1give1 protocol=HTTP port=54006 vpc_id=vpc\-deadbeef +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_elbv2.delete_target_group(name, region=None, key=None, keyid=None, profile=None) +Delete target group. +.INDENT 7.0 +.TP +.B name +(string) \- Target Group Name or Amazon Resource Name (ARN). +.TP +.B returns +(bool) \- True on success, False on failure. +.UNINDENT +.sp +CLI example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_elbv2.delete_target_group arn:aws:elasticloadbalancing:us\-west\-2:644138682826:targetgroup/learn1give1\-api/414788a16b5cf163 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -106327,7 +113199,7 @@ CLI example: .sp .nf .ft C -salt myminion boto_elbv2.exists arn:aws:elasticloadbalancing:us\-west\-2:644138682826:targetgroup/learn1give1\-api/414788a16b5cf163 +salt myminion boto_elbv2.target_group_exists arn:aws:elasticloadbalancing:us\-west\-2:644138682826:targetgroup/learn1give1\-api/414788a16b5cf163 .ft P .fi .UNINDENT @@ -106948,6 +113820,23 @@ salt myminion boto_iam.delete_user_policy myuser mypolicy .UNINDENT .INDENT 0.0 .TP +.B salt.modules.boto_iam.delete_virtual_mfa_device(serial, region=None, key=None, keyid=None, profile=None) +Deletes the specified virtual MFA device. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_iam.delete_virtual_mfa_device serial_num +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.boto_iam.describe_role(name, region=None, key=None, keyid=None, profile=None) Get information for a role. .sp @@ -107033,7 +113922,7 @@ salt myminion boto_iam.disassociate_profile_from_role myirole myiprofile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_iam.export_roles(path_prefix=\(aq/\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_iam.export_roles(path_prefix=u\(aq/\(aq, region=None, key=None, keyid=None, profile=None) Get all IAM role details. Produces results that can be used to create an sls file. .sp @@ -107046,7 +113935,7 @@ salt\-call boto_iam.export_roles \-\-out=txt | sed "s/local: //" > iam_roles.sls .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_iam.export_users(path_prefix=\(aq/\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_iam.export_users(path_prefix=u\(aq/\(aq, region=None, key=None, keyid=None, profile=None) Get all IAM user details. Produces results that can be used to create an sls file. .sp @@ -107136,7 +114025,7 @@ salt myminion boto_iam.get_all_group_policies mygroup .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_iam.get_all_groups(path_prefix=\(aq/\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_iam.get_all_groups(path_prefix=u\(aq/\(aq, region=None, key=None, keyid=None, profile=None) Get and return all IAM group details, starting at the optional path. .sp New in version 2016.3.0. @@ -107151,7 +114040,7 @@ salt\-call boto_iam.get_all_groups .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_iam.get_all_instance_profiles(path_prefix=\(aq/\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_iam.get_all_instance_profiles(path_prefix=u\(aq/\(aq, region=None, key=None, keyid=None, profile=None) Get and return all IAM instance profiles, starting at the optional path. .sp New in version 2016.11.0. @@ -107213,7 +114102,7 @@ CLI Example: .sp .nf .ft C -salt myminion boto_iam.get_group mygroup +salt myminion boto_iam.get_all_user_policies myuser .ft P .fi .UNINDENT @@ -107221,7 +114110,7 @@ salt myminion boto_iam.get_group mygroup .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_iam.get_all_users(path_prefix=\(aq/\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_iam.get_all_users(path_prefix=u\(aq/\(aq, region=None, key=None, keyid=None, profile=None) Get and return all IAM user details, starting at the optional path. .sp New in version 2016.3.0. @@ -107526,7 +114415,7 @@ salt myminion boto_iam.list_entities_for_policy mypolicy .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_iam.list_instance_profiles(path_prefix=\(aq/\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_iam.list_instance_profiles(path_prefix=u\(aq/\(aq, region=None, key=None, keyid=None, profile=None) List all IAM instance profiles, starting at the optional path. .sp New in version 2016.11.0. @@ -108760,6 +115649,23 @@ salt myminion boto_kinesis.increase_stream_retention_period my_stream N region=u .UNINDENT .INDENT 0.0 .TP +.B salt.modules.boto_kinesis.list_streams(region=None, key=None, keyid=None, profile=None) +Return a list of all streams visible to the current account +.sp +CLI example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_kinesis.list_streams +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.boto_kinesis.long_int(hash_key) The hash key is a 128\-bit int, sent as a string. It\(aqs necessary to convert to int/long for comparison operations. @@ -109430,7 +116336,7 @@ salt myminion boto_lambda.alias_exists myfunction myalias .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_lambda.create_alias(FunctionName, Name, FunctionVersion, Description=\(aq\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_lambda.create_alias(FunctionName, Name, FunctionVersion, Description=u\(aq\(aq, region=None, key=None, keyid=None, profile=None) Given a valid config, create an alias to a function. .sp Returns {created: true} if the alias was created and returns @@ -109472,7 +116378,7 @@ salt myminion boto_lamba.create_event_source_mapping arn::::eventsource myfuncti .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_lambda.create_function(FunctionName, Runtime, Role, Handler, ZipFile=None, S3Bucket=None, S3Key=None, S3ObjectVersion=None, Description=\(aq\(aq, Timeout=3, MemorySize=128, Publish=False, WaitForRole=False, RoleRetries=5, region=None, key=None, keyid=None, profile=None, VpcConfig=None, Environment=None) +.B salt.modules.boto_lambda.create_function(FunctionName, Runtime, Role, Handler, ZipFile=None, S3Bucket=None, S3Key=None, S3ObjectVersion=None, Description=u\(aq\(aq, Timeout=3, MemorySize=128, Publish=False, WaitForRole=False, RoleRetries=5, region=None, key=None, keyid=None, profile=None, VpcConfig=None, Environment=None) Given a valid config, create a function. .INDENT 7.0 .TP @@ -109945,10 +116851,10 @@ boto3 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_rds.create(name, allocated_storage, db_instance_class, engine, master_username, master_user_password, db_name=None, db_security_groups=None, vpc_security_group_ids=None, availability_zone=None, db_subnet_group_name=None, preferred_maintenance_window=None, db_parameter_group_name=None, backup_retention_period=None, preferred_backup_window=None, port=None, multi_az=None, engine_version=None, auto_minor_version_upgrade=None, license_model=None, iops=None, option_group_name=None, character_set_name=None, publicly_accessible=None, wait_status=None, tags=None, db_cluster_identifier=None, storage_type=None, tde_credential_arn=None, tde_credential_password=None, storage_encrypted=None, kms_key_id=None, domain=None, copy_tags_to_snapshot=None, monitoring_interval=None, monitoring_role_arn=None, domain_iam_role_name=None, region=None, promotion_tier=None, key=None, keyid=None, profile=None) -Create an RDS +.B salt.modules.boto_rds.create(name, allocated_storage, db_instance_class, engine, master_username, master_user_password, db_name=None, db_security_groups=None, vpc_security_group_ids=None, vpc_security_groups=None, availability_zone=None, db_subnet_group_name=None, preferred_maintenance_window=None, db_parameter_group_name=None, backup_retention_period=None, preferred_backup_window=None, port=None, multi_az=None, engine_version=None, auto_minor_version_upgrade=None, license_model=None, iops=None, option_group_name=None, character_set_name=None, publicly_accessible=None, wait_status=None, tags=None, db_cluster_identifier=None, storage_type=None, tde_credential_arn=None, tde_credential_password=None, storage_encrypted=None, kms_key_id=None, domain=None, copy_tags_to_snapshot=None, monitoring_interval=None, monitoring_role_arn=None, domain_iam_role_name=None, region=None, promotion_tier=None, key=None, keyid=None, profile=None) +Create an RDS Instance .sp -CLI example to create an RDS: +CLI example to create an RDS Instance: .INDENT 7.0 .INDENT 3.5 .sp @@ -110115,6 +117021,44 @@ salt myminion boto_rds.describe myrds .UNINDENT .INDENT 0.0 .TP +.B salt.modules.boto_rds.describe_db_instances(name=None, filters=None, jmespath=u\(aqDBInstances\(aq, region=None, key=None, keyid=None, profile=None) +Return a detailed listing of some, or all, DB Instances visible in the +current scope. Arbitrary subelements or subsections of the returned dataset +can be selected by passing in a valid JMSEPath filter as well. +.sp +CLI example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_rds.describe_db_instances jmespath=\(aqDBInstances[*].DBInstanceIdentifier\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_rds.describe_db_subnet_groups(name=None, filters=None, jmespath=u\(aqDBSubnetGroups\(aq, region=None, key=None, keyid=None, profile=None) +Return a detailed listing of some, or all, DB Subnet Groups visible in the +current scope. Arbitrary subelements or subsections of the returned dataset +can be selected by passing in a valid JMSEPath filter as well. +.sp +CLI example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_rds.describe_db_subnet_groups +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.boto_rds.describe_parameter_group(name, Filters=None, MaxRecords=None, Marker=None, region=None, key=None, keyid=None, profile=None) Returns a list of \fIDBParameterGroup\fP descriptions. CLI example to description of parameter group: @@ -110248,7 +117192,7 @@ salt myminion boto_rds.subnet_group_exists my\-param\-group regi .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_rds.update_parameter_group(name, parameters, apply_method=\(aqpending\-reboot\(aq, tags=None, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_rds.update_parameter_group(name, parameters, apply_method=u\(aqpending\-reboot\(aq, tags=None, region=None, key=None, keyid=None, profile=None) Update an RDS parameter group. .sp CLI example: @@ -110337,7 +117281,7 @@ boto .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_route53.add_record(name, value, zone, record_type, identifier=None, ttl=None, region=None, key=None, keyid=None, profile=None, wait_for_sync=True, split_dns=False, private_zone=False, retry_on_rate_limit=True, rate_limit_retries=5) +.B salt.modules.boto_route53.add_record(name, value, zone, record_type, identifier=None, ttl=None, region=None, key=None, keyid=None, profile=None, wait_for_sync=True, split_dns=False, private_zone=False, retry_on_rate_limit=None, rate_limit_retries=None, retry_on_errors=True, error_retries=5) Add a record to a zone. .sp CLI example: @@ -110354,24 +117298,135 @@ salt myminion boto_route53.add_record test.example.org 1.1.1.1 example.org A .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_route53.create_hosted_zone(domain_name, caller_ref=None, comment=\(aq\(aq, private_zone=False, vpc_id=None, vpc_name=None, vpc_region=None, region=None, key=None, keyid=None, profile=None) -Create a new Route53 Hosted Zone. Returns a Python data structure with -information about the newly created Hosted Zone. +.B salt.modules.boto_route53.create_healthcheck(ip_addr=None, fqdn=None, region=None, key=None, keyid=None, profile=None, port=53, hc_type=u\(aqTCP\(aq, resource_path=u\(aq\(aq, string_match=None, request_interval=30, failure_threshold=3, retry_on_errors=True, error_retries=5) +Create a Route53 healthcheck +.sp +New in version 2018.3.0. + +.sp +ip_addr +.INDENT 7.0 +.INDENT 3.5 +IP address to check. ip_addr or fqdn is required. +.UNINDENT +.UNINDENT +.sp +fqdn +.INDENT 7.0 +.INDENT 3.5 +Domain name of the endpoint to check. ip_addr or fqdn is required +.UNINDENT +.UNINDENT +.sp +port +.INDENT 7.0 +.INDENT 3.5 +Port to check +.UNINDENT +.UNINDENT +.sp +hc_type +.INDENT 7.0 +.INDENT 3.5 +Healthcheck type. HTTP | HTTPS | HTTP_STR_MATCH | HTTPS_STR_MATCH | TCP +.UNINDENT +.UNINDENT +.sp +resource_path +.INDENT 7.0 +.INDENT 3.5 +Path to check +.UNINDENT +.UNINDENT +.sp +string_match +.INDENT 7.0 +.INDENT 3.5 +If hc_type is HTTP_STR_MATCH or HTTPS_STR_MATCH, the string to search for in the +response body from the specified resource +.UNINDENT +.UNINDENT +.sp +request_interval +.INDENT 7.0 +.INDENT 3.5 +The number of seconds between the time that Amazon Route 53 gets a response from +your endpoint and the time that it sends the next health\-check request. +.UNINDENT +.UNINDENT +.sp +failure_threshold +.INDENT 7.0 +.INDENT 3.5 +The number of consecutive health checks that an endpoint must pass or fail for +Amazon Route 53 to change the current status of the endpoint from unhealthy to +healthy or vice versa. +.UNINDENT +.UNINDENT +.sp +region +.INDENT 7.0 +.INDENT 3.5 +Region endpoint to connect to +.UNINDENT +.UNINDENT +.sp +key +.INDENT 7.0 +.INDENT 3.5 +AWS key +.UNINDENT +.UNINDENT +.sp +keyid +.INDENT 7.0 +.INDENT 3.5 +AWS keyid +.UNINDENT +.UNINDENT +.sp +profile +.INDENT 7.0 +.INDENT 3.5 +AWS pillar profile +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion boto_route53.create_healthcheck 192.168.0.1 +salt myminion boto_route53.create_healthcheck 192.168.0.1 port=443 hc_type=HTTPS resource_path=/ fqdn=blog.saltstack.furniture +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.boto_route53.create_hosted_zone(domain_name, caller_ref=None, comment=u\(aq\(aq, private_zone=False, vpc_id=None, vpc_name=None, vpc_region=None, region=None, key=None, keyid=None, profile=None) +Create a new Route53 Hosted Zone. Returns a Python data structure with information about the +newly created Hosted Zone. .INDENT 7.0 .TP .B domain_name -The name of the domain. This should be a fully\-specified domain, and -should terminate with a period. This is the name you have registered -with your DNS registrar. It is also the name you will delegate from your -registrar to the Amazon Route 53 delegation servers returned in response +The name of the domain. This must be fully\-qualified, terminating with a period. This is +the name you have registered with your domain registrar. It is also the name you will +delegate from your registrar to the Amazon Route 53 delegation servers returned in response to this request. .TP .B caller_ref -A unique string that identifies the request and that allows -create_hosted_zone() calls to be retried without the risk of executing -the operation twice. You want to provide this where possible, since -additional calls while the first is in PENDING status will be accepted -and can lead to multiple copies of the zone being created in Route53. +A unique string that identifies the request and that allows create_hosted_zone() calls to +be retried without the risk of executing the operation twice. It can take several minutes +for the change to replicate globally, and change from PENDING to INSYNC status. Thus it\(aqs +best to provide some value for this where possible, since duplicate calls while the first +is in PENDING status will be accepted and can lead to multiple copies of the zone being +created. On the other hand, if a zone is created with a given caller_ref, then deleted, +a second attempt to create a zone with the same caller_ref will fail until that caller_ref +is flushed from the Route53 system, which can take upwards of 24 hours. .TP .B comment Any comments you want to include about the hosted zone. @@ -110380,33 +117435,30 @@ Any comments you want to include about the hosted zone. Set True if creating a private hosted zone. .TP .B vpc_id -When creating a private hosted zone, either the VPC ID or VPC Name to -associate with is required. Exclusive with vpe_name. Ignored if passed -for a non\-private zone. +When creating a private hosted zone, either the VPC ID or VPC Name to associate with is +required. Exclusive with vpe_name. Ignored when creating a non\-private zone. .TP .B vpc_name -When creating a private hosted zone, either the VPC ID or VPC Name to -associate with is required. Exclusive with vpe_id. Ignored if passed -for a non\-private zone. +When creating a private hosted zone, either the VPC ID or VPC Name to associate with is +required. Exclusive with vpe_id. Ignored when creating a non\-private zone. .TP .B vpc_region -When creating a private hosted zone, the region of the associated VPC is -required. If not provided, an effort will be made to determine it from -vpc_id or vpc_name, if possible. If this fails, you\(aqll need to provide -an explicit value for this option. Ignored if passed for a non\-private -zone. +When creating a private hosted zone, the region of the associated VPC is required. If not +provided, an effort will be made to determine it from vpc_id or vpc_name, where possible. +If this fails, you\(aqll need to provide an explicit value for this option. Ignored when +creating a non\-private zone. .TP .B region -Region endpoint to connect to +Region endpoint to connect to. .TP .B key -AWS key to bind with +AWS key to bind with. .TP .B keyid -AWS keyid to bind with +AWS keyid to bind with. .TP .B profile -Dict, or pillar key pointing to a dict, containing AWS region/key/keyid +Dict, or pillar key pointing to a dict, containing AWS region/key/keyid. .UNINDENT .sp CLI Example: @@ -110469,7 +117521,7 @@ salt myminion boto_route53.create_zone example.org .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_route53.delete_record(name, zone, record_type, identifier=None, all_records=False, region=None, key=None, keyid=None, profile=None, wait_for_sync=True, split_dns=False, private_zone=False, retry_on_rate_limit=True, rate_limit_retries=5) +.B salt.modules.boto_route53.delete_record(name, zone, record_type, identifier=None, all_records=False, region=None, key=None, keyid=None, profile=None, wait_for_sync=True, split_dns=False, private_zone=False, retry_on_rate_limit=None, rate_limit_retries=None, retry_on_errors=True, error_retries=5) Modify a record in a zone. .sp CLI example: @@ -110547,7 +117599,7 @@ salt myminion boto_route53.describe_hosted_zones domain_name=foo.bar.com. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_route53.get_record(name, zone, record_type, fetch_all=False, region=None, key=None, keyid=None, profile=None, split_dns=False, private_zone=False, identifier=None, retry_on_rate_limit=True, rate_limit_retries=5) +.B salt.modules.boto_route53.get_record(name, zone, record_type, fetch_all=False, region=None, key=None, keyid=None, profile=None, split_dns=False, private_zone=False, identifier=None, retry_on_rate_limit=None, rate_limit_retries=None, retry_on_errors=True, error_retries=5) Get a record from a zone. .sp CLI example: @@ -110628,7 +117680,7 @@ salt myminion boto_route53.list_all_zones_by_name .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_route53.update_record(name, value, zone, record_type, identifier=None, ttl=None, region=None, key=None, keyid=None, profile=None, wait_for_sync=True, split_dns=False, private_zone=False, retry_on_rate_limit=True, rate_limit_retries=5) +.B salt.modules.boto_route53.update_record(name, value, zone, record_type, identifier=None, ttl=None, region=None, key=None, keyid=None, profile=None, wait_for_sync=True, split_dns=False, private_zone=False, retry_on_rate_limit=None, rate_limit_retries=None, retry_on_errors=True, error_retries=5) Modify a record in a zone. .sp CLI example: @@ -110645,7 +117697,7 @@ salt myminion boto_route53.modify_record test.example.org 1.1.1.1 example.org A .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_route53.zone_exists(zone, region=None, key=None, keyid=None, profile=None, retry_on_rate_limit=True, rate_limit_retries=5) +.B salt.modules.boto_route53.zone_exists(zone, region=None, key=None, keyid=None, profile=None, retry_on_rate_limit=None, rate_limit_retries=None, retry_on_errors=True, error_retries=5) Check for the existence of a Route53 hosted zone. .sp New in version 2015.8.0. @@ -111851,7 +118903,7 @@ New in version 2014.7.0. This module accepts explicit sqs credentials but can also utilize IAM roles assigned to the instance through Instance Profiles. Dynamic credentials are then automatically obtained from AWS API and no further -configuration is necessary. More Information available at: +configuration is necessary. More information available at: .INDENT 7.0 .INDENT 3.5 .sp @@ -111908,11 +118960,11 @@ myprofile: .UNINDENT .TP .B depends -boto +boto3 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_sqs.create(name, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_sqs.create(name, attributes=None, region=None, key=None, keyid=None, profile=None) Create an SQS queue. .sp CLI Example: @@ -111963,26 +119015,6 @@ salt myminion boto_sqs.exists myqueue region=us\-east\-1 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_sqs.get_all_queues(prefix=None, region=None, key=None, keyid=None, profile=None) -Return a list of Queue() objects describing all visible queues. -.sp -New in version 2016.11.0. - -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt myminion boto_sqs.get_all_queues region=us\-east\-1 \-\-output yaml -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP .B salt.modules.boto_sqs.get_attributes(name, region=None, key=None, keyid=None, profile=None) Return attributes currently set on an SQS queue. .sp @@ -112000,7 +119032,7 @@ salt myminion boto_sqs.get_attributes myqueue .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_sqs.list(prefix=None, region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_sqs.list(prefix=u\(aq\(aq, region=None, key=None, keyid=None, profile=None) Return a list of the names of all visible queues. .sp New in version 2016.11.0. @@ -112242,7 +119274,7 @@ salt myminion boto_vpc.delete_vpc_peering_connection conn_id=pcx\-8a8939e3 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_vpc.accept_vpc_peering_connection(conn_id=\(aq\(aq, name=\(aq\(aq, region=None, key=None, keyid=None, profile=None, dry_run=False) +.B salt.modules.boto_vpc.accept_vpc_peering_connection(conn_id=u\(aq\(aq, name=u\(aq\(aq, region=None, key=None, keyid=None, profile=None, dry_run=False) Request a VPC peering connection between two VPCs. .sp New in version 2016.11.0. @@ -112955,7 +119987,7 @@ salt myminion boto_vpc.describe vpc_name=myvpc .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_vpc.describe_nat_gateways(nat_gateway_id=None, subnet_id=None, subnet_name=None, vpc_id=None, vpc_name=None, states=(\(aqpending\(aq, \(aqavailable\(aq), region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_vpc.describe_nat_gateways(nat_gateway_id=None, subnet_id=None, subnet_name=None, vpc_id=None, vpc_name=None, states=(u\(aqpending\(aq, u\(aqavailable\(aq), region=None, key=None, keyid=None, profile=None) Return a description of nat gateways matching the selection criteria .sp This function requires boto3 to be installed. @@ -113142,7 +120174,7 @@ salt myminion boto_vpc.describe_vpc_peering_connection salt\-vpc region=us\-west .B salt.modules.boto_vpc.describe_vpcs(vpc_id=None, name=None, cidr=None, tags=None, region=None, key=None, keyid=None, profile=None) Describe all VPCs, matching the filter criteria if provided. .sp -Returns a a list of dictionaries with interesting properties. +Returns a list of dictionaries with interesting properties. .sp New in version 2015.8.0. @@ -113373,7 +120405,7 @@ salt myminion boto_vpc.is_peering_connection_pending conn_id=pcx\-8a8939e3 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.boto_vpc.nat_gateway_exists(nat_gateway_id=None, subnet_id=None, subnet_name=None, vpc_id=None, vpc_name=None, states=(\(aqpending\(aq, \(aqavailable\(aq), region=None, key=None, keyid=None, profile=None) +.B salt.modules.boto_vpc.nat_gateway_exists(nat_gateway_id=None, subnet_id=None, subnet_name=None, vpc_id=None, vpc_name=None, states=(u\(aqpending\(aq, u\(aqavailable\(aq), region=None, key=None, keyid=None, profile=None) Checks if a nat gateway exists. .sp This function requires boto3 to be installed. @@ -113528,11 +120560,11 @@ ID of the requesting VPC. Exclusive with requester_vpc_name. Name tag of the requesting VPC. Exclusive with requester_vpc_id. .TP .B peer_vpc_id -ID of the VPC tp crete VPC peering connection with. This can be a VPC in +ID of the VPC to create VPC peering connection with. This can be a VPC in another account. Exclusive with peer_vpc_name. .TP .B peer_vpc_name -Name tag of the VPC tp crete VPC peering connection with. This can only +Name tag of the VPC to create VPC peering connection with. This can only be a VPC in the same account, else resolving it into a vpc ID will almost certainly fail. Exclusive with peer_vpc_id. .TP @@ -113947,7 +120979,7 @@ salt \(aq*\(aq bridge.show br0 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.bridge.stp(br=None, state=\(aqdisable\(aq, iface=None) +.B salt.modules.bridge.stp(br=None, state=u\(aqdisable\(aq, iface=None) Sets Spanning Tree Protocol state for a bridge .sp CLI Example: @@ -114584,7 +121616,7 @@ Capirca is not yet available on PyPI threrefore it has to be installed directly form Git: \fBpip install \-e git+git@github.com:google/capirca.git#egg=aclgen\fP\&. .INDENT 0.0 .TP -.B salt.modules.capirca_acl.get_filter_config(platform, filter_name, filter_options=None, terms=None, prepend=True, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=True, only_lower_merge=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=\(aq%Y/%m/%d\(aq) +.B salt.modules.capirca_acl.get_filter_config(platform, filter_name, filter_options=None, terms=None, prepend=True, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=True, only_lower_merge=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=u\(aq%Y/%m/%d\(aq) Return the configuration of a policy filter. .INDENT 7.0 .TP @@ -114699,7 +121731,7 @@ netacl: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.capirca_acl.get_filter_pillar(filter_name, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None) +.B salt.modules.capirca_acl.get_filter_pillar(filter_name, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None) Helper that can be used inside a state SLS, in order to get the filter configuration given its name. .INDENT 7.0 @@ -114721,7 +121753,7 @@ Included only for compatibility with .UNINDENT .INDENT 0.0 .TP -.B salt.modules.capirca_acl.get_policy_config(platform, filters=None, prepend=True, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=True, only_lower_merge=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=\(aq%Y/%m/%d\(aq) +.B salt.modules.capirca_acl.get_policy_config(platform, filters=None, prepend=True, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=True, only_lower_merge=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=u\(aq%Y/%m/%d\(aq) Return the configuration of the whole policy. .INDENT 7.0 .TP @@ -114876,7 +121908,7 @@ netacl: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.capirca_acl.get_term_config(platform, filter_name, term_name, filter_options=None, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=True, revision_id=None, revision_no=None, revision_date=True, revision_date_format=\(aq%Y/%m/%d\(aq, source_service=None, destination_service=None, **term_fields) +.B salt.modules.capirca_acl.get_term_config(platform, filter_name, term_name, filter_options=None, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=True, revision_id=None, revision_no=None, revision_date=True, revision_date_format=u\(aq%Y/%m/%d\(aq, source_service=None, destination_service=None, **term_fields) Return the configuration of a single policy term. .INDENT 7.0 .TP @@ -115078,6 +122110,8 @@ flattened_addr flattened_saddr .IP \(bu 2 flattened_daddr +.IP \(bu 2 +priority .UNINDENT .UNINDENT .UNINDENT @@ -115256,7 +122290,7 @@ exit .UNINDENT .INDENT 0.0 .TP -.B salt.modules.capirca_acl.get_term_pillar(filter_name, term_name, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None) +.B salt.modules.capirca_acl.get_term_pillar(filter_name, term_name, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None) Helper that can be used inside a state SLS, in order to get the term configuration given its name, under a certain filter uniquely identified by its name. @@ -115469,6 +122503,9 @@ Cassandra Database Module .sp New in version 2015.5.0. +.sp +This module works with Cassandra v2 and v3 and hence generates +queries based on the internal schema of said version. .INDENT 0.0 .TP .B depends @@ -115606,7 +122643,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq cql_query "SELECT * FROM users_by_name WHERE first_name = \(aqjane\(aq" +salt \(aqcassandra\-server\(aq cassandra_cql.cql_query "SELECT * FROM users_by_name WHERE first_name = \(aqjane\(aq" .ft P .fi .UNINDENT @@ -115671,7 +122708,7 @@ salt this\-node cassandra_cql.cql_query_with_prepare "name_select" "SELECT * FRO .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cassandra_cql.create_keyspace(keyspace, replication_strategy=\(aqSimpleStrategy\(aq, replication_factor=1, replication_datacenters=None, contact_points=None, port=None, cql_user=None, cql_pass=None) +.B salt.modules.cassandra_cql.create_keyspace(keyspace, replication_strategy=u\(aqSimpleStrategy\(aq, replication_factor=1, replication_datacenters=None, contact_points=None, port=None, cql_user=None, cql_pass=None) Create a new keyspace in Cassandra. .INDENT 7.0 .TP @@ -115808,7 +122845,7 @@ salt \(aqminion1\(aq cassandra_cql.drop_keyspace keyspace=test contact_points=mi .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cassandra_cql.grant_permission(username, resource=None, resource_type=\(aqkeyspace\(aq, permission=None, contact_points=None, port=None, cql_user=None, cql_pass=None) +.B salt.modules.cassandra_cql.grant_permission(username, resource=None, resource_type=u\(aqkeyspace\(aq, permission=None, contact_points=None, port=None, cql_user=None, cql_pass=None) Grant permissions to a user. .INDENT 7.0 .TP @@ -115919,8 +122956,6 @@ CLI Example: .nf .ft C salt \(aqminion1\(aq cassandra_cql.keyspace_exists keyspace=system - -salt \(aqminion1\(aq cassandra_cql.list_keyspaces keyspace=system contact_points=minion1 .ft P .fi .UNINDENT @@ -116010,7 +123045,7 @@ salt \(aqminion1\(aq cassandra_cql.list_keyspaces contact_points=minion1 port=90 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cassandra_cql.list_permissions(username=None, resource=None, resource_type=\(aqkeyspace\(aq, permission=None, contact_points=None, port=None, cql_user=None, cql_pass=None) +.B salt.modules.cassandra_cql.list_permissions(username=None, resource=None, resource_type=u\(aqkeyspace\(aq, permission=None, contact_points=None, port=None, cql_user=None, cql_pass=None) List permissions. .INDENT 7.0 .TP @@ -117506,7 +124541,7 @@ salt \(aq*\(aq chocolatey.enable_source .UNINDENT .INDENT 0.0 .TP -.B salt.modules.chocolatey.install(name, version=None, source=None, force=False, pre_versions=False, install_args=None, override_args=False, force_x86=False, package_args=None, allow_multiple=False) +.B salt.modules.chocolatey.install(name, version=None, source=None, force=False, pre_versions=False, install_args=None, override_args=False, force_x86=False, package_args=None, allow_multiple=False, execution_timeout=None) Instructs Chocolatey to install a package. .INDENT 7.0 .TP @@ -117565,6 +124600,14 @@ with \fBforce\fP\&. Does not work with all packages. Default is False. New in version 2017.7.0. +.IP \(bu 2 +\fBexecution_timeout\fP (\fI\%str\fP) \-\- +.IP \(bu 2 +\fBexecution timeout value you want to pass to the installation process. Default is None.\fP (\fIChocolatey\fP) \-\- +.sp +New in version 2018.3.0. + + .UNINDENT .TP .B Returns @@ -117971,7 +125014,7 @@ New in version 2016.3.4. .sp Instructs Chocolatey to upgrade packages on the system. (update is being -deprecated) +deprecated). This command will install the package if not installed. .INDENT 7.0 .TP .B Parameters @@ -118372,7 +125415,7 @@ salt minionname cloud.destroy myinstance .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cloud.full_query(query_type=\(aqlist_nodes_full\(aq) +.B salt.modules.cloud.full_query(query_type=u\(aqlist_nodes_full\(aq) List all available cloud provider data .sp CLI Example: @@ -118438,7 +125481,7 @@ salt minionname cloud.has_instance myinstance .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cloud.list_images(provider=\(aqall\(aq) +.B salt.modules.cloud.list_images(provider=u\(aqall\(aq) List cloud provider images for the given providers .sp CLI Example: @@ -118455,7 +125498,7 @@ salt minionname cloud.list_images my\-gce\-config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cloud.list_locations(provider=\(aqall\(aq) +.B salt.modules.cloud.list_locations(provider=u\(aqall\(aq) List cloud provider locations for the given providers .sp CLI Example: @@ -118472,7 +125515,7 @@ salt minionname cloud.list_locations my\-gce\-config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cloud.list_sizes(provider=\(aqall\(aq) +.B salt.modules.cloud.list_sizes(provider=u\(aqall\(aq) List cloud provider sizes for the given providers .sp CLI Example: @@ -118558,7 +125601,7 @@ salt minionname cloud.profile my\-gce\-config myinstance .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cloud.query(query_type=\(aqlist_nodes\(aq) +.B salt.modules.cloud.query(query_type=u\(aqlist_nodes\(aq) List cloud provider data for all providers .sp CLI Examples: @@ -118577,7 +125620,7 @@ salt minionname cloud.query list_nodes_select .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cloud.select_query(query_type=\(aqlist_nodes_select\(aq) +.B salt.modules.cloud.select_query(query_type=u\(aqlist_nodes_select\(aq) List selected nodes .sp CLI Example: @@ -118719,11 +125762,13 @@ Keep in mind that this module is insecure, in that it can give whomever has access to the master root execution access to all salt minions. .INDENT 0.0 .TP -.B salt.modules.cmdmod.exec_code(lang, code, cwd=None) +.B salt.modules.cmdmod.exec_code(lang, code, cwd=None, args=None, **kwargs) Pass in two strings, the first naming the executable language, aka \- python2, python3, ruby, perl, lua, etc. the second string containing the code you wish to execute. The stdout will be returned. .sp +All parameters from \fI\%cmd.run_all\fP except python_shell can be used. +.sp CLI Example: .INDENT 7.0 .INDENT 3.5 @@ -118731,6 +125776,7 @@ CLI Example: .nf .ft C salt \(aq*\(aq cmd.exec_code ruby \(aqputs "cheese"\(aq +salt \(aq*\(aq cmd.exec_code ruby \(aqputs "cheese"\(aq args=\(aq["arg1", "arg2"]\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -118738,12 +125784,14 @@ salt \(aq*\(aq cmd.exec_code ruby \(aqputs "cheese"\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.exec_code_all(lang, code, cwd=None) +.B salt.modules.cmdmod.exec_code_all(lang, code, cwd=None, args=None, **kwargs) Pass in two strings, the first naming the executable language, aka \- python2, python3, ruby, perl, lua, etc. the second string containing the code you wish to execute. All cmd artifacts (stdout, stderr, retcode, pid) will be returned. .sp +All parameters from \fI\%cmd.run_all\fP except python_shell can be used. +.sp CLI Example: .INDENT 7.0 .INDENT 3.5 @@ -118751,6 +125799,7 @@ CLI Example: .nf .ft C salt \(aq*\(aq cmd.exec_code_all ruby \(aqputs "cheese"\(aq +salt \(aq*\(aq cmd.exec_code_all ruby \(aqputs "cheese"\(aq args=\(aq["arg1", "arg2"]\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -118775,10 +125824,11 @@ salt \(aq*\(aq cmd.has_exec cat .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.powershell(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, quiet=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, password=None, depth=None, encode_cmd=False, **kwargs) +.B salt.modules.cmdmod.powershell(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, use_vt=False, password=None, depth=None, encode_cmd=False, **kwargs) Execute the passed PowerShell command and return the output as a dictionary. .sp -Other \fBcmd.*\fP functions return the raw text output of the command. This +Other \fBcmd.*\fP functions (besides \fBcmd.powershell_all\fP) +return the raw text output of the command. This function appends \fB| ConvertTo\-JSON\fP to the command and then parses the JSON into a Python dictionary. If you want the raw textual result of your PowerShell command you should use \fBcmd.run\fP with the \fBshell=powershell\fP @@ -118810,9 +125860,6 @@ and do not use untrusted inputs. .UNINDENT .UNINDENT .sp -Note that \fBenv\fP represents the environment variables for the command, and -should be formatted as a dict, or a YAML string which resolves to a dict. -.sp In addition to the normal \fBcmd.run\fP parameters, this command offers the \fBdepth\fP parameter to change the Windows default depth for the \fBConvertTo\-JSON\fP powershell command. The Windows default is 2. If you need @@ -118833,16 +125880,18 @@ returns useless data. .IP \(bu 2 \fBcmd\fP (\fI\%str\fP) \-\- The powershell command to run. .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 \fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the command to be run using the \fBstdin\fP parameter. This can be useful in cases -where sensitive information must be read from standard input.: +where sensitive information must be read from standard input. .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run command as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 \fBpassword\fP (\fI\%str\fP) \-\- .sp @@ -118853,72 +125902,28 @@ New in version 2016.3.0. .IP \(bu 2 -\fBshell\fP (\fI\%str\fP) \-\- Shell to execute under. Defaults to the system default -shell. +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. .IP \(bu 2 \fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional -arguments. Set to True to use shell features, such as pipes or redirection +arguments. Set to True to use shell features, such as pipes or +redirection. .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.powershell \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -118932,17 +125937,74 @@ variables and set only those provided in the \(aqenv\(aq argument to this function. .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBrstrip\fP (\fI\%bool\fP) \-\- Strip all whitespace off the end of output before it is returned. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG) regardless, unless \fBquiet\fP is used for this value. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBhide_output\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP, suppress stdout and stderr in the +return data. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + .IP \(bu 2 \fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to return. .IP \(bu 2 @@ -118951,8 +126013,6 @@ more interactively to the console and the logs. This is experimental. .IP \(bu 2 \fBreset_system_locale\fP (\fI\%bool\fP) \-\- Resets the system locale .IP \(bu 2 -\fBignore_retcode\fP (\fI\%bool\fP) \-\- Ignore the return code -.IP \(bu 2 \fBsaltenv\fP (\fI\%str\fP) \-\- The salt environment to use. Default is \(aqbase\(aq .IP \(bu 2 \fBdepth\fP (\fI\%int\fP) \-\- @@ -118993,101 +126053,164 @@ salt \(aq*\(aq cmd.powershell "$PSVersionTable.CLRVersion" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.retcode(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, umask=None, output_loglevel=\(aqdebug\(aq, log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, password=None, **kwargs) -Execute a shell command and return the command\(aqs return code. +.B salt.modules.cmdmod.powershell_all(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, quiet=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, use_vt=False, password=None, depth=None, encode_cmd=False, force_list=False, **kwargs) +Execute the passed PowerShell command and return a dictionary with a result +field representing the output of the command, as well as other fields +showing us what the PowerShell invocation wrote to \fBstderr\fP, the process +id, and the exit code of the invocation. +.sp +This function appends \fB| ConvertTo\-JSON\fP to the command before actually +invoking powershell. +.sp +An unquoted empty string is not valid JSON, but it\(aqs very normal for the +Powershell output to be exactly that. Therefore, we do not attempt to parse +empty Powershell output (which would result in an exception). Instead we +treat this as a special case and one of two things will happen: +.INDENT 7.0 +.IP \(bu 2 +If the value of the \fBforce_list\fP paramater is \fBTrue\fP, then the +\fBresult\fP field of the return dictionary will be an empty list. +.IP \(bu 2 +If the value of the \fBforce_list\fP paramater is \fBFalse\fP, then the +return dictionary \fBwill not have a result key added to it\fP\&. We aren\(aqt +setting \fBresult\fP to \fBNone\fP in this case, because \fBNone\fP is the +Python representation of "null" in JSON. (We likewise can\(aqt use \fBFalse\fP +for the equivalent reason.) +.UNINDENT +.sp +If Powershell\(aqs output is not an empty string and Python cannot parse its +content, then a \fBCommandExecutionError\fP exception will be raised. +.sp +If Powershell\(aqs output is not an empty string, Python is able to parse its +content, and the type of the resulting Python object is other than \fBlist\fP +then one of two things will happen: +.INDENT 7.0 +.IP \(bu 2 +If the value of the \fBforce_list\fP paramater is \fBTrue\fP, then the +\fBresult\fP field will be a singleton list with the Python object as its +sole member. +.IP \(bu 2 +If the value of the \fBforce_list\fP paramater is \fBFalse\fP, then the value +of \fBresult\fP will be the unmodified Python object. +.UNINDENT +.sp +If Powershell\(aqs output is not an empty string, Python is able to parse its +content, and the type of the resulting Python object is \fBlist\fP, then the +value of \fBresult\fP will be the unmodified Python object. The +\fBforce_list\fP paramater has no effect in this case. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +An example of why the \fBforce_list\fP paramater is useful is as +follows: The Powershell command \fBdir x | Convert\-ToJson\fP results in +.INDENT 0.0 +.IP \(bu 2 +no output when x is an empty directory. +.IP \(bu 2 +a dictionary object when x contains just one item. +.IP \(bu 2 +a list of dictionary objects when x contains multiple items. +.UNINDENT +.sp +By setting \fBforce_list\fP to \fBTrue\fP we will always end up with a +list of dictionary items, representing files, no matter how many files +x contains. Conversely, if \fBforce_list\fP is \fBFalse\fP, we will end +up with no \fBresult\fP key in our return dictionary when x is an empty +directory, and a dictionary object when x contains just one file. +.UNINDENT +.UNINDENT +.sp +If you want a similar function but with a raw textual result instead of a +Python dictionary, you should use \fBcmd.run_all\fP in combination with +\fBshell=powershell\fP\&. +.sp +The remaining fields in the return dictionary are described in more detail +in the \fBReturns\fP section. +.sp +Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq cmd.run_all \(aq$PSVersionTable.CLRVersion\(aq shell=powershell +salt \(aq*\(aq cmd.run_all \(aqGet\-NetTCPConnection\(aq shell=powershell +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + +.sp +\fBWARNING:\fP +.INDENT 7.0 +.INDENT 3.5 +This passes the cmd argument directly to PowerShell without any further +processing! Be absolutely sure that you have properly sanitized the +command passed to this function and do not use untrusted inputs. +.UNINDENT +.UNINDENT +.sp +In addition to the normal \fBcmd.run\fP parameters, this command offers the +\fBdepth\fP parameter to change the Windows default depth for the +\fBConvertTo\-JSON\fP powershell command. The Windows default is 2. If you need +more depth, set that here. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +For some commands, setting the depth to a value greater than 4 greatly +increases the time it takes for the command to return and in many cases +returns useless data. +.UNINDENT +.UNINDENT .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \(aqls \-lart /home\(aq +\fBcmd\fP (\fI\%str\fP) \-\- The powershell command to run. .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 \fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the -command to be run using the \fBstdin\fP parameter. This can be useful in cases -where sensitive information must be read from standard input.: +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run command as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 -\fBpassword\fP (\fI\%str\fP) \-\- -.sp -Windows only. Required when specifying \fBrunas\fP\&. This +\fBpassword\fP (\fI\%str\fP) \-\- Windows only. Required when specifying \fBrunas\fP\&. This parameter will be ignored on non\-Windows platforms. -.sp -New in version 2016.3.0. - - .IP \(bu 2 -\fBshell\fP (\fI\%str\fP) \-\- Shell to execute under. Defaults to the system default -shell. +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. .IP \(bu 2 \fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional -arguments. Set to True to use shell features, such as pipes or redirection +arguments. Set to True to use shell features, such as pipes or +redirection. .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.powershell_all \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -119101,33 +126224,265 @@ variables and set only those provided in the \(aqenv\(aq argument to this function. .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBrstrip\fP (\fI\%bool\fP) \-\- Strip all whitespace off the end of output before it is returned. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG) regardless, unless \fBquiet\fP is used for this value. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to +return. +.IP \(bu 2 +\fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output +more interactively to the console and the logs. This is experimental. +.IP \(bu 2 +\fBreset_system_locale\fP (\fI\%bool\fP) \-\- Resets the system locale +.IP \(bu 2 +\fBignore_retcode\fP \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBsaltenv\fP (\fI\%str\fP) \-\- The salt environment to use. Default is \(aqbase\(aq +.IP \(bu 2 +\fBdepth\fP (\fI\%int\fP) \-\- The number of levels of contained objects to be included. +Default is 2. Values greater than 4 seem to greatly increase the time +it takes for the command to complete for some commands. eg: \fBdir\fP +.IP \(bu 2 +\fBencode_cmd\fP (\fI\%bool\fP) \-\- Encode the command before executing. Use in cases +where characters may be dropped or incorrectly converted when executed. +Default is False. +.IP \(bu 2 +\fBforce_list\fP (\fI\%bool\fP) \-\- The purpose of this paramater is described in the +preamble of this function\(aqs documentation. Default value is False. +.UNINDENT +.TP +.B Returns +A dictionary with the following entries: +.INDENT 7.0 +.TP +.B result +For a complete description of this field, please refer to this +function\(aqs preamble. \fBThis key will not be added to the dictionary +when force_list is False and Powershell\(aqs output is the empty +string.\fP +.TP +.B stderr +What the PowerShell invocation wrote to \fBstderr\fP\&. +.TP +.B pid +The process id of the PowerShell invocation +.TP +.B retcode +This is the exit code of the invocation of PowerShell. +If the final execution status (in PowerShell) of our command +(with \fB| ConvertTo\-JSON\fP appended) is \fBFalse\fP this should be non\-0. +Likewise if PowerShell exited with \fB$LASTEXITCODE\fP set to some +non\-0 value, then \fBretcode\fP will end up with this value. +.UNINDENT + +.TP +.B Return type +\fI\%dict\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq cmd.powershell_all "$PSVersionTable.CLRVersion" +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq cmd.powershell_all "dir mydirectory" force_list=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cmdmod.retcode(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, umask=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, use_vt=False, password=None, **kwargs) +Execute a shell command and return the command\(aqs return code. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \fBls \-lart /home\fP +.IP \(bu 2 +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). +.IP \(bu 2 +\fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. +.IP \(bu 2 +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. +.IP \(bu 2 +\fBpassword\fP (\fI\%str\fP) \-\- +.sp +Windows only. Required when specifying \fBrunas\fP\&. This +parameter will be ignored on non\-Windows platforms. +.sp +New in version 2016.3.0. + + +.IP \(bu 2 +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. +.IP \(bu 2 +\fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional +arguments. Set to True to use shell features, such as pipes or +redirection. +.IP \(bu 2 +\fBenv\fP (\fI\%dict\fP) \-\- +.sp +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion cmd.retcode \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBclean_env\fP (\fI\%bool\fP) \-\- Attempt to clean out all other shell environment +variables and set only those provided in the \(aqenv\(aq argument to this +function. +.IP \(bu 2 +\fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. +.IP \(bu 2 +\fBrstrip\fP (\fI\%bool\fP) \-\- Strip all whitespace off the end of output before it is +returned. +.IP \(bu 2 +\fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. +.IP \(bu 2 +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. .IP \(bu 2 \fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to return. .IP \(bu 2 \fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. .UNINDENT -.UNINDENT -.sp -\fBNOTE:\fP -.INDENT 7.0 -.INDENT 3.5 -\fBenv\fP represents the environment variables for the command, and -should be formatted as a dict, or a YAML string which resolves to a dict. -.UNINDENT -.UNINDENT -.INDENT 7.0 .TP .B Return type \fI\%int\fP @@ -119167,7 +126522,7 @@ salt \(aq*\(aq cmd.retcode template=jinja "file {{grains.pythonpath[0]}}/python" .sp A string of standard input can be specified for the command to be run using the \fBstdin\fP parameter. This can be useful in cases where sensitive -information must be read from standard input.: +information must be read from standard input. .INDENT 7.0 .INDENT 3.5 .sp @@ -119181,11 +126536,8 @@ salt \(aq*\(aq cmd.retcode "grep f" stdin=\(aqone\entwo\enthree\enfour\enfive\en .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, bg=False, password=None, encoded_cmd=False, **kwargs) +.B salt.modules.cmdmod.run(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, use_vt=False, bg=False, password=None, encoded_cmd=False, raise_err=False, prepend_path=None, **kwargs) Execute the passed command and return the output as a string -.sp -Note that \fBenv\fP represents the environment variables for the command, and -should be formatted as a dict, or a YAML string which resolves to a dict. .INDENT 7.0 .TP .B Parameters @@ -119193,16 +126545,18 @@ should be formatted as a dict, or a YAML string which resolves to a dict. .IP \(bu 2 \fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \fBls \-lart /home\fP .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 \fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the -command to be run using the \fBstdin\fP parameter. This can be useful in cases -where sensitive information must be read from standard input. +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run command as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 \fBpassword\fP (\fI\%str\fP) \-\- .sp @@ -119213,8 +126567,8 @@ New in version 2016.3.0. .IP \(bu 2 -\fBshell\fP (\fI\%str\fP) \-\- Shell to execute under. Defaults to the system default -shell. +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. .IP \(bu 2 \fBpython_shell\fP (\fI\%bool\fP) \-\- If \fBFalse\fP, let python handle the positional arguments. Set to \fBTrue\fP to use shell features, such as pipes or @@ -119229,66 +126583,21 @@ New in version 2016.3.0. .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.run \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -119300,19 +126609,85 @@ mycommand: \fBclean_env\fP (\fI\%bool\fP) \-\- Attempt to clean out all other shell environment variables and set only those provided in the \(aqenv\(aq argument to this function. +.IP \(bu 2 +\fBprepend_path\fP (\fI\%str\fP) \-\- +.sp +$PATH segment to prepend (trailing \(aq:\(aq not +necessary) to $PATH +.sp +New in version 2018.3.0. + + .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBrstrip\fP (\fI\%bool\fP) \-\- Strip all whitespace off the end of output before it is returned. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG) regardless, unless \fBquiet\fP is used for this value. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBhide_output\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP, suppress stdout and stderr in the +return data. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + .IP \(bu 2 \fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to return. .IP \(bu 2 @@ -119321,6 +126696,9 @@ more interactively to the console and the logs. This is experimental. .IP \(bu 2 \fBencoded_cmd\fP (\fI\%bool\fP) \-\- Specify if the supplied command is encoded. Only applies to shell \(aqpowershell\(aq. +.IP \(bu 2 +\fBraise_err\fP (\fI\%bool\fP) \-\- If \fBTrue\fP and the command has a nonzero exit code, +a CommandExecutionError exception will be raised. .UNINDENT .UNINDENT .sp @@ -119380,7 +126758,7 @@ salt \(aq*\(aq cmd.run "Get\-ChildItem C:\e\e " shell=\(aqpowershell\(aq .sp A string of standard input can be specified for the command to be run using the \fBstdin\fP parameter. This can be useful in cases where sensitive -information must be read from standard input.: +information must be read from standard input. .INDENT 7.0 .INDENT 3.5 .sp @@ -119409,25 +126787,27 @@ salt \(aq*\(aq cmd.run cmd=\(aqsed \-e s/=/:/g\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run_all(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, redirect_stderr=False, password=None, **kwargs) +.B salt.modules.cmdmod.run_all(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, use_vt=False, redirect_stderr=False, password=None, encoded_cmd=False, prepend_path=None, **kwargs) Execute the passed command and return a dict of return data .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \(aqls \-lart /home\(aq +\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \fBls \-lart /home\fP .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 \fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the -command to be run using the \fBstdin\fP parameter. This can be useful in cases -where sensitive information must be read from standard input.: +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run command as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 \fBpassword\fP (\fI\%str\fP) \-\- .sp @@ -119438,72 +126818,28 @@ New in version 2016.3.0. .IP \(bu 2 -\fBshell\fP (\fI\%str\fP) \-\- Shell to execute under. Defaults to the system default -shell. +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. .IP \(bu 2 \fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional -arguments. Set to True to use shell features, such as pipes or redirection +arguments. Set to True to use shell features, such as pipes or +redirection. .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.run_all \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -119515,66 +126851,128 @@ mycommand: \fBclean_env\fP (\fI\%bool\fP) \-\- Attempt to clean out all other shell environment variables and set only those provided in the \(aqenv\(aq argument to this function. +.IP \(bu 2 +\fBprepend_path\fP (\fI\%str\fP) \-\- +.sp +$PATH segment to prepend (trailing \(aq:\(aq not +necessary) to $PATH +.sp +New in version 2018.3.0. + + .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBrstrip\fP (\fI\%bool\fP) \-\- Strip all whitespace off the end of output before it is returned. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG) regardless, unless \fBquiet\fP is used for this value. -.IP \(bu 2 -\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to return. -.IP \(bu 2 -\fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output -more interactively to the console and the logs. This is experimental. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. .UNINDENT .UNINDENT .sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp \fBNOTE:\fP -.INDENT 7.0 +.INDENT 2.0 .INDENT 3.5 -\fBenv\fP represents the environment variables for the command, and -should be formatted as a dict, or a YAML string which resolves to a dict. +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. .UNINDENT .UNINDENT -.INDENT 7.0 -.TP -.B Parameters -.INDENT 7.0 + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBhide_output\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP, suppress stdout and stderr in the +return data. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to +return. +.IP \(bu 2 +\fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output +more interactively to the console and the logs. This is experimental. +.IP \(bu 2 +\fBencoded_cmd\fP (\fI\%bool\fP) \-\- +.sp +Specify if the supplied command is encoded. +Only applies to shell \(aqpowershell\(aq. +.sp +New in version 2018.3.0. + + .IP \(bu 2 \fBredirect_stderr\fP (\fI\%bool\fP) \-\- .sp If set to \fBTrue\fP, then stderr will be -redirected to stdout. This is helpful for cases where obtaining both the -retcode and output is desired, but it is not desired to have the output -separated into both stdout and stderr. -.INDENT 2.0 -.INDENT 3.5 +redirected to stdout. This is helpful for cases where obtaining both +the retcode and output is desired, but it is not desired to have the +output separated into both stdout and stderr. +.sp New in version 2015.8.2. -.UNINDENT -.UNINDENT .IP \(bu 2 -\fBpassword\fP (\fI\%str\fP) \-\- +\fBpassword\fP \-\- .sp Windows only. Required when specifying \fBrunas\fP\&. This parameter will be ignored on non\-Windows platforms. -.sp +.INDENT 2.0 +.INDENT 3.5 New in version 2016.3.0. +.UNINDENT +.UNINDENT .IP \(bu 2 \fBbg\fP (\fI\%bool\fP) \-\- .sp If \fBTrue\fP, run command in background and do not await or -deliver it\(aqs results +deliver its results .sp New in version 2016.3.6. @@ -119610,7 +127008,7 @@ salt \(aq*\(aq cmd.run_all template=jinja "ls \-l /tmp/{{grains.id}} | awk \(aq/ .sp A string of standard input can be specified for the command to be run using the \fBstdin\fP parameter. This can be useful in cases where sensitive -information must be read from standard input.: +information must be read from standard input. .INDENT 7.0 .INDENT 3.5 .sp @@ -119624,18 +127022,17 @@ salt \(aq*\(aq cmd.run_all "grep f" stdin=\(aqone\entwo\enthree\enfour\enfive\en .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run_bg(cmd, cwd=None, runas=None, shell=\(aq/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, umask=None, timeout=None, output_loglevel=\(aqdebug\(aq, log_callback=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, password=None, **kwargs) +.B salt.modules.cmdmod.run_bg(cmd, cwd=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, umask=None, timeout=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, log_callback=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, password=None, prepend_path=None, **kwargs) Execute the passed command in the background and return it\(aqs PID .sp -Note that \fBenv\fP represents the environment variables for the command, and -should be formatted as a dict, or a YAML string which resolves to a dict. -.sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -If the init system is systemd and the backgrounded task should run even if the salt\-minion process -is restarted, prepend \fBsystemd\-run \-\-scope\fP to the command. This will reparent the process in its -own scope separate from salt\-minion, and will not be affected by restarting the minion service. +If the init system is systemd and the backgrounded task should run even +if the salt\-minion process is restarted, prepend \fBsystemd\-run +\-\-scope\fP to the command. This will reparent the process in its own +scope separate from salt\-minion, and will not be affected by restarting +the minion service. .UNINDENT .UNINDENT .INDENT 7.0 @@ -119643,18 +127040,60 @@ own scope separate from salt\-minion, and will not be affected by restarting the .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \(aqls \-lart /home\(aq +\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \fBls \-lart /home\fP .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG) regardless, unless \fBquiet\fP is used for this value. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run command as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 \fBpassword\fP (\fI\%str\fP) \-\- .sp @@ -119665,72 +127104,28 @@ New in version 2016.3.0. .IP \(bu 2 -\fBshell\fP (\fI\%str\fP) \-\- Shell to execute under. Defaults to the system default -shell. +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. .IP \(bu 2 \fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional -arguments. Set to True to use shell features, such as pipes or redirection +arguments. Set to True to use shell features, such as pipes or +redirection. .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.run_bg \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -119742,10 +127137,19 @@ mycommand: \fBclean_env\fP (\fI\%bool\fP) \-\- Attempt to clean out all other shell environment variables and set only those provided in the \(aqenv\(aq argument to this function. +.IP \(bu 2 +\fBprepend_path\fP (\fI\%str\fP) \-\- +.sp +$PATH segment to prepend (trailing \(aq:\(aq not +necessary) to $PATH +.sp +New in version 2018.3.0. + + .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 @@ -119756,16 +127160,16 @@ and wempy are supported \fBWARNING:\fP .INDENT 7.0 .INDENT 3.5 -This function does not process commands through a shell -unless the python_shell flag is set to True. This means that any +This function does not process commands through a shell unless the +\fBpython_shell\fP argument is set to \fBTrue\fP\&. This means that any shell\-specific functionality such as \(aqecho\(aq or the use of pipes, -redirection or &&, should either be migrated to cmd.shell or -have the python_shell=True flag set here. +redirection or &&, should either be migrated to cmd.shell or have the +python_shell=True flag set here. .sp -The use of python_shell=True means that the shell will accept _any_ input -including potentially malicious commands such as \(aqgood_command;rm \-rf /\(aq. -Be absolutely certain that you have sanitized your input prior to using -python_shell=True +The use of \fBpython_shell=True\fP means that the shell will accept _any_ +input including potentially malicious commands such as \(aqgood_command;rm +\-rf /\(aq. Be absolutely certain that you have sanitized your input prior +to using \fBpython_shell=True\fP\&. .UNINDENT .UNINDENT .sp @@ -119824,7 +127228,7 @@ salt \(aq*\(aq cmd.run_bg cmd=\(aqls \-lR / | sed \-e s/=/:/g > /tmp/dontwait\(a .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run_chroot(root, cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, python_shell=True, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqquiet\(aq, log_callback=None, quiet=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, bg=False, **kwargs) +.B salt.modules.cmdmod.run_chroot(root, cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=True, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel=u\(aqquiet\(aq, log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, use_vt=False, bg=False, **kwargs) New in version 2014.7.0. .sp @@ -119832,125 +127236,135 @@ This function runs \fI\%cmd.run_all\fP wrapped within a chroot, with dev and proc mounted in the chroot .INDENT 7.0 .TP -.B root -Path to the root of the jail to use. -.TP -.B cmd -The command to run. ex: \(aqls \-lart /home\(aq -.TP -.B cwd -The current working directory to execute the command in. defaults to -/root -.TP -.B stdin -A string of standard input can be specified for the command to be run using -the \fBstdin\fP parameter. This can be useful in cases where sensitive -information must be read from standard input.: -.TP -.B runas -User to run script as. -.TP -.B shell -Shell to execute under. Defaults to the system default shell. -.TP -.B python_shell -If False, let python handle the positional arguments. Set to True -to use shell features, such as pipes or redirection -.TP -.B env +.B Parameters .INDENT 7.0 +.IP \(bu 2 +\fBroot\fP (\fI\%str\fP) \-\- Path to the root of the jail to use. +.IP \(bu 2 +\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \fBls \-lart /home\fP +.IP \(bu 2 +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). +.IP \(bu 2 +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. +.IP \(bu 2 +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. +.IP \(bu 2 +\fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional +arguments. Set to True to use shell features, such as pipes or +redirection. +.IP \(bu 2 +\fBenv\fP (\fI\%dict\fP) \-\- +.sp +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP +.INDENT 2.0 .INDENT 3.5 -A list of environment variables to be set prior to execution. -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq +salt myminion cmd.run_chroot \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT .UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. .UNINDENT .UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} -.ft P -.fi +.IP \(bu 2 +\fBclean_env\fP (\fI\%dict\fP) \-\- Attempt to clean out all other shell environment +variables and set only those provided in the \(aqenv\(aq argument to this +function. +.IP \(bu 2 +\fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. +.IP \(bu 2 +\fBrstrip\fP (\fI\%bool\fP) \-\- Strip all whitespace off the end of output before it is returned. +.IP \(bu 2 +\fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. +.IP \(bu 2 +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. .UNINDENT .UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. .UNINDENT .UNINDENT -.INDENT 7.0 -.TP -.B clean_env: -Attempt to clean out all other shell environment variables and set -only those provided in the \(aqenv\(aq argument to this function. + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBhide_output\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP, suppress stdout and stderr in the +return data. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to return. +.IP \(bu 2 +\fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output more +interactively to the console and the logs. This is experimental. .UNINDENT .TP -.B template -If this setting is applied then the named templating engine will be -used to render the downloaded file. Currently jinja, mako, and wempy -are supported -.TP -.B rstrip -Strip all whitespace off the end of output before it is returned. -.TP -.B umask -The umask (in octal) to use when running the command. -.TP -.B output_loglevel -Control the loglevel at which the output from the command is logged. -Note that the command being run will still be logged (loglevel: DEBUG) -regardless, unless \fBquiet\fP is used for this value. -.TP -.B timeout -A timeout in seconds for the executed process to return. -.TP -.B use_vt -Use VT utils (saltstack) to stream the command output more -interactively to the console and the logs. -This is experimental. +.B Parar str stdin +A string of standard input can be specified for the +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. .UNINDENT .sp CLI Example: @@ -119967,25 +127381,27 @@ salt \(aq*\(aq cmd.run_chroot /var/lib/lxc/container_name/rootfs \(aqsh /tmp/boo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run_stderr(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, password=None, **kwargs) +.B salt.modules.cmdmod.run_stderr(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, use_vt=False, password=None, prepend_path=None, **kwargs) Execute a command and only return the standard error .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \(aqls \-lart /home\(aq +\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \fBls \-lart /home\fP .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 \fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the -command to be run using the \fBstdin\fP parameter. This can be useful in cases -where sensitive information must be read from standard input.: +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run command as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 \fBpassword\fP (\fI\%str\fP) \-\- .sp @@ -119996,72 +127412,28 @@ New in version 2016.3.0. .IP \(bu 2 -\fBshell\fP (\fI\%str\fP) \-\- Shell to execute under. Defaults to the system default -shell. +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. .IP \(bu 2 \fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional -arguments. Set to True to use shell features, such as pipes or redirection +arguments. Set to True to use shell features, such as pipes or +redirection. .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.run_stderr \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -120073,32 +127445,91 @@ mycommand: \fBclean_env\fP (\fI\%bool\fP) \-\- Attempt to clean out all other shell environment variables and set only those provided in the \(aqenv\(aq argument to this function. +.IP \(bu 2 +\fBprepend_path\fP (\fI\%str\fP) \-\- +.sp +$PATH segment to prepend (trailing \(aq:\(aq not +necessary) to $PATH +.sp +New in version 2018.3.0. + + .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBrstrip\fP (\fI\%bool\fP) \-\- Strip all whitespace off the end of output before it is returned. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG) regardless, unless \fBquiet\fP is used for this value. -.IP \(bu 2 -\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to return. -.IP \(bu 2 -\fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output -more interactively to the console and the logs. This is experimental. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. .UNINDENT .UNINDENT .sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp \fBNOTE:\fP -.INDENT 7.0 +.INDENT 2.0 .INDENT 3.5 -\fBenv\fP represents the environment variables for the command, and -should be formatted as a dict, or a YAML string which resolves to a dict. +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBhide_output\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP, suppress stdout and stderr in the +return data. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to +return. +.IP \(bu 2 +\fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output +more interactively to the console and the logs. This is experimental. .UNINDENT .UNINDENT .sp @@ -120130,7 +127561,7 @@ salt \(aq*\(aq cmd.run_stderr template=jinja "ls \-l /tmp/{{grains.id}} | awk \( .sp A string of standard input can be specified for the command to be run using the \fBstdin\fP parameter. This can be useful in cases where sensitive -information must be read from standard input.: +information must be read from standard input. .INDENT 7.0 .INDENT 3.5 .sp @@ -120144,25 +127575,27 @@ salt \(aq*\(aq cmd.run_stderr "grep f" stdin=\(aqone\entwo\enthree\enfour\enfive .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run_stdout(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, password=None, **kwargs) +.B salt.modules.cmdmod.run_stdout(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, use_vt=False, password=None, prepend_path=None, **kwargs) Execute a command, and only return the standard out .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \(aqls \-lart /home\(aq +\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \fBls \-lart /home\fP .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 \fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the -command to be run using the \fBstdin\fP parameter. This can be useful in cases -where sensitive information must be read from standard input.: +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run command as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 \fBpassword\fP (\fI\%str\fP) \-\- .sp @@ -120173,71 +127606,28 @@ New in version 2016.3.0. .IP \(bu 2 -\fBshell\fP (\fI\%str\fP) \-\- Shell to execute under. Defaults to the system default shell. +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. .IP \(bu 2 \fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional -arguments. Set to True to use shell features, such as pipes or redirection +arguments. Set to True to use shell features, such as pipes or +redirection. .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.run_stdout \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -120249,32 +127639,91 @@ mycommand: \fBclean_env\fP (\fI\%bool\fP) \-\- Attempt to clean out all other shell environment variables and set only those provided in the \(aqenv\(aq argument to this function. +.IP \(bu 2 +\fBprepend_path\fP (\fI\%str\fP) \-\- +.sp +$PATH segment to prepend (trailing \(aq:\(aq not necessary) +to $PATH +.sp +New in version 2018.3.0. + + .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBrstrip\fP (\fI\%bool\fP) \-\- Strip all whitespace off the end of output before it is returned. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG) regardless, unless \fBquiet\fP is used for this value. -.IP \(bu 2 -\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to return. -.IP \(bu 2 -\fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output -more interactively to the console and the logs. This is experimental. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. .UNINDENT .UNINDENT .sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp \fBNOTE:\fP -.INDENT 7.0 +.INDENT 2.0 .INDENT 3.5 -\fBenv\fP represents the environment variables for the command, and -should be formatted as a dict, or a YAML string which resolves to a dict. +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBhide_output\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP, suppress stdout and stderr in the +return data. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to +return. +.IP \(bu 2 +\fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output +more interactively to the console and the logs. This is experimental. .UNINDENT .UNINDENT .sp @@ -120306,7 +127755,7 @@ salt \(aq*\(aq cmd.run_stdout template=jinja "ls \-l /tmp/{{grains.id}} | awk \( .sp A string of standard input can be specified for the command to be run using the \fBstdin\fP parameter. This can be useful in cases where sensitive -information must be read from standard input.: +information must be read from standard input. .INDENT 7.0 .INDENT 3.5 .sp @@ -120320,7 +127769,7 @@ salt \(aq*\(aq cmd.run_stdout "grep f" stdin=\(aqone\entwo\enthree\enfour\enfive .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.script(source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, python_shell=None, env=None, template=None, umask=None, output_loglevel=\(aqdebug\(aq, log_callback=None, quiet=False, timeout=None, reset_system_locale=True, saltenv=\(aqbase\(aq, use_vt=False, bg=False, password=None, **kwargs) +.B salt.modules.cmdmod.script(source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, template=None, umask=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, saltenv=u\(aqbase\(aq, use_vt=False, bg=False, password=None, **kwargs) Download a script from a remote location and execute the script locally. The script can be located on the salt master file server or on an HTTP/FTP server. @@ -120333,24 +127782,38 @@ programming language. .INDENT 7.0 .IP \(bu 2 \fBsource\fP (\fI\%str\fP) \-\- The location of the script to download. If the file is -located on the master in the directory named spam, and is called eggs, the -source string is salt://spam/eggs +located on the master in the directory named spam, and is called eggs, +the source string is salt://spam/eggs .IP \(bu 2 -\fBargs\fP (\fI\%str\fP) \-\- String of command line args to pass to the script. Only +\fBargs\fP (\fI\%str\fP) \-\- +.sp +String of command line args to pass to the script. Only used if no args are specified as part of the \fIname\fP argument. To pass a string containing spaces in YAML, you will need to doubly\-quote it: -"arg1 \(aqarg two\(aq arg3" +.INDENT 2.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion cmd.script salt://foo.sh "arg1 \(aqarg two\(aq arg3" +.ft P +.fi +.UNINDENT +.UNINDENT + .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 \fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the -command to be run using the \fBstdin\fP parameter. This can be useful in cases -where sensitive information must be read from standard input.: +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run script as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 \fBpassword\fP (\fI\%str\fP) \-\- .sp @@ -120361,74 +127824,31 @@ New in version 2016.3.0. .IP \(bu 2 -\fBshell\fP (\fI\%str\fP) \-\- Shell to execute under. Defaults to the system default -shell. +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. .IP \(bu 2 \fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional -arguments. Set to True to use shell features, such as pipes or redirection +arguments. Set to True to use shell features, such as pipes or +redirection. .IP \(bu 2 -\fBbg\fP (\fI\%bool\fP) \-\- If True, run script in background and do not await or deliver it\(aqs results +\fBbg\fP (\fI\%bool\fP) \-\- If True, run script in background and do not await or +deliver it\(aqs results .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.script \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -120438,22 +127858,75 @@ mycommand: .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG)regardless, unless \fBquiet\fP is used for this value. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + .IP \(bu 2 -\fBquiet\fP (\fI\%bool\fP) \-\- The command will be executed quietly, meaning no log -entries of the actual command or its return data. This is deprecated as of -the \fB2014.1.0\fP release, and is being replaced with \fBoutput_loglevel: quiet\fP\&. +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + .IP \(bu 2 -\fBtimeout\fP (\fI\%int\fP) \-\- If the command has not terminated after timeout seconds, -send the subprocess sigterm, and if sigterm is ignored, follow up with -sigkill +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBhide_output\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP, suppress stdout and stderr in the +return data. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBtimeout\fP (\fI\%int\fP) \-\- If the command has not terminated after timeout +seconds, send the subprocess sigterm, and if sigterm is ignored, follow +up with sigkill .IP \(bu 2 \fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. @@ -120486,7 +127959,7 @@ salt \(aq*\(aq cmd.script salt://scripts/runme.sh stdin=\(aqone\entwo\enthree\en .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.script_retcode(source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, python_shell=None, env=None, template=\(aqjinja\(aq, umask=None, timeout=None, reset_system_locale=True, saltenv=\(aqbase\(aq, output_loglevel=\(aqdebug\(aq, log_callback=None, use_vt=False, password=None, **kwargs) +.B salt.modules.cmdmod.script_retcode(source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, template=u\(aqjinja\(aq, umask=None, timeout=None, reset_system_locale=True, saltenv=u\(aqbase\(aq, output_encoding=None, output_loglevel=u\(aqdebug\(aq, log_callback=None, use_vt=False, password=None, **kwargs) Download a script from a remote location and execute the script locally. The script can be located on the salt master file server or on an HTTP/FTP server. @@ -120503,24 +127976,26 @@ Only evaluate the script return code and do not block for terminal output .INDENT 7.0 .IP \(bu 2 \fBsource\fP (\fI\%str\fP) \-\- The location of the script to download. If the file is -located on the master in the directory named spam, and is called eggs, the -source string is salt://spam/eggs +located on the master in the directory named spam, and is called eggs, +the source string is salt://spam/eggs .IP \(bu 2 \fBargs\fP (\fI\%str\fP) \-\- String of command line args to pass to the script. Only used if no args are specified as part of the \fIname\fP argument. To pass a -string containing spaces in YAML, you will need to doubly\-quote it: "arg1 -\(aqarg two\(aq arg3" +string containing spaces in YAML, you will need to doubly\-quote it: +"arg1 \(aqarg two\(aq arg3" .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 \fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the -command to be run using the \fBstdin\fP parameter. This can be useful in cases -where sensitive information must be read from standard input.: +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run script as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 \fBpassword\fP (\fI\%str\fP) \-\- .sp @@ -120531,72 +128006,28 @@ New in version 2016.3.0. .IP \(bu 2 -\fBshell\fP (\fI\%str\fP) \-\- Shell to execute under. Defaults to the system default -shell. +\fBshell\fP (\fI\%str\fP) \-\- Specify an alternate shell. Defaults to the system\(aqs +default shell. .IP \(bu 2 \fBpython_shell\fP (\fI\%bool\fP) \-\- If False, let python handle the positional -arguments. Set to True to use shell features, such as pipes or redirection +arguments. Set to True to use shell features, such as pipes or +redirection. .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.script_retcode \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -120606,23 +128037,58 @@ mycommand: .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG) regardless, unless \fBquiet\fP is used for this value. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + .IP \(bu 2 -\fBquiet\fP (\fI\%bool\fP) \-\- The command will be executed quietly, meaning no log -entries of the actual command or its return data. This is deprecated as of -the \fB2014.1.0\fP release, and is being replaced with \fBoutput_loglevel: -quiet\fP\&. +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + .IP \(bu 2 -\fBtimeout\fP (\fI\%int\fP) \-\- If the command has not terminated after timeout seconds, -send the subprocess sigterm, and if sigterm is ignored, follow up with -sigkill +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBtimeout\fP (\fI\%int\fP) \-\- If the command has not terminated after timeout +seconds, send the subprocess sigterm, and if sigterm is ignored, follow +up with sigkill .IP \(bu 2 \fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. @@ -120645,7 +128111,7 @@ salt \(aq*\(aq cmd.script_retcode salt://scripts/windows_task.ps1 args=\(aq \-In .sp A string of standard input can be specified for the command to be run using the \fBstdin\fP parameter. This can be useful in cases where sensitive -information must be read from standard input.: +information must be read from standard input. .INDENT 7.0 .INDENT 3.5 .sp @@ -120659,7 +128125,7 @@ salt \(aq*\(aq cmd.script_retcode salt://scripts/runme.sh stdin=\(aqone\entwo\en .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.shell(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/zsh\(aq, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, log_callback=None, quiet=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, bg=False, password=None, **kwargs) +.B salt.modules.cmdmod.shell(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel=u\(aqdebug\(aq, log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=u\(aqbase\(aq, use_vt=False, bg=False, password=None, prepend_path=None, **kwargs) Execute the passed command and return the output as a string. .sp New in version 2015.5.0. @@ -120669,18 +128135,20 @@ New in version 2015.5.0. .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \(aqls \-lart /home\(aq +\fBcmd\fP (\fI\%str\fP) \-\- The command to run. ex: \fBls \-lart /home\fP .IP \(bu 2 -\fBcwd\fP (\fI\%str\fP) \-\- The current working directory to execute the command in. -Defaults to the home directory of the user specified by \fBrunas\fP\&. +\fBcwd\fP (\fI\%str\fP) \-\- The directory from which to execute the command. Defaults +to the home directory of the user specified by \fBrunas\fP (or the user +under which Salt is running if \fBrunas\fP is not specified). .IP \(bu 2 \fBstdin\fP (\fI\%str\fP) \-\- A string of standard input can be specified for the -command to be run using the \fBstdin\fP parameter. This can be useful in cases -where sensitive information must be read from standard input. +command to be run using the \fBstdin\fP parameter. This can be useful in +cases where sensitive information must be read from standard input. .IP \(bu 2 -\fBrunas\fP (\fI\%str\fP) \-\- User to run command as. If running on a Windows minion you -must also pass a password. The target user account must be in the -Administrators group. +\fBrunas\fP (\fI\%str\fP) \-\- Specify an alternate user to run the command. The default +behavior is to run as the user under which Salt is running. If running +on a Windows minion you must also use the \fBpassword\fP argument, and +the target user account must be in the Administrators group. .IP \(bu 2 \fBpassword\fP (\fI\%str\fP) \-\- .sp @@ -120697,66 +128165,21 @@ shell. \fBbg\fP (\fI\%bool\fP) \-\- If True, run command in background and do not await or deliver its results .IP \(bu 2 -\fBenv\fP (\fIlist\fP) \-\- +\fBenv\fP (\fI\%dict\fP) \-\- .sp -A list of environment variables to be set prior to -execution. +Environment variables to be set prior to execution. +.sp +\fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 -Example: +When passing environment variables on the CLI, they should be +passed as the string representation of a dictionary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt://scripts/foo.sh: - cmd.script: - \- env: - \- BATCH: \(aqyes\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWARNING:\fP -.INDENT 0.0 -.INDENT 3.5 -The above illustrates a common PyYAML pitfall, that \fByes\fP, -\fBno\fP, \fBon\fP, \fBoff\fP, \fBtrue\fP, and \fBfalse\fP are all loaded as -boolean \fBTrue\fP and \fBFalse\fP values, and must be enclosed in -quotes to be used as strings. More info on this (and other) PyYAML -idiosyncrasies can be found here\&. -.UNINDENT -.UNINDENT -.sp -Variables as values are not evaluated. So $PATH in the following -example is a literal \(aq$PATH\(aq: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt://scripts/bar.sh: - cmd.script: - \- env: "PATH=/some/path:$PATH" -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -One can still use the existing $PATH by using a bit of Jinja: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{% set current_path = salt[\(aqenviron.get\(aq](\(aqPATH\(aq, \(aq/bin:/usr/bin\(aq) %} - -mycommand: - cmd.run: - \- name: ls \-l / - \- env: - \- PATH: {{ [current_path, \(aq/my/special/bin\(aq]|join(\(aq:\(aq) }} +salt myminion cmd.shell \(aqsome command\(aq env=\(aq{"FOO": "bar"}\(aq .ft P .fi .UNINDENT @@ -120768,21 +128191,88 @@ mycommand: \fBclean_env\fP (\fI\%bool\fP) \-\- Attempt to clean out all other shell environment variables and set only those provided in the \(aqenv\(aq argument to this function. +.IP \(bu 2 +\fBprepend_path\fP (\fI\%str\fP) \-\- +.sp +$PATH segment to prepend (trailing \(aq:\(aq not necessary) +to $PATH +.sp +New in version 2018.3.0. + + .IP \(bu 2 \fBtemplate\fP (\fI\%str\fP) \-\- If this setting is applied then the named templating -engine will be used to render the downloaded file. Currently jinja, mako, -and wempy are supported +engine will be used to render the downloaded file. Currently jinja, +mako, and wempy are supported. .IP \(bu 2 \fBrstrip\fP (\fI\%bool\fP) \-\- Strip all whitespace off the end of output before it is returned. .IP \(bu 2 \fBumask\fP (\fI\%str\fP) \-\- The umask (in octal) to use when running the command. .IP \(bu 2 -\fBoutput_loglevel\fP (\fI\%str\fP) \-\- Control the loglevel at which the output from -the command is logged. Note that the command being run will still be logged -(loglevel: DEBUG) regardless, unless \fBquiet\fP is used for this value. +\fBoutput_encoding\fP (\fI\%str\fP) \-\- +.sp +Control the encoding used to decode the +command\(aqs output. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This should not need to be used in most cases. By default, Salt +will try to use the encoding detected from the system locale, and +will fall back to UTF\-8 if this fails. This should only need to be +used in cases where the output of the command is encoded in +something other than the system locale or UTF\-8. +.sp +To see the encoding Salt has detected from the system locale, check +the \fIlocale\fP line in the output of \fBtest.versions_report\fP\&. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + .IP \(bu 2 -\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to return. +\fBoutput_loglevel\fP (\fI\%str\fP) \-\- +.sp +Control the loglevel at which the output from +the command is logged to the minion log. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBignore_retcode\fP (\fI\%bool\fP) \-\- If the exit code of the command is nonzero, +this is treated as an error condition, and the output from the command +will be logged to the minion log. However, there are some cases where +programs use the return code for signaling and a nonzero exit code +doesn\(aqt necessarily mean failure. Pass this argument as \fBTrue\fP to +skip logging the output if the command has a nonzero exit code. +.IP \(bu 2 +\fBhide_output\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP, suppress stdout and stderr in the +return data. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBtimeout\fP (\fI\%int\fP) \-\- A timeout in seconds for the executed process to +return. .IP \(bu 2 \fBuse_vt\fP (\fI\%bool\fP) \-\- Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. @@ -120792,18 +128282,9 @@ more interactively to the console and the logs. This is experimental. \fBWARNING:\fP .INDENT 7.0 .INDENT 3.5 -This passes the cmd argument directly to the shell -without any further processing! Be absolutely sure that you -have properly sanitized the command passed to this function -and do not use untrusted inputs. -.UNINDENT -.UNINDENT -.sp -\fBNOTE:\fP -.INDENT 7.0 -.INDENT 3.5 -\fBenv\fP represents the environment variables for the command, and -should be formatted as a dict, or a YAML string which resolves to a dict. +This passes the cmd argument directly to the shell without any further +processing! Be absolutely sure that you have properly sanitized the +command passed to this function and do not use untrusted inputs. .UNINDENT .UNINDENT .sp @@ -120847,7 +128328,7 @@ salt \(aq*\(aq cmd.shell "Get\-ChildItem C:\e " shell=\(aqpowershell\(aq .sp A string of standard input can be specified for the command to be run using the \fBstdin\fP parameter. This can be useful in cases where sensitive -information must be read from standard input.: +information must be read from standard input. .INDENT 7.0 .INDENT 3.5 .sp @@ -120975,7 +128456,7 @@ salt \(aq*\(aq cmd.shells .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.tty(device, echo=\(aq\(aq) +.B salt.modules.cmdmod.tty(device, echo=u\(aq\(aq) Echo a string to a specific tty .sp CLI Example: @@ -121052,7 +128533,7 @@ salt \(aq*\(aq composer.did_composer_install /var/www/application .UNINDENT .INDENT 0.0 .TP -.B salt.modules.composer.install(directory, composer=None, php=None, runas=None, prefer_source=None, prefer_dist=None, no_scripts=None, no_plugins=None, optimize=None, no_dev=None, quiet=False, composer_home=\(aq/root\(aq) +.B salt.modules.composer.install(directory, composer=None, php=None, runas=None, prefer_source=None, prefer_dist=None, no_scripts=None, no_plugins=None, optimize=None, no_dev=None, quiet=False, composer_home=u\(aq/root\(aq) Install composer dependencies for a directory. .sp If composer has not been installed globally making it available in the @@ -121116,7 +128597,7 @@ salt \(aq*\(aq composer.install /var/www/application no_dev=True opt .UNINDENT .INDENT 0.0 .TP -.B salt.modules.composer.selfupdate(composer=None, php=None, runas=None, quiet=False, composer_home=\(aq/root\(aq) +.B salt.modules.composer.selfupdate(composer=None, php=None, runas=None, quiet=False, composer_home=u\(aq/root\(aq) Update composer itself. .sp If composer has not been installed globally making it available in the @@ -121157,7 +128638,7 @@ salt \(aq*\(aq composer.selfupdate .UNINDENT .INDENT 0.0 .TP -.B salt.modules.composer.update(directory, composer=None, php=None, runas=None, prefer_source=None, prefer_dist=None, no_scripts=None, no_plugins=None, optimize=None, no_dev=None, quiet=False, composer_home=\(aq/root\(aq) +.B salt.modules.composer.update(directory, composer=None, php=None, runas=None, prefer_source=None, prefer_dist=None, no_scripts=None, no_plugins=None, optimize=None, no_dev=None, quiet=False, composer_home=u\(aq/root\(aq) Update composer dependencies for a directory. .sp If \fIcomposer install\fP has not yet been run, this runs \fIcomposer install\fP @@ -121227,7 +128708,7 @@ salt \(aq*\(aq composer.update /var/www/application no_dev=True opti Return config information .INDENT 0.0 .TP -.B salt.modules.config.backup_mode(backup=\(aq\(aq) +.B salt.modules.config.backup_mode(backup=u\(aq\(aq) Return the backup mode .sp CLI Example: @@ -121284,7 +128765,7 @@ salt \(aq*\(aq config.gather_bootstrap_script .UNINDENT .INDENT 0.0 .TP -.B salt.modules.config.get(key, default=\(aq\(aq, delimiter=\(aq:\(aq, merge=None) +.B salt.modules.config.get(key, default=u\(aq\(aq, delimiter=u\(aq:\(aq, merge=None, omit_opts=False, omit_pillar=False, omit_master=False, omit_grains=False) Attempt to retrieve the named value from the minion config file, pillar, grains or the master config. If the named value is not available, return the value specified by \fBdefault\fP\&. If not specified, the default is an empty @@ -121493,7 +128974,7 @@ salt \(aq*\(aq config.manage_mode .UNINDENT .INDENT 0.0 .TP -.B salt.modules.config.merge(value, default=\(aq\(aq, omit_opts=False, omit_master=False, omit_pillar=False) +.B salt.modules.config.merge(value, default=u\(aq\(aq, omit_opts=False, omit_master=False, omit_pillar=False) Retrieves an option based on key, merging all matches. .sp Same as \fBoption()\fP except that it merges all matches, rather than taking @@ -121513,7 +128994,7 @@ salt \(aq*\(aq config.merge schedule .UNINDENT .INDENT 0.0 .TP -.B salt.modules.config.option(value, default=\(aq\(aq, omit_opts=False, omit_master=False, omit_pillar=False) +.B salt.modules.config.option(value, default=u\(aq\(aq, omit_opts=False, omit_master=False, omit_pillar=False) Pass in a generic option and receive the value that will be assigned .sp CLI Example: @@ -121553,7 +129034,7 @@ Interact with Consul \fI\%https://www.consul.io\fP .INDENT 0.0 .TP -.B salt.modules.consul.acl_clone(consul_url=None, **kwargs) +.B salt.modules.consul.acl_clone(consul_url=None, token=None, **kwargs) Information about an ACL token. .INDENT 7.0 .TP @@ -121584,7 +129065,7 @@ salt \(aq*\(aq consul.acl_info id=\(aqc1c4d223\-91cb\-3d1f\-1ee8\-f2af9e7b6716\( .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.acl_create(consul_url=None, **kwargs) +.B salt.modules.consul.acl_create(consul_url=None, token=None, **kwargs) Create a new ACL token. .INDENT 7.0 .TP @@ -121593,9 +129074,6 @@ Create a new ACL token. .IP \(bu 2 \fBconsul_url\fP \-\- The Consul server URL. .IP \(bu 2 -\fBid\fP \-\- Unique identifier for the ACL to create -leave it blank to let consul server generate one -.IP \(bu 2 \fBname\fP \-\- Meaningful indicator of the ACL\(aqs purpose. .IP \(bu 2 \fBtype\fP \-\- Type is either client or management. A management @@ -121624,7 +129102,7 @@ salt \(aq*\(aq consul.acl_create .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.acl_delete(consul_url=None, **kwargs) +.B salt.modules.consul.acl_delete(consul_url=None, token=None, **kwargs) Delete an ACL token. .INDENT 7.0 .TP @@ -121684,7 +129162,7 @@ salt \(aq*\(aq consul.acl_info id=\(aqc1c4d223\-91cb\-3d1f\-1ee8\-f2af9e7b6716\( .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.acl_list(consul_url=None, **kwargs) +.B salt.modules.consul.acl_list(consul_url=None, token=None, **kwargs) List the ACL tokens. .INDENT 7.0 .TP @@ -121709,7 +129187,7 @@ salt \(aq*\(aq consul.acl_list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.acl_update(consul_url=None, **kwargs) +.B salt.modules.consul.acl_update(consul_url=None, token=None, **kwargs) Update an ACL token. .INDENT 7.0 .TP @@ -121748,7 +129226,7 @@ salt \(aq*\(aq consul.acl_update .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_check_deregister(consul_url=None, checkid=None) +.B salt.modules.consul.agent_check_deregister(consul_url=None, token=None, checkid=None) The agent will take care of deregistering the check from the Catalog. .INDENT 7.0 .TP @@ -121778,7 +129256,7 @@ salt \(aq*\(aq consul.agent_check_deregister checkid=\(aqMemory Utilization\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_check_fail(consul_url=None, checkid=None, **kwargs) +.B salt.modules.consul.agent_check_fail(consul_url=None, token=None, checkid=None, **kwargs) This endpoint is used with a check that is of the TTL type. When this is called, the status of the check is set to critical and the TTL clock is reset. @@ -121813,7 +129291,7 @@ salt \(aq*\(aq consul.agent_check_fail checkid=\(aqredis_check1\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_check_pass(consul_url=None, checkid=None, **kwargs) +.B salt.modules.consul.agent_check_pass(consul_url=None, token=None, checkid=None, **kwargs) This endpoint is used with a check that is of the TTL type. When this is called, the status of the check is set to passing and the TTL clock is reset. @@ -121848,7 +129326,7 @@ salt \(aq*\(aq consul.agent_check_pass checkid=\(aqredis_check1\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_check_register(consul_url=None, **kwargs) +.B salt.modules.consul.agent_check_register(consul_url=None, token=None, **kwargs) The register endpoint is used to add a new check to the local agent. .INDENT 7.0 .TP @@ -121897,7 +129375,7 @@ salt \(aq*\(aq consul.agent_check_register name=\(aqMemory Utilization\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_check_warn(consul_url=None, checkid=None, **kwargs) +.B salt.modules.consul.agent_check_warn(consul_url=None, token=None, checkid=None, **kwargs) This endpoint is used with a check that is of the TTL type. When this is called, the status of the check is set to warning and the TTL clock is reset. @@ -121932,7 +129410,7 @@ salt \(aq*\(aq consul.agent_check_warn checkid=\(aqredis_check1\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_checks(consul_url=None) +.B salt.modules.consul.agent_checks(consul_url=None, token=None) Returns the checks the local agent is managing .INDENT 7.0 .TP @@ -121957,7 +129435,7 @@ salt \(aq*\(aq consul.agent_checks .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_join(consul_url=None, address=None, **kwargs) +.B salt.modules.consul.agent_join(consul_url=None, token=None, address=None, **kwargs) Triggers the local agent to join a node .INDENT 7.0 .TP @@ -121989,7 +129467,7 @@ salt \(aq*\(aq consul.agent_join address=\(aq192.168.1.1\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_leave(consul_url=None, node=None) +.B salt.modules.consul.agent_leave(consul_url=None, token=None, node=None) Used to instruct the agent to force a node into the left state. .INDENT 7.0 .TP @@ -122019,7 +129497,7 @@ salt \(aq*\(aq consul.agent_leave node=\(aqweb1.example.com\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_maintenance(consul_url=None, **kwargs) +.B salt.modules.consul.agent_maintenance(consul_url=None, token=None, **kwargs) Manages node maintenance mode .INDENT 7.0 .TP @@ -122056,7 +129534,7 @@ salt \(aq*\(aq consul.agent_maintenance enable=\(aqFalse\(aq reason=\(aqUpgrade .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_members(consul_url=None, **kwargs) +.B salt.modules.consul.agent_members(consul_url=None, token=None, **kwargs) Returns the members as seen by the local serf agent .INDENT 7.0 .TP @@ -122081,7 +129559,7 @@ salt \(aq*\(aq consul.agent_members .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_self(consul_url=None) +.B salt.modules.consul.agent_self(consul_url=None, token=None) Returns the local node configuration .INDENT 7.0 .TP @@ -122106,7 +129584,7 @@ salt \(aq*\(aq consul.agent_self .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_service_deregister(consul_url=None, serviceid=None) +.B salt.modules.consul.agent_service_deregister(consul_url=None, token=None, serviceid=None) Used to remove a service. .INDENT 7.0 .TP @@ -122136,7 +129614,7 @@ salt \(aq*\(aq consul.agent_service_deregister serviceid=\(aqredis\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_service_maintenance(consul_url=None, serviceid=None, **kwargs) +.B salt.modules.consul.agent_service_maintenance(consul_url=None, token=None, serviceid=None, **kwargs) Used to place a service into maintenance mode. .INDENT 7.0 .TP @@ -122172,7 +129650,7 @@ salt \(aq*\(aq consul.agent_service_deregister serviceid=\(aqredis\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_service_register(consul_url=None, **kwargs) +.B salt.modules.consul.agent_service_register(consul_url=None, token=None, **kwargs) The used to add a new service, with an optional health check, to the local agent. .INDENT 7.0 @@ -122229,7 +129707,7 @@ salt \(aq*\(aq consul.agent_service_register name=\(aqredis\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.agent_services(consul_url=None) +.B salt.modules.consul.agent_services(consul_url=None, token=None) Returns the services the local agent is managing .INDENT 7.0 .TP @@ -122254,7 +129732,7 @@ salt \(aq*\(aq consul.agent_services .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.catalog_datacenters(consul_url=None) +.B salt.modules.consul.catalog_datacenters(consul_url=None, token=None) Return list of available datacenters from catalog. .INDENT 7.0 .TP @@ -122279,7 +129757,7 @@ salt \(aq*\(aq consul.catalog_datacenters .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.catalog_deregister(consul_url=None, **kwargs) +.B salt.modules.consul.catalog_deregister(consul_url=None, token=None, **kwargs) Deregisters a node, service, or check .INDENT 7.0 .TP @@ -122317,7 +129795,7 @@ salt \(aq*\(aq consul.catalog_register node=\(aqnode1\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.catalog_node(consul_url=None, node=None, **kwargs) +.B salt.modules.consul.catalog_node(consul_url=None, token=None, node=None, **kwargs) Information about the registered node. .INDENT 7.0 .TP @@ -122350,7 +129828,7 @@ salt \(aq*\(aq consul.catalog_service service=\(aqredis\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.catalog_nodes(consul_url=None, **kwargs) +.B salt.modules.consul.catalog_nodes(consul_url=None, token=None, **kwargs) Return list of available nodes from catalog. .INDENT 7.0 .TP @@ -122381,7 +129859,7 @@ salt \(aq*\(aq consul.catalog_nodes .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.catalog_register(consul_url=None, **kwargs) +.B salt.modules.consul.catalog_register(consul_url=None, token=None, **kwargs) Registers a new node, service, or check .INDENT 7.0 .TP @@ -122440,7 +129918,7 @@ salt \(aq*\(aq consul.catalog_register node=\(aqnode1\(aq address=\(aq192.168.1. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.catalog_service(consul_url=None, service=None, **kwargs) +.B salt.modules.consul.catalog_service(consul_url=None, token=None, service=None, **kwargs) Information about the registered service. .INDENT 7.0 .TP @@ -122473,7 +129951,7 @@ salt \(aq*\(aq consul.catalog_service service=\(aqredis\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.catalog_services(consul_url=None, **kwargs) +.B salt.modules.consul.catalog_services(consul_url=None, token=None, **kwargs) Return list of available services rom catalog. .INDENT 7.0 .TP @@ -122504,7 +129982,7 @@ salt \(aq*\(aq consul.catalog_services .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.delete(consul_url=None, key=None, **kwargs) +.B salt.modules.consul.delete(consul_url=None, token=None, key=None, **kwargs) Delete values from Consul .INDENT 7.0 .TP @@ -122541,7 +130019,7 @@ salt \(aq*\(aq consul.delete key=\(aqweb\(aq recurse=\(aqTrue\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.event_fire(consul_url=None, name=None, **kwargs) +.B salt.modules.consul.event_fire(consul_url=None, token=None, name=None, **kwargs) List the ACL tokens. .INDENT 7.0 .TP @@ -122580,7 +130058,7 @@ salt \(aq*\(aq consul.event_fire name=\(aqdeploy\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.event_list(consul_url=None, **kwargs) +.B salt.modules.consul.event_list(consul_url=None, token=None, **kwargs) List the recent events. .INDENT 7.0 .TP @@ -122610,7 +130088,7 @@ salt \(aq*\(aq consul.event_list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.get(consul_url=None, key=None, recurse=False, decode=False, raw=False) +.B salt.modules.consul.get(consul_url=None, key=None, token=None, recurse=False, decode=False, raw=False) Get key from Consul .INDENT 7.0 .TP @@ -122667,7 +130145,7 @@ option will return only the raw value. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.health_checks(consul_url=None, service=None, **kwargs) +.B salt.modules.consul.health_checks(consul_url=None, token=None, service=None, **kwargs) Health information about the registered service. .INDENT 7.0 .TP @@ -122700,7 +130178,7 @@ salt \(aq*\(aq consul.health_checks service=\(aqredis1\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.health_node(consul_url=None, node=None, **kwargs) +.B salt.modules.consul.health_node(consul_url=None, token=None, node=None, **kwargs) Health information about the registered node. .INDENT 7.0 .TP @@ -122733,7 +130211,7 @@ salt \(aq*\(aq consul.health_node node=\(aqnode1\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.health_service(consul_url=None, service=None, **kwargs) +.B salt.modules.consul.health_service(consul_url=None, token=None, service=None, **kwargs) Health information about the registered service. .INDENT 7.0 .TP @@ -122773,7 +130251,7 @@ salt \(aq*\(aq consul.health_service service=\(aqredis1\(aq passing=\(aqTrue\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.health_state(consul_url=None, state=None, **kwargs) +.B salt.modules.consul.health_state(consul_url=None, token=None, state=None, **kwargs) Returns the checks in the state provided on the path. .INDENT 7.0 .TP @@ -122811,7 +130289,7 @@ salt \(aq*\(aq consul.health_state service=\(aqredis1\(aq passing=\(aqTrue\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.list(consul_url=None, key=None, **kwargs) +.B salt.modules.consul.list(consul_url=None, token=None, key=None, **kwargs) List keys in Consul .INDENT 7.0 .TP @@ -122843,7 +130321,7 @@ salt \(aq*\(aq consul.list key=\(aqweb\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.put(consul_url=None, key=None, value=None, **kwargs) +.B salt.modules.consul.put(consul_url=None, token=None, key=None, value=None, **kwargs) Put values into Consul .INDENT 7.0 .TP @@ -122894,7 +130372,7 @@ salt \(aq*\(aq consul.put key=\(aqweb/key1\(aq value="Hello there" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.session_create(consul_url=None, **kwargs) +.B salt.modules.consul.session_create(consul_url=None, token=None, **kwargs) Used to create a session. .INDENT 7.0 .TP @@ -122946,7 +130424,7 @@ salt \(aq*\(aq consul.session_create node=\(aqnode1\(aq name=\(aqmy\-session\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.session_destroy(consul_url=None, session=None, **kwargs) +.B salt.modules.consul.session_destroy(consul_url=None, token=None, session=None, **kwargs) Destroy session .INDENT 7.0 .TP @@ -122979,7 +130457,7 @@ salt \(aq*\(aq consul.session_destroy session=\(aqc1c4d223\-91cb\-3d1f\-1ee8\-f2 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.session_info(consul_url=None, session=None, **kwargs) +.B salt.modules.consul.session_info(consul_url=None, token=None, session=None, **kwargs) Information about a session .INDENT 7.0 .TP @@ -123012,7 +130490,7 @@ salt \(aq*\(aq consul.session_info session=\(aqc1c4d223\-91cb\-3d1f\-1ee8\-f2af9 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.session_list(consul_url=None, return_list=False, **kwargs) +.B salt.modules.consul.session_list(consul_url=None, token=None, return_list=False, **kwargs) Used to list sessions. .INDENT 7.0 .TP @@ -123047,7 +130525,7 @@ salt \(aq*\(aq consul.session_list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.status_leader(consul_url=None) +.B salt.modules.consul.status_leader(consul_url=None, token=None) Returns the current Raft leader .INDENT 7.0 .TP @@ -123072,7 +130550,7 @@ salt \(aq*\(aq consul.status_leader .UNINDENT .INDENT 0.0 .TP -.B salt.modules.consul.status_peers(consul_url) +.B salt.modules.consul.status_peers(consul_url, token=None) Returns the current Raft peer set .INDENT 7.0 .TP @@ -123081,7 +130559,7 @@ Returns the current Raft peer set .TP .B Returns Retrieves the Raft peers for the -datacenter in which the the agent is running. +datacenter in which the agent is running. .UNINDENT .sp CLI Example: @@ -123176,7 +130654,7 @@ salt myminion container_resource.run mycontainer \(aqps aux\(aq container_type=d Minion side functions for salt\-cp .INDENT 0.0 .TP -.B salt.modules.cp.cache_dir(path, saltenv=\(aqbase\(aq, include_empty=False, include_pat=None, exclude_pat=None) +.B salt.modules.cp.cache_dir(path, saltenv=u\(aqbase\(aq, include_empty=False, include_pat=None, exclude_pat=None) Download and cache everything under a directory from the master .INDENT 7.0 .TP @@ -123222,10 +130700,20 @@ salt \(aq*\(aq cp.cache_dir salt://path/to/dir include_pat=\(aqE@*.py$\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.cache_file(path, saltenv=\(aqbase\(aq) +.B salt.modules.cp.cache_file(path, saltenv=u\(aqbase\(aq, source_hash=None) Used to cache a single file on the Minion .sp -Returns the location of the new cached file on the Minion. +Returns the location of the new cached file on the Minion +.INDENT 7.0 +.TP +.B source_hash +If \fBname\fP is an http(s) or ftp URL and the file exists in the +minion\(aqs file cache, this option can be passed to keep the minion from +re\-downloading the file if the cached copy matches the specified hash. +.sp +New in version 2018.3.0. + +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -123268,7 +130756,7 @@ depending on the shell being used to run the command. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.cache_files(paths, saltenv=\(aqbase\(aq) +.B salt.modules.cp.cache_files(paths, saltenv=u\(aqbase\(aq) Used to gather many files from the Master, the gathered files will be saved in the minion cachedir reflective to the paths retrieved from the Master @@ -123344,7 +130832,7 @@ salt \(aq*\(aq cp.cache_local_file /etc/hosts .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.cache_master(saltenv=\(aqbase\(aq) +.B salt.modules.cp.cache_master(saltenv=u\(aqbase\(aq) Retrieve all of the files on the master and cache them locally .sp CLI Example: @@ -123361,7 +130849,7 @@ salt \(aq*\(aq cp.cache_master .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.get_dir(path, dest, saltenv=\(aqbase\(aq, template=None, gzip=None, **kwargs) +.B salt.modules.cp.get_dir(path, dest, saltenv=u\(aqbase\(aq, template=None, gzip=None, **kwargs) Used to recursively copy a directory from the salt master .sp CLI Example: @@ -123380,7 +130868,10 @@ get_dir supports the same template and gzip arguments as get_file. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.get_file(path, dest, saltenv=\(aqbase\(aq, makedirs=False, template=None, gzip=None, **kwargs) +.B salt.modules.cp.get_file(path, dest, saltenv=u\(aqbase\(aq, makedirs=False, template=None, gzip=None, **kwargs) +Changed in version 2018.3.0: \fBdest\fP can now be a directory + +.sp Used to get a single file from the salt master .sp CLI Example: @@ -123446,7 +130937,7 @@ depending on the shell being used to run the command. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.get_file_str(path, saltenv=\(aqbase\(aq) +.B salt.modules.cp.get_file_str(path, saltenv=u\(aqbase\(aq) Download a file from a URL to the Minion cache directory and return the contents of that file .sp @@ -123466,7 +130957,7 @@ salt \(aq*\(aq cp.get_file_str salt://my/file .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.get_template(path, dest, template=\(aqjinja\(aq, saltenv=\(aqbase\(aq, makedirs=False, **kwargs) +.B salt.modules.cp.get_template(path, dest, template=u\(aqjinja\(aq, saltenv=u\(aqbase\(aq, makedirs=False, **kwargs) Render a file as a template before setting it down. Warning, order is not the same as in fileclient.cp for non breaking old API. @@ -123485,7 +130976,10 @@ salt \(aq*\(aq cp.get_template salt://path/to/template /minion/dest .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.get_url(path, dest=\(aq\(aq, saltenv=\(aqbase\(aq, makedirs=False) +.B salt.modules.cp.get_url(path, dest=u\(aq\(aq, saltenv=u\(aqbase\(aq, makedirs=False, source_hash=None) +Changed in version 2018.3.0: \fBdest\fP can now be a directory + +.sp Used to get a single file from a URL. .INDENT 7.0 .TP @@ -123519,6 +131013,14 @@ and \fBfile://\fP URLs. The files fetched by \fBhttp://\fP and base Salt fileserver envrionment from which to retrieve the file. Ignored if \fBpath\fP is not a \fBsalt://\fP URL. +.TP +.B source_hash +If \fBpath\fP is an http(s) or ftp URL and the file exists in the +minion\(aqs file cache, this option can be passed to keep the minion from +re\-downloading the file if the cached copy matches the specified hash. +.sp +New in version 2018.3.0. + .UNINDENT .sp CLI Example: @@ -123536,7 +131038,7 @@ salt \(aq*\(aq cp.get_url http://www.slashdot.org /tmp/index.html .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.hash_file(path, saltenv=\(aqbase\(aq) +.B salt.modules.cp.hash_file(path, saltenv=u\(aqbase\(aq) Return the hash of a file, to get the hash of a file on the salt master file server prepend the path with salt:// otherwise, prepend the file with / for a local file. @@ -123555,7 +131057,7 @@ salt \(aq*\(aq cp.hash_file salt://path/to/file .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.is_cached(path, saltenv=\(aqbase\(aq) +.B salt.modules.cp.is_cached(path, saltenv=u\(aqbase\(aq) Return a boolean if the given path on the master has been cached on the minion .sp @@ -123573,7 +131075,7 @@ salt \(aq*\(aq cp.is_cached salt://path/to/file .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.list_master(saltenv=\(aqbase\(aq, prefix=\(aq\(aq) +.B salt.modules.cp.list_master(saltenv=u\(aqbase\(aq, prefix=u\(aq\(aq) List all of the files stored on the master .sp CLI Example: @@ -123590,7 +131092,7 @@ salt \(aq*\(aq cp.list_master .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.list_master_dirs(saltenv=\(aqbase\(aq, prefix=\(aq\(aq) +.B salt.modules.cp.list_master_dirs(saltenv=u\(aqbase\(aq, prefix=u\(aq\(aq) List all of the directories stored on the master .sp CLI Example: @@ -123607,7 +131109,7 @@ salt \(aq*\(aq cp.list_master_dirs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.list_master_symlinks(saltenv=\(aqbase\(aq, prefix=\(aq\(aq) +.B salt.modules.cp.list_master_symlinks(saltenv=u\(aqbase\(aq, prefix=u\(aq\(aq) List all of the symlinks stored on the master .sp CLI Example: @@ -123624,7 +131126,7 @@ salt \(aq*\(aq cp.list_master_symlinks .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.list_minion(saltenv=\(aqbase\(aq) +.B salt.modules.cp.list_minion(saltenv=u\(aqbase\(aq) List all of the files cached on the minion .sp CLI Example: @@ -123641,7 +131143,7 @@ salt \(aq*\(aq cp.list_minion .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.list_states(saltenv=\(aqbase\(aq) +.B salt.modules.cp.list_states(saltenv=u\(aqbase\(aq) List all of the available state modules in an environment .sp CLI Example: @@ -123750,7 +131252,7 @@ not intended to be used directly on the CLI. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cp.stat_file(path, saltenv=\(aqbase\(aq, octal=True) +.B salt.modules.cp.stat_file(path, saltenv=u\(aqbase\(aq, octal=True) Return the permissions of a file, to get the permissions of a file on the salt master file server prepend the path with salt:// otherwise, prepend the file with / for a local file. @@ -124127,7 +131629,7 @@ Linux .UNINDENT .INDENT 0.0 .TP -.B salt.modules.csf.allow(ip, port=None, proto=\(aqtcp\(aq, direction=\(aqin\(aq, port_origin=\(aqd\(aq, ip_origin=\(aqs\(aq, ttl=None, comment=\(aq\(aq) +.B salt.modules.csf.allow(ip, port=None, proto=u\(aqtcp\(aq, direction=u\(aqin\(aq, port_origin=u\(aqd\(aq, ip_origin=u\(aqs\(aq, ttl=None, comment=u\(aq\(aq) Add an rule to csf allowed hosts See \fB_access_rule()\fP\&. 1\- Add an IP: @@ -124146,7 +131648,7 @@ salt \(aq*\(aq csf.allow 127.0.0.1 comment="Allow localhost" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.csf.allow_port(port, proto=\(aqtcp\(aq, direction=\(aqboth\(aq) +.B salt.modules.csf.allow_port(port, proto=u\(aqtcp\(aq, direction=u\(aqboth\(aq) Like allow_ports, but it will append to the existing entry instead of replacing it. Takes a single port instead of a list of ports. @@ -124165,7 +131667,7 @@ salt \(aq*\(aq csf.allow_port 22 proto=\(aqtcp\(aq direction=\(aqin\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.csf.allow_ports(ports, proto=\(aqtcp\(aq, direction=\(aqin\(aq) +.B salt.modules.csf.allow_ports(ports, proto=u\(aqtcp\(aq, direction=u\(aqin\(aq) Fully replace the incoming or outgoing ports line in the csf.conf file \- e.g. TCP_IN, TCP_OUT, UDP_IN, UDP_OUT, etc. @@ -124184,7 +131686,7 @@ salt \(aq*\(aq csf.allow_ports ports="[22,80,443,4505,4506]" proto=\(aqtcp\(aq d .UNINDENT .INDENT 0.0 .TP -.B salt.modules.csf.deny(ip, port=None, proto=\(aqtcp\(aq, direction=\(aqin\(aq, port_origin=\(aqd\(aq, ip_origin=\(aqd\(aq, ttl=None, comment=\(aq\(aq) +.B salt.modules.csf.deny(ip, port=None, proto=u\(aqtcp\(aq, direction=u\(aqin\(aq, port_origin=u\(aqd\(aq, ip_origin=u\(aqd\(aq, ttl=None, comment=u\(aq\(aq) Add an rule to csf denied hosts See \fB_access_rule()\fP\&. 1\- Deny an IP: @@ -124235,7 +131737,7 @@ salt \(aq*\(aq csf.enable .UNINDENT .INDENT 0.0 .TP -.B salt.modules.csf.exists(method, ip, port=None, proto=\(aqtcp\(aq, direction=\(aqin\(aq, port_origin=\(aqd\(aq, ip_origin=\(aqd\(aq, ttl=None, comment=\(aq\(aq) +.B salt.modules.csf.exists(method, ip, port=None, proto=u\(aqtcp\(aq, direction=u\(aqin\(aq, port_origin=u\(aqd\(aq, ip_origin=u\(aqd\(aq, ttl=None, comment=u\(aq\(aq) Returns true a rule for the ip already exists based on the method supplied. Returns false if not found. @@ -124254,7 +131756,7 @@ salt \(aq*\(aq csf.exists tempdeny 1.2.3.4 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.csf.get_ports(proto=\(aqtcp\(aq, direction=\(aqin\(aq) +.B salt.modules.csf.get_ports(proto=u\(aqtcp\(aq, direction=u\(aqin\(aq) Lists ports from csf.conf based on direction and protocol. e.g. \- TCP_IN, TCP_OUT, UDP_IN, UDP_OUT, etc.. .sp @@ -124304,7 +131806,7 @@ salt \(aq*\(aq csf.running .UNINDENT .INDENT 0.0 .TP -.B salt.modules.csf.tempallow(ip=None, ttl=None, port=None, direction=None, comment=\(aq\(aq) +.B salt.modules.csf.tempallow(ip=None, ttl=None, port=None, direction=None, comment=u\(aq\(aq) Add an rule to the temporary ip allow list. See \fB_access_rule()\fP\&. 1\- Add an IP: @@ -124322,7 +131824,7 @@ salt \(aq*\(aq csf.tempallow 127.0.0.1 3600 port=22 direction=\(aqin\(aq comment .UNINDENT .INDENT 0.0 .TP -.B salt.modules.csf.tempdeny(ip=None, ttl=None, port=None, direction=None, comment=\(aq\(aq) +.B salt.modules.csf.tempdeny(ip=None, ttl=None, port=None, direction=None, comment=u\(aq\(aq) Add a rule to the temporary ip deny list. See \fB_access_rule()\fP\&. 1\- Add an IP: @@ -124381,7 +131883,7 @@ Manage cygwin packages. Module file to accompany the cyg state. .INDENT 0.0 .TP -.B salt.modules.cyg.check_valid_package(package, cyg_arch=\(aqx86_64\(aq, mirrors=None) +.B salt.modules.cyg.check_valid_package(package, cyg_arch=u\(aqx86_64\(aq, mirrors=None) Check if the package is valid on the given mirrors. .INDENT 7.0 .TP @@ -124412,7 +131914,7 @@ salt \(aq*\(aq cyg.check_valid_package .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cyg.install(packages=None, cyg_arch=\(aqx86_64\(aq, mirrors=None) +.B salt.modules.cyg.install(packages=None, cyg_arch=u\(aqx86_64\(aq, mirrors=None) Install one or several packages. .INDENT 7.0 .TP @@ -124441,7 +131943,7 @@ salt \(aq*\(aq cyg.install dos2unix mirrors=[{\(aqhttp://mirror\(aq: \(aqhttp:// .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cyg.list(package=\(aq\(aq, cyg_arch=\(aqx86_64\(aq) +.B salt.modules.cyg.list(package=u\(aq\(aq, cyg_arch=u\(aqx86_64\(aq) List locally installed packages. .INDENT 7.0 .TP @@ -124468,7 +131970,7 @@ salt \(aq*\(aq cyg.list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cyg.uninstall(packages, cyg_arch=\(aqx86_64\(aq, mirrors=None) +.B salt.modules.cyg.uninstall(packages, cyg_arch=u\(aqx86_64\(aq, mirrors=None) Uninstall one or several packages. .INDENT 7.0 .TP @@ -124496,7 +131998,7 @@ salt \(aq*\(aq cyg.uninstall dos2unix mirrors=[{\(aqhttp://mirror\(aq: \(aqhttp: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cyg.update(cyg_arch=\(aqx86_64\(aq, mirrors=None) +.B salt.modules.cyg.update(cyg_arch=u\(aqx86_64\(aq, mirrors=None) Update all packages. .INDENT 7.0 .TP @@ -124970,6 +132472,150 @@ salt \(aq*\(aq data.values .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.datadog_api +.sp +An execution module that interacts with the Datadog API +.sp +The following parameters are required for all functions. +.INDENT 0.0 +.TP +.B api_key +The datadog API key +.TP +.B app_key +The datadog application key +.UNINDENT +.sp +Full argument reference is available on the Datadog API reference page +\fI\%https://docs.datadoghq.com/api/\fP +.INDENT 0.0 +.TP +.B salt.modules.datadog_api.cancel_downtime(api_key=None, app_key=None, scope=None, id=None) +Cancel a downtime by id or by scope. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call datadog.cancel_downtime scope=\(aqhost:app01\(aq \e + api_key=\(aq0123456789\(aq \e + app_key=\(aq9876543210\(aq\(ga +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Arguments \- Either scope or id is required. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBid\fP \-\- The downtime ID +.IP \(bu 2 +\fBscope\fP \-\- The downtime scope +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.datadog_api.post_event(api_key=None, app_key=None, title=None, text=None, date_happened=None, priority=None, host=None, tags=None, alert_type=None, aggregation_key=None, source_type_name=None) +Post an event to the Datadog stream. +.sp +CLI Example +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call datadog.post_event api_key=\(aq0123456789\(aq \e + app_key=\(aq9876543210\(aq \e + title=\(aqSalt Highstate\(aq \e + text="Salt highstate was run on $(salt\-call grains.get id)" \e + tags=\(aq["service:salt", "event:highstate"]\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Required arguments +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBtitle\fP \-\- The event title. Limited to 100 characters. +.IP \(bu 2 +\fBtext\fP \-\- The body of the event. Limited to 4000 characters. The text +supports markdown. +.UNINDENT +.UNINDENT +.sp +Optional arguments +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBdate_happened\fP \-\- POSIX timestamp of the event. +.IP \(bu 2 +\fBpriority\fP \-\- The priority of the event (\(aqnormal\(aq or \(aqlow\(aq). +.IP \(bu 2 +\fBhost\fP \-\- Host name to associate with the event. +.IP \(bu 2 +\fBtags\fP \-\- A list of tags to apply to the event. +.IP \(bu 2 +\fBalert_type\fP \-\- "error", "warning", "info" or "success". +.IP \(bu 2 +\fBaggregation_key\fP \-\- An arbitrary string to use for aggregation, +max length of 100 characters. +.IP \(bu 2 +\fBsource_type_name\fP \-\- The type of event being posted. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.datadog_api.schedule_downtime(scope, api_key=None, app_key=None, monitor_id=None, start=None, end=None, message=None, recurrence=None, timezone=None, test=False) +Schedule downtime for a scope of monitors. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call datadog.schedule_downtime \(aqhost:app2\(aq \e + stop=$(date \-\-date=\(aq30 minutes\(aq +%s) \e + app_key=\(aq0123456789\(aq \e + api_key=\(aq9876543210\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Optional arguments +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmonitor_id\fP \-\- The ID of the monitor +.IP \(bu 2 +\fBstart\fP \-\- Start time in seconds since the epoch +.IP \(bu 2 +\fBend\fP \-\- End time in seconds since the epoch +.IP \(bu 2 +\fBmessage\fP \-\- A message to send in a notification for this downtime +.IP \(bu 2 +\fBrecurrence\fP \-\- Repeat this downtime periodically +.IP \(bu 2 +\fBtimezone\fP \-\- Specify the timezone +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.ddns .sp Support for RFC 2136 dynamic DNS updates. @@ -125017,7 +132663,7 @@ with an extra period in the file, similar to this: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ddns.add_host(zone, name, ttl, ip, nameserver=\(aq127.0.0.1\(aq, replace=True, timeout=5, port=53, **kwargs) +.B salt.modules.ddns.add_host(zone, name, ttl, ip, nameserver=u\(aq127.0.0.1\(aq, replace=True, timeout=5, port=53, **kwargs) Add, replace, or update the A and PTR (reverse) records for a host. .sp CLI Example: @@ -125034,7 +132680,7 @@ salt ns1 ddns.add_host example.com host1 60 10.1.1.1 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ddns.delete(zone, name, rdtype=None, data=None, nameserver=\(aq127.0.0.1\(aq, timeout=5, port=53, **kwargs) +.B salt.modules.ddns.delete(zone, name, rdtype=None, data=None, nameserver=u\(aq127.0.0.1\(aq, timeout=5, port=53, **kwargs) Delete a DNS record. .sp CLI Example: @@ -125051,7 +132697,7 @@ salt ns1 ddns.delete example.com host1 A .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ddns.delete_host(zone, name, nameserver=\(aq127.0.0.1\(aq, timeout=5, port=53, **kwargs) +.B salt.modules.ddns.delete_host(zone, name, nameserver=u\(aq127.0.0.1\(aq, timeout=5, port=53, **kwargs) Delete the forward and reverse records for a host. .sp Returns true if any records are deleted. @@ -125070,7 +132716,7 @@ salt ns1 ddns.delete_host example.com host1 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ddns.update(zone, name, ttl, rdtype, data, nameserver=\(aq127.0.0.1\(aq, timeout=5, replace=False, port=53, **kwargs) +.B salt.modules.ddns.update(zone, name, ttl, rdtype, data, nameserver=u\(aq127.0.0.1\(aq, timeout=5, replace=False, port=53, **kwargs) Add, replace, or update a DNS record. nameserver must be an IP address and the minion running this module must have update privileges on that server. @@ -125293,7 +132939,7 @@ salt \(aq*\(aq apache.check_site_enabled example.com.conf Module to provide Postgres compatibility to salt for debian family specific tools. .INDENT 0.0 .TP -.B salt.modules.deb_postgres.cluster_create(version, name=\(aqmain\(aq, port=None, locale=None, encoding=None, datadir=None) +.B salt.modules.deb_postgres.cluster_create(version, name=u\(aqmain\(aq, port=None, locale=None, encoding=None, datadir=None) Adds a cluster to the Postgres server. .sp CLI Example: @@ -125314,7 +132960,7 @@ salt \(aq*\(aq postgres.cluster_create \(aq9.3\(aq locale=\(aqfr_FR\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.deb_postgres.cluster_exists(version, name=\(aqmain\(aq) +.B salt.modules.deb_postgres.cluster_exists(version, name=u\(aqmain\(aq) Checks if a given version and name of a cluster exists. .sp CLI Example: @@ -125352,7 +132998,7 @@ salt \(aq*\(aq postgres.cluster_list verbose=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.deb_postgres.cluster_remove(version, name=\(aqmain\(aq, stop=False) +.B salt.modules.deb_postgres.cluster_remove(version, name=u\(aqmain\(aq, stop=False) Remove a cluster on a Postgres server. By default it doesn\(aqt try to stop the cluster. .sp @@ -125385,7 +133031,7 @@ environments. This also provides a function to generate debian repositories This module implements the pkgbuild interface .INDENT 0.0 .TP -.B salt.modules.debbuild.build(runas, tgt, dest_dir, spec, sources, deps, env, template, saltenv=\(aqbase\(aq, log_dir=\(aq/var/log/salt/pkgbuild\(aq) +.B salt.modules.debbuild.build(runas, tgt, dest_dir, spec, sources, deps, env, template, saltenv=u\(aqbase\(aq, log_dir=u\(aq/var/log/salt/pkgbuild\(aq) Given the package destination directory, the tarball containing debian files (e.g. control) and package sources, use pbuilder to safely build the platform package .sp @@ -125408,7 +133054,7 @@ and place it in /var/www/html/ on the minion .UNINDENT .INDENT 0.0 .TP -.B salt.modules.debbuild.make_repo(repodir, keyid=None, env=None, use_passphrase=False, gnupghome=\(aq/etc/salt/gpgkeys\(aq, runas=\(aqroot\(aq, timeout=15.0) +.B salt.modules.debbuild.make_repo(repodir, keyid=None, env=None, use_passphrase=False, gnupghome=u\(aq/etc/salt/gpgkeys\(aq, runas=u\(aqroot\(aq, timeout=15.0) Make a package repository and optionally sign it and packages present .sp Given the repodir (directory to create repository in), create a Debian @@ -125540,7 +133186,7 @@ salt \(aq*\(aq pkgbuild.make_repo /var/www/html .UNINDENT .INDENT 0.0 .TP -.B salt.modules.debbuild.make_src_pkg(dest_dir, spec, sources, env=None, template=None, saltenv=\(aqbase\(aq) +.B salt.modules.debbuild.make_src_pkg(dest_dir, spec, sources, env=None, template=None, saltenv=u\(aqbase\(aq) Create a platform specific source package from the given platform spec/control file and sources .sp CLI Example: @@ -125609,7 +133255,7 @@ salt \(aq*\(aq debconf.set [ ...] .UNINDENT .INDENT 0.0 .TP -.B salt.modules.debconfmod.set_file(path, saltenv=\(aqbase\(aq, **kwargs) +.B salt.modules.debconfmod.set_file(path, saltenv=u\(aqbase\(aq, **kwargs) Set answers to debconf questions from a file. .sp CLI Example: @@ -125626,7 +133272,7 @@ salt \(aq*\(aq debconf.set_file salt://pathto/pkg.selections .UNINDENT .INDENT 0.0 .TP -.B salt.modules.debconfmod.set_template(path, template, context, defaults, saltenv=\(aqbase\(aq, **kwargs) +.B salt.modules.debconfmod.set_template(path, template, context, defaults, saltenv=u\(aqbase\(aq, **kwargs) Set answers to debconf questions from a template. .INDENT 7.0 .TP @@ -125686,7 +133332,7 @@ salt \(aq*\(aq debconf.show .UNINDENT .SS salt.modules.debian_ip .sp -The networking module for Debian based distros +The networking module for Debian\-based distros .sp References: .INDENT 0.0 @@ -126120,8 +133766,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.debian_service.status(name, sig=None) -Return the status for a service, pass a signature to use to find -the service via ps +Return the status for a service. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Signature to use to find the service via ps +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -126129,7 +133796,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq service.status +salt \(aq*\(aq service.status [service signature] .ft P .fi .UNINDENT @@ -126153,9 +133820,25 @@ salt \(aq*\(aq service.stop .UNINDENT .UNINDENT .SS salt.modules.defaults +.sp +Module to work with salt formula defaults files .INDENT 0.0 .TP -.B salt.modules.defaults.get(key, default=\(aq\(aq) +.B salt.modules.defaults.deepcopy(source) +Allows deep copy of objects in formulas. +.INDENT 7.0 +.INDENT 3.5 +By default, Python does not copy objects, +it creates bindings between a target and an object. +.UNINDENT +.UNINDENT +.sp +It is more typical to use this in a templating language in formulas, +instead of directly on the command\-line. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.defaults.get(key, default=u\(aq\(aq) defaults.get is used much like pillar.get except that it will read a default value for a pillar from defaults.json or defaults.yaml files that are stored in the root of a salt formula. @@ -126180,16 +133863,24 @@ For example, querying \fBcore:users:root\fP will try to load .UNINDENT .INDENT 0.0 .TP -.B salt.modules.defaults.merge(dest, upd) +.B salt.modules.defaults.merge(dest, src, merge_lists=False, in_place=True) Allows deep merging of dicts in formulas. .INDENT 7.0 -.INDENT 3.5 +.TP +.B merge_lists +False +If True, it will also merge lists instead of replace their items. +.TP +.B in_place +True +If True, it will merge into dest dict, +if not it will make a new copy from that dict and return it. +.sp CLI Example: .. code\-block:: bash .sp salt \(aq*\(aq default.merge a=b d=e .UNINDENT -.UNINDENT .sp It is more typical to use this in a templating language in formulas, instead of directly on the command\-line. @@ -126318,7 +134009,7 @@ salt ns1 dig.NS google.com .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dig.SPF(domain, record=\(aqSPF\(aq, nameserver=None) +.B salt.modules.dig.SPF(domain, record=u\(aqSPF\(aq, nameserver=None) Return the allowed IPv4 ranges in the SPF record for \fBdomain\fP\&. .sp If record is \fBSPF\fP and the SPF record is empty, the TXT record will be @@ -126411,7 +134102,7 @@ salt \(aq*\(aq disk.dump /dev/sda1 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.disk.format(device, fs_type=\(aqext4\(aq, inode_size=None, lazy_itable_init=None, force=False) +.B salt.modules.disk.format(device, fs_type=u\(aqext4\(aq, inode_size=None, lazy_itable_init=None, force=False) Format a filesystem onto a device .sp New in version 2016.11.0. @@ -126813,7 +134504,7 @@ salt \(aq*\(aq dnsmasq.fullversion .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dnsmasq.get_config(config_file=\(aq/etc/dnsmasq.conf\(aq) +.B salt.modules.dnsmasq.get_config(config_file=u\(aq/etc/dnsmasq.conf\(aq) Dumps all options from the config file. .INDENT 7.0 .TP @@ -126837,7 +134528,7 @@ salt \(aq*\(aq dnsmasq.get_config config_file=/etc/dnsmasq.conf .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dnsmasq.set_config(config_file=\(aq/etc/dnsmasq.conf\(aq, follow=True, **kwargs) +.B salt.modules.dnsmasq.set_config(config_file=u\(aq/etc/dnsmasq.conf\(aq, follow=True, **kwargs) Sets a value or a set of values in the specified file. By default, if conf\-dir is configured in this file, salt will attempt to set the option in any file inside the conf\-dir where it has already been enabled. If it @@ -126990,7 +134681,7 @@ salt ns1 dnsutil.NS google.com .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dnsutil.SPF(domain, record=\(aqSPF\(aq, nameserver=None) +.B salt.modules.dnsutil.SPF(domain, record=u\(aqSPF\(aq, nameserver=None) Return the allowed IPv4 ranges in the SPF record for \fBdomain\fP\&. .sp If record is \fBSPF\fP and the SPF record is empty, the TXT record will be @@ -127028,7 +134719,7 @@ salt ns1 dnsutil.check_ip 127.0.0.1 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dnsutil.hosts_append(hostsfile=\(aq/etc/hosts\(aq, ip_addr=None, entries=None) +.B salt.modules.dnsutil.hosts_append(hostsfile=u\(aq/etc/hosts\(aq, ip_addr=None, entries=None) Append a single line to the /etc/hosts file. .sp CLI Example: @@ -127045,7 +134736,7 @@ salt \(aq*\(aq dnsutil.hosts_append /etc/hosts 127.0.0.1 ad1.yuk.co,ad2.yuk.co .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dnsutil.hosts_remove(hostsfile=\(aq/etc/hosts\(aq, entries=None) +.B salt.modules.dnsutil.hosts_remove(hostsfile=u\(aq/etc/hosts\(aq, entries=None) Remove a host from the /etc/hosts file. If doing so will leave a line containing only an IP address, then the line will be deleted. This function will leave comments and blank lines intact. @@ -127065,7 +134756,7 @@ salt \(aq*\(aq dnsutil.hosts_remove /etc/hosts ad2.yuk.co,ad1.yuk.co .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dnsutil.parse_hosts(hostsfile=\(aq/etc/hosts\(aq, hosts=None) +.B salt.modules.dnsutil.parse_hosts(hostsfile=u\(aq/etc/hosts\(aq, hosts=None) Parse /etc/hosts file. .sp CLI Example: @@ -127099,7 +134790,7 @@ salt ns1 dnsutil.parse_zone /var/lib/named/example.com.zone .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dnsutil.serial(zone=\(aq\(aq, update=False) +.B salt.modules.dnsutil.serial(zone=u\(aq\(aq, update=False) Return, store and update a dns serial for your zone files. .sp zone: a keyword for a specific zone @@ -127617,7 +135308,7 @@ salt myminion dockercompose.pause /path/where/docker\-compose/stored \(aq[janus] .INDENT 0.0 .TP .B salt.modules.dockercompose.up(path, service_names=None) -Create and start containers defined in the the docker\-compose.yml file +Create and start containers defined in the docker\-compose.yml file located in path, service_names is a python list, if omitted create and start all containers .INDENT 7.0 @@ -127863,17 +135554,35 @@ This execution module provides functions that shadow those from the \fBcmd\fP mo .SS Detailed Function Documentation .INDENT 0.0 .TP -.B salt.modules.dockermod.build(path=None, image=None, cache=True, rm=True, api_response=False, fileobj=None, dockerfile=None, buildargs=None) +.B salt.modules.dockermod.build(path=None, repository=None, tag=None, cache=True, rm=True, api_response=False, fileobj=None, dockerfile=None, buildargs=None, image=None) +Changed in version 2018.3.0: If the built image should be tagged, then the repository and tag must +now be passed separately using the \fBrepository\fP and \fBtag\fP +arguments, rather than together in the (now deprecated) \fBimage\fP +argument. + +.sp Builds a docker image from a Dockerfile or a URL .INDENT 7.0 .TP .B path Path to directory on the Minion containing a Dockerfile +.TP +.B repository +Optional repository name for the image being built +.sp +New in version 2018.3.0. + +.TP +.B tag +latest +Tag name for the image (required if \fBrepository\fP is passed) +.sp +New in version 2018.3.0. + .TP .B image -Image to be built, in \fBrepo:tag\fP notation. If just the repository -name is passed, a tag name of \fBlatest\fP will be assumed. If building -from a URL, this parameted can be omitted. +Deprecated since version 2018.3.0: Use both \fBrepository\fP and \fBtag\fP instead + .TP .B cache True @@ -127895,10 +135604,11 @@ to be passed in place of a file \fBpath\fP argument. This argument should not be used from the CLI, only from other Salt code. .TP .B dockerfile -Allows for an alternative Dockerfile to be specified. Path to alternative -Dockefile is relative to the build path for the Docker container. +Allows for an alternative Dockerfile to be specified. Path to +alternative Dockefile is relative to the build path for the Docker +container. .sp -New in version develop. +New in version 2016.11.0. .TP .B buildargs @@ -127931,14 +135641,14 @@ Minion .UNINDENT .UNINDENT .sp -\fI(Only present if the image specified by the "image" argument was not -present on the Minion, or if cache=False)\fP +\fI(Only present if the image specified by the "repository" and "tag" +arguments was not present on the Minion, or if cache=False)\fP .IP \(bu 2 \fBStatus\fP \- A string containing a summary of the pull action (usually a message saying that an image was downloaded, or that it was up to date). .sp -\fI(Only present if the image specified by the "image" argument was not -present on the Minion, or if cache=False)\fP +\fI(Only present if the image specified by the "repository" and "tag" +arguments was not present on the Minion, or if cache=False)\fP .UNINDENT .sp CLI Example: @@ -127947,12 +135657,9 @@ CLI Example: .sp .nf .ft C -salt myminion docker.build /path/to/docker/build/dir image=myimage:dev -salt myminion docker.build https://github.com/myuser/myrepo.git image=myimage:latest - -\&.. versionadded:: develop - -salt myminion docker.build /path/to/docker/build/dir dockerfile=Dockefile.different image=myimage:dev +salt myminion docker.build /path/to/docker/build/dir +salt myminion docker.build https://github.com/myuser/myrepo.git repository=myimage tag=latest +salt myminion docker.build /path/to/docker/build/dir dockerfile=Dockefile.different repository=myimage tag=dev .ft P .fi .UNINDENT @@ -127992,17 +135699,35 @@ salt myminion dockerng.call compassionate_mirzakhani test.arg arg1 arg2 key1=val .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.commit(name, image, message=None, author=None) +.B salt.modules.dockermod.commit(name, repository, tag=\(aqlatest\(aq, message=None, author=None, image=None) +Changed in version 2018.3.0: The repository and tag must now be passed separately using the +\fBrepository\fP and \fBtag\fP arguments, rather than together in the (now +deprecated) \fBimage\fP argument. + +.sp Commits a container, thereby promoting it to an image. Equivalent to running the \fBdocker commit\fP Docker CLI command. .INDENT 7.0 .TP .B name Container name or ID to commit +.TP +.B repository +Repository name for the image being committed +.sp +New in version 2018.3.0. + +.TP +.B tag +latest +Tag name for the image +.sp +New in version 2018.3.0. + .TP .B image -Image to be committed, in \fBrepo:tag\fP notation. If just the repository -name is passed, a tag name of \fBlatest\fP will be assumed. +Deprecated since version 2018.3.0: Use both \fBrepository\fP and \fBtag\fP instead + .TP .B message Commit message (Optional) @@ -128029,8 +135754,7 @@ CLI Example: .sp .nf .ft C -salt myminion docker.commit mycontainer myuser/myimage -salt myminion docker.commit mycontainer myuser/myimage:mytag +salt myminion docker.commit mycontainer myuser/myimage mytag .ft P .fi .UNINDENT @@ -128039,8 +135763,139 @@ salt myminion docker.commit mycontainer myuser/myimage:mytag .INDENT 0.0 .TP .B salt.modules.dockermod.compare_container(first, second, ignore=None) +This function is an alias of \fBcompare_containers\fP\&. +.INDENT 7.0 +.INDENT 3.5 New in version 2017.7.0. +.sp +Changed in version 2018.3.0: Renamed from \fBdocker.compare_container\fP to +\fBdocker.compare_containers\fP (old function name remains as an alias) + +.sp +Compare two containers\(aq Config and and HostConfig and return any +differences between the two. +.INDENT 0.0 +.TP +.B first +Name or ID of first container +.TP +.B second +Name or ID of second container +.TP +.B ignore +A comma\-separated list (or Python list) of keys to ignore when +comparing. This is useful when comparing two otherwise identical +containers which have different hostnames. +.UNINDENT +.sp +CLI Examples: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion docker.compare_containers foo bar +salt myminion docker.compare_containers foo bar ignore=Hostname +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.dockermod.compare_container_networks(first, second) +New in version 2018.3.0. + +.sp +Returns the differences between two containers\(aq networks. When a network is +only present one of the two containers, that network\(aqs diff will simply be +represented with \fBTrue\fP for the side of the diff in which the network is +present) and \fBFalse\fP for the side of the diff in which the network is +absent. +.sp +This function works by comparing the contents of both containers\(aq +\fBNetworks\fP keys (under \fBNetworkSettings\fP) in the return data from +\fI\%docker.inspect_container\fP\&. Because each network contains +some items that either A) only set at runtime, B) naturally varying from +container to container, or both, by default the following keys in each +network are examined: +.INDENT 7.0 +.IP \(bu 2 +\fBAliases\fP +.IP \(bu 2 +\fBLinks\fP +.IP \(bu 2 +\fBIPAMConfig\fP +.UNINDENT +.sp +The exception to this is if \fBIPAMConfig\fP is unset (i.e. null) in one +container but not the other. This happens when no static IP configuration +is set, and automatic IP configuration is in effect. So, in order to report +on changes between automatic IP configuration in one container and static +IP configuration in another container (as we need to do for the +\fBdocker_container.running\fP +state), automatic IP configuration will also be checked in these cases. +.sp +This function uses the +.nf +:minion_opts:\(gadocker.compare_container_networks\(ga +.fi + +minion config option to determine which keys to examine. This provides +flexibility in the event that features added in a future Docker release +necessitate changes to how Salt compares networks. In these cases, rather +than waiting for a new Salt release one can just set + +.nf +:minion_opts:\(gadocker.compare_container_networks\(ga +.fi +\&. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +The checks for automatic IP configuration described above only apply if +\fBIPAMConfig\fP is among the keys set for static IP checks in + +.nf +:minion_opts:\(gadocker.compare_container_networks\(ga +.fi +\&. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B first +Name or ID of first container (old) +.TP +.B second +Name or ID of second container (new) +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion docker.compare_container_networks foo bar +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.dockermod.compare_containers(first, second, ignore=None) +New in version 2017.7.0. + +.sp +Changed in version 2018.3.0: Renamed from \fBdocker.compare_container\fP to +\fBdocker.compare_containers\fP (old function name remains as an alias) + .sp Compare two containers\(aq Config and and HostConfig and return any differences between the two. @@ -128057,24 +135912,39 @@ A comma\-separated list (or Python list) of keys to ignore when comparing. This is useful when comparing two otherwise identical containers which have different hostnames. .UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion docker.compare_containers foo bar +salt myminion docker.compare_containers foo bar ignore=Hostname +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.connect_container_to_network(container, network_id, ipv4_address=None) -Connect container to network. +.B salt.modules.dockermod.compare_networks(first, second, ignore=\(aqName, Id, Created, Containers\(aq) +New in version 2018.3.0. + +.sp +Compare two networks and return any differences between the two .INDENT 7.0 .TP -.B container -Container name or ID +.B first +Name or ID of first container .TP -.B network_id -ID of network +.B second +Name or ID of second container .TP -.B ipv4_address -The IPv4 address to connect to the container -.sp -New in version 2017.7.0. - +.B ignore +Name,Id,Created,Containers +A comma\-separated list (or Python list) of keys to ignore when +comparing. .UNINDENT .sp CLI Example: @@ -128083,7 +135953,7 @@ CLI Example: .sp .nf .ft C -salt myminion docker.connect_container_from_network web\-1 1f9d2454d0872b68dd9e8744c6e7a4c66b86f10abaccc21e14f7f014f729b2bc +salt myminion docker.compare_network foo bar .ft P .fi .UNINDENT @@ -128091,7 +135961,76 @@ salt myminion docker.connect_container_from_network web\-1 1f9d2454d0872b68dd9e8 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.copy_from(name, *args, **kwargs) +.B salt.modules.dockermod.connect_container_to_network(container, net_id, **kwargs) +New in version 2015.8.3. + +.sp +Changed in version 2017.7.0: Support for \fBipv4_address\fP argument added + +.sp +Changed in version 2018.3.0: All arguments are now passed through to +\fI\%connect_container_to_network()\fP, allowing for any new arguments added +to this function to be supported automagically. + +.sp +Connect container to network. See the \fI\%connect_container_to_network()\fP +docs for information on supported arguments. +.INDENT 7.0 +.TP +.B container +Container name or ID +.TP +.B net_id +Network name or ID +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion docker.connect_container_to_network web\-1 mynet +salt myminion docker.connect_container_to_network web\-1 mynet ipv4_address=10.20.0.10 +salt myminion docker.connect_container_to_network web\-1 1f9d2454d0872b68dd9e8744c6e7a4c66b86f10abaccc21e14f7f014f729b2bc +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.dockermod.connected(name, verbose=False) +New in version 2018.3.0. + +.sp +Return a list of running containers attached to the specified network +.INDENT 7.0 +.TP +.B name +Network name +.TP +.B verbose +False +If \fBTrue\fP, return extended info about each container (IP +configuration, etc.) +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion docker.connected net_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.dockermod.copy_from(name, source, dest, overwrite=False, makedirs=False) Copy a file from inside a container to the Minion .INDENT 7.0 .TP @@ -128134,7 +136073,7 @@ salt myminion docker.copy_from mycontainer /var/log/nginx/access.log /home/myuse .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.copy_to(name, *args, **kwargs) +.B salt.modules.dockermod.copy_to(name, source, dest, exec_driver=None, overwrite=False, makedirs=False) Copy a file from the host into a container .INDENT 7.0 .TP @@ -128194,10 +136133,17 @@ Image from which to create the container .B name Name for the new container. If not provided, Docker will randomly generate one for you (it will be included in the return data). +.TP +.B start +False +If \fBTrue\fP, start container after creating it +.sp +New in version 2018.3.0. + .TP .B skip_translate This function translates Salt CLI or SLS input into the format which -\fI\%docker\-py\fP expects. However, in the event that Salt\(aqs translation logic +docker\-py expects. However, in the event that Salt\(aqs translation logic fails (due to potential changes in the Docker Remote API, or to bugs in the translation code), this argument can be used to exert granular control over which arguments are translated and which are not. @@ -128208,7 +136154,7 @@ skipped. Alternatively, pass \fBTrue\fP and \fIall\fP translation will be skipped. .sp Skipping tranlsation allows for arguments to be formatted directly in -the format which \fI\%docker\-py\fP expects. This allows for API changes and +the format which docker\-py expects. This allows for API changes and other issues to be more easily worked around. An example of using this option to skip translation would be: .INDENT 7.0 @@ -128225,22 +136171,24 @@ salt myminion docker.create image=centos:7.3.1611 skip_translate=environment env See the following links for more information: .INDENT 7.0 .IP \(bu 2 -\fI\%docker\-py Low\-level API\fP + +.nf +\(gadocker\-py Low\-level API\(ga_ +.fi + .IP \(bu 2 \fI\%Docker Engine API\fP .UNINDENT -.UNINDENT -.INDENT 7.0 .TP .B ignore_collisions False -Since many of \fI\%docker\-py\fP\(aqs arguments differ in name from their CLI +Since many of docker\-py\(aqs arguments differ in name from their CLI counterparts (with which most Docker users are more familiar), Salt -detects usage of these and aliases them to the \fI\%docker\-py\fP version of -that argument. However, if both the alias and the \fI\%docker\-py\fP version of +detects usage of these and aliases them to the docker\-py version of +that argument. However, if both the alias and the docker\-py version of the same argument (e.g. \fBenv\fP and \fBenvironment\fP) are used, an error will be raised. Set this argument to \fBTrue\fP to suppress these errors -and keep the \fI\%docker\-py\fP version of the argument. +and keep the docker\-py version of the argument. .TP .B validate_ip_addrs True @@ -128675,23 +136623,17 @@ default value on Windows client is \fBhyperv\fP\&. On Linux, only Add metadata to the container. Labels can be set both with and without values: .sp -Examples (\fIwith\fP values): +Examples: .INDENT 7.0 .IP \(bu 2 -\fBlabels="label1=value1,label2=value2"\fP +\fBlabels=foo,bar=baz\fP .IP \(bu 2 -\fBlabels="[\(aqlabel1=value1\(aq, \(aqlabel2=value2\(aq]"\fP -.IP \(bu 2 -\fBlabels="{\(aqlabel1\(aq: \(aqvalue1\(aq, \(aqlabel2\(aq: \(aqvalue2\(aq}"\fP +\fBlabels="[\(aqfoo\(aq, \(aqbar=baz\(aq]"\fP .UNINDENT .sp -Examples (\fIwithout\fP values): -.INDENT 7.0 -.IP \(bu 2 -\fBlabels=label1,label2\fP -.IP \(bu 2 -\fBlabels="[\(aqlabel1\(aq, \(aqlabel2\(aq]"\fP -.UNINDENT +Changed in version 2018.3.0: Labels both with and without values can now be mixed. Earlier +releases only permitted one method or the other. + .TP .B links Link this container to another. Links should be specified in the format @@ -129141,24 +137083,289 @@ salt myminion docker.create centos:7 name=mycent7 interactive=True tty=True comm .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.create_network(name, driver=None) +.B salt.modules.dockermod.create_network(name, skip_translate=None, ignore_collisions=False, validate_ip_addrs=True, client_timeout=60, **kwargs) +Changed in version 2018.3.0: Support added for network configuration options other than \fBdriver\fP +and \fBdriver_opts\fP, as well as IPAM configuration. + +.sp Create a new network +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This function supports all arguments for network and IPAM pool +configuration which are available for the release of docker\-py +installed on the minion. For that reason, the arguments described below +in the \fI\%NETWORK CONFIGURATION ARGUMENTS\fP and \fI\%IP ADDRESS +MANAGEMENT (IPAM)\fP +sections may not accurately reflect what is available on the minion. +The \fI\%docker.get_client_args\fP function can be used to check +the available arguments for the installed version of docker\-py (they +are found in the \fBnetwork_config\fP and \fBipam_config\fP sections of the +return data), but Salt will not prevent a user from attempting to use +an argument which is unsupported in the release of Docker which is +installed. In those cases, network creation be attempted but will fail. +.UNINDENT +.UNINDENT .INDENT 7.0 .TP -.B network_id -ID of network +.B name +Network name .TP -.B driver -Driver of the network +.B skip_translate +This function translates Salt CLI or SLS input into the format which +docker\-py expects. However, in the event that Salt\(aqs translation logic +fails (due to potential changes in the Docker Remote API, or to bugs in +the translation code), this argument can be used to exert granular +control over which arguments are translated and which are not. +.sp +Pass this argument as a comma\-separated list (or Python list) of +arguments, and translation for each passed argument name will be +skipped. Alternatively, pass \fBTrue\fP and \fIall\fP translation will be +skipped. +.sp +Skipping tranlsation allows for arguments to be formatted directly in +the format which docker\-py expects. This allows for API changes and +other issues to be more easily worked around. See the following links +for more information: +.INDENT 7.0 +.IP \(bu 2 +docker\-py \fI\%low\-level API\fP +.IP \(bu 2 +\fI\%Docker Engine API\fP .UNINDENT .sp -CLI Example: +New in version 2018.3.0. + +.TP +.B ignore_collisions +False +Since many of docker\-py\(aqs arguments differ in name from their CLI +counterparts (with which most Docker users are more familiar), Salt +detects usage of these and aliases them to the docker\-py version of +that argument. However, if both the alias and the docker\-py version of +the same argument (e.g. \fBoptions\fP and \fBdriver_opts\fP) are used, an error +will be raised. Set this argument to \fBTrue\fP to suppress these errors +and keep the docker\-py version of the argument. +.sp +New in version 2018.3.0. + +.TP +.B validate_ip_addrs +True +For parameters which accept IP addresses as input, IP address +validation will be performed. To disable, set this to \fBFalse\fP +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +When validating subnets, whether or not the IP portion of the +subnet is a valid subnet boundary will not be checked. The IP will +portion will be validated, and the subnet size will be checked to +confirm it is a valid number (1\-32 for IPv4, 1\-128 for IPv6). +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + +.UNINDENT +.sp +\fBNETWORK CONFIGURATION ARGUMENTS\fP +.INDENT 7.0 +.TP +.B driver +Network driver +.sp +Example: \fBdriver=macvlan\fP +.TP +.B driver_opts (or \fIdriver_opt\fP, or \fIoptions\fP) +Options for the network driver. Either a dictionary of option names and +values or a Python list of strings in the format \fBvarname=value\fP\&. +.sp +Examples: +.INDENT 7.0 +.IP \(bu 2 +\fBdriver_opts=\(aqmacvlan_mode=bridge,parent=eth0\(aq\fP +.IP \(bu 2 +\fBdriver_opts="[\(aqmacvlan_mode=bridge\(aq, \(aqparent=eth0\(aq]"\fP +.IP \(bu 2 +\fBdriver_opts="{\(aqmacvlan_mode\(aq: \(aqbridge\(aq, \(aqparent\(aq: \(aqeth0\(aq}"\fP +.UNINDENT +.TP +.B check_duplicate +True +If \fBTrue\fP, checks for networks with duplicate names. Since networks +are primarily keyed based on a random ID and not on the name, and +network name is strictly a user\-friendly alias to the network which is +uniquely identified using ID, there is no guaranteed way to check for +duplicates. This option providess a best effort, checking for any +networks which have the same name, but it is not guaranteed to catch +all name collisions. +.sp +Example: \fBcheck_duplicate=False\fP +.TP +.B internal +False +If \fBTrue\fP, restricts external access to the network +.sp +Example: \fBinternal=True\fP +.TP +.B labels +Add metadata to the network. Labels can be set both with and without +values: +.sp +Examples (\fIwith\fP values): +.INDENT 7.0 +.IP \(bu 2 +\fBlabels="label1=value1,label2=value2"\fP +.IP \(bu 2 +\fBlabels="[\(aqlabel1=value1\(aq, \(aqlabel2=value2\(aq]"\fP +.IP \(bu 2 +\fBlabels="{\(aqlabel1\(aq: \(aqvalue1\(aq, \(aqlabel2\(aq: \(aqvalue2\(aq}"\fP +.UNINDENT +.sp +Examples (\fIwithout\fP values): +.INDENT 7.0 +.IP \(bu 2 +\fBlabels=label1,label2\fP +.IP \(bu 2 +\fBlabels="[\(aqlabel1\(aq, \(aqlabel2\(aq]"\fP +.UNINDENT +.TP +.B enable_ipv6 (or \fIipv6\fP) +False +Enable IPv6 on the network +.sp +Example: \fBenable_ipv6=True\fP +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +While it should go without saying, this argument must be set to +\fBTrue\fP to configure an IPv6 subnet\&. Also, if this option is +turned on without an IPv6 subnet explicitly configured, you will +get an error unless you have set up a fixed IPv6 subnet. Consult +the +.nf +\(gaDocker IPv6 docs\(ga_ +.fi + for information on how to do this. +.UNINDENT +.UNINDENT +.TP +.B attachable +False +If \fBTrue\fP, and the network is in the global scope, non\-service +containers on worker nodes will be able to connect to the network. +.sp +Example: \fBattachable=True\fP +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +While support for this option was added in API version 1.24, its +value was not added to the inpsect results until API version 1.26. +The version of Docker which is available for CentOS 7 runs API +version 1.24, meaning that while Salt can pass this argument to the +API, it has no way of knowing the value of this config option in an +existing Docker network. +.UNINDENT +.UNINDENT +.TP +.B scope +Specify the network\(aqs scope (\fBlocal\fP, \fBglobal\fP or \fBswarm\fP) +.sp +Example: \fBscope=local\fP +.TP +.B ingress +False +If \fBTrue\fP, create an ingress network which provides the routing\-mesh in +swarm mode +.sp +Example: \fBingress=True\fP +.UNINDENT +.sp +\fBIP ADDRESS MANAGEMENT (IPAM)\fP +.sp +This function supports networks with either IPv4, or both IPv4 and IPv6. If +configuring IPv4, then you can pass the IPAM arguments as shown below, as +individual arguments on the Salt CLI. However, if configuring IPv4 and +IPv6, the arguments must be passed as a list of dictionaries, in the +\fBipam_pools\fP argument. See the \fBCLI Examples\fP below. \fI\%These docs\fP also +have more information on these arguments. +.sp +\fIIPAM ARGUMENTS\fP +.INDENT 7.0 +.TP +.B ipam_driver +IPAM driver to use, if different from the default one +.sp +Example: \fBipam_driver=foo\fP +.TP +.B ipam_opts +Options for the IPAM driver. Either a dictionary of option names +and values or a Python list of strings in the format +\fBvarname=value\fP\&. +.sp +Examples: +.INDENT 7.0 +.IP \(bu 2 +\fBipam_opts=\(aqfoo=bar,baz=qux\(aq\fP +.IP \(bu 2 +\fBipam_opts="[\(aqfoo=bar\(aq, \(aqbaz=quz\(aq]"\fP +.IP \(bu 2 +\fBipam_opts="{\(aqfoo\(aq: \(aqbar\(aq, \(aqbaz\(aq: \(aqqux\(aq}"\fP +.UNINDENT +.UNINDENT +.sp +\fIIPAM POOL ARGUMENTS\fP +.INDENT 7.0 +.TP +.B subnet +Subnet in CIDR format that represents a network segment +.sp +Example: \fBsubnet=192.168.50.0/25\fP +.TP +.B iprange (or \fIip_range\fP) +Allocate container IP from a sub\-range within the subnet +.sp +Subnet in CIDR format that represents a network segment +.sp +Example: \fBiprange=192.168.50.64/26\fP +.TP +.B gateway +IPv4 gateway for the master subnet +.sp +Example: \fBgateway=192.168.50.1\fP +.TP +.B aux_addresses (or \fIaux_address\fP) +A dictionary of mapping container names to IP addresses which should be +allocated for them should they connect to the network. Either a +dictionary of option names and values or a Python list of strings in +the format \fBhost=ipaddr\fP\&. +.sp +Examples: +.INDENT 7.0 +.IP \(bu 2 +\fBaux_addresses=\(aqfoo.bar.tld=192.168.50.10,hello.world.tld=192.168.50.11\(aq\fP +.IP \(bu 2 +\fBaux_addresses="[\(aqfoo.bar.tld=192.168.50.10\(aq, \(aqhello.world.tld=192.168.50.11\(aq]"\fP +.IP \(bu 2 +\fBaux_addresses="{\(aqfoo.bar.tld\(aq: \(aq192.168.50.10\(aq, \(aqhello.world.tld\(aq: \(aq192.168.50.11\(aq}"\fP +.UNINDENT +.UNINDENT +.sp +CLI Examples: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C salt myminion docker.create_network web_network driver=bridge +# IPv4 +salt myminion docker.create_network macvlan_network driver=macvlan driver_opts="{\(aqparent\(aq:\(aqeth0\(aq}" gateway=172.20.0.1 subnet=172.20.0.0/24 +# IPv4 and IPv6 +salt myminion docker.create_network mynet ipam_pools=\(aq[{"subnet": "10.0.0.0/24", "gateway": "10.0.0.1"}, {"subnet": "fe3f:2180:26:1::60/123", "gateway": "fe3f:2180:26:1::61"}]\(aq .ft P .fi .UNINDENT @@ -129284,7 +137491,7 @@ salt myminion docker.depends 0123456789ab .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.diff(name, *args, **kwargs) +.B salt.modules.dockermod.diff(name) Get information on changes made to container\(aqs filesystem since it was created. Equivalent to running the \fBdocker diff\fP Docker CLI command. .INDENT 7.0 @@ -129322,23 +137529,55 @@ salt myminion docker.diff mycontainer .UNINDENT .INDENT 0.0 .TP +.B salt.modules.dockermod.disconnect_all_containers_from_network(network_id) +New in version 2018.3.0. + +.sp +Runs \fI\%docker.disconnect_container_from_network\fP on all +containers connected to the specified network, and returns the names of all +containers that were disconnected. +.INDENT 7.0 +.TP +.B network_id +Network name or ID +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion docker.disconnect_all_containers_from_network mynet +salt myminion docker.disconnect_all_containers_from_network 1f9d2454d0872b68dd9e8744c6e7a4c66b86f10abaccc21e14f7f014f729b2bc +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.dockermod.disconnect_container_from_network(container, network_id) -Disconnect container from network. +New in version 2015.8.3. + +.sp +Disconnect container from network .INDENT 7.0 .TP .B container Container name or ID .TP .B network_id -ID of network +Network name or ID .UNINDENT .sp -CLI Example: +CLI Examples: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C +salt myminion docker.disconnect_container_from_network web\-1 mynet salt myminion docker.disconnect_container_from_network web\-1 1f9d2454d0872b68dd9e8744c6e7a4c66b86f10abaccc21e14f7f014f729b2bc .ft P .fi @@ -129373,7 +137612,7 @@ salt myminion docker.exists mycontainer .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.export(name, *args, **kwargs) +.B salt.modules.dockermod.export(name, path, overwrite=False, makedirs=False, compression=None, **kwargs) Exports a container to a tar archive. It can also optionally compress that tar archive, and push it up to the Master. .INDENT 7.0 @@ -129460,7 +137699,7 @@ salt myminion docker.export mycontainer /tmp/mycontainer.tar.xz push=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.get_client_args() +.B salt.modules.dockermod.get_client_args(limit=None) New in version 2016.3.6,2016.11.4,2017.7.0. .sp @@ -129468,8 +137707,44 @@ Changed in version 2017.7.0: Replaced the container config args with the ones fr \fBcreate_container\fP function. .sp -Returns the args for docker\-py\(aqs \fI\%low\-level API\fP, organized by args for -container creation, host config, and networking config. +Changed in version 2018.3.0: Added ability to limit the input to specific client functions + +.sp +Many functions in Salt have been written to support the full list of +arguments for a given function in docker\-py\(aqs \fI\%low\-level API\fP\&. However, +depending on the version of docker\-py installed on the minion, the +available arguments may differ. This function will get the arguments for +various functions in the installed version of docker\-py, to be used as a +reference. +.INDENT 7.0 +.TP +.B limit +An optional list of categories for which to limit the return. This is +useful if only a specific set of arguments is desired, and also keeps +other function\(aqs argspecs from needlessly being examined. +.UNINDENT +.sp +\fBAVAILABLE LIMITS\fP +.INDENT 7.0 +.IP \(bu 2 +\fBcreate_container\fP \- arguments accepted by \fI\%create_container()\fP (used +by \fI\%docker.create\fP) +.IP \(bu 2 +\fBhost_config\fP \- arguments accepted by \fI\%create_host_config()\fP (used to +build the host config for \fI\%docker.create\fP) +.IP \(bu 2 +\fBconnect_container_to_network\fP \- arguments used by +\fI\%connect_container_to_network()\fP to construct an endpoint config when +connecting to a network (used by +\fI\%docker.connect_container_to_network\fP) +.IP \(bu 2 +\fBcreate_network\fP \- arguments accepted by \fI\%create_network()\fP (used by +\fI\%docker.create_network\fP) +.IP \(bu 2 +\fBipam_config\fP \- arguments used to create an \fI\%IPAM pool\fP (used by +\fI\%docker.create_network\fP +in the process of constructing an IPAM config dictionary) +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -129478,6 +137753,8 @@ CLI Example: .nf .ft C salt myminion docker.get_client_args +salt myminion docker.get_client_args logs +salt myminion docker.get_client_args create_container,connect_container_to_network .ft P .fi .UNINDENT @@ -129597,7 +137874,12 @@ salt myminion docker.images all=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.import(source, image, api_response=False) +.B salt.modules.dockermod.import(source, repository, tag=\(aqlatest\(aq, api_response=False, image=None) +Changed in version 2018.3.0: The repository and tag must now be passed separately using the +\fBrepository\fP and \fBtag\fP arguments, rather than together in the (now +deprecated) \fBimage\fP argument. + +.sp Imports content from a local tarball or a URL as a new docker image .INDENT 7.0 .TP @@ -129607,11 +137889,23 @@ file on the Salt fileserver (i.e. \fBsalt://path/to/rootfs/tarball.tar.xz\fP\&. To import a file from a saltenv other than \fBbase\fP (e.g. \fBdev\fP), pass it at the end of the URL (ex. \fBsalt://path/to/rootfs/tarball.tar.xz?saltenv=dev\fP). +.TP +.B repository +Repository name for the image being imported +.sp +New in version 2018.3.0. + +.TP +.B tag +latest +Tag name for the image +.sp +New in version 2018.3.0. + .TP .B image -Image to be created by the import, in \fBrepo:tag\fP notation. If just -the repository name is passed, a tag name of \fBlatest\fP will be -assumed. +Deprecated since version 2018.3.0: Use both \fBrepository\fP and \fBtag\fP instead + .TP .B api_response False @@ -129709,7 +138003,7 @@ salt myminion docker.inspect busybox .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.inspect_container(name, *args, **kwargs) +.B salt.modules.dockermod.inspect_container(name) Retrieves container information. Equivalent to running the \fBdocker inspect\fP Docker CLI command, but will only look for container information. .INDENT 7.0 @@ -129925,7 +138219,13 @@ salt myminion docker.list_tags .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.load(path, image=None) +.B salt.modules.dockermod.load(path, repository=None, tag=None, image=None) +Changed in version 2018.3.0: If the loaded image should be tagged, then the repository and tag must +now be passed separately using the \fBrepository\fP and \fBtag\fP +arguments, rather than together in the (now deprecated) \fBimage\fP +argument. + +.sp Load a tar archive that was created using \fI\%docker.save\fP (or via the Docker CLI using \fBdocker save\fP). .INDENT 7.0 .TP @@ -129936,12 +138236,24 @@ URL of a file on the Salt fileserver (i.e. saltenv other than \fBbase\fP (e.g. \fBdev\fP), pass it at the end of the URL (ex. \fBsalt://path/to/rootfs/tarball.tar.xz?saltenv=dev\fP). .TP -.B image -None +.B repository If specified, the topmost layer of the newly\-loaded image will be -tagged with the specified repo and tag using \fBdocker.tag\fP\&. The image name should be specified in -\fBrepo:tag\fP notation. If just the repository name is passed, a tag -name of \fBlatest\fP will be assumed. +tagged with the specified repo using \fBdocker.tag\fP\&. If a repository name is provided, then +the \fBtag\fP argument is also required. +.sp +New in version 2018.3.0. + +.TP +.B tag +Tag name to go along with the repository name, if the loaded image is +to be tagged. +.sp +New in version 2018.3.0. + +.TP +.B image +Deprecated since version 2018.3.0: Use both \fBrepository\fP and \fBtag\fP instead + .UNINDENT .sp \fBRETURN DATA\fP @@ -129974,7 +138286,7 @@ CLI Example: .nf .ft C salt myminion docker.load /path/to/image.tar -salt myminion docker.load salt://path/to/docker/saved/image.tar image=myuser/myimage:mytag +salt myminion docker.load salt://path/to/docker/saved/image.tar repository=myuser/myimage tag=mytag .ft P .fi .UNINDENT @@ -130024,22 +138336,66 @@ salt myminion docker.login hub https://mydomain.tld/registry/ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.logs(name) -Returns the logs for the container. Equivalent to running the \fBdocker -logs\fP Docker CLI command. +.B salt.modules.dockermod.logs(name, **kwargs) +Changed in version 2018.3.0: Support for all of docker\-py\(aqs \fI\%logs()\fP function\(aqs arguments, with the +exception of \fBstream\fP\&. + +.sp +Returns the logs for the container. An interface to docker\-py\(aqs \fI\%logs()\fP +function. .INDENT 7.0 .TP .B name Container name or ID +.TP +.B stdout +True +Return stdout lines +.TP +.B stderr +True +Return stdout lines +.TP +.B timestamps +False +Show timestamps +.TP +.B tail +all +Output specified number of lines at the end of logs. Either an integer +number of lines or the string \fBall\fP\&. +.TP +.B since +Show logs since the specified time, passed as a UNIX epoch timestamp. +Optionally, if \fI\%timelib\fP is installed on the minion the timestamp can be +passed as a string which will be resolved to a date using +\fBtimelib.strtodatetime()\fP\&. +.TP +.B follow +False +If \fBTrue\fP, this function will block until the container exits and +return the logs when it does. The default behavior is to return what is +in the log at the time this function is executed. .UNINDENT .sp -CLI Example: +CLI Examples: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C +# All logs salt myminion docker.logs mycontainer +# Last 100 lines of log +salt myminion docker.logs mycontainer tail=100 +# Just stderr +salt myminion docker.logs mycontainer stdout=False +# Logs since a specific UNIX timestamp +salt myminion docker.logs mycontainer since=1511688459 +# Flexible format for "since" argument (requires timelib) +salt myminion docker.logs mycontainer since=\(aq1 hour ago\(aq +salt myminion docker.logs mycontainer since=\(aq1 week ago\(aq +salt myminion docker.logs mycontainer since=\(aq1 fortnight ago\(aq .ft P .fi .UNINDENT @@ -130051,6 +138407,9 @@ salt myminion docker.logs mycontainer Changed in version 2017.7.0: The \fBnames\fP and \fBids\fP can be passed as a comma\-separated list now, as well as a Python list. +.sp +Changed in version 2018.3.0: The \fBContainers\fP key for each network is no longer always empty. + .sp List existing networks .INDENT 7.0 @@ -130112,7 +138471,7 @@ salt myminion docker.pause mycontainer .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.pid(name, *args, **kwargs) +.B salt.modules.dockermod.pid(name) Returns the PID of a container .INDENT 7.0 .TP @@ -130135,7 +138494,7 @@ salt myminion docker.pid 0123456789ab .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.port(name, *args, **kwargs) +.B salt.modules.dockermod.port(name, private_port=None) Returns port mapping information for a given container. Equivalent to running the \fBdocker port\fP Docker CLI command. .INDENT 7.0 @@ -130229,12 +138588,16 @@ salt myminion docker.ps filters="{\(aqlabel\(aq: \(aqrole=web\(aq}" .INDENT 0.0 .TP .B salt.modules.dockermod.pull(image, insecure_registry=False, api_response=False, client_timeout=60) +Changed in version 2018.3.0: If no tag is specified in the \fBimage\fP argument, all tags for the +image will be pulled. For this reason is it recommended to pass +\fBimage\fP using the \fBrepo:tag\fP notation. + +.sp Pulls an image from a Docker registry .INDENT 7.0 .TP .B image -Image to be pulled, in \fBrepo:tag\fP notation. If just the repository -name is passed, a tag name of \fBlatest\fP will be assumed. +Image to be pulled .TP .B insecure_registry False @@ -130307,12 +138670,10 @@ page to configure authentication credentials. .INDENT 7.0 .TP .B image -Image to be pushed, in \fBrepo:tag\fP notation. -.sp -Changed in version 2015.8.4: If just the repository name is passed, then all tagged images for -the specified repo will be pushed. In prior releases, a tag of -\fBlatest\fP was assumed if the tag was omitted. - +Image to be pushed. If just the repository name is passed, then all +tagged images for the specified repo will be pushed. If the image name +is passed in \fBrepo:tag\fP notation, only the specified image will be +pushed. .TP .B insecure_registry False @@ -130369,15 +138730,16 @@ Remove a network .INDENT 7.0 .TP .B network_id -ID of network +Network name or ID .UNINDENT .sp -CLI Example: +CLI Examples: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C +salt myminion docker.remove_network mynet salt myminion docker.remove_network 1f9d2454d0872b68dd9e8744c6e7a4c66b86f10abaccc21e14f7f014f729b2bc .ft P .fi @@ -130441,25 +138803,65 @@ salt myminion docker.rename foo bar .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.resolve_tag(name, tags=None) -New in version 2017.7.2,Oxygen. +.B salt.modules.dockermod.resolve_image_id(name) +New in version 2018.3.0. .sp -Given an image tag, check the locally\-pulled tags (using -\fI\%docker.list_tags\fP) and return -the matching tag. This helps disambiguate differences on some platforms -where images from the Docker Hub are prefixed with \fBdocker.io/\fP\&. If an -image name with no tag is passed, a tag of \fBlatest\fP is assumed. +Given an image name (or partial image ID), return the full image ID. If no +match is found among the locally\-pulled images, then \fBFalse\fP will be +returned. .sp -If the specified image is not pulled locally, this function will return -\fBFalse\fP\&. +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion docker.resolve_image_id foo +salt myminion docker.resolve_image_id foo:bar +salt myminion docker.resolve_image_id 36540f359ca3 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.dockermod.resolve_tag(name, tags=None, **kwargs) +New in version 2017.7.2. + +.sp +Changed in version 2018.3.0: Instead of matching against pulled tags using +\fI\%docker.list_tags\fP, this +function now simply inspects the passed image name using +\fI\%docker.inspect_image\fP +and returns the first matching tag. If no matching tags are found, it +is assumed that the passed image is an untagged image ID, and the full +ID is returned. + +.sp +Inspects the specified image name and returns the first matching tag in the +inspect results. If the specified image is not pulled locally, this +function will return \fBFalse\fP\&. .INDENT 7.0 +.TP +.B name +Image name to resolve. If the image is found but there are no tags, +this means that the image name passed was an untagged image. In this +case the image ID will be returned. +.TP +.B all +False +If \fBTrue\fP, a list of all matching tags will be returned. If the image +is found but there are no tags, then a list will still be returned, but +it will simply contain the image ID. +.sp +New in version 2018.3.0. + .TP .B tags -An optional Python list of tags to check against. If passed, then -\fI\%docker.list_tags\fP will not -be run to get a list of tags. This is useful when resolving a number of -tags at the same time. +Deprecated since version 2018.3.0: Ignored if passed, will be removed in the Neon release. + .UNINDENT .sp CLI Examples: @@ -130469,7 +138871,8 @@ CLI Examples: .nf .ft C salt myminion docker.resolve_tag busybox -salt myminion docker.resolve_tag busybox:latest +salt myminion docker.resolve_tag centos:7 all=True +salt myminion docker.resolve_tag c9f378ac27d9 .ft P .fi .UNINDENT @@ -130477,7 +138880,7 @@ salt myminion docker.resolve_tag busybox:latest .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.restart(name, *args, **kwargs) +.B salt.modules.dockermod.restart(name, timeout=10) Restarts a container .INDENT 7.0 .TP @@ -130593,6 +138996,12 @@ a running container. .sp New in version 2017.7.0. +.TP +.B timeout +Optional timeout to be passed to \fI\%docker.stop\fP if stopping the container. +.sp +New in version 2018.3.0. + .TP .B volumes False @@ -130775,6 +139184,66 @@ salt myminion docker.run_all mycontainer \(aqls \-l /etc\(aq .UNINDENT .INDENT 0.0 .TP +.B salt.modules.dockermod.run_container(*args, **kwargs) +New in version 2018.3.0. + +.sp +Equivalent to \fBdocker run\fP on the Docker CLI. Runs the container, waits +for it to exit, and returns the container\(aqs logs when complete. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Not to be confused with \fI\%docker.run\fP, which provides a \fBcmd.run\fP\-like interface for executing commands in a +running container. +.UNINDENT +.UNINDENT +.sp +This function accepts the same arguments as \fI\%docker.create\fP, with the exception of \fBstart\fP\&. In +addition, it accepts the arguments from \fI\%docker.logs\fP, with the exception of \fBfollow\fP, to +control how logs are returned. Finally, the \fBbg\fP argument described below +can be used to optionally run the container in the background (the default +behavior is to block until the container exits). +.INDENT 7.0 +.TP +.B bg +False +If \fBTrue\fP, this function will not wait for the container to exit and +will not return its logs. It will however return the container\(aqs name +and ID, allowing for \fI\%docker.logs\fP to be used to view the logs. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +The logs will be inaccessible once the container exits if +\fBauto_remove\fP is set to \fBTrue\fP, so keep this in mind. +.UNINDENT +.UNINDENT +.TP +.B replace +False +If \fBTrue\fP, and if the named container already exists, this will +remove the existing container. The default behavior is to return a +\fBFalse\fP result when the container already exists. +.TP +.B force +False +If \fBTrue\fP, and the named container already exists, \fIand\fP \fBreplace\fP +is also set to \fBTrue\fP, then the container will be forcibly removed. +Otherwise, the state will not proceed and will return a \fBFalse\fP +result. +.TP +.B networks +Networks to which the container should be connected. If automatic IP +configuration is being used, the networks can be a simple list of +network names. If custom IP configuration is being used, then this +argument must be passed as a dictionary. +.UNINDENT +.sp +CLI Examples: +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.dockermod.run_stderr(name, cmd, exec_driver=None, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) Run \fBcmd.run_stderr\fP within a container @@ -131192,7 +139661,7 @@ salt myminion docker.signal mycontainer SIGHUP .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.sls(name, mods=None, saltenv=\(aqbase\(aq, **kwargs) +.B salt.modules.dockermod.sls(name, mods=None, **kwargs) Apply the states defined by the specified SLS modules to the running container .sp @@ -131214,6 +139683,30 @@ apply to the container. base Specify the environment from which to retrieve the SLS indicated by the \fImods\fP parameter. +.TP +.B pillarenv +Specify a Pillar environment to be used when applying states. This +can also be set in the minion config file using the +\fBpillarenv\fP option. When neither the +\fBpillarenv\fP minion config option nor this CLI argument is +used, all Pillar environments will be merged together. +.sp +New in version 2018.3.0. + +.TP +.B pillar +Custom Pillar values, passed as a dictionary of key\-value pairs +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Values passed this way will override Pillar values set via +\fBpillar_roots\fP or an external Pillar source. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + .UNINDENT .sp CLI Example: @@ -131230,7 +139723,12 @@ salt myminion docker.sls compassionate_mirzakhani mods=rails,web .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.sls_build(name, base=\(aqopensuse/python\(aq, mods=None, saltenv=\(aqbase\(aq, dryrun=False, **kwargs) +.B salt.modules.dockermod.sls_build(repository, tag=\(aqlatest\(aq, base=\(aqopensuse/python\(aq, mods=None, dryrun=False, **kwargs) +Changed in version 2018.3.0: The repository and tag must now be passed separately using the +\fBrepository\fP and \fBtag\fP arguments, rather than together in the (now +deprecated) \fBimage\fP argument. + +.sp Build a Docker image using the specified SLS modules on top of base image .sp New in version 2016.11.0. @@ -131238,16 +139736,29 @@ New in version 2016.11.0. .sp The base image does not need to have Salt installed, but Python is required. .INDENT 7.0 +.TP +.B repository +Repository name for the image to be built +.sp +New in version 2018.3.0. + +.TP +.B tag +latest +Tag name for the image to be built +.sp +New in version 2018.3.0. + .TP .B name -Image name to be built and committed +Deprecated since version 2018.3.0: Use both \fBrepository\fP and \fBtag\fP instead + .TP .B base opensuse/python Name or ID of the base image .TP .B mods -None A string containing comma\-separated list of SLS with defined states to apply to the base image. .TP @@ -131256,14 +139767,29 @@ base Specify the environment from which to retrieve the SLS indicated by the \fImods\fP parameter. .TP -.B base -the base image +.B pillarenv +Specify a Pillar environment to be used when applying states. This +can also be set in the minion config file using the +\fBpillarenv\fP option. When neither the +\fBpillarenv\fP minion config option nor this CLI argument is +used, all Pillar environments will be merged together. +.sp +New in version 2018.3.0. + .TP -.B mods -the state modules to execute during build -.TP -.B saltenv -the salt environment to use +.B pillar +Custom Pillar values, passed as a dictionary of key\-value pairs +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Values passed this way will override Pillar values set via +\fBpillar_roots\fP or an external Pillar source. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + .TP .B dryrun: False when set to True the container will not be commited at the end of @@ -131324,7 +139850,7 @@ salt myminion docker.start mycontainer .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.state(name, *args, **kwargs) +.B salt.modules.dockermod.state(name) Returns the state of the container .INDENT 7.0 .TP @@ -131403,17 +139929,35 @@ salt myminion docker.stop mycontainer timeout=20 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.tag(name, image, force=False) +.B salt.modules.dockermod.tag(name, repository, tag=\(aqlatest\(aq, force=False, image=None) +Changed in version 2018.3.0: The repository and tag must now be passed separately using the +\fBrepository\fP and \fBtag\fP arguments, rather than together in the (now +deprecated) \fBimage\fP argument. + +.sp Tag an image into a repository and return \fBTrue\fP\&. If the tag was unsuccessful, an error will be raised. .INDENT 7.0 .TP .B name ID of image +.TP +.B repository +Repository name for the image to be built +.sp +New in version 2018.3.0. + +.TP +.B tag +latest +Tag name for the image to be built +.sp +New in version 2018.3.0. + .TP .B image -Tag to apply to the image, in \fBrepo:tag\fP notation. If just the -repository name is passed, a tag name of \fBlatest\fP will be assumed. +Deprecated since version 2018.3.0: Use both \fBrepository\fP and \fBtag\fP instead + .TP .B force False @@ -131426,8 +139970,7 @@ CLI Example: .sp .nf .ft C -salt myminion docker.tag 0123456789ab myrepo/mycontainer -salt myminion docker.tag 0123456789ab myrepo/mycontainer:mytag +salt myminion docker.tag 0123456789ab myrepo/mycontainer mytag .ft P .fi .UNINDENT @@ -131435,7 +139978,7 @@ salt myminion docker.tag 0123456789ab myrepo/mycontainer:mytag .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockermod.top(name, *args, **kwargs) +.B salt.modules.dockermod.top(name) Runs the \fIdocker top\fP command on a specific container .INDENT 7.0 .TP @@ -131595,7 +140138,7 @@ salt myminion docker.wait mycontainer Support for DEB packages .INDENT 0.0 .TP -.B salt.modules.dpkg.bin_pkg_info(path, saltenv=\(aqbase\(aq) +.B salt.modules.dpkg.bin_pkg_info(path, saltenv=u\(aqbase\(aq) New in version 2015.8.0. .sp @@ -134039,7 +142582,7 @@ Some functionality might be limited by elasticsearch\-py and Elasticsearch serve .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.alias_create(indices, alias, hosts=None, body=None, profile=None) +.B salt.modules.elasticsearch.alias_create(indices, alias, hosts=None, body=None, profile=None, source=None) Create an alias for a specific index/indices .INDENT 7.0 .TP @@ -134051,6 +142594,9 @@ Alias name .TP .B body Optional definition such as routing or filter as defined in \fI\%https://www.elastic.co/guide/en/elasticsearch/reference/current/indices\-aliases.html\fP +.TP +.B source +URL of file specifying optional definition such as routing or filter. Cannot be used in combination with \fBbody\fP\&. .UNINDENT .sp CLI example: @@ -134067,7 +142613,7 @@ salt myminion elasticsearch.alias_create testindex_v1 testindex .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.alias_delete(indices, aliases, hosts=None, body=None, profile=None) +.B salt.modules.elasticsearch.alias_delete(indices, aliases, hosts=None, body=None, profile=None, source=None) Delete an alias of an index .INDENT 7.0 .TP @@ -134142,7 +142688,7 @@ salt myminion elasticsearch.alias_get testindex .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.cluster_health(index=None, level=\(aqcluster\(aq, local=False, hosts=None, profile=None) +.B salt.modules.elasticsearch.cluster_health(index=None, level=u\(aqcluster\(aq, local=False, hosts=None, profile=None) New in version 2017.7.0. .sp @@ -134198,7 +142744,7 @@ salt myminion elasticsearch.stats .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.document_create(index, doc_type, body=None, id=None, hosts=None, profile=None) +.B salt.modules.elasticsearch.document_create(index, doc_type, body=None, id=None, hosts=None, profile=None, source=None) Create a document in a specified index .INDENT 7.0 .TP @@ -134211,6 +142757,9 @@ Type of the document .B body Document to store .TP +.B source +URL of file specifying document to store. Cannot be used in combination with \fBbody\fP\&. +.TP .B id Optional unique document identifier for specified doc_type (empty for random) .UNINDENT @@ -134257,7 +142806,7 @@ salt myminion elasticsearch.document_delete testindex doctype1 AUx\-384m0Bug_8U8 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.document_exists(index, id, doc_type=\(aq_all\(aq, hosts=None, profile=None) +.B salt.modules.elasticsearch.document_exists(index, id, doc_type=u\(aq_all\(aq, hosts=None, profile=None) Return a boolean indicating whether given document exists .INDENT 7.0 .TP @@ -134285,7 +142834,7 @@ salt myminion elasticsearch.document_exists testindex AUx\-384m0Bug_8U80wQZ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.document_get(index, id, doc_type=\(aq_all\(aq, hosts=None, profile=None) +.B salt.modules.elasticsearch.document_get(index, id, doc_type=u\(aq_all\(aq, hosts=None, profile=None) Check for the existence of a document and if it exists, return it .INDENT 7.0 .TP @@ -134313,7 +142862,7 @@ salt myminion elasticsearch.document_get testindex AUx\-384m0Bug_8U80wQZ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.index_close(index, allow_no_indices=True, expand_wildcards=\(aqopen\(aq, ignore_unavailable=True, hosts=None, profile=None) +.B salt.modules.elasticsearch.index_close(index, allow_no_indices=True, expand_wildcards=u\(aqopen\(aq, ignore_unavailable=True, hosts=None, profile=None) New in version 2017.7.0. .sp @@ -134347,7 +142896,7 @@ salt myminion elasticsearch.index_close testindex .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.index_create(index, body=None, hosts=None, profile=None) +.B salt.modules.elasticsearch.index_create(index, body=None, hosts=None, profile=None, source=None) Create an index .INDENT 7.0 .TP @@ -134356,6 +142905,9 @@ Index name .TP .B body Index definition, such as settings and mappings as defined in \fI\%https://www.elastic.co/guide/en/elasticsearch/reference/current/indices\-create\-index.html\fP +.TP +.B source +URL to file specifying index definition. Cannot be used in combination with \fBbody\fP\&. .UNINDENT .sp CLI example: @@ -134439,7 +142991,7 @@ salt myminion elasticsearch.index_get testindex .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.index_open(index, allow_no_indices=True, expand_wildcards=\(aqclosed\(aq, ignore_unavailable=True, hosts=None, profile=None) +.B salt.modules.elasticsearch.index_open(index, allow_no_indices=True, expand_wildcards=u\(aqclosed\(aq, ignore_unavailable=True, hosts=None, profile=None) New in version 2017.7.0. .sp @@ -134473,7 +143025,7 @@ salt myminion elasticsearch.index_open testindex .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.index_template_create(name, body, hosts=None, profile=None) +.B salt.modules.elasticsearch.index_template_create(name, body=None, hosts=None, profile=None, source=None) Create an index template .INDENT 7.0 .TP @@ -134482,6 +143034,9 @@ Index template name .TP .B body Template definition as specified in \fI\%http://www.elastic.co/guide/en/elasticsearch/reference/current/indices\-templates.html\fP +.TP +.B source +URL to file specifying template definition. Cannot be used in combination with \fBbody\fP\&. .UNINDENT .sp CLI example: @@ -134585,7 +143140,7 @@ salt myminion elasticsearch.info profile=elasticsearch\-extra .UNINDENT .INDENT 0.0 .TP -.B salt.modules.elasticsearch.mapping_create(index, doc_type, body, hosts=None, profile=None) +.B salt.modules.elasticsearch.mapping_create(index, doc_type, body=None, hosts=None, profile=None, source=None) Create a mapping in a given index .INDENT 7.0 .TP @@ -134597,6 +143152,9 @@ Name of the document type .TP .B body Mapping definition as specified in \fI\%https://www.elastic.co/guide/en/elasticsearch/reference/current/indices\-put\-mapping.html\fP +.TP +.B source +URL to file specifying mapping definition. Cannot be used in combination with \fBbody\fP\&. .UNINDENT .sp CLI example: @@ -135166,7 +143724,7 @@ Support for getting and setting the environment variables of the current salt process. .INDENT 0.0 .TP -.B salt.modules.environ.get(key, default=\(aq\(aq) +.B salt.modules.environ.get(key, default=u\(aq\(aq) Get a single salt process environment variable. .INDENT 7.0 .TP @@ -135221,7 +143779,7 @@ salt \(aq*\(aq environ.has_value foo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.environ.item(keys, default=\(aq\(aq) +.B salt.modules.environ.item(keys, default=u\(aq\(aq) Get one or more salt process environment variables. Returns a dict. .INDENT 7.0 @@ -135300,7 +143858,7 @@ Default: False .TP .B permanent On Windows minions this will set the environment variable in the -registry so that it is always added as a environment variable when +registry so that it is always added as an environment variable when applications open. If you want to set the variable to HKLM instead of HKCU just pass in "HKLM" for this parameter. On all other minion types this will be ignored. Note: This will only take affect on applications @@ -135343,7 +143901,7 @@ Default: False. .TP .B permanent On Windows minions this will set the environment variable in the -registry so that it is always added as a environment variable when +registry so that it is always added as an environment variable when applications open. If you want to set the variable to HKLM instead of HKCU just pass in "HKLM" for this parameter. On all other minion types this will be ignored. Note: This will only take affect on applications @@ -135620,7 +144178,7 @@ pillars. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.etcd_mod.get(key, recurse=False, profile=None) +.B salt.modules.etcd_mod.get(key, recurse=False, profile=None, **kwargs) New in version 2014.7.0. .sp @@ -135635,6 +144193,7 @@ CLI Examples: salt myminion etcd.get /path/to/key salt myminion etcd.get /path/to/key profile=my_etcd_config salt myminion etcd.get /path/to/key recurse=True profile=my_etcd_config +salt myminion etcd.get /path/to/key host=127.0.0.1 port=2379 .ft P .fi .UNINDENT @@ -135642,7 +144201,7 @@ salt myminion etcd.get /path/to/key recurse=True profile=my_etcd_config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.etcd_mod.ls(path=\(aq/\(aq, profile=None) +.B salt.modules.etcd_mod.ls(path=u\(aq/\(aq, profile=None, **kwargs) New in version 2014.7.0. .sp @@ -135657,6 +144216,7 @@ CLI Example: .ft C salt myminion etcd.ls /path/to/dir/ salt myminion etcd.ls /path/to/dir/ profile=my_etcd_config +salt myminion etcd.ls /path/to/dir/ host=127.0.0.1 port=2379 .ft P .fi .UNINDENT @@ -135664,7 +144224,7 @@ salt myminion etcd.ls /path/to/dir/ profile=my_etcd_config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.etcd_mod.rm(key, recurse=False, profile=None) +.B salt.modules.etcd_mod.rm(key, recurse=False, profile=None, **kwargs) New in version 2014.7.0. .sp @@ -135679,6 +144239,7 @@ CLI Example: .ft C salt myminion etcd.rm /path/to/key salt myminion etcd.rm /path/to/key profile=my_etcd_config +salt myminion etcd.rm /path/to/key host=127.0.0.1 port=2379 salt myminion etcd.rm /path/to/dir recurse=True profile=my_etcd_config .ft P .fi @@ -135687,7 +144248,7 @@ salt myminion etcd.rm /path/to/dir recurse=True profile=my_etcd_config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.etcd_mod.set(key, value, profile=None, ttl=None, directory=False) +.B salt.modules.etcd_mod.set(key, value, profile=None, ttl=None, directory=False, **kwargs) New in version 2014.7.0. .sp @@ -135702,6 +144263,7 @@ CLI Example: .ft C salt myminion etcd.set /path/to/key value salt myminion etcd.set /path/to/key value profile=my_etcd_config +salt myminion etcd.set /path/to/key value host=127.0.0.1 port=2379 salt myminion etcd.set /path/to/dir \(aq\(aq directory=True salt myminion etcd.set /path/to/key value ttl=5 .ft P @@ -135711,7 +144273,7 @@ salt myminion etcd.set /path/to/key value ttl=5 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.etcd_mod.tree(path=\(aq/\(aq, profile=None) +.B salt.modules.etcd_mod.tree(path=u\(aq/\(aq, profile=None, **kwargs) New in version 2014.7.0. .sp @@ -135725,6 +144287,7 @@ CLI Example: .ft C salt myminion etcd.tree salt myminion etcd.tree profile=my_etcd_config +salt myminion etcd.tree host=127.0.0.1 port=2379 salt myminion etcd.tree /path/to/keys profile=my_etcd_config .ft P .fi @@ -135733,7 +144296,7 @@ salt myminion etcd.tree /path/to/keys profile=my_etcd_config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.etcd_mod.update(fields, path=\(aq\(aq, profile=None) +.B salt.modules.etcd_mod.update(fields, path=u\(aq\(aq, profile=None, **kwargs) New in version 2016.3.0. .sp @@ -135794,6 +144357,7 @@ CLI Example: .ft C salt myminion etcd.update "{\(aq/path/to/key\(aq: \(aqbaz\(aq, \(aq/another/key\(aq: \(aqbar\(aq}" salt myminion etcd.update "{\(aq/path/to/key\(aq: \(aqbaz\(aq, \(aq/another/key\(aq: \(aqbar\(aq}" profile=my_etcd_config +salt myminion etcd.update "{\(aq/path/to/key\(aq: \(aqbaz\(aq, \(aq/another/key\(aq: \(aqbar\(aq}" host=127.0.0.1 port=2379 salt myminion etcd.update "{\(aq/path/to/key\(aq: \(aqbaz\(aq, \(aq/another/key\(aq: \(aqbar\(aq}" path=\(aq/some/root\(aq .ft P .fi @@ -135802,7 +144366,7 @@ salt myminion etcd.update "{\(aq/path/to/key\(aq: \(aqbaz\(aq, \(aq/another/key\ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.etcd_mod.watch(key, recurse=False, profile=None, timeout=0, index=None) +.B salt.modules.etcd_mod.watch(key, recurse=False, profile=None, timeout=0, index=None, **kwargs) New in version 2016.3.0. .sp @@ -135822,6 +144386,7 @@ CLI Example: salt myminion etcd.watch /path/to/key salt myminion etcd.watch /path/to/key timeout=10 salt myminion etcd.watch /patch/to/key profile=my_etcd_config index=10 +salt myminion etcd.watch /patch/to/key host=127.0.0.1 port=2379 .ft P .fi .UNINDENT @@ -136440,7 +145005,7 @@ salt \(aq*\(aq file.basename \(aqtest/test.config\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.blockreplace(path, marker_start=\(aq#\-\- start managed zone \-\-\(aq, marker_end=\(aq#\-\- end managed zone \-\-\(aq, content=\(aq\(aq, append_if_not_found=False, prepend_if_not_found=False, backup=\(aq.bak\(aq, dry_run=False, show_changes=True, append_newline=False) +.B salt.modules.file.blockreplace(path, marker_start=u\(aq#\-\- start managed zone \-\-\(aq, marker_end=u\(aq#\-\- end managed zone \-\-\(aq, content=u\(aq\(aq, append_if_not_found=False, prepend_if_not_found=False, backup=u\(aq.bak\(aq, dry_run=False, show_changes=True, append_newline=False) New in version 2014.1.0. .sp @@ -136522,7 +145087,60 @@ salt \(aq*\(aq file.blockreplace /etc/hosts \(aq#\-\- start managed zone foobar .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.check_file_meta(name, sfn, source, source_sum, user, group, mode, saltenv, contents=None) +.B salt.modules.file.chattr(*args, **kwargs) +New in version 2018.3.0. + +.sp +Change the attributes of files +.INDENT 7.0 +.TP +.B +.nf +* +.fi +args +list of files to modify attributes of +.UNINDENT +.sp + +.nf +** +.fi +kwargs \- the following are valid pairs: +.INDENT 7.0 +.TP +.B operator +add|remove +determines whether attributes should be added or removed from files +.TP +.B attributes +acdijstuADST +string of characters representing attributes to add/remove from files +.TP +.B version +a version number to assign to the files +.TP +.B flags +[RVf] +flags to assign to chattr (recurse, verbose, suppress most errors) +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq file.chattr foo1.txt foo2.txt operator=add attributes=ai +salt \(aq*\(aq file.chattr foo3.txt operator=remove attributes=i version=2 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.file.check_file_meta(name, sfn, source, source_sum, user, group, mode, attrs, saltenv, contents=None) Check for the changes in the file metadata. .sp CLI Example: @@ -136576,6 +145194,12 @@ Destination file group owner .TP .B mode Destination file permissions mode +.TP +.B attrs +Destination file attributes +.sp +New in version 2018.3.0. + .TP .B saltenv Salt environment used to resolve source files @@ -136623,7 +145247,7 @@ salt \(aq*\(aq file.check_hash /etc/fstab md5=e138491e9d5b97023cea823fe17bac22 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.check_managed(name, source, source_hash, source_hash_name, user, group, mode, template, context, defaults, saltenv, contents=None, skip_verify=False, **kwargs) +.B salt.modules.file.check_managed(name, source, source_hash, source_hash_name, user, group, mode, attrs, template, context, defaults, saltenv, contents=None, skip_verify=False, **kwargs) Check to see what changes need to be made for a file .sp CLI Example: @@ -136640,7 +145264,7 @@ salt \(aq*\(aq file.check_managed /etc/httpd/conf.d/httpd.conf salt://http/httpd .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.check_managed_changes(name, source, source_hash, source_hash_name, user, group, mode, template, context, defaults, saltenv, contents=None, skip_verify=False, keep_mode=False, **kwargs) +.B salt.modules.file.check_managed_changes(name, source, source_hash, source_hash_name, user, group, mode, attrs, template, context, defaults, saltenv, contents=None, skip_verify=False, keep_mode=False, **kwargs) Return a dictionary of what changes need to be made for a file .sp CLI Example: @@ -136657,8 +145281,9 @@ salt \(aq*\(aq file.check_managed_changes /etc/httpd/conf.d/httpd.conf salt://ht .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.check_perms(name, ret, user, group, mode, follow_symlinks=False) -Check the permissions on files and chown if needed +.B salt.modules.file.check_perms(name, ret, user, group, mode, attrs=None, follow_symlinks=False) +Check the permissions on files, modify attributes and chown if needed. File +attributes are only verified if lsattr(1) is installed. .sp CLI Example: .INDENT 7.0 @@ -136666,7 +145291,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq file.check_perms /etc/sudoers \(aq{}\(aq root root 400 +salt \(aq*\(aq file.check_perms /etc/sudoers \(aq{}\(aq root root 400 ai .ft P .fi .UNINDENT @@ -136730,7 +145355,7 @@ salt \(aq*\(aq file.chown /etc/passwd root root .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.comment(path, regex, char=\(aq#\(aq, backup=\(aq.bak\(aq) +.B salt.modules.file.comment(path, regex, char=u\(aq#\(aq, backup=u\(aq.bak\(aq) Deprecated since version 0.17.0: Use \fI\%replace()\fP instead. .sp @@ -136779,7 +145404,7 @@ salt \(aq*\(aq file.comment /etc/modules pcspkr .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.comment_line(path, regex, char=\(aq#\(aq, cmnt=True, backup=\(aq.bak\(aq) +.B salt.modules.file.comment_line(path, regex, char=u\(aq#\(aq, cmnt=True, backup=u\(aq.bak\(aq) Comment or Uncomment a line in a text file. .INDENT 7.0 .TP @@ -136884,7 +145509,7 @@ salt \(aq*\(aq file.contains_glob /etc/foobar \(aq*cheese*\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.contains_regex(path, regex, lchar=\(aq\(aq) +.B salt.modules.file.contains_regex(path, regex, lchar=u\(aq\(aq) Deprecated since version 0.17.0: Use \fI\%search()\fP instead. .sp @@ -137040,7 +145665,7 @@ salt \(aq*\(aq file.diskusage /path/to/check .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.extract_hash(hash_fn, hash_type=\(aqsha256\(aq, file_name=\(aq\(aq, source=\(aq\(aq, source_hash_name=None) +.B salt.modules.file.extract_hash(hash_fn, hash_type=u\(aqsha256\(aq, file_name=u\(aq\(aq, source=u\(aq\(aq, source_hash_name=None) Changed in version 2016.3.5: Prior to this version, only the \fBfile_name\fP argument was considered for filename matches in the hash file. This would be problematic for cases in which the user was relying on a remote checksum file that they @@ -137304,16 +145929,72 @@ salt \(aq*\(aq file.get_devmm /dev/chr .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.get_diff(minionfile, masterfile, saltenv=\(aqbase\(aq) -Return unified diff of file compared to file on master +.B salt.modules.file.get_diff(file1, file2, saltenv=u\(aqbase\(aq, show_filenames=True, show_changes=True, template=False, source_hash_file1=None, source_hash_file2=None) +Return unified diff of two files +.INDENT 7.0 +.TP +.B file1 +The first file to feed into the diff utility .sp -CLI Example: +Changed in version 2018.3.0: Can now be either a local or remote file. In earlier releases, +thuis had to be a file local to the minion. + +.TP +.B file2 +The second file to feed into the diff utility +.sp +Changed in version 2018.3.0: Can now be either a local or remote file. In earlier releases, this +had to be a file on the salt fileserver (i.e. +\fBsalt://somefile.txt\fP) + +.TP +.B show_filenames +True +Set to \fBFalse\fP to hide the filenames in the top two lines of the +diff. +.TP +.B show_changes +True +If set to \fBFalse\fP, and there are differences, then instead of a diff +a simple message stating that show_changes is set to \fBFalse\fP will be +returned. +.TP +.B template +False +Set to \fBTrue\fP if two templates are being compared. This is not useful +except for within states, with the \fBobfuscate_templates\fP option set +to \fBTrue\fP\&. +.sp +New in version 2018.3.0. + +.TP +.B source_hash_file1 +If \fBfile1\fP is an http(s)/ftp URL and the file exists in the minion\(aqs +file cache, this option can be passed to keep the minion from +re\-downloading the archive if the cached copy matches the specified +hash. +.sp +New in version 2018.3.0. + +.TP +.B source_hash_file2 +If \fBfile2\fP is an http(s)/ftp URL and the file exists in the minion\(aqs +file cache, this option can be passed to keep the minion from +re\-downloading the archive if the cached copy matches the specified +hash. +.sp +New in version 2018.3.0. + +.UNINDENT +.sp +CLI Examples: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C salt \(aq*\(aq file.get_diff /home/fred/.vimrc salt://users/fred/.vimrc +salt \(aq*\(aq file.get_diff /tmp/foo.txt /tmp/bar.txt .ft P .fi .UNINDENT @@ -137377,7 +146058,7 @@ Changed in version 0.16.4: \fBfollow_symlinks\fP option added .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.get_hash(path, form=\(aqsha256\(aq, chunk_size=65536) +.B salt.modules.file.get_hash(path, form=u\(aqsha256\(aq, chunk_size=65536) Get the hash sum of a file .INDENT 7.0 .TP @@ -137418,7 +146099,7 @@ salt \(aq*\(aq file.get_hash /etc/shadow .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.get_managed(name, template, source, source_hash, source_hash_name, user, group, mode, saltenv, context, defaults, skip_verify=False, **kwargs) +.B salt.modules.file.get_managed(name, template, source, source_hash, source_hash_name, user, group, mode, attrs, saltenv, context, defaults, skip_verify=False, **kwargs) Return the managed file data for file.managed .INDENT 7.0 .TP @@ -137449,6 +146130,12 @@ Group owner of file .TP .B mode Permissions of file +.TP +.B attrs +Attributes of file +.sp +New in version 2018.3.0. + .TP .B context Variables to add to the template context @@ -137524,7 +146211,7 @@ salt \(aq*\(aq file.get_selinux_context /etc/hosts .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.get_source_sum(file_name=\(aq\(aq, source=\(aq\(aq, source_hash=None, source_hash_name=None, saltenv=\(aqbase\(aq) +.B salt.modules.file.get_source_sum(file_name=u\(aq\(aq, source=u\(aq\(aq, source_hash=None, source_hash_name=None, saltenv=u\(aqbase\(aq) New in version 2016.11.0. .sp @@ -137576,7 +146263,7 @@ salt \(aq*\(aq file.get_source_sum /tmp/foo.tar.gz source=http://mydomain.tld/fo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.get_sum(path, form=\(aqsha256\(aq) +.B salt.modules.file.get_sum(path, form=u\(aqsha256\(aq) Return the checksum for the given file. The following checksum algorithms are supported: .INDENT 7.0 @@ -138138,6 +146825,32 @@ salt \(aq*\(aq file.list_backups_dir /foo/bar/baz/ .UNINDENT .INDENT 0.0 .TP +.B salt.modules.file.lsattr(path) +New in version 2018.3.0. + +.sp +Obtain the modifiable attributes of the given file. If path +is to a directory, an empty list is returned. +.INDENT 7.0 +.TP +.B path +path to file to obtain attributes of. File/directory must exist. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq file.lsattr foo1.txt +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.file.lstat(path) New in version 2014.1.0. @@ -138187,7 +146900,7 @@ salt \(aq*\(aq file.makedirs /opt/code/ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.makedirs_perms(name, user=None, group=None, mode=\(aq0755\(aq) +.B salt.modules.file.makedirs_perms(name, user=None, group=None, mode=u\(aq0755\(aq) Taken and modified from os.makedirs to set user, group and mode for each directory created. .sp @@ -138205,7 +146918,7 @@ salt \(aq*\(aq file.makedirs_perms /opt/code .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.manage_file(name, sfn, ret, source, source_sum, user, group, mode, saltenv, backup, makedirs=False, template=None, show_changes=True, contents=None, dir_mode=None, follow_symlinks=True, skip_verify=False, keep_mode=False, encoding=None, encoding_errors=\(aqstrict\(aq, **kwargs) +.B salt.modules.file.manage_file(name, sfn, ret, source, source_sum, user, group, mode, attrs, saltenv, backup, makedirs=False, template=None, show_changes=True, contents=None, dir_mode=None, follow_symlinks=True, skip_verify=False, keep_mode=False, encoding=None, encoding_errors=u\(aqstrict\(aq, **kwargs) Checks the destination against what was retrieved with get_managed and makes the appropriate modifications (if necessary). .INDENT 7.0 @@ -138243,6 +146956,12 @@ group owner .TP .B backup backup_mode +.TP +.B attrs +attributes to be set on file: \(aq\(aq means remove all of them +.sp +New in version 2018.3.0. + .TP .B makedirs make directories if they do not exist @@ -138287,11 +147006,10 @@ cannot mirror the mode on the salt\-ssh minion .UNINDENT .TP .B encoding -None -If None, str() will be applied to contents. -If not None, specified encoding will be used. -See \fI\%https://docs.python.org/3/library/codecs.html#standard\-encodings\fP -for the list of available encodings. +If specified, then the specified encoding will be used. Otherwise, the +file will be encoded using the system locale (usually UTF\-8). See +\fI\%https://docs.python.org/3/library/codecs.html#standard\-encodings\fP for +the list of available encodings. .sp New in version 2017.7.0. @@ -138340,7 +147058,7 @@ salt \(aq*\(aq file.mkdir /opt/jetty/context .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.mknod(name, ntype, major=0, minor=0, user=None, group=None, mode=\(aq0600\(aq) +.B salt.modules.file.mknod(name, ntype, major=0, minor=0, user=None, group=None, mode=u\(aq0600\(aq) New in version 0.17.0. .sp @@ -138363,7 +147081,7 @@ salt \(aq*\(aq file.nknod /dev/fifo p .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.mknod_blkdev(name, major, minor, user=None, group=None, mode=\(aq0660\(aq) +.B salt.modules.file.mknod_blkdev(name, major, minor, user=None, group=None, mode=u\(aq0660\(aq) New in version 0.17.0. .sp @@ -138383,7 +147101,7 @@ salt \(aq*\(aq file.mknod_blkdev /dev/blk 8 999 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.mknod_chrdev(name, major, minor, user=None, group=None, mode=\(aq0660\(aq) +.B salt.modules.file.mknod_chrdev(name, major, minor, user=None, group=None, mode=u\(aq0660\(aq) New in version 0.17.0. .sp @@ -138403,7 +147121,7 @@ salt \(aq*\(aq file.mknod_chrdev /dev/chr 180 31 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.mknod_fifo(name, user=None, group=None, mode=\(aq0660\(aq) +.B salt.modules.file.mknod_fifo(name, user=None, group=None, mode=u\(aq0660\(aq) New in version 0.17.0. .sp @@ -138523,7 +147241,7 @@ salt \(aq*\(aq file.pardir .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.patch(originalfile, patchfile, options=\(aq\(aq, dry_run=False) +.B salt.modules.file.patch(originalfile, patchfile, options=u\(aq\(aq, dry_run=False) New in version 0.10.4. .sp @@ -138651,7 +147369,7 @@ salt \(aq*\(aq file.prepend /etc/motd args="[\(aqcheese=spam\(aq,\(aqspam=cheese .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.psed(path, before, after, limit=\(aq\(aq, backup=\(aq.bak\(aq, flags=\(aqgMS\(aq, escape_all=False, multi=False) +.B salt.modules.file.psed(path, before, after, limit=u\(aq\(aq, backup=u\(aq.bak\(aq, flags=u\(aqgMS\(aq, escape_all=False, multi=False) Deprecated since version 0.17.0: Use \fI\%replace()\fP instead. .sp @@ -138830,7 +147548,7 @@ salt \(aq*\(aq file.rename /path/to/src /path/to/dst .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.replace(path, pattern, repl, count=0, flags=8, bufsize=1, append_if_not_found=False, prepend_if_not_found=False, not_found_content=None, backup=\(aq.bak\(aq, dry_run=False, search_only=False, show_changes=True, ignore_if_missing=False, preserve_inode=True, backslash_literal=False) +.B salt.modules.file.replace(path, pattern, repl, count=0, flags=8, bufsize=1, append_if_not_found=False, prepend_if_not_found=False, not_found_content=None, backup=u\(aq.bak\(aq, dry_run=False, search_only=False, show_changes=True, ignore_if_missing=False, preserve_inode=True, backslash_literal=False) New in version 0.17.0. .sp @@ -139089,7 +147807,7 @@ salt \(aq*\(aq file.search /etc/crontab \(aqmymaintenance.sh\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.sed(path, before, after, limit=\(aq\(aq, backup=\(aq.bak\(aq, options=\(aq\-r \-e\(aq, flags=\(aqg\(aq, escape_all=False, negate_match=False) +.B salt.modules.file.sed(path, before, after, limit=u\(aq\(aq, backup=u\(aq.bak\(aq, options=u\(aq\-r \-e\(aq, flags=u\(aqg\(aq, escape_all=False, negate_match=False) Deprecated since version 0.17.0: Use \fI\%replace()\fP instead. .sp @@ -139161,7 +147879,7 @@ salt \(aq*\(aq file.sed /etc/httpd/httpd.conf \(aqLogLevel warn\(aq \(aqLogLevel .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.sed_contains(path, text, limit=\(aq\(aq, flags=\(aqg\(aq) +.B salt.modules.file.sed_contains(path, text, limit=u\(aq\(aq, flags=u\(aqg\(aq) Deprecated since version 0.17.0: Use \fI\%search()\fP instead. .sp @@ -139280,7 +147998,8 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq file.set_selinux_context path +salt \(aq*\(aq file.set_selinux_context path +salt \(aq*\(aq file.set_selinux_context /etc/yum.repos.d/epel.repo system_u object_r system_conf_t s0 .ft P .fi .UNINDENT @@ -139438,7 +148157,7 @@ salt \(aq*\(aq file.uid_to_user 0 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.file.uncomment(path, regex, char=\(aq#\(aq, backup=\(aq.bak\(aq) +.B salt.modules.file.uncomment(path, regex, char=u\(aq#\(aq, backup=u\(aq.bak\(aq) Deprecated since version 0.17.0: Use \fI\%replace()\fP instead. .sp @@ -139610,7 +148329,7 @@ salt \(aq*\(aq firewalld.add_masquerade dmz .UNINDENT .INDENT 0.0 .TP -.B salt.modules.firewalld.add_port(zone, port, permanent=True) +.B salt.modules.firewalld.add_port(zone, port, permanent=True, force_masquerade=None) Allow specific ports in a zone. .sp New in version 2015.8.0. @@ -139630,7 +148349,7 @@ salt \(aq*\(aq firewalld.add_port internal 443/tcp .UNINDENT .INDENT 0.0 .TP -.B salt.modules.firewalld.add_port_fwd(zone, src, dest, proto=\(aqtcp\(aq, dstaddr=\(aq\(aq, permanent=True) +.B salt.modules.firewalld.add_port_fwd(zone, src, dest, proto=u\(aqtcp\(aq, dstaddr=u\(aq\(aq, permanent=True, force_masquerade=None) Add port forwarding. .sp New in version 2015.8.0. @@ -140355,7 +149074,7 @@ salt \(aq*\(aq firewalld.remove_port internal 443/tcp .UNINDENT .INDENT 0.0 .TP -.B salt.modules.firewalld.remove_port_fwd(zone, src, dest, proto=\(aqtcp\(aq, dstaddr=\(aq\(aq, permanent=True) +.B salt.modules.firewalld.remove_port_fwd(zone, src, dest, proto=u\(aqtcp\(aq, dstaddr=u\(aq\(aq, permanent=True) Remove Port Forwarding. .sp New in version 2015.8.0. @@ -140556,7 +149275,7 @@ salt \(aq*\(aq sysctl.get hw.physmem .UNINDENT .INDENT 0.0 .TP -.B salt.modules.freebsd_sysctl.persist(name, value, config=\(aq/etc/sysctl.conf\(aq) +.B salt.modules.freebsd_sysctl.persist(name, value, config=u\(aq/etc/sysctl.conf\(aq) Assign and persist a simple sysctl parameter for this minion .sp CLI Example: @@ -140756,7 +149475,7 @@ salt \(aq*\(aq jail.is_enabled .UNINDENT .INDENT 0.0 .TP -.B salt.modules.freebsdjail.restart(jail=\(aq\(aq) +.B salt.modules.freebsdjail.restart(jail=u\(aq\(aq) Restart the specified jail or all, if none specified .sp CLI Example: @@ -140790,7 +149509,7 @@ salt \(aq*\(aq jail.show_config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.freebsdjail.start(jail=\(aq\(aq) +.B salt.modules.freebsdjail.start(jail=u\(aq\(aq) Start the specified jail or all, if none specified .sp CLI Example: @@ -140824,7 +149543,7 @@ salt \(aq*\(aq jail.status .UNINDENT .INDENT 0.0 .TP -.B salt.modules.freebsdjail.stop(jail=\(aq\(aq) +.B salt.modules.freebsdjail.stop(jail=u\(aq\(aq) Stop the specified jail or all, if none specified .sp CLI Example: @@ -141363,7 +150082,7 @@ New in version 2014.1.0. .sp This module allows you to install ports using \fBBATCH=yes\fP to bypass -configuration prompts. It is recommended to use the \fBports state\fP to install ports, but it it also possible to use +configuration prompts. It is recommended to use the \fBports state\fP to install ports, but it is also possible to use this module exclusively from the command line. .INDENT 0.0 .INDENT 3.5 @@ -141892,17 +150611,32 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.freebsdservice.status(name, sig=None, jail=None) -Return the status for a service (True or False). -.INDENT 7.0 -.TP -.B name -Name of service -.UNINDENT +Return the status for a service. +If the name contains globbing, a dict mapping service name to True/False +values is returned. .sp Changed in version 2016.3.4. .sp -jail: optional jid or jail name +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Signature to use to find the service via ps +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -141910,7 +150644,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq service.status +salt \(aq*\(aq service.status [service signature] .ft P .fi .UNINDENT @@ -142005,7 +150739,7 @@ salt \(aq*\(aq gem.install redphone gem_bin=/opt/sensu/embedded/bin/gem .UNINDENT .INDENT 0.0 .TP -.B salt.modules.gem.list(prefix=\(aq\(aq, ruby=None, runas=None, gem_bin=None) +.B salt.modules.gem.list(prefix=u\(aq\(aq, ruby=None, runas=None, gem_bin=None) List locally installed gems. .INDENT 7.0 .TP @@ -142253,7 +150987,7 @@ salt \(aq*\(aq gem.update vagrant .UNINDENT .INDENT 0.0 .TP -.B salt.modules.gem.update_system(version=\(aq\(aq, ruby=None, runas=None, gem_bin=None) +.B salt.modules.gem.update_system(version=u\(aq\(aq, ruby=None, runas=None, gem_bin=None) Update rubygems. .INDENT 7.0 .TP @@ -142312,7 +151046,7 @@ salt myminion genesis.avail_platforms .UNINDENT .INDENT 0.0 .TP -.B salt.modules.genesis.bootstrap(platform, root, img_format=\(aqdir\(aq, fs_format=\(aqext2\(aq, fs_opts=None, arch=None, flavor=None, repo_url=None, static_qemu=None, img_size=None, mount_dir=None, pkg_cache=None, pkgs=None, exclude_pkgs=None, epel_url=\(aqhttp://download.fedoraproject.org/pub/epel/6/i386/epel\-release\-6\-8.noarch.rpm\(aq) +.B salt.modules.genesis.bootstrap(platform, root, img_format=u\(aqdir\(aq, fs_format=u\(aqext2\(aq, fs_opts=None, arch=None, flavor=None, repo_url=None, static_qemu=None, img_size=None, mount_dir=None, pkg_cache=None, pkgs=None, exclude_pkgs=None, epel_url=u\(aqhttp://download.fedoraproject.org/pub/epel/6/i386/epel\-release\-6\-8.noarch.rpm\(aq) Create an image for a specific platform. .sp Please note that this function \fIMUST\fP be run as root, as images that are @@ -142436,7 +151170,7 @@ New in version Beryllium. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.genesis.pack(name, root, path=None, pack_format=\(aqtar\(aq, compress=\(aqbzip2\(aq) +.B salt.modules.genesis.pack(name, root, path=None, pack_format=u\(aqtar\(aq, compress=u\(aqbzip2\(aq) Pack up a directory structure, into a specific format .sp CLI Examples: @@ -142454,7 +151188,7 @@ salt myminion genesis.pack centos /root/centos pack_format=\(aqtar\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.genesis.unpack(name, dest=None, path=None, pack_format=\(aqtar\(aq, compress=\(aqbz2\(aq) +.B salt.modules.genesis.unpack(name, dest=None, path=None, pack_format=u\(aqtar\(aq, compress=u\(aqbz2\(aq) Unpack an image into a directory structure .sp CLI Example: @@ -142695,9 +151429,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.gentoo_service.status(name, sig=None) -Return the status for a service, returns the PID or an empty string if the -service is running or not, pass a signature to use to find the service via -ps +Return the status for a service. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Signature to use to find the service via ps +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -142750,7 +151504,7 @@ salt \(aq*\(aq service.zap Support for Gentoolkit .INDENT 0.0 .TP -.B salt.modules.gentoolkitmod.eclean_dist(destructive=False, package_names=False, size_limit=0, time_limit=0, fetch_restricted=False, exclude_file=\(aq/etc/eclean/distfiles.exclude\(aq) +.B salt.modules.gentoolkitmod.eclean_dist(destructive=False, package_names=False, size_limit=0, time_limit=0, fetch_restricted=False, exclude_file=u\(aq/etc/eclean/distfiles.exclude\(aq) Clean obsolete portage sources .INDENT 7.0 .TP @@ -142811,7 +151565,7 @@ salt \(aq*\(aq gentoolkit.eclean_dist destructive=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.gentoolkitmod.eclean_pkg(destructive=False, package_names=False, time_limit=0, exclude_file=\(aq/etc/eclean/packages.exclude\(aq) +.B salt.modules.gentoolkitmod.eclean_pkg(destructive=False, package_names=False, time_limit=0, exclude_file=u\(aq/etc/eclean/packages.exclude\(aq) Clean obsolete binary packages .INDENT 7.0 .TP @@ -142925,7 +151679,7 @@ salt \(aq*\(aq gentoolkit.revdep_rebuild Support for the Git SCM .INDENT 0.0 .TP -.B salt.modules.git.add(cwd, filename, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.add(cwd, filename, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) Changed in version 2015.8.0: The \fB\-\-verbose\fP command line argument is now implied .sp @@ -143004,7 +151758,7 @@ salt myminion git.add /path/to/repo foo/bar.py opts=\(aq\-\-dry\-run\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.archive(cwd, output, rev=\(aqHEAD\(aq, prefix=None, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False, **kwargs) +.B salt.modules.git.archive(cwd, output, rev=u\(aqHEAD\(aq, prefix=None, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False, **kwargs) Changed in version 2015.8.0: Returns \fBTrue\fP if successful, raises an error if not. .sp @@ -143134,7 +151888,7 @@ salt myminion git.archive /path/to/repo /path/to/archive.tar .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.branch(cwd, name=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.branch(cwd, name=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) Interface to \fI\%git\-branch(1)\fP .INDENT 7.0 .TP @@ -143223,7 +151977,7 @@ salt myminion git.branch /path/to/repo newbranch opts=\(aq\-m oldbranch\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.checkout(cwd, rev=None, force=False, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.checkout(cwd, rev=None, force=False, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) Interface to \fI\%git\-checkout(1)\fP .INDENT 7.0 .TP @@ -143313,7 +152067,7 @@ salt myminion git.checkout /path/to/repo opts=\(aq\-b newbranch\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.clone(cwd, url=None, name=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, identity=None, https_user=None, https_pass=None, ignore_retcode=False, saltenv=\(aqbase\(aq) +.B salt.modules.git.clone(cwd, url=None, name=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, identity=None, https_user=None, https_pass=None, ignore_retcode=False, saltenv=u\(aqbase\(aq) Interface to \fI\%git\-clone(1)\fP .INDENT 7.0 .TP @@ -143435,7 +152189,7 @@ salt myminion git.clone /path/to/repo_parent_dir git://github.com/saltstack/salt .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.commit(cwd, message, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, filename=None, ignore_retcode=False) +.B salt.modules.git.commit(cwd, message, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, filename=None, ignore_retcode=False) Interface to \fI\%git\-commit(1)\fP .INDENT 7.0 .TP @@ -143873,7 +152627,7 @@ salt myminion git.current_branch /path/to/repo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.describe(cwd, rev=\(aqHEAD\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.describe(cwd, rev=u\(aqHEAD\(aq, user=None, password=None, ignore_retcode=False) Returns the \fI\%git\-describe(1)\fP string (or the SHA1 hash if there are no tags) for the given revision. .INDENT 7.0 @@ -143924,7 +152678,7 @@ salt myminion git.describe /path/to/repo develop .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.diff(cwd, item1=None, item2=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, no_index=False, cached=False, paths=None) +.B salt.modules.git.diff(cwd, item1=None, item2=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, no_index=False, cached=False, paths=None) New in version 2015.8.12,2016.3.3,2016.11.0. .sp @@ -144045,7 +152799,7 @@ salt myminion git.diff /path/to/repo no_index=True paths=path/to/file1,/absolute .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.fetch(cwd, remote=None, force=False, refspecs=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, identity=None, ignore_retcode=False, saltenv=\(aqbase\(aq) +.B salt.modules.git.fetch(cwd, remote=None, force=False, refspecs=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, identity=None, ignore_retcode=False, saltenv=u\(aqbase\(aq) Changed in version 2015.8.2: Return data is now a dictionary containing information on branches and tags that were added/updated @@ -144172,7 +152926,7 @@ salt myminion git.fetch /path/to/repo identity=/root/.ssh/id_rsa .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.init(cwd, bare=False, template=None, separate_git_dir=None, shared=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.init(cwd, bare=False, template=None, separate_git_dir=None, shared=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) Interface to \fI\%git\-init(1)\fP .INDENT 7.0 .TP @@ -144501,7 +153255,7 @@ salt myminion git.list_worktrees /path/to/repo stale=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.ls_remote(cwd=None, remote=\(aqorigin\(aq, ref=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, identity=None, https_user=None, https_pass=None, ignore_retcode=False, saltenv=\(aqbase\(aq) +.B salt.modules.git.ls_remote(cwd=None, remote=u\(aqorigin\(aq, ref=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, identity=None, https_user=None, https_pass=None, ignore_retcode=False, saltenv=u\(aqbase\(aq) Interface to \fI\%git\-ls\-remote(1)\fP\&. Returns the upstream hash for a remote reference. .INDENT 7.0 @@ -144634,7 +153388,7 @@ salt myminion git.ls_remote remote=https://mydomain.tld/repo.git ref=mytag opts= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.merge(cwd, rev=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False, **kwargs) +.B salt.modules.git.merge(cwd, rev=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False, **kwargs) Interface to \fI\%git\-merge(1)\fP .INDENT 7.0 .TP @@ -144718,7 +153472,7 @@ salt myminion git.merge /path/to/repo rev=upstream/foo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.merge_base(cwd, refs=None, octopus=False, is_ancestor=False, independent=False, fork_point=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False, **kwargs) +.B salt.modules.git.merge_base(cwd, refs=None, octopus=False, is_ancestor=False, independent=False, fork_point=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False, **kwargs) New in version 2015.8.0. .sp @@ -144910,7 +153664,7 @@ salt myminion git.merge_tree /path/to/repo HEAD upstream/dev base=aaf3c3d .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.pull(cwd, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, identity=None, ignore_retcode=False, saltenv=\(aqbase\(aq) +.B salt.modules.git.pull(cwd, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, identity=None, ignore_retcode=False, saltenv=u\(aqbase\(aq) Interface to \fI\%git\-pull(1)\fP .INDENT 7.0 .TP @@ -145012,7 +153766,7 @@ salt myminion git.pull /path/to/repo opts=\(aq\-\-rebase origin master\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.push(cwd, remote=None, ref=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, identity=None, ignore_retcode=False, saltenv=\(aqbase\(aq, **kwargs) +.B salt.modules.git.push(cwd, remote=None, ref=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, identity=None, ignore_retcode=False, saltenv=u\(aqbase\(aq, **kwargs) Interface to \fI\%git\-push(1)\fP .INDENT 7.0 .TP @@ -145137,7 +153891,7 @@ salt myminion git.push /path/to/repo upstream :temp .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.rebase(cwd, rev=\(aqmaster\(aq, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.rebase(cwd, rev=u\(aqmaster\(aq, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) Interface to \fI\%git\-rebase(1)\fP .INDENT 7.0 .TP @@ -145215,7 +153969,7 @@ salt myminion git.rebase /path/to/repo origin/master opts=\(aq\-\-onto newbranch .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.remote_get(cwd, remote=\(aqorigin\(aq, user=None, password=None, redact_auth=True, ignore_retcode=False) +.B salt.modules.git.remote_get(cwd, remote=u\(aqorigin\(aq, user=None, password=None, redact_auth=True, ignore_retcode=False) Get the fetch and push URL for a specific remote .INDENT 7.0 .TP @@ -145283,7 +154037,7 @@ salt myminion git.remote_get /path/to/repo upstream .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.remote_refs(url, heads=False, tags=False, user=None, password=None, identity=None, https_user=None, https_pass=None, ignore_retcode=False, saltenv=\(aqbase\(aq) +.B salt.modules.git.remote_refs(url, heads=False, tags=False, user=None, password=None, identity=None, https_user=None, https_pass=None, ignore_retcode=False, saltenv=u\(aqbase\(aq) New in version 2015.8.0. .sp @@ -145372,7 +154126,7 @@ salt myminion git.remote_refs https://github.com/saltstack/salt.git .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.remote_set(cwd, url, remote=\(aqorigin\(aq, user=None, password=None, https_user=None, https_pass=None, push_url=None, push_https_user=None, push_https_pass=None, ignore_retcode=False) +.B salt.modules.git.remote_set(cwd, url, remote=u\(aqorigin\(aq, user=None, password=None, https_user=None, https_pass=None, push_url=None, push_https_user=None, push_https_pass=None, ignore_retcode=False) .INDENT 7.0 .TP .B cwd @@ -145521,7 +154275,7 @@ salt myminion git.remotes /path/to/repo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.reset(cwd, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.reset(cwd, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) Interface to \fI\%git\-reset(1)\fP, returns the stdout from the git command .INDENT 7.0 .TP @@ -145596,7 +154350,7 @@ salt myminion git.reset /path/to/repo opts=\(aq\-\-hard origin/master\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.rev_parse(cwd, rev=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.rev_parse(cwd, rev=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) New in version 2015.8.0. .sp @@ -145676,7 +154430,7 @@ salt myminion git.rev_parse /path/to/repo opts=\(aq\-\-is\-bare\-repository\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.revision(cwd, rev=\(aqHEAD\(aq, short=False, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.revision(cwd, rev=u\(aqHEAD\(aq, short=False, user=None, password=None, ignore_retcode=False) Returns the SHA1 hash of a given identifier (hash, branch, tag, HEAD, etc.) .INDENT 7.0 .TP @@ -145729,7 +154483,7 @@ salt myminion git.revision /path/to/repo mybranch .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.rm(cwd, filename, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.rm(cwd, filename, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) Interface to \fI\%git\-rm(1)\fP .INDENT 7.0 .TP @@ -145814,7 +154568,7 @@ salt myminion git.rm /path/to/repo foo/baz opts=\(aq\-r\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.stash(cwd, action=\(aqsave\(aq, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.stash(cwd, action=u\(aqsave\(aq, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) Interface to \fI\%git\-stash(1)\fP, returns the stdout from the git command .INDENT 7.0 .TP @@ -145932,7 +154686,7 @@ salt myminion git.status /path/to/repo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.submodule(cwd, command, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, identity=None, ignore_retcode=False, saltenv=\(aqbase\(aq, **kwargs) +.B salt.modules.git.submodule(cwd, command, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, identity=None, ignore_retcode=False, saltenv=u\(aqbase\(aq, **kwargs) Changed in version 2015.8.0: Added the \fBcommand\fP argument to allow for operations other than \fBupdate\fP to be run on submodules, and deprecated the \fBinit\fP argument. To do a submodule update with \fBinit=True\fP moving forward, @@ -146070,7 +154824,7 @@ salt myminion git.submodule /path/to/repo/sub/repo deinit .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.symbolic_ref(cwd, ref, value=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.symbolic_ref(cwd, ref, value=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) New in version 2015.8.0. .sp @@ -146180,7 +154934,7 @@ salt myminion git.version .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.worktree_add(cwd, worktree_path, ref=None, reset_branch=None, force=None, detach=False, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False, **kwargs) +.B salt.modules.git.worktree_add(cwd, worktree_path, ref=None, reset_branch=None, force=None, detach=False, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False, **kwargs) New in version 2015.8.0. .sp @@ -146291,7 +155045,7 @@ salt myminion git.worktree_add /path/to/repo/main ../hotfix branch=hotfix21 ref= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.git.worktree_prune(cwd, dry_run=False, verbose=True, expire=None, opts=\(aq\(aq, git_opts=\(aq\(aq, user=None, password=None, ignore_retcode=False) +.B salt.modules.git.worktree_prune(cwd, dry_run=False, verbose=True, expire=None, opts=u\(aq\(aq, git_opts=u\(aq\(aq, user=None, password=None, ignore_retcode=False) New in version 2015.8.0. .sp @@ -146471,7 +155225,7 @@ github: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.add_repo(name, description=None, homepage=None, private=None, has_issues=None, has_wiki=None, has_downloads=None, auto_init=None, gitignore_template=None, license_template=None, profile=\(aqgithub\(aq) +.B salt.modules.github.add_repo(name, description=None, homepage=None, private=None, has_issues=None, has_wiki=None, has_downloads=None, auto_init=None, gitignore_template=None, license_template=None, profile=u\(aqgithub\(aq) Create a new github repository. .INDENT 7.0 .TP @@ -146527,7 +155281,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.add_team(name, description=None, repo_names=None, privacy=None, permission=None, profile=\(aqgithub\(aq) +.B salt.modules.github.add_team(name, description=None, repo_names=None, privacy=None, permission=None, profile=u\(aqgithub\(aq) Create a new Github team within an organization. .INDENT 7.0 .TP @@ -146568,7 +155322,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.add_team_member(name, team_name, profile=\(aqgithub\(aq) +.B salt.modules.github.add_team_member(name, team_name, profile=u\(aqgithub\(aq) Adds a team member to a team with team_name. .INDENT 7.0 .TP @@ -146599,7 +155353,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.add_team_repo(repo_name, team_name, profile=\(aqgithub\(aq, permission=None) +.B salt.modules.github.add_team_repo(repo_name, team_name, profile=u\(aqgithub\(aq, permission=None) Adds a repository to a team with team_name. .INDENT 7.0 .TP @@ -146638,7 +155392,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.add_user(name, profile=\(aqgithub\(aq) +.B salt.modules.github.add_user(name, profile=u\(aqgithub\(aq) Add a GitHub user. .INDENT 7.0 .TP @@ -146663,7 +155417,7 @@ salt myminion github.add_user github\-handle .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.edit_repo(name, description=None, homepage=None, private=None, has_issues=None, has_wiki=None, has_downloads=None, profile=\(aqgithub\(aq) +.B salt.modules.github.edit_repo(name, description=None, homepage=None, private=None, has_issues=None, has_wiki=None, has_downloads=None, profile=u\(aqgithub\(aq) Updates an existing Github repository. .INDENT 7.0 .TP @@ -146710,7 +155464,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.edit_team(name, description=None, privacy=None, permission=None, profile=\(aqgithub\(aq) +.B salt.modules.github.edit_team(name, description=None, privacy=None, permission=None, profile=u\(aqgithub\(aq) Updates an existing Github team. .INDENT 7.0 .TP @@ -146748,7 +155502,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_issue(issue_number, repo_name=None, profile=\(aqgithub\(aq, output=\(aqmin\(aq) +.B salt.modules.github.get_issue(issue_number, repo_name=None, profile=u\(aqgithub\(aq, output=u\(aqmin\(aq) Return information about a single issue in a named repository. .sp New in version 2016.11.0. @@ -146787,7 +155541,7 @@ salt myminion github.get_issue 514 repo_name=salt .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_issue_comments(issue_number, repo_name=None, profile=\(aqgithub\(aq, since=None, output=\(aqmin\(aq) +.B salt.modules.github.get_issue_comments(issue_number, repo_name=None, profile=u\(aqgithub\(aq, since=None, output=u\(aqmin\(aq) Return information about the comments for a given issue in a named repository. .sp New in version 2016.11.0. @@ -146830,7 +155584,7 @@ salt myminion github.get_issue 514 repo_name=salt .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_issues(repo_name=None, profile=\(aqgithub\(aq, milestone=None, state=\(aqopen\(aq, assignee=None, creator=None, mentioned=None, labels=None, sort=\(aqcreated\(aq, direction=\(aqdesc\(aq, since=None, output=\(aqmin\(aq, per_page=None) +.B salt.modules.github.get_issues(repo_name=None, profile=u\(aqgithub\(aq, milestone=None, state=u\(aqopen\(aq, assignee=None, creator=None, mentioned=None, labels=None, sort=u\(aqcreated\(aq, direction=u\(aqdesc\(aq, since=None, output=u\(aqmin\(aq, per_page=None) Returns information for all issues in a given repository, based on the search options. .sp New in version 2016.11.0. @@ -146911,7 +155665,7 @@ salt myminion github.get_issues my\-github\-repo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_milestone(number=None, name=None, repo_name=None, profile=\(aqgithub\(aq, output=\(aqmin\(aq) +.B salt.modules.github.get_milestone(number=None, name=None, repo_name=None, profile=u\(aqgithub\(aq, output=u\(aqmin\(aq) Return information about a single milestone in a named repository. .sp New in version 2016.11.0. @@ -146954,7 +155708,7 @@ salt myminion github.get_milestone name=my_milestone .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_milestones(repo_name=None, profile=\(aqgithub\(aq, state=\(aqopen\(aq, sort=\(aqdue_on\(aq, direction=\(aqasc\(aq, output=\(aqmin\(aq, per_page=None) +.B salt.modules.github.get_milestones(repo_name=None, profile=u\(aqgithub\(aq, state=u\(aqopen\(aq, sort=u\(aqdue_on\(aq, direction=u\(aqasc\(aq, output=u\(aqmin\(aq, per_page=None) Return information about milestones for a given repository. .sp New in version 2016.11.0. @@ -147005,7 +155759,7 @@ salt myminion github.get_milestones .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_prs(repo_name=None, profile=\(aqgithub\(aq, state=\(aqopen\(aq, head=None, base=None, sort=\(aqcreated\(aq, direction=\(aqdesc\(aq, output=\(aqmin\(aq, per_page=None) +.B salt.modules.github.get_prs(repo_name=None, profile=u\(aqgithub\(aq, state=u\(aqopen\(aq, head=None, base=None, sort=u\(aqcreated\(aq, direction=u\(aqdesc\(aq, output=u\(aqmin\(aq, per_page=None) Returns information for all pull requests in a given repository, based on the search options provided. .sp @@ -147070,7 +155824,7 @@ salt myminion github.get_prs base=2016.11 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_repo_info(repo_name, profile=\(aqgithub\(aq, ignore_cache=False) +.B salt.modules.github.get_repo_info(repo_name, profile=u\(aqgithub\(aq, ignore_cache=False) Return information for a given repo. .sp New in version 2016.11.0. @@ -147099,7 +155853,7 @@ salt myminion github.get_repo_info salt profile=\(aqmy\-github\-profile\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_repo_teams(repo_name, profile=\(aqgithub\(aq) +.B salt.modules.github.get_repo_teams(repo_name, profile=u\(aqgithub\(aq) Return teams belonging to a repository. .sp New in version 2017.7.0. @@ -147128,7 +155882,7 @@ salt myminion github.get_repo_teams salt profile=\(aqmy\-github\-profile\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_team(name, profile=\(aqgithub\(aq) +.B salt.modules.github.get_team(name, profile=u\(aqgithub\(aq) Returns the team details if a team with the given name exists, or None otherwise. .INDENT 7.0 @@ -147154,7 +155908,7 @@ salt myminion github.get_team \(aqteam_name\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.get_user(name, profile=\(aqgithub\(aq, user_details=False) +.B salt.modules.github.get_user(name, profile=u\(aqgithub\(aq, user_details=False) Get a GitHub user by name. .INDENT 7.0 .TP @@ -147186,7 +155940,7 @@ salt myminion github.get_user github\-handle user_details=true .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.is_team_member(name, team_name, profile=\(aqgithub\(aq) +.B salt.modules.github.is_team_member(name, team_name, profile=u\(aqgithub\(aq) Returns True if the github user is in the team with team_name, or False otherwise. .INDENT 7.0 @@ -147218,7 +155972,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.list_members_without_mfa(profile=\(aqgithub\(aq, ignore_cache=False) +.B salt.modules.github.list_members_without_mfa(profile=u\(aqgithub\(aq, ignore_cache=False) List all members (in lower case) without MFA turned on. .INDENT 7.0 .TP @@ -147246,7 +156000,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.list_private_repos(profile=\(aqgithub\(aq) +.B salt.modules.github.list_private_repos(profile=u\(aqgithub\(aq) List private repositories within the organization. Dependent upon the access rights of the profile token. .sp @@ -147273,7 +156027,7 @@ salt myminion github.list_private_repos profile=\(aqmy\-github\-profile\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.list_public_repos(profile=\(aqgithub\(aq) +.B salt.modules.github.list_public_repos(profile=u\(aqgithub\(aq) List public repositories within the organization. .sp New in version 2016.11.0. @@ -147299,7 +156053,7 @@ salt myminion github.list_public_repos profile=\(aqmy\-github\-profile\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.list_repos(profile=\(aqgithub\(aq) +.B salt.modules.github.list_repos(profile=u\(aqgithub\(aq) List all repositories within the organization. Includes public and private repositories within the organization Dependent upon the access rights of the profile token. @@ -147327,7 +156081,7 @@ salt myminion github.list_repos profile=\(aqmy\-github\-profile\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.list_team_members(team_name, profile=\(aqgithub\(aq, ignore_cache=False) +.B salt.modules.github.list_team_members(team_name, profile=u\(aqgithub\(aq, ignore_cache=False) Gets the names of team members in lower case. .INDENT 7.0 .TP @@ -147358,7 +156112,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.list_team_repos(team_name, profile=\(aqgithub\(aq, ignore_cache=False) +.B salt.modules.github.list_team_repos(team_name, profile=u\(aqgithub\(aq, ignore_cache=False) Gets the repo details for a given team as a dict from repo_name to repo details. Note that repo names are always in lower case. .INDENT 7.0 @@ -147390,7 +156144,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.list_teams(profile=\(aqgithub\(aq, ignore_cache=False) +.B salt.modules.github.list_teams(profile=u\(aqgithub\(aq, ignore_cache=False) Lists all teams with the organization. .INDENT 7.0 .TP @@ -147418,7 +156172,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.list_users(profile=\(aqgithub\(aq, ignore_cache=False) +.B salt.modules.github.list_users(profile=u\(aqgithub\(aq, ignore_cache=False) List all users within the organization. .INDENT 7.0 .TP @@ -147447,7 +156201,7 @@ salt myminion github.list_users profile=\(aqmy\-github\-profile\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.remove_repo(name, profile=\(aqgithub\(aq) +.B salt.modules.github.remove_repo(name, profile=u\(aqgithub\(aq) Remove a Github repository. .INDENT 7.0 .TP @@ -147475,7 +156229,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.remove_team(name, profile=\(aqgithub\(aq) +.B salt.modules.github.remove_team(name, profile=u\(aqgithub\(aq) Remove a github team. .INDENT 7.0 .TP @@ -147503,7 +156257,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.remove_team_member(name, team_name, profile=\(aqgithub\(aq) +.B salt.modules.github.remove_team_member(name, team_name, profile=u\(aqgithub\(aq) Removes a team member from a team with team_name. .INDENT 7.0 .TP @@ -147534,7 +156288,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.remove_team_repo(repo_name, team_name, profile=\(aqgithub\(aq) +.B salt.modules.github.remove_team_repo(repo_name, team_name, profile=u\(aqgithub\(aq) Removes a repository from a team with team_name. .INDENT 7.0 .TP @@ -147565,7 +156319,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.github.remove_user(name, profile=\(aqgithub\(aq) +.B salt.modules.github.remove_user(name, profile=u\(aqgithub\(aq) Remove a Github user by name. .INDENT 7.0 .TP @@ -147657,7 +156411,7 @@ salt \(aq*\(aq glance.image_list profile=openstack1 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.glance.image_create(name, location=None, profile=None, visibility=None, container_format=\(aqbare\(aq, disk_format=\(aqraw\(aq, protected=None) +.B salt.modules.glance.image_create(name, location=None, profile=None, visibility=None, container_format=u\(aqbare\(aq, disk_format=u\(aqraw\(aq, protected=None) Create an image (glance image\-create) .sp CLI Example, old format: @@ -147829,7 +156583,7 @@ List of bricks to add to the volume .UNINDENT .INDENT 0.0 .TP -.B salt.modules.glusterfs.create_volume(name, bricks, stripe=False, replica=False, device_vg=False, transport=\(aqtcp\(aq, start=False, force=False) +.B salt.modules.glusterfs.create_volume(name, bricks, stripe=False, replica=False, device_vg=False, transport=u\(aqtcp\(aq, start=False, force=False) Create a glusterfs volume. .INDENT 7.0 .TP @@ -148956,7 +157710,7 @@ salt \(aq*\(aq gpg.trust_key keys=3FAD9F1E trust_level=\(aqultimately\(aq user=\ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.gpg.verify(text=None, user=None, filename=None, gnupghome=None) +.B salt.modules.gpg.verify(text=None, user=None, filename=None, gnupghome=None, signature=None) Verify a message or file .INDENT 7.0 .TP @@ -148973,7 +157727,13 @@ Passing the user as \fBsalt\fP will set the GnuPG home directory to the .TP .B gnupghome Specify the location where GPG keyring and related files are stored. +.TP +.B signature +Specify the filename of a detached signature. .UNINDENT +.sp +New in version 2018.3.0. + .sp CLI Example: .INDENT 7.0 @@ -149025,7 +157785,7 @@ grafana: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.create_datasource(orgname=None, profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.create_datasource(orgname=None, profile=u\(aqgrafana\(aq, **kwargs) Create a new datasource in an organisation. .INDENT 7.0 .TP @@ -149095,7 +157855,7 @@ salt \(aq*\(aq grafana4.create_datasource .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.create_org(profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.create_org(profile=u\(aqgrafana\(aq, **kwargs) Create a new organization. .INDENT 7.0 .TP @@ -149121,7 +157881,7 @@ salt \(aq*\(aq grafana4.create_org .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.create_org_user(orgname=None, profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.create_org_user(orgname=None, profile=u\(aqgrafana\(aq, **kwargs) Add user to the organization. .INDENT 7.0 .TP @@ -149166,7 +157926,7 @@ salt \(aq*\(aq grafana4.create_org_user loginOrEmail= ro .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.create_update_dashboard(orgname=None, profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.create_update_dashboard(orgname=None, profile=u\(aqgrafana\(aq, **kwargs) Create or update a dashboard. .INDENT 7.0 .TP @@ -149198,7 +157958,7 @@ salt \(aq*\(aq grafana4.create_update_dashboard dashboard= overwrite= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.create_user(profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.create_user(profile=u\(aqgrafana\(aq, **kwargs) Create a new user. .INDENT 7.0 .TP @@ -149233,7 +157993,7 @@ salt \(aq*\(aq grafana4.create_user login= password= email= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.delete_datasource(datasourceid, orgname=None, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.delete_datasource(datasourceid, orgname=None, profile=u\(aqgrafana\(aq) Delete a datasource. .INDENT 7.0 .TP @@ -149288,7 +158048,7 @@ salt \(aq*\(aq grafana4.delete_datasource .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.delete_org(orgid, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.delete_org(orgid, profile=u\(aqgrafana\(aq) Delete an organization. .INDENT 7.0 .TP @@ -149314,7 +158074,7 @@ salt \(aq*\(aq grafana4.delete_org .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.delete_org_user(userid, orgname=None, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.delete_org_user(userid, orgname=None, profile=u\(aqgrafana\(aq) Remove user from the organization. .INDENT 7.0 .TP @@ -149343,7 +158103,7 @@ salt \(aq*\(aq grafana4.delete_org_user .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.delete_user(userid, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.delete_user(userid, profile=u\(aqgrafana\(aq) Delete a user. .INDENT 7.0 .TP @@ -149369,7 +158129,7 @@ salt \(aq*\(aq grafana4.delete_user .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.delete_user_org(userid, orgid, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.delete_user_org(userid, orgid, profile=u\(aqgrafana\(aq) Remove a user from an organization. .INDENT 7.0 .TP @@ -149398,7 +158158,7 @@ salt \(aq*\(aq grafana4.delete_user_org .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_dashboard(slug, orgname=None, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_dashboard(slug, orgname=None, profile=u\(aqgrafana\(aq) Get a dashboard. .INDENT 7.0 .TP @@ -149427,7 +158187,7 @@ salt \(aq*\(aq grafana4.get_dashboard .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_datasource(name, orgname=None, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_datasource(name, orgname=None, profile=u\(aqgrafana\(aq) Show a single datasource in an organisation. .INDENT 7.0 .TP @@ -149456,7 +158216,7 @@ salt \(aq*\(aq grafana4.get_datasource .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_datasources(orgname=None, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_datasources(orgname=None, profile=u\(aqgrafana\(aq) List all datasources in an organisation. .INDENT 7.0 .TP @@ -149482,7 +158242,7 @@ salt \(aq*\(aq grafana4.get_datasources .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_org(name, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_org(name, profile=u\(aqgrafana\(aq) Show a single organization. .INDENT 7.0 .TP @@ -149508,7 +158268,7 @@ salt \(aq*\(aq grafana4.get_org .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_org_address(orgname=None, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_org_address(orgname=None, profile=u\(aqgrafana\(aq) Get the organization address. .INDENT 7.0 .TP @@ -149534,7 +158294,7 @@ salt \(aq*\(aq grafana4.get_org_address .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_org_prefs(orgname=None, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_org_prefs(orgname=None, profile=u\(aqgrafana\(aq) Get the organization preferences. .INDENT 7.0 .TP @@ -149560,7 +158320,7 @@ salt \(aq*\(aq grafana4.get_org_prefs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_org_users(orgname=None, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_org_users(orgname=None, profile=u\(aqgrafana\(aq) Get the list of users that belong to the organization. .INDENT 7.0 .TP @@ -149586,7 +158346,7 @@ salt \(aq*\(aq grafana4.get_org_users .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_orgs(profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_orgs(profile=u\(aqgrafana\(aq) List all organizations. .INDENT 7.0 .TP @@ -149609,7 +158369,7 @@ salt \(aq*\(aq grafana4.get_orgs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_user(login, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_user(login, profile=u\(aqgrafana\(aq) Show a single user. .INDENT 7.0 .TP @@ -149635,7 +158395,7 @@ salt \(aq*\(aq grafana4.get_user .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_user_data(userid, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_user_data(userid, profile=u\(aqgrafana\(aq) Get user data. .INDENT 7.0 .TP @@ -149661,7 +158421,7 @@ salt \(aq*\(aq grafana4.get_user_data .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_user_orgs(userid, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_user_orgs(userid, profile=u\(aqgrafana\(aq) Get the list of organisations a user belong to. .INDENT 7.0 .TP @@ -149687,7 +158447,7 @@ salt \(aq*\(aq grafana4.get_user_orgs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.get_users(profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.get_users(profile=u\(aqgrafana\(aq) List all users. .INDENT 7.0 .TP @@ -149710,7 +158470,7 @@ salt \(aq*\(aq grafana4.get_users .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.switch_org(orgname, profile=\(aqgrafana\(aq) +.B salt.modules.grafana4.switch_org(orgname, profile=u\(aqgrafana\(aq) Switch the current organization. .INDENT 7.0 .TP @@ -149736,7 +158496,7 @@ salt \(aq*\(aq grafana4.switch_org .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.update_datasource(datasourceid, orgname=None, profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.update_datasource(datasourceid, orgname=None, profile=u\(aqgrafana\(aq, **kwargs) Update a datasource. .INDENT 7.0 .TP @@ -149806,7 +158566,7 @@ salt \(aq*\(aq grafana4.update_datasource .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.update_org(orgid, profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.update_org(orgid, profile=u\(aqgrafana\(aq, **kwargs) Update an existing organization. .INDENT 7.0 .TP @@ -149835,7 +158595,7 @@ salt \(aq*\(aq grafana4.update_org name= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.update_org_address(orgname=None, profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.update_org_address(orgname=None, profile=u\(aqgrafana\(aq, **kwargs) Update the organization address. .INDENT 7.0 .TP @@ -149879,7 +158639,7 @@ salt \(aq*\(aq grafana4.update_org_address country= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.update_org_prefs(orgname=None, profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.update_org_prefs(orgname=None, profile=u\(aqgrafana\(aq, **kwargs) Update the organization preferences. .INDENT 7.0 .TP @@ -149914,7 +158674,7 @@ salt \(aq*\(aq grafana4.update_org_prefs theme= timezone= loginOrEmail= login= email= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.update_user_password(userid, profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.update_user_password(userid, profile=u\(aqgrafana\(aq, **kwargs) Update a user password. .INDENT 7.0 .TP @@ -150026,7 +158786,7 @@ salt \(aq*\(aq grafana4.update_user_password password= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grafana4.update_user_permissions(userid, profile=\(aqgrafana\(aq, **kwargs) +.B salt.modules.grafana4.update_user_permissions(userid, profile=u\(aqgrafana\(aq, **kwargs) Update a user password. .INDENT 7.0 .TP @@ -150125,6 +158885,16 @@ The grain key from which to delete the value. .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq grains.delkey key +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -150181,7 +158951,7 @@ salt \(aq*\(aq grains.equals systemd:version 219 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grains.fetch(key, default=\(aq\(aq, delimiter=\(aq:\(aq, ordered=True) +.B salt.modules.grains.fetch(key, default=u\(aq\(aq, delimiter=\(aq:\(aq, ordered=True) Attempt to retrieve the named value from grains, if the named value is not available return the passed default. The default return is an empty string. .sp @@ -150250,7 +159020,7 @@ salt \(aq*\(aq grains.get abc::def|ghi delimiter=\(aq|\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grains.filter_by(lookup_dict, grain=\(aqos_family\(aq, merge=None, default=\(aqdefault\(aq, base=None) +.B salt.modules.grains.filter_by(lookup_dict, grain=u\(aqos_family\(aq, merge=None, default=u\(aqdefault\(aq, base=None) New in version 0.17.0. .sp @@ -150402,7 +159172,7 @@ salt \(aq*\(aq grains.filter_by \(aq{default: {A: {B: C}, D: E}, F: {A: {B: G}}, .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grains.get(key, default=\(aq\(aq, delimiter=\(aq:\(aq, ordered=True) +.B salt.modules.grains.get(key, default=u\(aq\(aq, delimiter=\(aq:\(aq, ordered=True) Attempt to retrieve the named value from grains, if the named value is not available return the passed default. The default return is an empty string. .sp @@ -150471,7 +159241,7 @@ salt \(aq*\(aq grains.get abc::def|ghi delimiter=\(aq|\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grains.get_or_set_hash(name, length=8, chars=\(aqabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(\-_=+)\(aq) +.B salt.modules.grains.get_or_set_hash(name, length=8, chars=u\(aqabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(\-_=+)\(aq) Perform a one\-time generation of a hash and write it to the local grains. If that grain has already been set return the value instead. .sp @@ -150672,7 +159442,7 @@ salt \(aq*\(aq grains.remove key val .UNINDENT .INDENT 0.0 .TP -.B salt.modules.grains.set(key, val=\(aq\(aq, force=False, destructive=False, delimiter=\(aq:\(aq) +.B salt.modules.grains.set(key, val=u\(aq\(aq, force=False, destructive=False, delimiter=\(aq:\(aq) Set a key to an arbitrary value. It is used like setval but works with nested keys. .sp @@ -150968,7 +159738,7 @@ libguestfs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.guestfs.mount(location, access=\(aqrw\(aq, root=None) +.B salt.modules.guestfs.mount(location, access=u\(aqrw\(aq, root=None) Mount an image .sp CLI Example: @@ -151094,7 +159864,7 @@ New in version 2014.7.0. .INDENT 0.0 .TP -.B salt.modules.haproxyconn.disable_server(name, backend, socket=\(aq/var/run/haproxy.sock\(aq) +.B salt.modules.haproxyconn.disable_server(name, backend, socket=u\(aq/var/run/haproxy.sock\(aq) Disable server in haproxy. .INDENT 7.0 .TP @@ -151105,7 +159875,7 @@ Server to disable haproxy backend, or all backends if "*" is supplied .TP .B socket -haproxy stats socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP .UNINDENT .sp CLI Example: @@ -151122,7 +159892,7 @@ salt \(aq*\(aq haproxy.disable_server db1.example.com mysql .UNINDENT .INDENT 0.0 .TP -.B salt.modules.haproxyconn.enable_server(name, backend, socket=\(aq/var/run/haproxy.sock\(aq) +.B salt.modules.haproxyconn.enable_server(name, backend, socket=u\(aq/var/run/haproxy.sock\(aq) Enable Server in haproxy .INDENT 7.0 .TP @@ -151133,7 +159903,7 @@ Server to enable haproxy backend, or all backends if "*" is supplied .TP .B socket -haproxy stats socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP .UNINDENT .sp CLI Example: @@ -151150,7 +159920,32 @@ salt \(aq*\(aq haproxy.enable_server web1.example.com www .UNINDENT .INDENT 0.0 .TP -.B salt.modules.haproxyconn.get_sessions(name, backend, socket=\(aq/var/run/haproxy.sock\(aq) +.B salt.modules.haproxyconn.get_backend(backend, socket=u\(aq/var/run/haproxy.sock\(aq) +Receive information about a specific backend. +.INDENT 7.0 +.TP +.B backend +haproxy backend +.TP +.B socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq haproxy.get_backend mysql +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.haproxyconn.get_sessions(name, backend, socket=u\(aq/var/run/haproxy.sock\(aq) New in version 2016.11.0. .sp @@ -151164,7 +159959,7 @@ Server name haproxy backend .TP .B socket -haproxy stats socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP .UNINDENT .sp CLI Example: @@ -151181,7 +159976,7 @@ salt \(aq*\(aq haproxy.get_sessions web1.example.com www .UNINDENT .INDENT 0.0 .TP -.B salt.modules.haproxyconn.get_weight(name, backend, socket=\(aq/var/run/haproxy.sock\(aq) +.B salt.modules.haproxyconn.get_weight(name, backend, socket=u\(aq/var/run/haproxy.sock\(aq) Get server weight .INDENT 7.0 .TP @@ -151192,7 +159987,7 @@ Server name haproxy backend .TP .B socket -haproxy stats socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP .UNINDENT .sp CLI Example: @@ -151209,7 +160004,54 @@ salt \(aq*\(aq haproxy.get_weight web1.example.com www .UNINDENT .INDENT 0.0 .TP -.B salt.modules.haproxyconn.list_servers(backend, socket=\(aq/var/run/haproxy.sock\(aq, objectify=False) +.B salt.modules.haproxyconn.list_backends(servers=True, socket=u\(aq/var/run/haproxy.sock\(aq) +List HaProxy Backends +.INDENT 7.0 +.TP +.B socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP +.TP +.B servers +list backends with servers +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq haproxy.list_backends +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.haproxyconn.list_frontends(socket=u\(aq/var/run/haproxy.sock\(aq) +List HaProxy frontends +.INDENT 7.0 +.TP +.B socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq haproxy.list_frontends +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.haproxyconn.list_servers(backend, socket=u\(aq/var/run/haproxy.sock\(aq, objectify=False) List servers in haproxy backend. .INDENT 7.0 .TP @@ -151217,7 +160059,7 @@ List servers in haproxy backend. haproxy backend .TP .B socket -haproxy stats socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP .UNINDENT .sp CLI Example: @@ -151234,7 +160076,7 @@ salt \(aq*\(aq haproxy.list_servers mysql .UNINDENT .INDENT 0.0 .TP -.B salt.modules.haproxyconn.set_state(name, backend, state, socket=\(aq/var/run/haproxy.sock\(aq) +.B salt.modules.haproxyconn.set_state(name, backend, state, socket=u\(aq/var/run/haproxy.sock\(aq) Force a server\(aqs administrative state to a new state. This can be useful to disable load balancing and/or any traffic to a server. Setting the state to "ready" puts the server in normal mode, and the command is the equivalent of @@ -151253,6 +160095,9 @@ haproxy backend .TP .B state A string of the state to set. Must be \(aqready\(aq, \(aqdrain\(aq, or \(aqmaint\(aq +.TP +.B socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP .UNINDENT .sp CLI Example: @@ -151269,7 +160114,7 @@ salt \(aq*\(aq haproxy.set_state my_proxy_server my_backend ready .UNINDENT .INDENT 0.0 .TP -.B salt.modules.haproxyconn.set_weight(name, backend, weight=0, socket=\(aq/var/run/haproxy.sock\(aq) +.B salt.modules.haproxyconn.set_weight(name, backend, weight=0, socket=u\(aq/var/run/haproxy.sock\(aq) Set server weight .INDENT 7.0 .TP @@ -151283,7 +160128,7 @@ haproxy backend Server Weight .TP .B socket -haproxy stats socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP .UNINDENT .sp CLI Example: @@ -151300,12 +160145,12 @@ salt \(aq*\(aq haproxy.set_weight web1.example.com www 13 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.haproxyconn.show_backends(socket=\(aq/var/run/haproxy.sock\(aq) +.B salt.modules.haproxyconn.show_backends(socket=u\(aq/var/run/haproxy.sock\(aq) Show HaProxy Backends .INDENT 7.0 .TP .B socket -haproxy stats socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP .UNINDENT .sp CLI Example: @@ -151322,12 +160167,12 @@ salt \(aq*\(aq haproxy.show_backends .UNINDENT .INDENT 0.0 .TP -.B salt.modules.haproxyconn.show_frontends(socket=\(aq/var/run/haproxy.sock\(aq) +.B salt.modules.haproxyconn.show_frontends(socket=u\(aq/var/run/haproxy.sock\(aq) Show HaProxy frontends .INDENT 7.0 .TP .B socket -haproxy stats socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP .UNINDENT .sp CLI Example: @@ -151342,6 +160187,40 @@ salt \(aq*\(aq haproxy.show_frontends .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.haproxyconn.wait_state(backend, server, value=u\(aqup\(aq, timeout=300, socket=u\(aq/var/run/haproxy.sock\(aq) +Wait for a specific server state +.INDENT 7.0 +.TP +.B backend +haproxy backend +.TP +.B server +targeted server +.TP +.B value +state value +.TP +.B timeout +timeout before giving up state value, default 5 min +.TP +.B socket +haproxy stats socket, default \fB/var/run/haproxy.sock\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq haproxy.wait_state mysql server01 up 60 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.hashutil .sp A collection of hashing and encoding functions @@ -151492,7 +160371,7 @@ salt \(aq*\(aq hashutil.base64_encodestring \(aqget salted\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.hashutil.digest(instr, checksum=\(aqmd5\(aq) +.B salt.modules.hashutil.digest(instr, checksum=u\(aqmd5\(aq) Return a checksum digest for a string .INDENT 7.0 .TP @@ -151519,7 +160398,7 @@ salt \(aq*\(aq hashutil.digest \(aqget salted\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.hashutil.digest_file(infile, checksum=\(aqmd5\(aq) +.B salt.modules.hashutil.digest_file(infile, checksum=u\(aqmd5\(aq) Return a checksum digest for a file .INDENT 7.0 .TP @@ -151926,7 +160805,7 @@ salt \(aq*\(aq heat.update_stack name=mystack \e Support for the Mercurial SCM .INDENT 0.0 .TP -.B salt.modules.hg.archive(cwd, output, rev=\(aqtip\(aq, fmt=None, prefix=None, user=None) +.B salt.modules.hg.archive(cwd, output, rev=u\(aqtip\(aq, fmt=None, prefix=None, user=None) Export a tarball from the repository .INDENT 7.0 .TP @@ -152009,7 +160888,7 @@ salt \(aq*\(aq hg.clone /path/to/repo https://bitbucket.org/birkenfeld/sphinx .UNINDENT .INDENT 0.0 .TP -.B salt.modules.hg.describe(cwd, rev=\(aqtip\(aq, user=None) +.B salt.modules.hg.describe(cwd, rev=u\(aqtip\(aq, user=None) Mimic git describe and return an identifier for the given revision .INDENT 7.0 .TP @@ -152079,7 +160958,7 @@ salt \(aq*\(aq hg.pull /path/to/repo opts=\-u .UNINDENT .INDENT 0.0 .TP -.B salt.modules.hg.revision(cwd, rev=\(aqtip\(aq, short=False, user=None) +.B salt.modules.hg.revision(cwd, rev=u\(aqtip\(aq, short=False, user=None) Returns the long hash of a given identifier (hash, branch, tag, HEAD, etc) .INDENT 7.0 .TP @@ -152359,7 +161238,7 @@ salt \(aq*\(aq hipchat.list_users api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 api_v .UNINDENT .INDENT 0.0 .TP -.B salt.modules.hipchat.send_message(room_id, message, from_name, api_url=None, api_key=None, api_version=None, color=\(aqyellow\(aq, notify=False) +.B salt.modules.hipchat.send_message(room_id, message, from_name, api_url=None, api_key=None, api_version=None, color=u\(aqyellow\(aq, notify=False) Send a message to a HipChat room. .INDENT 7.0 .TP @@ -152555,7 +161434,7 @@ The functions here will load inside the webutil module. This allows other functions that don\(aqt use htpasswd to use the webutil module name. .INDENT 0.0 .TP -.B salt.modules.htpasswd.useradd(pwfile, user, password, opts=\(aq\(aq, runas=None) +.B salt.modules.htpasswd.useradd(pwfile, user, password, opts=u\(aq\(aq, runas=None) Add a user to htpasswd file using the htpasswd command. If the htpasswd file does not exist, it will be created. .INDENT 7.0 @@ -152638,7 +161517,7 @@ salt \(aq*\(aq webutil.userdel /etc/httpd/htpasswd larry .UNINDENT .INDENT 0.0 .TP -.B salt.modules.htpasswd.verify(pwfile, user, password, opts=\(aq\(aq, runas=None) +.B salt.modules.htpasswd.verify(pwfile, user, password, opts=u\(aq\(aq, runas=None) Return True if the htpasswd file exists, the user has an entry, and their password matches. .INDENT 7.0 @@ -154343,7 +163222,7 @@ salt \(aq*\(aq influxdb08.login_test .UNINDENT .INDENT 0.0 .TP -.B salt.modules.influx08.query(database, query, time_precision=\(aqs\(aq, chunked=False, user=None, password=None, host=None, port=None) +.B salt.modules.influx08.query(database, query, time_precision=u\(aqs\(aq, chunked=False, user=None, password=None, host=None, port=None) Querying data .INDENT 7.0 .TP @@ -154721,100 +163600,510 @@ salt \(aq*\(aq influxdb08.user_remove .UNINDENT .SS salt.modules.infoblox .sp -Module for managing Infoblox -.sp -Will look for pillar data infoblox:server, infoblox:user, infoblox:password if not passed to functions -.sp -New in version 2016.3.0. - +This module have been tested on infoblox API v1.2.1, +other versions of the API are likly workable. .INDENT 0.0 .TP .B depends +libinfoblox, \fI\%https://github.com/steverweber/libinfoblox\fP +.sp +libinfoblox can be installed using \fIpip install libinfoblox\fP +.UNINDENT +.sp +API documents can be found on your infoblox server at: +.INDENT 0.0 +.INDENT 3.5 +\fI\%https://INFOBLOX/wapidoc\fP +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B configuration +The following configuration defaults can be +defined (pillar or config files \(aq/etc/salt/master.d/infoblox.conf\(aq): +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +infoblox.config: + api_sslverify: True + api_url: \(aqhttps://INFOBLOX/wapi/v1.2.1\(aq + api_user: \(aqusername\(aq + api_key: \(aqpassword\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Many of the functions accept \fIapi_opts\fP to override the API config. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call infoblox.get_host name=my.host.com api_url: \(aqhttps://INFOBLOX/wapi/v1.2.1\(aq api_user=admin api_key=passs +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.create_a(data, **api_opts) +Create A record. +.sp +This is a helper function to \fIcreate_object\fP\&. +See your infoblox API for full \fIdata\fP format. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B salt\-call infoblox.create_a data = +name: \(aqfastlinux.math.example.ca\(aq +ipv4addr: \(aq127.0.0.1\(aq +view: External +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.create_cname(data, **api_opts) +Create a cname record. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.create_cname data={ "comment": "cname to example server", "name": "example.example.com", "zone": "example.com", "view": "Internal", "canonical": "example\-ha\-0.example.com" } +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.create_host(data, **api_opts) +Add host record +.INDENT 7.0 +.TP +.B Avoid race conditions, use func:nextavailableip for ipv[4,6]addrs: .INDENT 7.0 .IP \(bu 2 -requests +func:nextavailableip:network/ZG54dfgsrDFEFfsfsLzA:10.0.0.0/8/default +.IP \(bu 2 +func:nextavailableip:10.0.0.0/8 +.IP \(bu 2 +func:nextavailableip:10.0.0.0/8,external +.IP \(bu 2 +func:nextavailableip:10.0.0.3\-10.0.0.10 .UNINDENT .UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.infoblox.add_record(name, value, record_type, dns_view, infoblox_server=None, infoblox_user=None, infoblox_password=None, infoblox_api_version=\(aqv1.4.2\(aq, sslVerify=True) -add a record to an infoblox dns view -.INDENT 7.0 -.TP -.B name -the record name -.TP -.B value -.INDENT 7.0 -.TP -.B the value for the entry -can make use of infoblox functions for next available IP, like \(aqfunc:nextavailableip:10.1.0.0/24\(aq -.UNINDENT -.TP -.B record_type -the record type (cname, a, host, etc) -.TP -.B dns_view -the DNS view to add the record to -.TP -.B infoblox_server -the infoblox server hostname (can also use the infoblox:server pillar) -.TP -.B infoblox_user -the infoblox user to connect with (can also use the infoblox:user pillar) -.TP -.B infoblox_password -the infoblox user\(aqs password (can also use the infolblox:password pillar) -.TP -.B infoblox_api_version -the infoblox api version to use -.TP -.B sslVerify -should ssl verification be done on the connection to the Infoblox REST API -.UNINDENT +.sp +See your infoblox API for full \fIdata\fP format. .sp CLI Example: .INDENT 7.0 .INDENT 3.5 +.INDENT 0.0 +.TP +.B salt\-call infoblox.create_host data = +.INDENT 7.0 +.INDENT 3.5 +{\(aqname\(aq: \(aqhostname.example.ca\(aq, +\(aqaliases\(aq: [\(aqhostname.math.example.ca\(aq], +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B \(aqextattrs\(aq: [{\(aqBusiness Contact\(aq: {\(aqvalue\(aq: \fI\%\(aqexample@example.ca\fP\(aq}}, +{\(aqPol8 Classification\(aq: {\(aqvalue\(aq: \(aqRestricted\(aq}}, +{\(aqPrimary OU\(aq: {\(aqvalue\(aq: \(aqCS\(aq}}, +{\(aqTechnical Contact\(aq: {\(aqvalue\(aq: \fI\%\(aqexample@example.ca\fP\(aq}}], +.TP +.B \(aqipv4addrs\(aq: [{\(aqconfigure_for_dhcp\(aq: True, +\(aqipv4addr\(aq: \(aqfunc:nextavailableip:129.97.139.0/24\(aq, +\(aqmac\(aq: \(aq00:50:56:84:6e:ae\(aq}], +.UNINDENT .sp +\(aqipv6addrs\(aq: [], } +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.create_ipv4_range(data, **api_opts) +Create a ipv4 range +.sp +This is a helper function to \fIcreate_object\fP +See your infoblox API for full \fIdata\fP format. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B salt\-call infoblox.create_ipv4_range data={ +start_addr: \(aq129.97.150.160\(aq, +end_addr: \(aq129.97.150.170\(aq} +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.create_object(object_type, data, **api_opts) +Create raw infoblox object +This is a low level api call. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.update_object object_type=record:host data={} +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.delete_a(name=None, ipv4addr=None, allow_array=False, **api_opts) +Delete A record +.sp +If the A record is used as a round robin you can set + .nf -.ft C -salt \(aqmyminion\(aq infoblox.add_record alias.network.name canonical.network.name MyView -.ft P +\(ga .fi +allow_array=true to delete all records for the hostname. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.delete_a name=abc.example.com +salt\-call infoblox.delete_a ipv4addr=192.168.3.5 +salt\-call infoblox.delete_a name=acname.example.com allow_array=true .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.infoblox.delete_record(name, dns_view, record_type, infoblox_server=None, infoblox_user=None, infoblox_password=None, infoblox_api_version=\(aqv1.4.2\(aq, sslVerify=True) -delete a record +.B salt.modules.infoblox.delete_cname(name=None, canonical=None, **api_opts) +Delete CNAME. This is a helper call to delete_object. +.sp +If record is not found, return True +.sp +CLI Example: .INDENT 7.0 -.TP -.B name -name of the record -.TP -.B dns_view -the DNS view to remove the record from -.TP -.B record_type -the record type (a, cname, host, etc) -.TP -.B infoblox_server -the infoblox server hostname (can also use the infoblox:server pillar) -.TP -.B infoblox_user -the infoblox user to connect with (can also use the infoblox:user pillar) -.TP -.B infoblox_password -the infoblox user\(aqs password (can also use the infolblox:password pillar) -.TP -.B infoblox_api_version -the infoblox api version to use -.TP -.B sslVerify -should ssl verification be done on the connection to the Infoblox REST API +.INDENT 3.5 +salt\-call infoblox.delete_cname name=example.example.com +salt\-call infoblox.delete_cname canonical=example\-ha\-0.example.com .UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.delete_host(name=None, mac=None, ipv4addr=None, **api_opts) +Delete host +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.delete_host name=example.domain.com +salt\-call infoblox.delete_host ipv4addr=123.123.122.12 +salt\-call infoblox.delete_host ipv4addr=123.123.122.12 mac=00:50:56:84:6e:ae +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.delete_ipv4_range(start_addr=None, end_addr=None, **api_opts) +Delete ip range. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.delete_ipv4_range start_addr=123.123.122.12 +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.delete_object(objref, **api_opts) +Delete infoblox object. +This is a low level api call. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.delete_object objref=[ref_of_object] +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.diff_objects(obja, objb) +Diff two complex infoblox objects. +This is used from salt states to detect changes in objects. +.sp +Using \fIfunc:nextavailableip\fP will not cause a diff if the ipaddres is in range +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_a(name=None, ipv4addr=None, allow_array=True, **api_opts) +Get A record +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_a name=abc.example.com +salt\-call infoblox.get_a ipv4addr=192.168.3.5 +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_cname(name=None, canonical=None, return_fields=None, **api_opts) +Get CNAME information. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_cname name=example.example.com +salt\-call infoblox.get_cname canonical=example\-ha\-0.example.com +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_host(name=None, ipv4addr=None, mac=None, return_fields=None, **api_opts) +Get host information +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_host hostname.domain.ca +salt\-call infoblox.get_host ipv4addr=123.123.122.12 +salt\-call infoblox.get_host mac=00:50:56:84:6e:ae +.sp +return_fields= +\fI\%https://INFOBLOX/wapidoc/objects/record.host.html#fields\-list\fP +.sp +return_fields=\(aqipv4addrs,aliases,name,configure_for_dns,extattrs,disable,view,comment,zone\(aq +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_host_advanced(name=None, ipv4addr=None, mac=None, **api_opts) +Get all host information +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_host_advanced hostname.domain.ca +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_host_domainname(name, domains=None, **api_opts) +Get host domain name +.sp +If no domains are passed, the hostname is checked for a zone in infoblox, if no zone split on first dot. +.sp +If domains are provided, the best match out of the list is returned. +.sp +If none are found the return is None +.sp +dots at end of names are ignored. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call uwl.get_host_domainname name=localhost.t.domain.com domains=[\(aqdomain.com\(aq, \(aqt.domain.com.\(aq] +.sp +# returns: t.domain.com +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_host_hostname(name, domains=None, **api_opts) +Get hostname +.sp +If no domains are passed, the hostname is checked for a zone in infoblox, if no zone split on first dot. +.sp +If domains are provided, the best match out of the list is truncated from the fqdn leaving the hostname. +.sp +If no matching domains are found the fqdn is returned. +.sp +dots at end of names are ignored. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_host_hostname fqdn=localhost.xxx.t.domain.com domains="[\(aqdomain.com\(aq, \(aqt.domain.com\(aq]" +#returns: localhost.xxx +.sp +salt\-call infoblox.get_host_hostname fqdn=localhost.xxx.t.domain.com +#returns: localhost +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_host_ipv4(name=None, mac=None, allow_array=False, **api_opts) +Get ipv4 address from host record. +.sp +Use \fIallow_array\fP to return possible mutiple values. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_host_ipv4 host=localhost.domain.com +salt\-call infoblox.get_host_ipv4 mac=00:50:56:84:6e:ae +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_host_ipv4addr_info(ipv4addr=None, mac=None, discovered_data=None, return_fields=None, **api_opts) +Get host ipv4addr information +.sp +return_fields=\(aqmac,host,configure_for_dhcp,ipv4addr\(aq +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_ipv4addr ipv4addr=123.123.122.12 +salt\-call infoblox.get_ipv4addr mac=00:50:56:84:6e:ae +salt\-call infoblox.get_ipv4addr mac=00:50:56:84:6e:ae return_fields=host +return_fields=\(aqmac,host,configure_for_dhcp,ipv4addr\(aq +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_host_ipv6addr_info(ipv6addr=None, mac=None, discovered_data=None, return_fields=None, **api_opts) +Get host ipv6addr information +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_host_ipv6addr_info ipv6addr=2001:db8:85a3:8d3:1349:8a2e:370:7348 +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_host_mac(name=None, allow_array=False, **api_opts) +Get mac address from host record. +.sp +Use \fIallow_array\fP to return possible mutiple values. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_host_mac host=localhost.domain.com +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_ipv4_range(start_addr=None, end_addr=None, return_fields=None, **api_opts) +Get ip range +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_ipv4_range start_addr=123.123.122.12 +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_network(ipv4addr=None, network=None, return_fields=None, **api_opts) +Get list of all networks. +This is helpfull when looking up subnets to +use with func:nextavailableip +.sp +This call is offen slow and not cached! +.sp +some return_fields +comment,network,network_view,ddns_domainname,disable,enable_ddns +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_network +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.get_object(objref, data=None, return_fields=None, max_results=None, ensure_none_or_one_result=False, **api_opts) +Get raw infoblox object. +This is a low level api call. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.get_object objref=[_ref of object] +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.is_ipaddr_in_ipfunc_range(ipaddr, ipfunc) +Return true if the ipaddress is in the range of the nextavailableip function +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.is_ipaddr_in_ipfunc_range ipaddr="10.0.2.2" ipfunc="func:nextavailableip:10.0.0.0/8" +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.update_cname(name, data, **api_opts) +Update CNAME. This is a helper call to update_object. +.sp +Find a CNAME \fI_ref\fP then call update_object with the record data. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B salt\-call infoblox.update_cname name=example.example.com data="{ +\(aqcanonical\(aq:\(aqexample\-ha\-0.example.com\(aq, +\(aquse_ttl\(aq:true, +\(aqttl\(aq:200, +\(aqcomment\(aq:\(aqSalt managed CNAME\(aq}" +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.update_host(name, data, **api_opts) +Update host record. This is a helper call to update_object. +.sp +Find a hosts \fI_ref\fP then call update_object with the record data. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +salt\-call infoblox.update_host name=fqdn data={} +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.infoblox.update_object(objref, data, **api_opts) +Update raw infoblox object. +This is a low level api call. .sp CLI Example: .INDENT 7.0 @@ -154822,136 +164111,7 @@ CLI Example: .sp .nf .ft C -salt my\-minion infoblox.delete_record some.dns.record MyInfobloxView A sslVerify=False -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.infoblox.get_network(network_name, network_view=None, infoblox_server=None, infoblox_user=None, infoblox_password=None, infoblox_api_version=\(aqv1.4.2\(aq, sslVerify=True) -get a network from infoblox -.INDENT 7.0 -.TP -.B network_name -The name of the network in IPAM -.TP -.B network_view -The name of the network view the network belongs to -.TP -.B infoblox_server -the infoblox server hostname (can also use the infoblox:server pillar) -.TP -.B infoblox_user -the infoblox user to connect with (can also use the infoblox:user pillar) -.TP -.B infoblox_password -the infoblox user\(aqs password (can also use the infolblox:password pillar) -.TP -.B infoblox_api_version -the infoblox api version to use -.TP -.B sslVerify -should ssl verification be done on the connection to the Infoblox REST API -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt myminion infoblox.get_network \(aq10.0.0.0/8\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.infoblox.get_record(record_name, record_type=\(aqhost\(aq, infoblox_server=None, infoblox_user=None, infoblox_password=None, dns_view=None, infoblox_api_version=\(aqv1.4.2\(aq, sslVerify=True) -get a record from infoblox -.INDENT 7.0 -.TP -.B record_name -name of the record to search for -.TP -.B record_type -type of reacord to search for (host, cname, a, etc...defaults to host) -.TP -.B infoblox_server -the infoblox server hostname (can also use the infoblox:server pillar) -.TP -.B infoblox_user -the infoblox user to connect with (can also use the infoblox:user pillar) -.TP -.B infoblox_password -the infoblox user\(aqs password (can also use the infolblox:password pillar) -.TP -.B dns_view -the infoblox DNS view to search, if not specified all views are searched -.TP -.B infoblox_api_version -the infoblox api version to use -.TP -.B sslVerify -should ssl verification be done on the connection to the Infoblox REST API -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt myminion infoblox.get_record some.host.com A sslVerify=False -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.infoblox.update_record(name, value, dns_view, record_type, infoblox_server=None, infoblox_user=None, infoblox_password=None, infoblox_api_version=\(aqv1.4.2\(aq, sslVerify=True) -update an entry to an infoblox dns view -.INDENT 7.0 -.TP -.B name -the dns name -.TP -.B value -the value for the record -.TP -.B record_type -the record type (a, cname, etc) -.TP -.B dns_view -the DNS view to add the record to -.TP -.B infoblox_server -the infoblox server hostname (can also use the infoblox:server pillar) -.TP -.B infoblox_user -the infoblox user to connect with (can also use the infoblox:user pillar) -.TP -.B infoblox_password -the infoblox user\(aqs password (can also use the infolblox:password pillar) -.TP -.B infoblox_api_version -the infoblox api version to use -.TP -.B sslVerify -should ssl verification be done on the connection to the Infoblox REST API -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq infoblox.update_record alias.network.name canonical.network.name MyInfobloxView cname sslVerify=False +salt\-call infoblox.update_object objref=[ref_of_object] data={} .ft P .fi .UNINDENT @@ -154978,7 +164138,7 @@ all (for example /etc/sysctl.conf) .INDENT 0.0 .TP -.B salt.modules.ini_manage.get_option(file_name, section, option, separator=\(aq=\(aq) +.B salt.modules.ini_manage.get_option(file_name, section, option, separator=u\(aq=\(aq) Get value of a key from a section in an ini file. Returns \fBNone\fP if no matching key was found. .sp @@ -155011,7 +164171,7 @@ salt \(aq*\(aq ini.get_option /path/to/ini section_name option_name .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ini_manage.get_section(file_name, section, separator=\(aq=\(aq) +.B salt.modules.ini_manage.get_section(file_name, section, separator=u\(aq=\(aq) Retrieve a section from an ini file. Returns the section as dictionary. If the section is not found, an empty dictionary is returned. .sp @@ -155044,7 +164204,7 @@ salt \(aq*\(aq ini.get_section /path/to/ini section_name .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ini_manage.remove_option(file_name, section, option, separator=\(aq=\(aq) +.B salt.modules.ini_manage.remove_option(file_name, section, option, separator=u\(aq=\(aq) Remove a key/value pair from a section in an ini file. Returns the value of the removed key, or \fBNone\fP if nothing was removed. .sp @@ -155077,7 +164237,7 @@ salt \(aq*\(aq ini.remove_option /path/to/ini section_name option_name .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ini_manage.remove_section(file_name, section, separator=\(aq=\(aq) +.B salt.modules.ini_manage.remove_section(file_name, section, separator=u\(aq=\(aq) Remove a section in an ini file. Returns the removed section as dictionary, or \fBNone\fP if nothing was removed. .sp @@ -155110,7 +164270,7 @@ salt \(aq*\(aq ini.remove_section /path/to/ini section_name .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ini_manage.set_option(file_name, sections=None, separator=\(aq=\(aq) +.B salt.modules.ini_manage.set_option(file_name, sections=None, separator=u\(aq=\(aq) Edit an ini file, replacing one or more sections. Returns a dictionary containing the changes made. .INDENT 7.0 @@ -155516,7 +164676,7 @@ Load data by keys. Module for full system inspection. .INDENT 0.0 .TP -.B salt.modules.inspector.build(format=\(aqqcow2\(aq, path=\(aq/tmp/\(aq) +.B salt.modules.inspector.build(format=u\(aqqcow2\(aq, path=u\(aq/tmp/\(aq) Build an image from a current system description. The image is a system image can be output in bootable ISO or QCOW2 formats. .sp @@ -155565,7 +164725,7 @@ salt myminion inspector.delete all=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.inspector.export(local=False, path=\(aq/tmp\(aq, format=\(aqqcow2\(aq) +.B salt.modules.inspector.export(local=False, path=u\(aq/tmp\(aq, format=u\(aqqcow2\(aq) Export an image description for Kiwi. .sp Parameters: @@ -155595,7 +164755,7 @@ salt myminion inspector.export format=iso path=/opt/builds/ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.inspector.inspect(mode=\(aqall\(aq, priority=19, **kwargs) +.B salt.modules.inspector.inspect(mode=u\(aqall\(aq, priority=19, **kwargs) Start node inspection and save the data to the database for further query. .sp Parameters: @@ -155745,7 +164905,7 @@ salt myminion introspect.enabled_service_owners .UNINDENT .INDENT 0.0 .TP -.B salt.modules.introspect.running_service_owners(exclude=(\(aq/dev\(aq, \(aq/home\(aq, \(aq/media\(aq, \(aq/proc\(aq, \(aq/run\(aq, \(aq/sys/\(aq, \(aq/tmp\(aq, \(aq/var\(aq)) +.B salt.modules.introspect.running_service_owners(exclude=(u\(aq/dev\(aq, u\(aq/home\(aq, u\(aq/media\(aq, u\(aq/proc\(aq, u\(aq/run\(aq, u\(aq/sys/\(aq, u\(aq/tmp\(aq, u\(aq/var\(aq)) Determine which packages own the currently running services. By default, excludes files whose full path starts with \fB/dev\fP, \fB/home\fP, \fB/media\fP, \fB/proc\fP, \fB/run\fP, \fB/sys\fP, \fB/tmp\fP and \fB/var\fP\&. This can be @@ -155829,7 +164989,7 @@ salt\-call ipmi.get_user api_host=myipmienabled.system .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipmi.create_user(uid, name, password, channel=14, callback=False, link_auth=True, ipmi_msg=True, privilege_level=\(aqadministrator\(aq, **kwargs) +.B salt.modules.ipmi.create_user(uid, name, password, channel=14, callback=False, link_auth=True, ipmi_msg=True, privilege_level=u\(aqadministrator\(aq, **kwargs) create/ensure a user is created with provided settings. .INDENT 7.0 .TP @@ -155949,7 +165109,7 @@ salt\-call ipmi.get_bootdev api_host=127.0.0.1 api_user=admin api_pass=pass .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipmi.get_channel_access(channel=14, read_mode=\(aqnon_volatile\(aq, **kwargs) +.B salt.modules.ipmi.get_channel_access(channel=14, read_mode=u\(aqnon_volatile\(aq, **kwargs) :param kwargs:api_host=\(aq127.0.0.1\(aq api_user=\(aqadmin\(aq api_pass=\(aqexample\(aq api_port=623 .INDENT 7.0 .TP @@ -156533,7 +165693,7 @@ salt\-call ipmi.raw_command netfn=0x06 command=0x46 data=[0x02] .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipmi.set_bootdev(bootdev=\(aqdefault\(aq, persist=False, uefiboot=False, **kwargs) +.B salt.modules.ipmi.set_bootdev(bootdev=u\(aqdefault\(aq, persist=False, uefiboot=False, **kwargs) Set boot device to use on next reboot .INDENT 7.0 .TP @@ -156600,7 +165760,7 @@ salt\-call ipmi.set_bootdev bootdev=network persist=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipmi.set_channel_access(channel=14, access_update_mode=\(aqnon_volatile\(aq, alerting=False, per_msg_auth=False, user_level_auth=False, access_mode=\(aqalways\(aq, privilege_update_mode=\(aqnon_volatile\(aq, privilege_level=\(aqadministrator\(aq, **kwargs) +.B salt.modules.ipmi.set_channel_access(channel=14, access_update_mode=u\(aqnon_volatile\(aq, alerting=False, per_msg_auth=False, user_level_auth=False, access_mode=u\(aqalways\(aq, privilege_update_mode=u\(aqnon_volatile\(aq, privilege_level=u\(aqadministrator\(aq, **kwargs) Set channel access .INDENT 7.0 .TP @@ -156804,7 +165964,7 @@ salt\-call ipmi.set_identify .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipmi.set_power(state=\(aqpower_on\(aq, wait=True, **kwargs) +.B salt.modules.ipmi.set_power(state=u\(aqpower_on\(aq, wait=True, **kwargs) Request power state change .INDENT 7.0 .TP @@ -156863,7 +166023,7 @@ salt\-call ipmi.set_power state=shutdown wait=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipmi.set_user_access(uid, channel=14, callback=True, link_auth=True, ipmi_msg=True, privilege_level=\(aqadministrator\(aq, **kwargs) +.B salt.modules.ipmi.set_user_access(uid, channel=14, callback=True, link_auth=True, ipmi_msg=True, privilege_level=u\(aqadministrator\(aq, **kwargs) Set user access .INDENT 7.0 .TP @@ -157006,7 +166166,7 @@ salt\-call ipmi.set_user_name uid=2 name=\(aqsteverweber\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipmi.set_user_password(uid, mode=\(aqset_password\(aq, password=None, **kwargs) +.B salt.modules.ipmi.set_user_password(uid, mode=u\(aqset_password\(aq, password=None, **kwargs) Set user password and (modes) .INDENT 7.0 .TP @@ -157110,7 +166270,7 @@ salt\-call ipmi.user_delete uid=2 Support for ipset .INDENT 0.0 .TP -.B salt.modules.ipset.add(set=None, entry=None, family=\(aqipv4\(aq, **kwargs) +.B salt.modules.ipset.add(setname=None, entry=None, family=u\(aqipv4\(aq, **kwargs) Append an entry to the specified set. .sp CLI Example: @@ -157129,7 +166289,7 @@ salt \(aq*\(aq ipset.add setname 192.168.0.3,AA:BB:CC:DD:EE:FF .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipset.check(set=None, entry=None, family=\(aqipv4\(aq) +.B salt.modules.ipset.check(set=None, entry=None, family=u\(aqipv4\(aq) Check that an entry exists in the specified set. .INDENT 7.0 .TP @@ -157170,7 +166330,7 @@ salt \(aq*\(aq ipset.check setname \(aq192.168.0.1 comment "Hello"\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipset.check_set(set=None, family=\(aqipv4\(aq) +.B salt.modules.ipset.check_set(set=None, family=u\(aqipv4\(aq) Check that given ipset set exists. .sp New in version 2014.7.0. @@ -157190,7 +166350,7 @@ salt \(aq*\(aq ipset.check_set setname .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipset.delete(set=None, entry=None, family=\(aqipv4\(aq, **kwargs) +.B salt.modules.ipset.delete(set=None, entry=None, family=u\(aqipv4\(aq, **kwargs) Delete an entry from the specified set. .sp CLI Example: @@ -157207,7 +166367,7 @@ salt \(aq*\(aq ipset.delete setname 192.168.0.3,AA:BB:CC:DD:EE:FF .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipset.delete_set(set=None, family=\(aqipv4\(aq) +.B salt.modules.ipset.delete_set(set=None, family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -157230,7 +166390,7 @@ salt \(aq*\(aq ipset.delete_set custom_set family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipset.flush(set=None, family=\(aqipv4\(aq) +.B salt.modules.ipset.flush(set=None, family=u\(aqipv4\(aq) Flush entries in the specified set, Flush all sets if set is not specified. .sp @@ -157255,7 +166415,7 @@ salt \(aq*\(aq ipset.flush set .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipset.list_sets(family=\(aqipv4\(aq) +.B salt.modules.ipset.list_sets(family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -157275,7 +166435,7 @@ salt \(aq*\(aq ipset.list_sets .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipset.new_set(set=None, set_type=None, family=\(aqipv4\(aq, comment=False, **kwargs) +.B salt.modules.ipset.new_set(set=None, set_type=None, family=u\(aqipv4\(aq, comment=False, **kwargs) New in version 2014.7.0. .sp @@ -157300,7 +166460,7 @@ salt \(aq*\(aq ipset.new_set custom_set list:set family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipset.rename_set(set=None, new_set=None, family=\(aqipv4\(aq) +.B salt.modules.ipset.rename_set(set=None, new_set=None, family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -157323,7 +166483,7 @@ salt \(aq*\(aq ipset.rename_set custom_set new_set=new_set_name family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ipset.test(set=None, entry=None, family=\(aqipv4\(aq, **kwargs) +.B salt.modules.ipset.test(set=None, entry=None, family=u\(aqipv4\(aq, **kwargs) Test if an entry is in the specified set. .sp CLI Example: @@ -157395,7 +166555,7 @@ iptables.save_filters: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.append(table=\(aqfilter\(aq, chain=None, rule=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.append(table=u\(aqfilter\(aq, chain=None, rule=None, family=u\(aqipv4\(aq) Append a rule to the specified table/chain. .INDENT 7.0 .TP @@ -157425,7 +166585,7 @@ salt \(aq*\(aq iptables.append filter INPUT \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.build_rule(table=\(aqfilter\(aq, chain=None, command=None, position=\(aq\(aq, full=None, family=\(aqipv4\(aq, **kwargs) +.B salt.modules.iptables.build_rule(table=u\(aqfilter\(aq, chain=None, command=None, position=u\(aq\(aq, full=None, family=u\(aqipv4\(aq, **kwargs) Build a well\-formatted iptables rule based on kwargs. A \fItable\fP and \fIchain\fP are not required, unless \fIfull\fP is True. .sp @@ -157437,6 +166597,7 @@ be used from the command line. If a position is required (as with \fI\-I\fP or \fI\-D\fP), it may be specified as \fIposition\fP\&. This will only be useful if \fIfull\fP is True. .sp +If \fIstate\fP is passed, it will be ignored, use \fIconnstate\fP\&. If \fIconnstate\fP is passed in, it will automatically be changed to \fIstate\fP\&. .sp To pass in jump options that doesn\(aqt take arguments, pass in an empty @@ -157452,19 +166613,19 @@ salt \(aq*\(aq iptables.build_rule match=state \e connstate=RELATED,ESTABLISHED jump=ACCEPT salt \(aq*\(aq iptables.build_rule filter INPUT command=I position=3 \e - full=True match=state state=RELATED,ESTABLISHED jump=ACCEPT + full=True match=state connstate=RELATED,ESTABLISHED jump=ACCEPT salt \(aq*\(aq iptables.build_rule filter INPUT command=A \e - full=True match=state state=RELATED,ESTABLISHED \e + full=True match=state connstate=RELATED,ESTABLISHED \e source=\(aq127.0.0.1\(aq jump=ACCEPT \&.. Invert Rules salt \(aq*\(aq iptables.build_rule filter INPUT command=A \e - full=True match=state state=RELATED,ESTABLISHED \e - source=\(aq! 127.0.0.1\(aq jump=ACCEPT + full=True match=state connstate=RELATED,ESTABLISHED \e + source=\(aq!127.0.0.1\(aq jump=ACCEPT salt \(aq*\(aq iptables.build_rule filter INPUT command=A \e - full=True match=state state=RELATED,ESTABLISHED \e + full=True match=state connstate=RELATED,ESTABLISHED \e destination=\(aqnot 127.0.0.1\(aq jump=ACCEPT IPv6: @@ -157472,7 +166633,7 @@ salt \(aq*\(aq iptables.build_rule match=state \e connstate=RELATED,ESTABLISHED jump=ACCEPT \e family=ipv6 salt \(aq*\(aq iptables.build_rule filter INPUT command=I position=3 \e - full=True match=state state=RELATED,ESTABLISHED jump=ACCEPT \e + full=True match=state connstate=RELATED,ESTABLISHED jump=ACCEPT \e family=ipv6 .ft P .fi @@ -157481,7 +166642,7 @@ salt \(aq*\(aq iptables.build_rule filter INPUT command=I position=3 \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.check(table=\(aqfilter\(aq, chain=None, rule=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.check(table=u\(aqfilter\(aq, chain=None, rule=None, family=u\(aqipv4\(aq) Check for the existence of a rule in the table and chain .INDENT 7.0 .TP @@ -157511,7 +166672,7 @@ salt \(aq*\(aq iptables.check filter INPUT \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.check_chain(table=\(aqfilter\(aq, chain=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.check_chain(table=u\(aqfilter\(aq, chain=None, family=u\(aqipv4\(aq) New in version 2014.1.0. .sp @@ -157534,7 +166695,7 @@ salt \(aq*\(aq iptables.check_chain filter INPUT family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.delete(table, chain=None, position=None, rule=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.delete(table, chain=None, position=None, rule=None, family=u\(aqipv4\(aq) .INDENT 7.0 .TP .B Delete a rule from the specified table/chain, specifying either the rule @@ -157568,7 +166729,7 @@ salt \(aq*\(aq iptables.delete filter INPUT \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.delete_chain(table=\(aqfilter\(aq, chain=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.delete_chain(table=u\(aqfilter\(aq, chain=None, family=u\(aqipv4\(aq) New in version 2014.1.0. .sp @@ -157591,7 +166752,7 @@ salt \(aq*\(aq iptables.delete_chain filter CUSTOM_CHAIN family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.flush(table=\(aqfilter\(aq, chain=\(aq\(aq, family=\(aqipv4\(aq) +.B salt.modules.iptables.flush(table=u\(aqfilter\(aq, chain=u\(aq\(aq, family=u\(aqipv4\(aq) Flush the chain in the specified table, flush all chains in the specified table if not specified chain. .sp @@ -157612,7 +166773,7 @@ salt \(aq*\(aq iptables.flush filter INPUT family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.get_policy(table=\(aqfilter\(aq, chain=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.get_policy(table=u\(aqfilter\(aq, chain=None, family=u\(aqipv4\(aq) Return the current policy for the specified table/chain .sp CLI Example: @@ -157632,7 +166793,7 @@ salt \(aq*\(aq iptables.get_policy filter INPUT family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.get_rules(family=\(aqipv4\(aq) +.B salt.modules.iptables.get_rules(family=u\(aqipv4\(aq) Return a data structure of the current, in\-memory rules .sp CLI Example: @@ -157652,7 +166813,7 @@ salt \(aq*\(aq iptables.get_rules family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.get_saved_policy(table=\(aqfilter\(aq, chain=None, conf_file=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.get_saved_policy(table=u\(aqfilter\(aq, chain=None, conf_file=None, family=u\(aqipv4\(aq) Return the current policy for the specified table/chain .sp CLI Examples: @@ -157676,7 +166837,7 @@ salt \(aq*\(aq iptables.get_saved_policy filter INPUT \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.get_saved_rules(conf_file=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.get_saved_rules(conf_file=None, family=u\(aqipv4\(aq) Return a data structure of the rules in the conf file .sp CLI Example: @@ -157696,7 +166857,7 @@ salt \(aq*\(aq iptables.get_saved_rules family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.insert(table=\(aqfilter\(aq, chain=None, position=None, rule=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.insert(table=u\(aqfilter\(aq, chain=None, position=None, rule=None, family=u\(aqipv4\(aq) Insert a rule into the specified table/chain, at the specified position. .INDENT 7.0 .TP @@ -157731,7 +166892,7 @@ salt \(aq*\(aq iptables.insert filter INPUT position=3 \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.new_chain(table=\(aqfilter\(aq, chain=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.new_chain(table=u\(aqfilter\(aq, chain=None, family=u\(aqipv4\(aq) New in version 2014.1.0. .sp @@ -157754,7 +166915,7 @@ salt \(aq*\(aq iptables.new_chain filter CUSTOM_CHAIN family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.save(filename=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.save(filename=None, family=u\(aqipv4\(aq) Save the current in\-memory rules to disk .sp CLI Example: @@ -157774,7 +166935,7 @@ salt \(aq*\(aq iptables.save /etc/sysconfig/iptables family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.set_policy(table=\(aqfilter\(aq, chain=None, policy=None, family=\(aqipv4\(aq) +.B salt.modules.iptables.set_policy(table=u\(aqfilter\(aq, chain=None, policy=None, family=u\(aqipv4\(aq) Set the current policy for the specified table/chain .sp CLI Example: @@ -157794,7 +166955,7 @@ salt \(aq*\(aq iptables.set_policy filter INPUT ACCEPT family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.iptables.version(family=\(aqipv4\(aq) +.B salt.modules.iptables.version(family=u\(aqipv4\(aq) Return version from iptables \-\-version .sp CLI Example: @@ -158485,7 +167646,7 @@ salt \(aq*\(aq jenkins.build_job jobname .UNINDENT .INDENT 0.0 .TP -.B salt.modules.jenkins.create_job(name=None, config_xml=None, saltenv=\(aqbase\(aq) +.B salt.modules.jenkins.create_job(name=None, config_xml=None, saltenv=u\(aqbase\(aq) Return the configuration file. .INDENT 7.0 .TP @@ -158778,10 +167939,20 @@ Execute a groovy script on the jenkins master .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq jenkins.run \(aqJenkins.instance.doSafeRestart()\(aq +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.jenkins.update_job(name=None, config_xml=None, saltenv=\(aqbase\(aq) +.B salt.modules.jenkins.update_job(name=None, config_xml=None, saltenv=u\(aqbase\(aq) Return the updated configuration file. .INDENT 7.0 .TP @@ -158836,7 +168007,7 @@ use the latest salt code from github until the next release. Refer to \fBjunos\fP for information on connecting to junos proxy. .INDENT 0.0 .TP -.B salt.modules.junos.cli(command=None, format=\(aqtext\(aq, **kwargs) +.B salt.modules.junos.cli(command=None, format=u\(aqtext\(aq, **kwargs) Executes the CLI commands and returns the output in specified format. (default is text) The ouput can also be stored in a file. .sp Usage: @@ -159430,7 +168601,7 @@ Path to the file where any diffs will be written. (default = None) .UNINDENT .INDENT 0.0 .TP -.B salt.modules.junos.rpc(cmd=None, dest=None, format=\(aqxml\(aq, **kwargs) +.B salt.modules.junos.rpc(cmd=None, dest=None, format=u\(aqxml\(aq, **kwargs) This function executes the rpc provided as arguments on the junos device. The returned data can be stored in a file. .sp @@ -159464,7 +168635,7 @@ The rpc to be executed. (default = None) \fBOptional\fP \-\- .INDENT 2.0 .IP \(bu 2 dest: -Destination file where the rpc ouput is stored. (default = None) +Destination file where the rpc output is stored. (default = None) Note that the file will be stored on the proxy minion. To push the files to the master use the salt\(aqs following execution module: \fBcp.push\fP @@ -159685,7 +168856,7 @@ salt \(aq*\(aq k8s.create_namespace namespace_name http://kube\-master.cluster.l .UNINDENT .INDENT 0.0 .TP -.B salt.modules.k8s.create_secret(namespace, name, sources, apiserver_url=None, force=False, update=False, saltenv=\(aqbase\(aq) +.B salt.modules.k8s.create_secret(namespace, name, sources, apiserver_url=None, force=False, update=False, saltenv=u\(aqbase\(aq) New in version 2016.3.0. .sp @@ -159795,7 +168966,7 @@ salt \(aq*\(aq k8s.get_labels kube\-node.cluster.local http://kube\-master.clust .UNINDENT .INDENT 0.0 .TP -.B salt.modules.k8s.get_namespaces(namespace=\(aq\(aq, apiserver_url=None) +.B salt.modules.k8s.get_namespaces(namespace=u\(aq\(aq, apiserver_url=None) New in version 2016.3.0. .sp @@ -159840,7 +169011,7 @@ salt \(aq*\(aq k8s.get_namespaces namespace_name http://kube\-master.cluster.loc .UNINDENT .INDENT 0.0 .TP -.B salt.modules.k8s.get_secrets(namespace, name=\(aq\(aq, apiserver_url=None, decode=False, brief=False) +.B salt.modules.k8s.get_secrets(namespace, name=u\(aq\(aq, apiserver_url=None, decode=False, brief=False) Get k8s namespaces .sp CLI Example: @@ -159922,7 +169093,7 @@ salt \(aq*\(aq k8s.label_present hw/disktype ssd kube\-node.cluster.local http:/ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.k8s.update_secret(namespace, name, sources, apiserver_url=None, force=True, saltenv=\(aqbase\(aq) +.B salt.modules.k8s.update_secret(namespace, name, sources, apiserver_url=None, force=True, saltenv=u\(aqbase\(aq) New in version 2016.3.0. .sp @@ -160009,7 +169180,7 @@ New in version 2016.11.0. .INDENT 0.0 .TP -.B salt.modules.kapacitor.define_task(name, tick_script, task_type=\(aqstream\(aq, database=None, retention_policy=\(aqdefault\(aq) +.B salt.modules.kapacitor.define_task(name, tick_script, task_type=u\(aqstream\(aq, database=None, retention_policy=u\(aqdefault\(aq) Define a task. Serves as both create/update. .INDENT 7.0 .TP @@ -160305,6 +169476,410 @@ salt \(aqkde.example.com\(aq kerberos.list_principals .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.kernelpkg_linux_apt +.sp +Manage Linux kernel packages on APT\-based systems +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_apt.active() +Return the version of the running kernel. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.active +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_apt.cleanup(keep_latest=True) +Remove all unused kernel packages from the system. +.INDENT 7.0 +.TP +.B keep_latest +True +In the event that the active kernel is not the latest one installed, setting this to True +will retain the latest kernel package, in addition to the active one. If False, all kernel +packages other than the active one will be removed. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.cleanup +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_apt.latest_available() +Return the version of the latest kernel from the package repositories. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.latest_available +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_apt.latest_installed() +Return the version of the latest installed kernel. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.latest_installed +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This function may not return the same value as +\fI\%active()\fP if a new kernel +has been installed and the system has not yet been rebooted. +The \fI\%needs_reboot()\fP function +exists to detect this condition. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_apt.list_installed() +Return a list of all installed kernels. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.list_installed +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_apt.needs_reboot() +Detect if a new kernel version has been installed but is not running. +Returns True if a new kernel is installed, False otherwise. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.needs_reboot +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_apt.remove(release) +Remove a specific version of the kernel. +.INDENT 7.0 +.TP +.B release +The release number of an installed kernel. This must be the entire release +number as returned by \fI\%list_installed()\fP, +not the package name. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.remove 4.4.0\-70\-generic +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_apt.upgrade(reboot=False, at_time=None) +Upgrade the kernel and optionally reboot the system. +.INDENT 7.0 +.TP +.B reboot +False +Request a reboot if a new kernel is available. +.TP +.B at_time +immediate +Schedule the reboot at some point in the future. This argument +is ignored if \fBreboot=False\fP\&. See +\fBreboot()\fP for more details +on this argument. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.upgrade +salt \(aq*\(aq kernelpkg.upgrade reboot=True at_time=1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +An immediate reboot often shuts down the system before the minion +has a chance to return, resulting in errors. A minimal delay (1 minute) +is useful to ensure the result is delivered to the master. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_apt.upgrade_available() +Detect if a new kernel version is available in the repositories. +Returns True if a new kernel is avaliable, False otherwise. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.upgrade_available +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.SS salt.modules.kernelpkg_linux_yum +.sp +Manage Linux kernel packages on YUM\-based systems +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_yum.active() +Return the version of the running kernel. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.active +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_yum.cleanup(keep_latest=True) +Remove all unused kernel packages from the system. +.INDENT 7.0 +.TP +.B keep_latest +True +In the event that the active kernel is not the latest one installed, setting this to True +will retain the latest kernel package, in addition to the active one. If False, all kernel +packages other than the active one will be removed. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.cleanup +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_yum.latest_available() +Return the version of the latest kernel from the package repositories. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.latest_available +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_yum.latest_installed() +Return the version of the latest installed kernel. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.latest_installed +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This function may not return the same value as +\fI\%active()\fP if a new kernel +has been installed and the system has not yet been rebooted. +The \fI\%needs_reboot()\fP function +exists to detect this condition. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_yum.list_installed() +Return a list of all installed kernels. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.list_installed +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_yum.needs_reboot() +Detect if a new kernel version has been installed but is not running. +Returns True if a new kernel is installed, False otherwise. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.needs_reboot +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_yum.remove(release) +Remove a specific version of the kernel. +.INDENT 7.0 +.TP +.B release +The release number of an installed kernel. This must be the entire release +number as returned by \fI\%list_installed()\fP, +not the package name. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.remove 3.10.0\-327.el7 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_yum.upgrade(reboot=False, at_time=None) +Upgrade the kernel and optionally reboot the system. +.INDENT 7.0 +.TP +.B reboot +False +Request a reboot if a new kernel is available. +.TP +.B at_time +immediate +Schedule the reboot at some point in the future. This argument +is ignored if \fBreboot=False\fP\&. See +\fBreboot()\fP for more details +on this argument. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.upgrade +salt \(aq*\(aq kernelpkg.upgrade reboot=True at_time=1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +An immediate reboot often shuts down the system before the minion +has a chance to return, resulting in errors. A minimal delay (1 minute) +is useful to ensure the result is delivered to the master. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.kernelpkg_linux_yum.upgrade_available() +Detect if a new kernel version is available in the repositories. +Returns True if a new kernel is avaliable, False otherwise. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kernelpkg.upgrade_available +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.key .sp Functions to view the minion\(aqs public key information @@ -161494,8 +171069,18 @@ It\(aqs base64 encoded certificates/keys in one line. For an item only one field should be provided. Either a \fIdata\fP or a \fIfile\fP entry. In case both are provided the \fIfile\fP entry is prefered. .INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq kubernetes.nodes api_url=http://k8s\-api\-server:port api_user=myuser api_password=pass +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 .TP -.B salt.modules.kubernetes.configmaps(namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.configmaps(namespace=u\(aqdefault\(aq, **kwargs) Return a list of kubernetes configmaps defined in the namespace .sp CLI Examples: @@ -161513,8 +171098,22 @@ salt \(aq*\(aq kubernetes.configmaps namespace=default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.create_configmap(name, namespace, data, source, template, saltenv, **kwargs) +.B salt.modules.kubernetes.create_configmap(name, namespace, data, source=None, template=None, saltenv=u\(aqbase\(aq, **kwargs) Creates the kubernetes configmap as defined by the user. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq kubernetes.create_configmap settings default \(aq{"example.conf": "# example file"}\(aq + +salt \(aqminion2\(aq kubernetes.create_configmap name=settings namespace=default data=\(aq{"example.conf": "# example file"}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -161539,8 +171138,22 @@ Creates the kubernetes deployment as defined by the user. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.create_secret(name, namespace, data, source, template, saltenv, **kwargs) +.B salt.modules.kubernetes.create_secret(name, namespace=u\(aqdefault\(aq, data=None, source=None, template=None, saltenv=u\(aqbase\(aq, **kwargs) Creates the kubernetes secret as defined by the user. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq kubernetes.create_secret passwords default \(aq{"db": "letmein"}\(aq + +salt \(aqminion2\(aq kubernetes.create_secret name=passwords namespace=default data=\(aq{"db": "letmein"}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -161549,7 +171162,7 @@ Creates the kubernetes service as defined by the user. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.delete_configmap(name, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.delete_configmap(name, namespace=u\(aqdefault\(aq, **kwargs) Deletes the kubernetes configmap defined by name and namespace .sp CLI Examples: @@ -161567,7 +171180,7 @@ salt \(aq*\(aq kubernetes.delete_configmap name=settings namespace=default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.delete_deployment(name, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.delete_deployment(name, namespace=u\(aqdefault\(aq, **kwargs) Deletes the kubernetes deployment defined by name and namespace .sp CLI Examples: @@ -161603,7 +171216,7 @@ salt \(aq*\(aq kubernetes.delete_namespace name=salt .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.delete_pod(name, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.delete_pod(name, namespace=u\(aqdefault\(aq, **kwargs) Deletes the kubernetes pod defined by name and namespace .sp CLI Examples: @@ -161621,7 +171234,7 @@ salt \(aq*\(aq kubernetes.delete_pod name=guestbook\-708336848\-5nl8c namespace= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.delete_secret(name, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.delete_secret(name, namespace=u\(aqdefault\(aq, **kwargs) Deletes the kubernetes secret defined by name and namespace .sp CLI Examples: @@ -161639,7 +171252,7 @@ salt \(aq*\(aq kubernetes.delete_secret name=confidential namespace=default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.delete_service(name, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.delete_service(name, namespace=u\(aqdefault\(aq, **kwargs) Deletes the kubernetes service defined by name and namespace .sp CLI Examples: @@ -161657,7 +171270,7 @@ salt \(aq*\(aq kubernetes.delete_service name=my\-nginx namespace=default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.deployments(namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.deployments(namespace=u\(aqdefault\(aq, **kwargs) Return a list of kubernetes deployments defined in the namespace .sp CLI Examples: @@ -161793,7 +171406,7 @@ salt \(aq*\(aq kubernetes.ping .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.pods(namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.pods(namespace=u\(aqdefault\(aq, **kwargs) Return a list of kubernetes pods defined in the namespace .sp CLI Examples: @@ -161811,31 +171424,59 @@ salt \(aq*\(aq kubernetes.pods namespace=default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.replace_configmap(name, data, source, template, saltenv, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.replace_configmap(name, data, source=None, template=None, saltenv=u\(aqbase\(aq, namespace=u\(aqdefault\(aq, **kwargs) Replaces an existing configmap with a new one defined by name and -namespace, having the specificed data. +namespace with the specified data. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq kubernetes.replace_configmap settings default \(aq{"example.conf": "# example file"}\(aq + +salt \(aqminion2\(aq kubernetes.replace_configmap name=settings namespace=default data=\(aq{"example.conf": "# example file"}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.replace_deployment(name, metadata, spec, source, template, saltenv, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.replace_deployment(name, metadata, spec, source, template, saltenv, namespace=u\(aqdefault\(aq, **kwargs) Replaces an existing deployment with a new one defined by name and namespace, having the specificed metadata and spec. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.replace_secret(name, data, source, template, saltenv, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.replace_secret(name, data, source=None, template=None, saltenv=u\(aqbase\(aq, namespace=u\(aqdefault\(aq, **kwargs) Replaces an existing secret with a new one defined by name and namespace, having the specificed data. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq kubernetes.replace_secret name=passwords data=\(aq{"db": "letmein"}\(aq + +salt \(aqminion2\(aq kubernetes.replace_secret name=passwords namespace=saltstack data=\(aq{"db": "passw0rd"}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.replace_service(name, metadata, spec, source, template, old_service, saltenv, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.replace_service(name, metadata, spec, source, template, old_service, saltenv, namespace=u\(aqdefault\(aq, **kwargs) Replaces an existing service with a new one defined by name and namespace, having the specificed metadata and spec. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.secrets(namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.secrets(namespace=u\(aqdefault\(aq, **kwargs) Return a list of kubernetes secrets defined in the namespace .sp CLI Examples: @@ -161853,7 +171494,7 @@ salt \(aq*\(aq kubernetes.secrets namespace=default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.services(namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.services(namespace=u\(aqdefault\(aq, **kwargs) Return a list of kubernetes services defined in the namespace .sp CLI Examples: @@ -161871,7 +171512,7 @@ salt \(aq*\(aq kubernetes.services namespace=default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.show_configmap(name, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.show_configmap(name, namespace=u\(aqdefault\(aq, **kwargs) Return the kubernetes configmap defined by name and namespace. .sp CLI Examples: @@ -161889,7 +171530,7 @@ salt \(aq*\(aq kubernetes.show_configmap name=game\-config namespace=default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.show_deployment(name, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.show_deployment(name, namespace=u\(aqdefault\(aq, **kwargs) Return the kubernetes deployment defined by name and namespace .sp CLI Examples: @@ -161924,7 +171565,7 @@ salt \(aq*\(aq kubernetes.show_namespace kube\-system .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.show_pod(name, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.show_pod(name, namespace=u\(aqdefault\(aq, **kwargs) Return POD information for a given pod name defined in the namespace .sp CLI Examples: @@ -161942,7 +171583,7 @@ salt \(aq*\(aq kubernetes.show_pod guestbook\-708336848\-fqr2x namespace=default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.show_secret(name, namespace=\(aqdefault\(aq, decode=False, **kwargs) +.B salt.modules.kubernetes.show_secret(name, namespace=u\(aqdefault\(aq, decode=False, **kwargs) Return the kubernetes secret defined by name and namespace. The secrets can be decoded if specified by the user. Warning: this has security implications. @@ -161963,7 +171604,7 @@ salt \(aq*\(aq kubernetes.show_secret name=confidential decode=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.kubernetes.show_service(name, namespace=\(aqdefault\(aq, **kwargs) +.B salt.modules.kubernetes.show_service(name, namespace=u\(aqdefault\(aq, **kwargs) Return the kubernetes service defined by name and namespace .sp CLI Examples: @@ -162123,9 +171764,30 @@ salt \(aq*\(aq service.start /System/Library/LaunchDaemons/org.ntp.ntpd.plist .UNINDENT .INDENT 0.0 .TP -.B salt.modules.launchctl.status(job_label, runas=None) -Return the status for a service, returns a bool whether the service is -running. +.B salt.modules.launchctl.status(name, runas=None) +Return the status for a service via systemd. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBrunas\fP (\fI\%str\fP) \-\- User to run launchctl commands +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -162133,7 +171795,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq service.status +salt \(aq*\(aq service.status .ft P .fi .UNINDENT @@ -162242,7 +171904,7 @@ salt \(aq*\(aq layman.list_local .UNINDENT .INDENT 0.0 .TP -.B salt.modules.layman.sync(overlay=\(aqALL\(aq) +.B salt.modules.layman.sync(overlay=u\(aqALL\(aq) Update the specified overlay. Use \(aqALL\(aq to synchronize all overlays. This is the default if no overlay is specified. .INDENT 7.0 @@ -162744,7 +172406,7 @@ directives="(\(aqadd\(aq, \(aqexample\(aq, [\(aqexample_val\(aq])" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ldap3.search(connect_spec, base, scope=\(aqsubtree\(aq, filterstr=\(aq(objectClass=*)\(aq, attrlist=None, attrsonly=0) +.B salt.modules.ldap3.search(connect_spec, base, scope=u\(aqsubtree\(aq, filterstr=u\(aq(objectClass=*)\(aq, attrlist=None, attrsonly=0) Search an LDAP database. .INDENT 7.0 .TP @@ -162932,6 +172594,1917 @@ scope=1 attrs=\(aq\(aq server=\(aqlocalhost\(aq port=\(aq7393\(aq tls=True bindp .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.libcloud_compute module +.SS Apache Libcloud Compute Management +.sp +Connection module for Apache Libcloud Compute management for a full list +of supported clouds, see \fI\%http://libcloud.readthedocs.io/en/latest/compute/supported_providers.html\fP +.sp +Clouds include Amazon EC2, Azure, Google GCE, VMware, OpenStack Nova +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B configuration +This module uses a configuration profile for one or multiple cloud providers +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +libcloud_compute: + profile_test1: + driver: google + key: service\-account@googlecloud.net + secret: /path/to.key.json + profile_test2: + driver: arm + key: 12345 + secret: mysecret +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B depends +apache\-libcloud +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.attach_volume(node_id, volume_id, profile, device=None, **libcloud_kwargs) +Attaches volume to node. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBnode_id\fP (\fBstr\fP) \-\- Node ID to target +.IP \(bu 2 +\fBvolume_id\fP (\fBstr\fP) \-\- Volume ID from which to attach +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBdevice\fP (\fBstr\fP) \-\- Where the device is exposed, e.g. \(aq/dev/sdb\(aq +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs attach_volume method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.detach_volume vol1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.copy_image(source_region, image_id, name, profile, description=None, **libcloud_kwargs) +Copies an image from a source region to the current region. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBsource_region\fP (\fBstr\fP) \-\- Region to copy the node from. +.IP \(bu 2 +\fBimage_id\fP (\fBstr\fP) \-\- Image to copy. +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- name for new image. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBdescription\fP \-\- description for new image. +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs copy_image method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.copy_image us\-east1 image1 \(aqnew image\(aq profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.create_image(node_id, name, profile, description=None, **libcloud_kwargs) +Create an image from a node +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBnode_id\fP (\fBstr\fP) \-\- Node to run the task on. +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- name for new image. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBdescription\fP (\fBdescription\fP) \-\- description for new image. +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs create_image method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.create_image server1 my_image profile1 +salt myminion libcloud_compute.create_image server1 my_image profile1 description=\(aqtest image\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.create_key_pair(name, profile, **libcloud_kwargs) +Create a single key pair by name +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Name of the key pair to create. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs create_key_pair method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.create_key_pair pair1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.create_volume(size, name, profile, location_id=None, **libcloud_kwargs) +Create a storage volume +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBsize\fP (\fBint\fP) \-\- Size of volume in gigabytes (required) +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Name of the volume to be created +.IP \(bu 2 +\fBlocation_id\fP (\fBstr\fP) \-\- Which data center to create a volume in. If +empty, undefined behavior will be selected. +(optional) +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_volumes method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.create_volume 1000 vol1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.create_volume_snapshot(volume_id, profile, name=None, **libcloud_kwargs) +Create a storage volume snapshot +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBvolume_id\fP (\fBstr\fP) \-\- Volume ID from which to create the new +snapshot. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Name of the snapshot to be created (optional) +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs create_volume_snapshot method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.create_volume_snapshot vol1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.delete_image(image_id, profile, **libcloud_kwargs) +Delete an image of a node +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBimage_id\fP (\fBstr\fP) \-\- Image to delete +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs delete_image method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.delete_image image1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.delete_key_pair(name, profile, **libcloud_kwargs) +Delete a key pair +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Key pair name. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs import_key_pair_from_xxx method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.delete_key_pair pair1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.destroy_node(node_id, profile, **libcloud_kwargs) +Destroy a node in the cloud +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBnode_id\fP (\fBstr\fP) \-\- Unique ID of the node to destory +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs destroy_node method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.destry_node as\-2346 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.destroy_volume(volume_id, profile, **libcloud_kwargs) +Destroy a volume. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBvolume_id\fP (\fBstr\fP) \-\- Volume ID from which to destroy +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs destroy_volume method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.destroy_volume vol1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.destroy_volume_snapshot(volume_id, snapshot_id, profile, **libcloud_kwargs) +Destroy a volume snapshot. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBvolume_id\fP (\fBstr\fP) \-\- Volume ID from which the snapshot belongs +.IP \(bu 2 +\fBsnapshot_id\fP (\fBstr\fP) \-\- Volume Snapshot ID from which to destroy +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs destroy_volume_snapshot method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.destroy_volume_snapshot snap1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.detach_volume(volume_id, profile, **libcloud_kwargs) +Detaches a volume from a node. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBvolume_id\fP (\fBstr\fP) \-\- Volume ID from which to detach +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs detach_volume method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.detach_volume vol1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.extra(method, profile, **libcloud_kwargs) +Call an extended method on the driver +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmethod\fP (\fBstr\fP) \-\- Driver\(aqs method name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.extra ex_get_permissions google container_name=my_container object_name=me.jpg \-\-out=yaml +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.get_image(image_id, profile, **libcloud_kwargs) +Get an image of a node +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBimage_id\fP (\fBstr\fP) \-\- Image to fetch +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs delete_image method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.get_image image1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.get_key_pair(name, profile, **libcloud_kwargs) +Get a single key pair by name +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Name of the key pair to retrieve. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs get_key_pair method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.get_key_pair pair1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.import_key_pair(name, key, profile, key_type=None, **libcloud_kwargs) +Import a new public key from string or a file path +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Key pair name. +.IP \(bu 2 +\fBkey\fP (\fBstr\fP or path \fBstr\fP) \-\- Public key material, the string or a path to a file +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBkey_type\fP (\fBstr\fP) \-\- The key pair type, either \fIFILE\fP or \fISTRING\fP\&. Will detect if not provided +and assume that if the string is a path to an existing path it is a FILE, else STRING. +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs import_key_pair_from_xxx method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.import_key_pair pair1 key_value_data123 profile1 +salt myminion libcloud_compute.import_key_pair pair1 /path/to/key profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.list_images(profile, location_id=None, **libcloud_kwargs) +Return a list of images for this cloud +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlocation_id\fP (\fBstr\fP) \-\- The location key, from list_locations +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_images method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.list_images profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.list_key_pairs(profile, **libcloud_kwargs) +List all the available key pair objects. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_key_pairs method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.list_key_pairs profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.list_locations(profile, **libcloud_kwargs) +Return a list of locations for this cloud +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_locations method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.list_locations profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.list_nodes(profile, **libcloud_kwargs) +Return a list of nodes +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_nodes method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.list_nodes profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.list_sizes(profile, location_id=None, **libcloud_kwargs) +Return a list of node sizes +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlocation_id\fP (\fBstr\fP) \-\- The location key, from list_locations +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_sizes method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.list_sizes profile1 +salt myminion libcloud_compute.list_sizes profile1 us\-east1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.list_volume_snapshots(volume_id, profile, **libcloud_kwargs) +Return a list of storage volumes snapshots for this cloud +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBvolume_id\fP (\fBstr\fP) \-\- The volume identifier +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_volume_snapshots method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.list_volume_snapshots vol1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.list_volumes(profile, **libcloud_kwargs) +Return a list of storage volumes for this cloud +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_volumes method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.list_volumes profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_compute.reboot_node(node_id, profile, **libcloud_kwargs) +Reboot a node in the cloud +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBnode_id\fP (\fBstr\fP) \-\- Unique ID of the node to reboot +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs reboot_node method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_compute.reboot_node as\-2346 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.SS salt.modules.libcloud_dns module +.SS Apache Libcloud DNS Management +.sp +Connection module for Apache Libcloud DNS management +.sp +New in version 2016.11.0. + +.INDENT 0.0 +.TP +.B configuration +This module uses a configuration profile for one or multiple DNS providers +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +libcloud_dns: + profile_test1: + driver: cloudflare + key: 12345 + secret: mysecret + profile_test2: + driver: godaddy + key: 12345 + secret: mysecret + shopper_id: 12345 +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B depends +apache\-libcloud +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.create_record(name, zone_id, type, data, profile) +Create a new record. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Record name without the domain name (e.g. www). +Note: If you want to create a record for a base domain +name, you should specify empty string (\(aq\(aq) for this +argument. +.IP \(bu 2 +\fBzone_id\fP (\fBstr\fP) \-\- Zone where the requested record is created. +.IP \(bu 2 +\fBtype\fP (\fBstr\fP) \-\- DNS record type (A, AAAA, ...). +.IP \(bu 2 +\fBdata\fP (\fBstr\fP) \-\- Data for the record (depends on the record type). +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.create_record www google.com A 12.32.12.2 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.create_zone(domain, profile, type=u\(aqmaster\(aq, ttl=None) +Create a new zone. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBdomain\fP (\fBstr\fP) \-\- Zone domain name (e.g. example.com) +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBtype\fP (\fBstr\fP) \-\- Zone type (master / slave). +.IP \(bu 2 +\fBttl\fP (\fBint\fP) \-\- TTL for new records. (optional) +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.create_zone google.com profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.delete_record(zone_id, record_id, profile) +Delete a record. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBzone_id\fP (\fBstr\fP) \-\- Zone to delete. +.IP \(bu 2 +\fBrecord_id\fP (\fBstr\fP) \-\- Record to delete. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.TP +.B Return type +\fBbool\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.delete_record google.com www profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.delete_zone(zone_id, profile) +Delete a zone. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBzone_id\fP (\fBstr\fP) \-\- Zone to delete. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.TP +.B Return type +\fBbool\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.delete_zone google.com profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.extra(method, profile, **libcloud_kwargs) +Call an extended method on the driver +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmethod\fP (\fBstr\fP) \-\- Driver\(aqs method name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs delete_container method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.extra ex_get_permissions google container_name=my_container object_name=me.jpg \-\-out=yaml +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.get_bind_data(zone_id, profile) +Export Zone to the BIND compatible format. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBzone_id\fP (\fBstr\fP) \-\- Zone to export. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.TP +.B Returns +Zone data in BIND compatible format. +.TP +.B Return type +\fBstr\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.get_bind_data google.com profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.get_record(zone_id, record_id, profile) +Get record information for the given zone_id on the given profile +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBzone_id\fP (\fBstr\fP) \-\- Zone to export. +.IP \(bu 2 +\fBrecord_id\fP (\fBstr\fP) \-\- Record to delete. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.get_record google.com www profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.get_zone(zone_id, profile) +Get zone information for the given zone_id on the given profile +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBzone_id\fP (\fBstr\fP) \-\- Zone to export. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.get_zone google.com profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.list_record_types(profile) +List available record types for the given profile, e.g. A, AAAA +.INDENT 7.0 +.TP +.B Parameters +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.list_record_types profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.list_records(zone_id, profile, type=None) +List records for the given zone_id on the given profile +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBzone_id\fP (\fBstr\fP) \-\- Zone to export. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBtype\fP (\fBstr\fP) \-\- The record type, e.g. A, NS +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.list_records google.com profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.list_zones(profile) +List zones for the given profile +.INDENT 7.0 +.TP +.B Parameters +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.list_zones profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_dns.update_zone(zone_id, domain, profile, type=u\(aqmaster\(aq, ttl=None) +Update an existing zone. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBzone_id\fP (\fBstr\fP) \-\- Zone ID to update. +.IP \(bu 2 +\fBdomain\fP (\fBstr\fP) \-\- Zone domain name (e.g. example.com) +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBtype\fP (\fBstr\fP) \-\- Zone type (master / slave). +.IP \(bu 2 +\fBttl\fP (\fBint\fP) \-\- TTL for new records. (optional) +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_dns.update_zone google.com google.com profile1 type=slave +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.SS salt.modules.libcloud_loadbalancer +.SS Apache Libcloud Load Balancer Management +.sp +Connection module for Apache Libcloud Storage load balancer management for a full list +of supported clouds, see \fI\%http://libcloud.readthedocs.io/en/latest/loadbalancer/supported_providers.html\fP +.sp +Clouds include Amazon ELB, ALB, Google, Aliyun, CloudStack, Softlayer +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B configuration +This module uses a configuration profile for one or multiple Storage providers +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +libcloud_loadbalancer: + profile_test1: + driver: gce + key: GOOG0123456789ABCXYZ + secret: mysecret + profile_test2: + driver: alb + key: 12345 + secret: mysecret +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B depends +apache\-libcloud +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.balancer_attach_member(balancer_id, ip, port, profile, extra=None, **libcloud_kwargs) +Add a new member to the load balancer +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBbalancer_id\fP (\fBstr\fP) \-\- id of a load balancer you want to fetch +.IP \(bu 2 +\fBip\fP (\fBstr\fP) \-\- IP address for the new member +.IP \(bu 2 +\fBport\fP (\fBint\fP) \-\- Port for the new member +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs balancer_attach_member method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.balancer_attach_member balancer123 1.2.3.4 80 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.balancer_detach_member(balancer_id, member_id, profile, **libcloud_kwargs) +Add a new member to the load balancer +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBbalancer_id\fP (\fBstr\fP) \-\- id of a load balancer you want to fetch +.IP \(bu 2 +\fBip\fP (\fBstr\fP) \-\- IP address for the new member +.IP \(bu 2 +\fBport\fP (\fBint\fP) \-\- Port for the new member +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs balancer_detach_member method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.balancer_detach_member balancer123 member123 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.create_balancer(name, port, protocol, profile, algorithm=None, members=None, **libcloud_kwargs) +Create a new load balancer instance +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Name of the new load balancer (required) +.IP \(bu 2 +\fBport\fP (\fBstr\fP) \-\- Port the load balancer should listen on, defaults to 80 +.IP \(bu 2 +\fBprotocol\fP (\fBstr\fP) \-\- Loadbalancer protocol, defaults to http. +.IP \(bu 2 +\fBalgorithm\fP (\fBstr\fP) \-\- Load balancing algorithm, defaults to ROUND_ROBIN. See Algorithm type +in Libcloud documentation for a full listing. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs create_balancer method +.UNINDENT +.TP +.B Returns +The details of the new balancer +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.create_balancer my_balancer 80 http profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.destroy_balancer(balancer_id, profile, **libcloud_kwargs) +Destroy a load balancer +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBbalancer_id\fP (\fBstr\fP) \-\- LoadBalancer ID which should be used +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs destroy_balancer method +.UNINDENT +.TP +.B Returns +\fBTrue\fP if the destroy was successful, otherwise \fBFalse\fP\&. +.TP +.B Return type +\fBbool\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.destroy_balancer balancer_1 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.extra(method, profile, **libcloud_kwargs) +Call an extended method on the driver +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmethod\fP (\fBstr\fP) \-\- Driver\(aqs method name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_loadbalancer.extra ex_get_permissions google container_name=my_container object_name=me.jpg \-\-out=yaml +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.get_balancer(balancer_id, profile, **libcloud_kwargs) +Get the details for a load balancer by ID +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBbalancer_id\fP (\fBstr\fP) \-\- id of a load balancer you want to fetch +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs get_balancer method +.UNINDENT +.TP +.B Returns +the load balancer details +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.get_balancer balancer123 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.get_balancer_by_name(name, profile, **libcloud_kwargs) +Get the details for a load balancer by name +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Name of a load balancer you want to fetch +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_balancers method +.UNINDENT +.TP +.B Returns +the load balancer details +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.get_balancer_by_name my_balancer profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.list_balancer_members(balancer_id, profile, **libcloud_kwargs) +List the members of a load balancer +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBbalancer_id\fP (\fBstr\fP) \-\- id of a load balancer you want to fetch +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_balancer_members method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.list_balancer_members balancer123 profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.list_balancers(profile, **libcloud_kwargs) +Return a list of load balancers. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_balancers method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.list_balancers profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.list_protocols(profile, **libcloud_kwargs) +Return a list of supported protocols. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_protocols method +.UNINDENT +.TP +.B Returns +a list of supported protocols +.TP +.B Return type +\fBlist\fP of \fBstr\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.list_protocols profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_loadbalancer.list_supported_algorithms(profile, **libcloud_kwargs) +Get the supported algorithms for a profile +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_supported_algorithms method +.UNINDENT +.TP +.B Returns +The supported algorithms +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.list_supported_algorithms profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.SS salt.modules.libcloud_storage module +.SS Apache Libcloud Storage Management +.sp +Connection module for Apache Libcloud Storage (object/blob) management for a full list +of supported clouds, see \fI\%http://libcloud.readthedocs.io/en/latest/storage/supported_providers.html\fP +.sp +Clouds include Amazon S3, Google Storage, Aliyun, Azure Blobs, Ceph, OpenStack swift +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B configuration +This module uses a configuration profile for one or multiple Storage providers +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +libcloud_storage: + profile_test1: + driver: google_storage + key: GOOG0123456789ABCXYZ + secret: mysecret + profile_test2: + driver: s3 + key: 12345 + secret: mysecret +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B depends +apache\-libcloud +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.create_container(container_name, profile, **libcloud_kwargs) +Create a container in the cloud +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer_name\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs create_container method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.create_container MyFolder profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.delete_container(container_name, profile, **libcloud_kwargs) +Delete an object container in the cloud +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer_name\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs delete_container method +.UNINDENT +.TP +.B Returns +True if an object container has been successfully deleted, False +otherwise. +.TP +.B Return type +\fBbool\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.delete_container MyFolder profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.delete_object(container_name, object_name, profile, **libcloud_kwargs) +Delete an object in the cloud +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer_name\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBobject_name\fP (\fBstr\fP) \-\- Object name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs delete_object method +.UNINDENT +.TP +.B Returns +True if an object has been successfully deleted, False +otherwise. +.TP +.B Return type +\fBbool\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.delete_object MyFolder me.jpg profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.download_object(container_name, object_name, destination_path, profile, overwrite_existing=False, delete_on_failure=True, **libcloud_kwargs) +Download an object to the specified destination path. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer_name\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBobject_name\fP (\fBstr\fP) \-\- Object name +.IP \(bu 2 +\fBdestination_path\fP (\fBstr\fP) \-\- Full path to a file or a directory where the +incoming file will be saved. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBoverwrite_existing\fP (\fBbool\fP) \-\- True to overwrite an existing file, +defaults to False. +.IP \(bu 2 +\fBdelete_on_failure\fP (\fBbool\fP) \-\- True to delete a partially downloaded file if +the download was not successful (hash +mismatch / file size). +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs download_object method +.UNINDENT +.TP +.B Returns +True if an object has been successfully downloaded, False +otherwise. +.TP +.B Return type +\fBbool\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.download_object MyFolder me.jpg /tmp/me.jpg profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.extra(method, profile, **libcloud_kwargs) +Call an extended method on the driver +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmethod\fP (\fBstr\fP) \-\- Driver\(aqs method name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs delete_container method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.extra ex_get_permissions google container_name=my_container object_name=me.jpg \-\-out=yaml +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.get_container(container_name, profile, **libcloud_kwargs) +List container details for the given container_name on the given profile +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer_name\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs get_container method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.get_container MyFolder profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.get_container_object(container_name, object_name, profile, **libcloud_kwargs) +Get the details for a container object (file or object in the cloud) +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer_name\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBobject_name\fP (\fBstr\fP) \-\- Object name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs get_container_object method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.get_container_object MyFolder MyFile.xyz profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.list_container_objects(container_name, profile, **libcloud_kwargs) +List container objects (e.g. files) for the given container_id on the given profile +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer_name\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_container_objects method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.list_container_objects MyFolder profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.list_containers(profile, **libcloud_kwargs) +Return a list of containers. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs list_containers method +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.list_containers profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.libcloud_storage.upload_object(file_path, container_name, object_name, profile, extra=None, verify_hash=True, headers=None, **libcloud_kwargs) +Upload an object currently located on a disk. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBfile_path\fP (\fBstr\fP) \-\- Path to the object on disk. +.IP \(bu 2 +\fBcontainer_name\fP (\fBstr\fP) \-\- Destination container. +.IP \(bu 2 +\fBobject_name\fP (\fBstr\fP) \-\- Object name. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBverify_hash\fP (\fBbool\fP) \-\- Verify hash +.IP \(bu 2 +\fBextra\fP (\fBdict\fP) \-\- Extra attributes (driver specific). (optional) +.IP \(bu 2 +\fBheaders\fP (\fBdict\fP) \-\- (optional) Additional request headers, +such as CORS headers. For example: +headers = {\(aqAccess\-Control\-Allow\-Origin\(aq: \(aq\fI\%http://mozilla.com\fP\(aq} +.IP \(bu 2 +\fBlibcloud_kwargs\fP (\fBdict\fP) \-\- Extra arguments for the driver\(aqs upload_object method +.UNINDENT +.TP +.B Returns +The object name in the cloud +.TP +.B Return type +\fBstr\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion libcloud_storage.upload_object /file/to/me.jpg MyFolder me.jpg profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.linux_acl .sp Support for Linux File Access Control Lists @@ -162939,7 +174512,7 @@ Support for Linux File Access Control Lists The Linux ACL module requires the \fIgetfacl\fP and \fIsetfacl\fP binaries. .INDENT 0.0 .TP -.B salt.modules.linux_acl.delfacl(acl_type, acl_name=\(aq\(aq, *args, **kwargs) +.B salt.modules.linux_acl.delfacl(acl_type, acl_name=u\(aq\(aq, *args, **kwargs) Remove specific FACL from the specified file(s) .sp CLI Examples: @@ -162979,7 +174552,7 @@ salt \(aq*\(aq acl.getfacl /tmp/house/kitchen /tmp/house/livingroom recursive=Tr .UNINDENT .INDENT 0.0 .TP -.B salt.modules.linux_acl.modfacl(acl_type, acl_name=\(aq\(aq, perms=\(aq\(aq, *args, **kwargs) +.B salt.modules.linux_acl.modfacl(acl_type, acl_name=u\(aq\(aq, perms=u\(aq\(aq, *args, **kwargs) Add or modify a FACL for the specified file(s) .sp CLI Examples: @@ -162993,6 +174566,7 @@ salt \(aq*\(aq acl.modfacl default:group mygroup rx /tmp/house/kitchen salt \(aq*\(aq acl.modfacl d:u myuser 7 /tmp/house/kitchen salt \(aq*\(aq acl.modfacl g mygroup 0 /tmp/house/kitchen /tmp/house/livingroom salt \(aq*\(aq acl.modfacl user myuser rwx /tmp/house/kitchen recursive=True +salt \(aq*\(aq acl.modfacl user myuser rwx /tmp/house/kitchen raise_err=True .ft P .fi .UNINDENT @@ -163128,7 +174702,7 @@ salt \(aq*\(aq lvm.fullversion .UNINDENT .INDENT 0.0 .TP -.B salt.modules.linux_lvm.lvcreate(lvname, vgname, size=None, extents=None, snapshot=None, pv=None, thinvolume=False, thinpool=False, **kwargs) +.B salt.modules.linux_lvm.lvcreate(lvname, vgname, size=None, extents=None, snapshot=None, pv=None, thinvolume=False, thinpool=False, force=False, **kwargs) Create a new logical volume, with option for which physical volume to be used .sp CLI Examples: @@ -163165,7 +174739,7 @@ salt \(aq*\(aq lvm.lvcreate new_thinvolume_name vg_name/thinpool_name size=10G t .UNINDENT .INDENT 0.0 .TP -.B salt.modules.linux_lvm.lvdisplay(lvname=\(aq\(aq) +.B salt.modules.linux_lvm.lvdisplay(lvname=u\(aq\(aq, quiet=False) Return information about the logical volume(s) .sp CLI Examples: @@ -163240,7 +174814,7 @@ salt mymachine lvm.pvcreate /dev/sdb1 dataalignmentoffset=7s .UNINDENT .INDENT 0.0 .TP -.B salt.modules.linux_lvm.pvdisplay(pvname=\(aq\(aq, real=False) +.B salt.modules.linux_lvm.pvdisplay(pvname=u\(aq\(aq, real=False) Return information about the physical volume(s) .INDENT 7.0 .TP @@ -163326,7 +174900,7 @@ salt mymachine lvm.vgcreate my_vg /dev/sdb1 clustered=y .UNINDENT .INDENT 0.0 .TP -.B salt.modules.linux_lvm.vgdisplay(vgname=\(aq\(aq) +.B salt.modules.linux_lvm.vgdisplay(vgname=u\(aq\(aq) Return information about the volume group(s) .sp CLI Examples: @@ -163589,7 +175163,7 @@ salt \(aq*\(aq locale.set_locale \(aqen_US.UTF\-8\(aq Module for using the locate utilities .INDENT 0.0 .TP -.B salt.modules.locate.locate(pattern, database=\(aq\(aq, limit=0, **kwargs) +.B salt.modules.locate.locate(pattern, database=u\(aq\(aq, limit=0, **kwargs) Performs a file lookup. Valid options (and their defaults) are: .INDENT 7.0 .INDENT 3.5 @@ -163681,7 +175255,43 @@ salt \(aq*\(aq locate.version Module for managing Solaris logadm based log rotations. .INDENT 0.0 .TP -.B salt.modules.logadm.remove(name, conf_file=\(aq/etc/logadm.conf\(aq) +.B salt.modules.logadm.list_conf(conf_file=u\(aq/etc/logadm.conf\(aq, log_file=None, include_unset=False) +Show parsed configuration +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B conf_file +string +path to logadm.conf, defaults to /etc/logadm.conf +.TP +.B log_file +string +optional show only one log file +.TP +.B include_unset +boolean +include unset flags in output +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq logadm.list_conf +salt \(aq*\(aq logadm.list_conf log=/var/log/syslog +salt \(aq*\(aq logadm.list_conf include_unset=False +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.logadm.remove(name, conf_file=u\(aq/etc/logadm.conf\(aq) Remove log pattern from logadm .sp CLI Example: @@ -163698,8 +175308,43 @@ salt \(aq*\(aq logadm.remove myapplog .UNINDENT .INDENT 0.0 .TP -.B salt.modules.logadm.rotate(name, pattern=False, count=False, age=False, size=False, copy=True, conf_file=\(aq/etc/logadm.conf\(aq) +.B salt.modules.logadm.rotate(name, pattern=None, conf_file=u\(aq/etc/logadm.conf\(aq, **kwargs) Set up pattern for logging. +.INDENT 7.0 +.TP +.B name +string +alias for entryname +.TP +.B pattern +string +alias for log_file +.TP +.B conf_file +string +optional path to alternative configuration file +.TP +.B +.nf +** +.fi +kwargs +boolean|string|int +optional additional flags and parameters +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +\fBname\fP and \fBpattern\fP were kept for backwards compatibility reasons. +.sp +\fBname\fP is an alias for the \fBentryname\fP argument, \fBpattern\fP is an alias +for \fBlog_file\fP\&. These aliasses wil only be used if the \fBentryname\fP and +\fBlog_file\fP arguments are not passed. +.sp +For a full list of arguments see \fB\(galogadm.show_args\(ga\fP\&. +.UNINDENT +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -163708,6 +175353,7 @@ CLI Example: .nf .ft C salt \(aq*\(aq logadm.rotate myapplog pattern=\(aq/var/log/myapp/*.log\(aq count=7 +salt \(aq*\(aq logadm.rotate myapplog log_file=\(aq/var/log/myapp/*.log\(aq count=4 owner=myappd mode=\(aq0700\(aq .ft P .fi .UNINDENT @@ -163715,8 +175361,38 @@ salt \(aq*\(aq logadm.rotate myapplog pattern=\(aq/var/log/myapp/*.log\(aq count .UNINDENT .INDENT 0.0 .TP -.B salt.modules.logadm.show_conf(conf_file=\(aq/etc/logadm.conf\(aq) -Show parsed configuration +.B salt.modules.logadm.show_args(*args, **kwargs) +Show which arguments map to which flags and options. +.sp +New in version 2018.3.0. + +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq logadm.show_args +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.logadm.show_conf(conf_file=u\(aq/etc/logadm.conf\(aq, name=None) +Show configuration +.INDENT 7.0 +.TP +.B conf_file +string +path to logadm.conf, defaults to /etc/logadm.conf +.TP +.B name +string +optional show only a single entry +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -163725,6 +175401,7 @@ CLI Example: .nf .ft C salt \(aq*\(aq logadm.show_conf +salt \(aq*\(aq logadm.show_conf name=/var/log/syslog .ft P .fi .UNINDENT @@ -163797,7 +175474,7 @@ Log message at level WARNING. Module for managing logrotate. .INDENT 0.0 .TP -.B salt.modules.logrotate.get(key, value=None, conf_file=\(aq/etc/logrotate.conf\(aq) +.B salt.modules.logrotate.get(key, value=None, conf_file=u\(aq/etc/logrotate.conf\(aq) Get the value for a specific configuration line. .INDENT 7.0 .TP @@ -163834,7 +175511,7 @@ salt \(aq*\(aq logrotate.get /var/log/wtmp rotate /etc/logrotate.conf .UNINDENT .INDENT 0.0 .TP -.B salt.modules.logrotate.set(key, value, setting=None, conf_file=\(aq/etc/logrotate.conf\(aq) +.B salt.modules.logrotate.set(key, value, setting=None, conf_file=u\(aq/etc/logrotate.conf\(aq) Set a new value for a specific configuration line. .INDENT 7.0 .TP @@ -163903,7 +175580,7 @@ and make changes in the appropriate file. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.logrotate.show_conf(conf_file=\(aq/etc/logrotate.conf\(aq) +.B salt.modules.logrotate.show_conf(conf_file=u\(aq/etc/logrotate.conf\(aq) Show parsed configuration .INDENT 7.0 .TP @@ -163934,7 +175611,7 @@ salt \(aq*\(aq logrotate.show_conf Support for LVS (Linux Virtual Server) .INDENT 0.0 .TP -.B salt.modules.lvs.add_server(protocol=None, service_address=None, server_address=None, packet_forward_method=\(aqdr\(aq, weight=1, **kwargs) +.B salt.modules.lvs.add_server(protocol=None, service_address=None, server_address=None, packet_forward_method=u\(aqdr\(aq, weight=1, **kwargs) Add a real server to a virtual service. .INDENT 7.0 .TP @@ -163968,7 +175645,7 @@ salt \(aq*\(aq lvs.add_server tcp 1.1.1.1:80 192.168.0.11:8080 nat 1 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lvs.add_service(protocol=None, service_address=None, scheduler=\(aqwlc\(aq) +.B salt.modules.lvs.add_service(protocol=None, service_address=None, scheduler=u\(aqwlc\(aq) Add a virtual service. .INDENT 7.0 .TP @@ -164574,11 +176251,9 @@ any extra argument for the salt minion config .TP .B dnsservers list of DNS servers to set inside the container -(Defaults to 8.8.8.8 and 4.4.4.4 until Oxygen release) .TP .B dns_via_dhcp do not set the dns servers, let them be set by the dhcp. -(Defaults to False until Oxygen release) .TP .B autostart autostart the container at boot time @@ -164916,7 +176591,7 @@ salt \(aq*\(aq lxc.destroy foo stop=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.edit_conf(conf_file, out_format=\(aqsimple\(aq, read_only=False, lxc_config=None, **kwargs) +.B salt.modules.lxc.edit_conf(conf_file, out_format=u\(aqsimple\(aq, read_only=False, lxc_config=None, **kwargs) Edit an LXC configuration file. If a setting is already present inside the file, its value will be replaced. If it does not exist, it will be appended to the end of the file. Comments and blank lines will be kept in\-tact if @@ -165528,7 +177203,7 @@ salt \(aq*\(aq lxc.ls active=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.read_conf(conf_file, out_format=\(aqsimple\(aq) +.B salt.modules.lxc.read_conf(conf_file, out_format=u\(aqsimple\(aq) Read in an LXC configuration file. By default returns a simple, unsorted dict, but can also return a more detailed structure including blank lines and comments. @@ -165704,7 +177379,7 @@ salt myminion lxc.restart name .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.retcode(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.retcode(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=u\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.5.0. .sp @@ -165792,7 +177467,7 @@ salt myminion lxc.retcode mycontainer \(aqip addr show\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.run(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.run(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=u\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.8.0. .sp @@ -165880,7 +177555,7 @@ salt myminion lxc.run mycontainer \(aqifconfig \-a\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.run_all(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.run_all(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=u\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.5.0. .sp @@ -165975,7 +177650,7 @@ salt myminion lxc.run_all mycontainer \(aqip addr show\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.run_stderr(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.run_stderr(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=u\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.5.0. .sp @@ -166061,7 +177736,7 @@ salt myminion lxc.run_stderr mycontainer \(aqip addr show\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.run_stdout(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.run_stdout(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, path=None, ignore_retcode=False, chroot_fallback=False, keep_env=u\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.5.0. .sp @@ -167237,7 +178912,7 @@ The user to write the defaults to .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_defaults.write(domain, key, value, type=\(aqstring\(aq, user=None) +.B salt.modules.mac_defaults.write(domain, key, value, type=u\(aqstring\(aq, user=None) Write a default to the system .sp CLI Example: @@ -167526,7 +179201,7 @@ New in version 2016.3.0. .INDENT 0.0 .TP -.B salt.modules.mac_keychain.get_default_keychain(user=None, domain=\(aquser\(aq) +.B salt.modules.mac_keychain.get_default_keychain(user=None, domain=u\(aquser\(aq) Get the default keychain .INDENT 7.0 .TP @@ -167607,7 +179282,7 @@ salt \(aq*\(aq keychain.get_hash /tmp/test.p12 test123 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_keychain.install(cert, password, keychain=\(aq/Library/Keychains/System.keychain\(aq, allow_any=False, keychain_password=None) +.B salt.modules.mac_keychain.install(cert, password, keychain=u\(aq/Library/Keychains/System.keychain\(aq, allow_any=False, keychain_password=None) Install a certificate .INDENT 7.0 .TP @@ -167650,7 +179325,7 @@ salt \(aq*\(aq keychain.install test.p12 test123 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_keychain.list_certs(keychain=\(aq/Library/Keychains/System.keychain\(aq) +.B salt.modules.mac_keychain.list_certs(keychain=u\(aq/Library/Keychains/System.keychain\(aq) List all of the installed certificates .INDENT 7.0 .TP @@ -167673,7 +179348,7 @@ salt \(aq*\(aq keychain.list_certs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_keychain.set_default_keychain(keychain, domain=\(aquser\(aq, user=None) +.B salt.modules.mac_keychain.set_default_keychain(keychain, domain=u\(aquser\(aq, user=None) Set the default keychain .INDENT 7.0 .TP @@ -167701,7 +179376,7 @@ salt \(aq*\(aq keychain.set_keychain /Users/fred/Library/Keychains/login.keychai .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_keychain.uninstall(cert_name, keychain=\(aq/Library/Keychains/System.keychain\(aq, keychain_password=None) +.B salt.modules.mac_keychain.uninstall(cert_name, keychain=u\(aq/Library/Keychains/System.keychain\(aq, keychain_password=None) Uninstall a certificate from a keychain .INDENT 7.0 .TP @@ -167821,7 +179496,7 @@ salt \(aq*\(aq macpackage.get_pkg_id /tmp/test.pkg .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_package.install(pkg, target=\(aqLocalSystem\(aq, store=False, allow_untrusted=False) +.B salt.modules.mac_package.install(pkg, target=u\(aqLocalSystem\(aq, store=False, allow_untrusted=False) Install a pkg file .INDENT 7.0 .TP @@ -167859,7 +179534,7 @@ salt \(aq*\(aq macpackage.install test.pkg .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_package.install_app(app, target=\(aq/Applications/\(aq) +.B salt.modules.mac_package.install_app(app, target=u\(aq/Applications/\(aq) Install an app file by moving it into the specified Applications directory .INDENT 7.0 .TP @@ -169545,10 +181220,10 @@ salt \(aq*\(aq service.stop org.cups.cupsd .UNINDENT .SS salt.modules.mac_shadow module .sp +Manage macOS local directory passwords and policies +.sp New in version 2016.3.0. -.sp -Manage macOS local directory passwords and policies. .sp Note that it is usually better to apply password policies through the creation of a configuration profile. @@ -170608,7 +182283,7 @@ salt \(aq*\(aq sysctl.get hw.physmem .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_sysctl.persist(name, value, config=\(aq/etc/sysctl.conf\(aq, apply_change=False) +.B salt.modules.mac_sysctl.persist(name, value, config=u\(aq/etc/sysctl.conf\(aq, apply_change=False) Assign and persist a simple sysctl parameter for this minion .INDENT 7.0 .TP @@ -170659,11 +182334,10 @@ salt \(aq*\(aq sysctl.show .UNINDENT .SS salt.modules.mac_system module .sp +System module for sleeping, restarting, and shutting down the system on Mac OS X +.sp New in version 2016.3.0. -.sp -System module for sleeping, restarting, and shutting down the system on Mac OS -X. .sp \fBWARNING:\fP .INDENT 0.0 @@ -170967,7 +182641,7 @@ salt \(aq*\(aq system.restart \(aq12:00 PM fri\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_system.set_boot_arch(arch=\(aqdefault\(aq) +.B salt.modules.mac_system.set_boot_arch(arch=u\(aqdefault\(aq) Set the kernel to boot in 32 or 64 bit mode on next boot. .sp \fBNOTE:\fP @@ -171654,7 +183328,7 @@ salt \(aq*\(aq timezone.set_time \(aq"17:34"\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mac_timezone.set_time_server(time_server=\(aqtime.apple.com\(aq) +.B salt.modules.mac_timezone.set_time_server(time_server=u\(aqtime.apple.com\(aq) Designates a network time server. Enter the IP address or DNS name for the network time server. .INDENT 7.0 @@ -173405,6 +185079,138 @@ salt \(aq*\(aq makeconf.var_contains \(aqLINGUAS\(aq \(aqen\(aq .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.mandrill +.SS Mandrill +.sp +Send out emails using the \fI\%Mandrill\fP \fI\%API\fP\&. +.sp +In the minion configuration file, the following block is required: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +mandrill: + key: +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B salt.modules.mandrill.send(message, async=False, ip_pool=None, send_at=None, api_url=None, api_version=None, api_key=None) +Send out the email using the details from the \fBmessage\fP argument. +.INDENT 7.0 +.TP +.B message +The information on the message to send. This argument must be +sent as dictionary with at fields as specified in the Mandrill API +documentation. +.TP +.B async: \fBFalse\fP +Enable a background sending mode that is optimized for bulk sending. +In async mode, messages/send will immediately return a status of +"queued" for every recipient. To handle rejections when sending in async +mode, set up a webhook for the \(aqreject\(aq event. Defaults to false for +messages with no more than 10 recipients; messages with more than 10 +recipients are always sent asynchronously, regardless of the value of +async. +.TP +.B ip_pool +The name of the dedicated ip pool that should be used to send the +message. If you do not have any dedicated IPs, this parameter has no +effect. If you specify a pool that does not exist, your default pool +will be used instead. +.TP +.B send_at +When this message should be sent as a UTC timestamp in +\fBYYYY\-MM\-DD HH:MM:SS\fP format. If you specify a time in the past, +the message will be sent immediately. An additional fee applies for +scheduled email, and this feature is only available to accounts with a +positive balance. +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Fur further details please consult the \fI\%API documentation\fP\&. +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +$ salt \(aq*\(aq mandrill.send message="{\(aqsubject\(aq: \(aqHi\(aq, \(aqfrom_email\(aq: \(aqtest@example.com\(aq, \(aqto\(aq: [{\(aqemail\(aq: \(aqrecv@example.com\(aq, \(aqtype\(aq: \(aqto\(aq}]}" +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBmessage\fP structure example (as YAML for readability): +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +message: + text: | + This is the body of the email. + This is the second line. + subject: Email subject + from_name: Test At Example Dot Com + from_email: test@example.com + to: + \- email: recv@example.com + type: to + name: Recv At Example Dot Com + \- email: cc@example.com + type: cc + name: CC At Example Dot Com + important: true + track_clicks: true + track_opens: true + attachments: + \- type: text/x\-yaml + name: yaml_file.yml + content: aV9hbV9zdXBlcl9jdXJpb3VzOiB0cnVl +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Output example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +minion: + \-\-\-\-\-\-\-\-\-\- + comment: + out: + |_ + \-\-\-\-\-\-\-\-\-\- + _id: + c4353540a3c123eca112bbdd704ab6 + email: + recv@example.com + reject_reason: + None + status: + sent + result: + True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.marathon module .sp Module providing a simple management interface to a marathon cluster. @@ -173608,7 +185414,7 @@ salt \(aq*\(aq match.data \(aqspam:eggs\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.match.filter_by(lookup, tgt_type=\(aqcompound\(aq, minion_id=None, expr_form=None, default=\(aqdefault\(aq) +.B salt.modules.match.filter_by(lookup, tgt_type=u\(aqcompound\(aq, minion_id=None, expr_form=None, default=u\(aqdefault\(aq) Return the first match in a dictionary of target patterns .sp New in version 2014.7.0. @@ -173898,7 +185704,7 @@ Deprecated since version 2015.8.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.match.search_by(lookup, tgt_type=\(aqcompound\(aq, minion_id=None) +.B salt.modules.match.search_by(lookup, tgt_type=u\(aqcompound\(aq, minion_id=None) Search a dictionary of target strings for matching targets .sp This is the inverse of \fI\%match.filter_by\fP and allows matching values instead of @@ -174004,6 +185810,23 @@ salt \(aq*\(aq mattermost.post_message message=\(aqBuild is done" Salt module to manage RAID arrays with mdadm .INDENT 0.0 .TP +.B salt.modules.mdadm.add(name, device) +Add new device to RAID array. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq raid.add /dev/md0 /dev/sda1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.mdadm.assemble(name, devices, test_mode=False, **kwargs) Assemble a RAID device. .sp @@ -174052,7 +185875,7 @@ For more info, read the \fBmdadm\fP manpage. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mdadm.create(name, level, devices, metadata=\(aqdefault\(aq, test_mode=False, **kwargs) +.B salt.modules.mdadm.create(name, level, devices, metadata=u\(aqdefault\(aq, test_mode=False, **kwargs) Create a RAID device. .sp Changed in version 2014.7.0. @@ -174155,7 +185978,7 @@ salt \(aq*\(aq raid.destroy /dev/md0 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mdadm.detail(device=\(aq/dev/md0\(aq) +.B salt.modules.mdadm.detail(device=u\(aq/dev/md0\(aq) Show detail for a specified RAID device .sp CLI Example: @@ -174172,6 +185995,23 @@ salt \(aq*\(aq raid.detail \(aq/dev/md0\(aq .UNINDENT .INDENT 0.0 .TP +.B salt.modules.mdadm.examine(device) +Show detail for a specified RAID component device +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq raid.examine \(aq/dev/sda1\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.mdadm.list() List the RAID devices. .sp @@ -174351,7 +186191,7 @@ New in version 2014.1.0. .INDENT 0.0 .TP -.B salt.modules.memcached.add(key, value, host=\(aq127.0.0.1\(aq, port=11211, time=0, min_compress_len=0) +.B salt.modules.memcached.add(key, value, host=u\(aq127.0.0.1\(aq, port=11211, time=0, min_compress_len=0) Add a key to the memcached server, but only if it does not exist. Returns False if the key already exists. .sp @@ -174369,7 +186209,7 @@ salt \(aq*\(aq memcached.add .UNINDENT .INDENT 0.0 .TP -.B salt.modules.memcached.decrement(key, delta=1, host=\(aq127.0.0.1\(aq, port=11211) +.B salt.modules.memcached.decrement(key, delta=1, host=u\(aq127.0.0.1\(aq, port=11211) Decrement the value of a key .sp CLI Example: @@ -174387,7 +186227,7 @@ salt \(aq*\(aq memcached.decrement 2 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.memcached.delete(key, host=\(aq127.0.0.1\(aq, port=11211, time=0) +.B salt.modules.memcached.delete(key, host=u\(aq127.0.0.1\(aq, port=11211, time=0) Delete a key from memcache server .sp CLI Example: @@ -174404,7 +186244,7 @@ salt \(aq*\(aq memcached.delete .UNINDENT .INDENT 0.0 .TP -.B salt.modules.memcached.get(key, host=\(aq127.0.0.1\(aq, port=11211) +.B salt.modules.memcached.get(key, host=u\(aq127.0.0.1\(aq, port=11211) Retrieve value for a key .sp CLI Example: @@ -174421,7 +186261,7 @@ salt \(aq*\(aq memcached.get .UNINDENT .INDENT 0.0 .TP -.B salt.modules.memcached.increment(key, delta=1, host=\(aq127.0.0.1\(aq, port=11211) +.B salt.modules.memcached.increment(key, delta=1, host=u\(aq127.0.0.1\(aq, port=11211) Increment the value of a key .sp CLI Example: @@ -174439,7 +186279,7 @@ salt \(aq*\(aq memcached.increment 2 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.memcached.replace(key, value, host=\(aq127.0.0.1\(aq, port=11211, time=0, min_compress_len=0) +.B salt.modules.memcached.replace(key, value, host=u\(aq127.0.0.1\(aq, port=11211, time=0, min_compress_len=0) Replace a key on the memcached server. This only succeeds if the key already exists. This is the opposite of \fI\%memcached.add\fP .sp @@ -174457,7 +186297,7 @@ salt \(aq*\(aq memcached.replace .UNINDENT .INDENT 0.0 .TP -.B salt.modules.memcached.set(key, value, host=\(aq127.0.0.1\(aq, port=11211, time=0, min_compress_len=0) +.B salt.modules.memcached.set(key, value, host=u\(aq127.0.0.1\(aq, port=11211, time=0, min_compress_len=0) Set a key on the memcached server, overwriting the value if it exists. .sp CLI Example: @@ -174474,7 +186314,7 @@ salt \(aq*\(aq memcached.set .UNINDENT .INDENT 0.0 .TP -.B salt.modules.memcached.status(host=\(aq127.0.0.1\(aq, port=11211) +.B salt.modules.memcached.status(host=u\(aq127.0.0.1\(aq, port=11211) Get memcached status .sp CLI Example: @@ -174528,7 +186368,7 @@ salt \(aq*\(aq mine.flush .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mine.get(tgt, fun, tgt_type=\(aqglob\(aq, exclude_minion=False, expr_form=None) +.B salt.modules.mine.get(tgt, fun, tgt_type=u\(aqglob\(aq, exclude_minion=False, expr_form=None) Get data from the mine based on the target, function and tgt_type .sp Targets can be matched based on any standard matching system that can be @@ -174566,7 +186406,7 @@ CLI Example: .ft C salt \(aq*\(aq mine.get \(aq*\(aq network.interfaces salt \(aq*\(aq mine.get \(aqos:Fedora\(aq network.interfaces grain -salt \(aq*\(aq mine.get \(aqos:Fedora and S@192.168.5.0/24\(aq network.ipaddrs compound +salt \(aq*\(aq mine.get \(aqG@os:Fedora and S@192.168.5.0/24\(aq network.ipaddrs compound .ft P .fi .UNINDENT @@ -174903,7 +186743,7 @@ salt \(aq*\(aq random.get_str 128 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mod_random.hash(value, algorithm=\(aqsha512\(aq) +.B salt.modules.mod_random.hash(value, algorithm=u\(aqsha512\(aq) New in version 2014.7.0. .sp @@ -174986,7 +186826,7 @@ salt \(aq*\(aq random.seed 10 hash=None .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mod_random.shadow_hash(crypt_salt=None, password=None, algorithm=\(aqsha512\(aq) +.B salt.modules.mod_random.shadow_hash(crypt_salt=None, password=None, algorithm=u\(aqsha512\(aq) Generates a salted hash suitable for /etc/shadow. .INDENT 7.0 .TP @@ -175019,7 +186859,7 @@ salt \(aq*\(aq random.shadow_hash \(aqMy5alT\(aq \(aqMyP@asswd\(aq md5 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mod_random.str_encode(value, encoder=\(aqbase64\(aq) +.B salt.modules.mod_random.str_encode(value, encoder=u\(aqbase64\(aq) New in version 2014.7.0. .INDENT 7.0 @@ -175081,7 +186921,7 @@ modjk: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.bulk_activate(workers, lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.bulk_activate(workers, lbn, profile=u\(aqdefault\(aq) Activate all the given workers in the specific load balancer .sp CLI Examples: @@ -175102,7 +186942,7 @@ salt \(aq*\(aq modjk.bulk_activate ["node1","node2","node3"] loadbalancer1 other .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.bulk_disable(workers, lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.bulk_disable(workers, lbn, profile=u\(aqdefault\(aq) Disable all the given workers in the specific load balancer .sp CLI Examples: @@ -175123,7 +186963,7 @@ salt \(aq*\(aq modjk.bulk_disable ["node1","node2","node3"] loadbalancer1 other\ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.bulk_recover(workers, lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.bulk_recover(workers, lbn, profile=u\(aqdefault\(aq) Recover all the given workers in the specific load balancer .sp CLI Examples: @@ -175144,7 +186984,7 @@ salt \(aq*\(aq modjk.bulk_recover ["node1","node2","node3"] loadbalancer1 other\ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.bulk_stop(workers, lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.bulk_stop(workers, lbn, profile=u\(aqdefault\(aq) Stop all the given workers in the specific load balancer .sp CLI Examples: @@ -175165,7 +187005,7 @@ salt \(aq*\(aq modjk.bulk_stop ["node1","node2","node3"] loadbalancer1 other\-pr .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.dump_config(profile=\(aqdefault\(aq) +.B salt.modules.modjk.dump_config(profile=u\(aqdefault\(aq) Dump the original configuration that was loaded from disk .sp CLI Examples: @@ -175183,7 +187023,7 @@ salt \(aq*\(aq modjk.dump_config other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.get_running(profile=\(aqdefault\(aq) +.B salt.modules.modjk.get_running(profile=u\(aqdefault\(aq) Get the current running config (not from disk) .sp CLI Examples: @@ -175201,7 +187041,7 @@ salt \(aq*\(aq modjk.get_running other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.lb_edit(lbn, settings, profile=\(aqdefault\(aq) +.B salt.modules.modjk.lb_edit(lbn, settings, profile=u\(aqdefault\(aq) Edit the loadbalancer settings .sp Note: \fI\%http://tomcat.apache.org/connectors\-doc/reference/status.html\fP @@ -175222,7 +187062,7 @@ salt \(aq*\(aq modjk.lb_edit loadbalancer1 "{\(aqvlr\(aq: 1, \(aqvlt\(aq: 60}" o .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.list_configured_members(lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.list_configured_members(lbn, profile=u\(aqdefault\(aq) Return a list of member workers from the configuration files .sp CLI Examples: @@ -175240,7 +187080,7 @@ salt \(aq*\(aq modjk.list_configured_members loadbalancer1 other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.recover_all(lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.recover_all(lbn, profile=u\(aqdefault\(aq) Set the all the workers in lbn to recover and activate them if they are not .sp CLI Examples: @@ -175258,7 +187098,7 @@ salt \(aq*\(aq modjk.recover_all loadbalancer1 other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.reset_stats(lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.reset_stats(lbn, profile=u\(aqdefault\(aq) Reset all runtime statistics for the load balancer .sp CLI Examples: @@ -175276,7 +187116,7 @@ salt \(aq*\(aq modjk.reset_stats loadbalancer1 other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.version(profile=\(aqdefault\(aq) +.B salt.modules.modjk.version(profile=u\(aqdefault\(aq) Return the modjk version .sp CLI Examples: @@ -175294,7 +187134,7 @@ salt \(aq*\(aq modjk.version other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.worker_activate(worker, lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.worker_activate(worker, lbn, profile=u\(aqdefault\(aq) Set the worker to activate state in the lbn load balancer .sp CLI Examples: @@ -175312,7 +187152,7 @@ salt \(aq*\(aq modjk.worker_activate node1 loadbalancer1 other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.worker_disable(worker, lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.worker_disable(worker, lbn, profile=u\(aqdefault\(aq) Set the worker to disable state in the lbn load balancer .sp CLI Examples: @@ -175330,7 +187170,7 @@ salt \(aq*\(aq modjk.worker_disable node1 loadbalancer1 other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.worker_edit(worker, lbn, settings, profile=\(aqdefault\(aq) +.B salt.modules.modjk.worker_edit(worker, lbn, settings, profile=u\(aqdefault\(aq) Edit the worker settings .sp Note: \fI\%http://tomcat.apache.org/connectors\-doc/reference/status.html\fP @@ -175351,7 +187191,7 @@ salt \(aq*\(aq modjk.worker_edit node1 loadbalancer1 "{\(aqvwf\(aq: 500, \(aqvwd .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.worker_recover(worker, lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.worker_recover(worker, lbn, profile=u\(aqdefault\(aq) Set the worker to recover this module will fail if it is in OK state .sp @@ -175370,7 +187210,7 @@ salt \(aq*\(aq modjk.worker_recover node1 loadbalancer1 other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.worker_status(worker, profile=\(aqdefault\(aq) +.B salt.modules.modjk.worker_status(worker, profile=u\(aqdefault\(aq) Return the state of the worker .sp CLI Examples: @@ -175388,7 +187228,7 @@ salt \(aq*\(aq modjk.worker_status node1 other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.worker_stop(worker, lbn, profile=\(aqdefault\(aq) +.B salt.modules.modjk.worker_stop(worker, lbn, profile=u\(aqdefault\(aq) Set the worker to stopped state in the lbn load balancer .sp CLI Examples: @@ -175406,7 +187246,7 @@ salt \(aq*\(aq modjk.worker_activate node1 loadbalancer1 other\-profile .UNINDENT .INDENT 0.0 .TP -.B salt.modules.modjk.workers(profile=\(aqdefault\(aq) +.B salt.modules.modjk.workers(profile=u\(aqdefault\(aq) Return a list of member workers and their status .sp CLI Examples: @@ -175500,7 +187340,7 @@ salt \(aq*\(aq mongodb.db_remove .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mongodb.find(collection, query=None, user=None, password=None, host=None, port=None, database=\(aqadmin\(aq, authdb=None) +.B salt.modules.mongodb.find(collection, query=None, user=None, password=None, host=None, port=None, database=u\(aqadmin\(aq, authdb=None) Find an object or list of objects in a collection .sp CLI Example: @@ -175517,7 +187357,7 @@ salt \(aq*\(aq mongodb.find mycollection \(aq[{"foo": "FOO", "bar": "BAR"}]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mongodb.insert(objects, collection, user=None, password=None, host=None, port=None, database=\(aqadmin\(aq, authdb=None) +.B salt.modules.mongodb.insert(objects, collection, user=None, password=None, host=None, port=None, database=u\(aqadmin\(aq, authdb=None) Insert an object or list of objects into a collection .sp CLI Example: @@ -175534,7 +187374,7 @@ salt \(aq*\(aq mongodb.insert \(aq[{"foo": "FOO", "bar": "BAR"}, {"foo": "BAZ", .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mongodb.remove(collection, query=None, user=None, password=None, host=None, port=None, database=\(aqadmin\(aq, w=1, authdb=None) +.B salt.modules.mongodb.remove(collection, query=None, user=None, password=None, host=None, port=None, database=u\(aqadmin\(aq, w=1, authdb=None) Remove an object or list of objects into a collection .sp CLI Example: @@ -175551,7 +187391,7 @@ salt \(aq*\(aq mongodb.remove mycollection \(aq[{"foo": "FOO", "bar": "BAR"}, {" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mongodb.update_one(objects, collection, user=None, password=None, host=None, port=None, database=\(aqadmin\(aq, authdb=None) +.B salt.modules.mongodb.update_one(objects, collection, user=None, password=None, host=None, port=None, database=u\(aqadmin\(aq, authdb=None) Update an object into a collection \fI\%http://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.update_one\fP .sp @@ -175572,7 +187412,7 @@ salt \(aq*\(aq mongodb.update_one \(aq{"_id": "my_minion"} {"bar": "BAR"}\(aq my .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mongodb.user_create(name, passwd, user=None, password=None, host=None, port=None, database=\(aqadmin\(aq, authdb=None, roles=None) +.B salt.modules.mongodb.user_create(name, passwd, user=None, password=None, host=None, port=None, database=u\(aqadmin\(aq, authdb=None, roles=None) Create a Mongodb user .sp CLI Example: @@ -175589,7 +187429,7 @@ salt \(aq*\(aq mongodb.user_create

.UNINDENT .INDENT 0.0 .TP -.B salt.modules.mongodb.user_remove(name, user=None, password=None, host=None, port=None, database=\(aqadmin\(aq, authdb=None) +.B salt.modules.mongodb.user_remove(name, user=None, password=None, host=None, port=None, database=u\(aqadmin\(aq, authdb=None) Remove a Mongodb user .sp CLI Example: @@ -175738,7 +187578,7 @@ salt \(aq*\(aq mongodb.user_roles_exists johndoe \(aq[{"role": "readWrite", "db" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mongodb.version(user=None, password=None, host=None, port=None, database=\(aqadmin\(aq, authdb=None) +.B salt.modules.mongodb.version(user=None, password=None, host=None, port=None, database=u\(aqadmin\(aq, authdb=None) Get MongoDB instance version .sp CLI Example: @@ -175874,7 +187714,7 @@ salt \(aq*\(aq monit.start .UNINDENT .INDENT 0.0 .TP -.B salt.modules.monit.status(svc_name=\(aq\(aq) +.B salt.modules.monit.status(svc_name=u\(aq\(aq) Display a process status from monit .sp CLI Example: @@ -175909,7 +187749,7 @@ salt \(aq*\(aq monit.stop .UNINDENT .INDENT 0.0 .TP -.B salt.modules.monit.summary(svc_name=\(aq\(aq) +.B salt.modules.monit.summary(svc_name=u\(aq\(aq) Display a summary from monit .sp CLI Example: @@ -176076,7 +187916,7 @@ salt \(aq*\(aq mount.active .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.automaster(config=\(aq/etc/auto_salt\(aq) +.B salt.modules.mount.automaster(config=u\(aq/etc/auto_salt\(aq) List the contents of the auto master .sp CLI Example: @@ -176093,7 +187933,27 @@ salt \(aq*\(aq mount.automaster .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.fstab(config=\(aq/etc/fstab\(aq) +.B salt.modules.mount.delete_mount_cache(real_name) +New in version 2018.3.0. + +.sp +Provide information if the path is mounted +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq mount.delete_mount_cache /mnt/share +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.mount.fstab(config=u\(aq/etc/fstab\(aq) Changed in version 2016.3.2. .sp @@ -176150,7 +188010,7 @@ salt \(aq*\(aq mount.is_mounted /mnt/share .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.mount(name, device, mkmnt=False, fstype=\(aq\(aq, opts=\(aqdefaults\(aq, user=None, util=\(aqmount\(aq) +.B salt.modules.mount.mount(name, device, mkmnt=False, fstype=u\(aq\(aq, opts=u\(aqdefaults\(aq, user=None, util=u\(aqmount\(aq) Mount a device .sp CLI Example: @@ -176167,7 +188027,27 @@ salt \(aq*\(aq mount.mount /mnt/foo /dev/sdz1 True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.remount(name, device, mkmnt=False, fstype=\(aq\(aq, opts=\(aqdefaults\(aq, user=None) +.B salt.modules.mount.read_mount_cache(name) +New in version 2018.3.0. + +.sp +Provide information if the path is mounted +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq mount.read_mount_cache /mnt/share +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.mount.remount(name, device, mkmnt=False, fstype=u\(aq\(aq, opts=u\(aqdefaults\(aq, user=None) Attempt to remount a device, if the device is not already mounted, mount is called .sp @@ -176185,7 +188065,7 @@ salt \(aq*\(aq mount.remount /mnt/foo /dev/sdz1 True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.rm_automaster(name, device, config=\(aq/etc/auto_salt\(aq) +.B salt.modules.mount.rm_automaster(name, device, config=u\(aq/etc/auto_salt\(aq) Remove the mount point from the auto_master .sp CLI Example: @@ -176202,7 +188082,7 @@ salt \(aq*\(aq mount.rm_automaster /mnt/foo /dev/sdg .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.rm_fstab(name, device, config=\(aq/etc/fstab\(aq) +.B salt.modules.mount.rm_fstab(name, device, config=u\(aq/etc/fstab\(aq) Changed in version 2016.3.2. .sp @@ -176222,7 +188102,7 @@ salt \(aq*\(aq mount.rm_fstab /mnt/foo /dev/sdg .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.rm_vfstab(name, device, config=\(aq/etc/vfstab\(aq) +.B salt.modules.mount.rm_vfstab(name, device, config=u\(aq/etc/vfstab\(aq) New in version 2016.3.2. .sp @@ -176242,7 +188122,7 @@ salt \(aq*\(aq mount.rm_vfstab /mnt/foo /device/c0t0d0p0 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.set_automaster(name, device, fstype, opts=\(aq\(aq, config=\(aq/etc/auto_salt\(aq, test=False, **kwargs) +.B salt.modules.mount.set_automaster(name, device, fstype, opts=u\(aq\(aq, config=u\(aq/etc/auto_salt\(aq, test=False, **kwargs) Verify that this mount is represented in the auto_salt, change the mount to match the data passed, or add the mount if it is not present. .sp @@ -176260,7 +188140,7 @@ salt \(aq*\(aq mount.set_automaster /mnt/foo /dev/sdz1 ext4 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.set_fstab(name, device, fstype, opts=\(aqdefaults\(aq, dump=0, pass_num=0, config=\(aq/etc/fstab\(aq, test=False, match_on=\(aqauto\(aq, **kwargs) +.B salt.modules.mount.set_fstab(name, device, fstype, opts=u\(aqdefaults\(aq, dump=0, pass_num=0, config=u\(aq/etc/fstab\(aq, test=False, match_on=u\(aqauto\(aq, **kwargs) Verify that this mount is represented in the fstab, change the mount to match the data passed, or add the mount if it is not present. .sp @@ -176278,7 +188158,7 @@ salt \(aq*\(aq mount.set_fstab /mnt/foo /dev/sdz1 ext4 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.set_vfstab(name, device, fstype, opts=\(aq\-\(aq, device_fsck=\(aq\-\(aq, pass_fsck=\(aq\-\(aq, mount_at_boot=\(aqyes\(aq, config=\(aq/etc/vfstab\(aq, test=False, match_on=\(aqauto\(aq, **kwargs) +.B salt.modules.mount.set_vfstab(name, device, fstype, opts=u\(aq\-\(aq, device_fsck=u\(aq\-\(aq, pass_fsck=u\(aq\-\(aq, mount_at_boot=u\(aqyes\(aq, config=u\(aq/etc/vfstab\(aq, test=False, match_on=u\(aqauto\(aq, **kwargs) \&..verionadded:: 2016.3.2 Verify that this mount is represented in the fstab, change the mount to match the data passed, or add the mount if it is not present. @@ -176357,7 +188237,7 @@ salt \(aq*\(aq mount.swaps .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.umount(name, device=None, user=None, util=\(aqmount\(aq) +.B salt.modules.mount.umount(name, device=None, user=None, util=u\(aqmount\(aq) Attempt to unmount a device by specifying the directory it is mounted on .sp CLI Example: @@ -176387,7 +188267,7 @@ salt \(aq*\(aq mount.umount /mnt/foo /dev/xvdc1 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mount.vfstab(config=\(aq/etc/vfstab\(aq) +.B salt.modules.mount.vfstab(config=u\(aq/etc/vfstab\(aq) New in version 2016.3.2. .sp @@ -176405,6 +188285,45 @@ salt \(aq*\(aq mount.vfstab .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.mount.write_mount_cache(real_name, device, mkmnt, fstype, mount_opts) +New in version 2018.3.0. + +.sp +Provide information if the path is mounted +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBreal_name\fP \-\- The real name of the mount point where the device is mounted. +.IP \(bu 2 +\fBdevice\fP \-\- The device that is being mounted. +.IP \(bu 2 +\fBmkmnt\fP \-\- Whether or not the mount point should be created. +.IP \(bu 2 +\fBfstype\fP \-\- The file system that is used. +.IP \(bu 2 +\fBmount_opts\fP \-\- Additional options used when mounting the device. +.UNINDENT +.TP +.B Returns +Boolean if message was sent successfully. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq mount.write_mount_cache /mnt/share /dev/sda1 False ext4 defaults,nosuid +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.mssql .sp Module to provide MS SQL Server compatibility to salt. @@ -176444,6 +188363,21 @@ configs or pillars. .UNINDENT .INDENT 0.0 .TP +.B salt.modules.mssql.db_create(database, containment=u\(aqNONE\(aq, new_database_options=None, **kwargs) +Creates a new database. +Does not update options of existing databases. +new_database_options can only be a list of strings +.sp +CLI Example: +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +salt minion mssql.db_create DB_NAME +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.mssql.db_exists(database_name, **kwargs) Find if a specific database exists on the MS SQL server. .sp @@ -176496,8 +188430,30 @@ salt minion mssql.db_remove database_name=\(aqDBNAME\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mssql.login_exists(login, **kwargs) +.B salt.modules.mssql.login_create(login, new_login_password=None, new_login_domain=u\(aq\(aq, new_login_roles=None, new_login_options=None, **kwargs) +Creates a new login. +Does not update password of existing logins. +For Windows authentication, provide new_login_domain. +For SQL Server authentication, prvide new_login_password. +Since hashed passwords are varbinary values, if the +new_login_password is \(aqint / long\(aq, it will be considered +to be HASHED. +new_login_roles can only be a list of SERVER roles +new_login_options can only be a list of strings +.sp +CLI Example: +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +salt minion mssql.login_create LOGIN_NAME database=DBNAME [new_login_password=PASSWORD] +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.mssql.login_exists(login, domain=u\(aq\(aq, **kwargs) Find if a login exists in the MS SQL server. +domain, if provided, will be prepended to login .sp CLI Example: .INDENT 7.0 @@ -176513,10 +188469,8 @@ salt minion mssql.login_exists \(aqLOGIN\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mssql.role_create(role, owner=None, **kwargs) -Creates a new database role. -If no owner is specified, the role will be owned by the user that -executes CREATE ROLE, which is the user argument or mssql.user option. +.B salt.modules.mssql.login_remove(login, **kwargs) +Removes an login. .sp CLI Example: .INDENT 7.0 @@ -176524,7 +188478,27 @@ CLI Example: .sp .nf .ft C -salt minion mssql.role_create role=product01 owner=sysdba +salt minion mssql.login_remove LOGINNAME +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.mssql.role_create(role, owner=None, grants=None, **kwargs) +Creates a new database role. +If no owner is specified, the role will be owned by the user that +executes CREATE ROLE, which is the user argument or mssql.user option. +grants is list of strings. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt minion mssql.role_create role=product01 owner=sysdba grants=\(aq["SELECT", "INSERT", "UPDATE", "DELETE", "EXECUTE"]\(aq .ft P .fi .UNINDENT @@ -176600,33 +188574,25 @@ salt minion mssql.tsql_query \(aqSELECT @@version as version\(aq as_dict=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mssql.user_create(username, new_login_password=None, **kwargs) +.B salt.modules.mssql.user_create(username, login=None, domain=u\(aq\(aq, database=None, roles=None, options=None, **kwargs) Creates a new user. -If new_login_password is not specified, the user will be created without a login. +If login is not specified, the user will be created without a login. +domain, if provided, will be prepended to username. +options can only be a list of strings .sp CLI Example: +.. code\-block:: bash .INDENT 7.0 .INDENT 3.5 -.sp -.nf -.ft C -salt minion mssql.user_create USERNAME database=DBNAME [new_login_password=PASSWORD] -.ft P -.fi +salt minion mssql.user_create USERNAME database=DBNAME .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mssql.user_exists(username, **kwargs) +.B salt.modules.mssql.user_exists(username, domain=u\(aq\(aq, database=None, **kwargs) Find if an user exists in a specific database on the MS SQL server. -.sp -\fBNOTE:\fP -.INDENT 7.0 -.INDENT 3.5 -\fIdatabase\fP argument is mandatory -.UNINDENT -.UNINDENT +domain, if provided, will be prepended to username .sp CLI Example: .INDENT 7.0 @@ -177201,7 +189167,7 @@ salt \(aq*\(aq mysql.get_slave_status .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mysql.grant_add(grant, database, user, host=\(aqlocalhost\(aq, grant_option=False, escape=True, ssl_option=False, **connection_args) +.B salt.modules.mysql.grant_add(grant, database, user, host=u\(aqlocalhost\(aq, grant_option=False, escape=True, ssl_option=False, **connection_args) Adds a grant to the MySQL server. .sp For database, make sure you specify database.table or database.* @@ -177220,7 +189186,7 @@ salt \(aq*\(aq mysql.grant_add \(aqSELECT,INSERT,UPDATE,...\(aq \(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mysql.grant_exists(grant, database, user, host=\(aqlocalhost\(aq, grant_option=False, escape=True, **connection_args) +.B salt.modules.mysql.grant_exists(grant, database, user, host=u\(aqlocalhost\(aq, grant_option=False, escape=True, **connection_args) Checks to see if a grant exists in the database .sp CLI Example: @@ -177237,7 +189203,7 @@ salt \(aq*\(aq mysql.grant_exists \(aqSELECT,INSERT,UPDATE,...\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mysql.grant_revoke(grant, database, user, host=\(aqlocalhost\(aq, grant_option=False, escape=True, **connection_args) +.B salt.modules.mysql.grant_revoke(grant, database, user, host=u\(aqlocalhost\(aq, grant_option=False, escape=True, **connection_args) Removes a grant from the MySQL server. .sp CLI Example: @@ -177545,7 +189511,7 @@ salt \(aq*\(aq mysql.tokenize_grant "GRANT SELECT, INSERT ON testdb. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mysql.user_chpass(user, host=\(aqlocalhost\(aq, password=None, password_hash=None, allow_passwordless=False, unix_socket=None, password_column=None, **connection_args) +.B salt.modules.mysql.user_chpass(user, host=u\(aqlocalhost\(aq, password=None, password_hash=None, allow_passwordless=False, unix_socket=None, password_column=None, **connection_args) Change password for a MySQL user .INDENT 7.0 .TP @@ -177601,7 +189567,7 @@ salt \(aq*\(aq mysql.user_chpass frank localhost allow_passwordless=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mysql.user_create(user, host=\(aqlocalhost\(aq, password=None, password_hash=None, allow_passwordless=False, unix_socket=False, password_column=None, **connection_args) +.B salt.modules.mysql.user_create(user, host=u\(aqlocalhost\(aq, password=None, password_hash=None, allow_passwordless=False, unix_socket=False, password_column=None, **connection_args) Creates a MySQL user .INDENT 7.0 .TP @@ -177660,7 +189626,7 @@ salt \(aq*\(aq mysql.user_create \(aqusername\(aq \(aqhostname\(aq allow_passwor .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mysql.user_exists(user, host=\(aqlocalhost\(aq, password=None, password_hash=None, passwordless=False, unix_socket=False, password_column=None, **connection_args) +.B salt.modules.mysql.user_exists(user, host=u\(aqlocalhost\(aq, password=None, password_hash=None, passwordless=False, unix_socket=False, password_column=None, **connection_args) Checks if a user exists on the MySQL server. A login can be checked to see if passwordless login is permitted by omitting \fBpassword\fP and \fBpassword_hash\fP, and using \fBpasswordless=True\fP\&. @@ -177685,7 +189651,7 @@ salt \(aq*\(aq mysql.user_exists \(aqusername\(aq password_column=\(aqauthentica .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mysql.user_grants(user, host=\(aqlocalhost\(aq, **connection_args) +.B salt.modules.mysql.user_grants(user, host=u\(aqlocalhost\(aq, **connection_args) Shows the grants for the given MySQL user (if it exists) .sp CLI Example: @@ -177702,7 +189668,7 @@ salt \(aq*\(aq mysql.user_grants \(aqfrank\(aq \(aqlocalhost\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mysql.user_info(user, host=\(aqlocalhost\(aq, **connection_args) +.B salt.modules.mysql.user_info(user, host=u\(aqlocalhost\(aq, **connection_args) Get full info on a MySQL user .sp CLI Example: @@ -177736,7 +189702,7 @@ salt \(aq*\(aq mysql.user_list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.mysql.user_remove(user, host=\(aqlocalhost\(aq, **connection_args) +.B salt.modules.mysql.user_remove(user, host=u\(aqlocalhost\(aq, **connection_args) Delete MySQL user .sp CLI Example: @@ -177784,28 +189750,79 @@ regardless if they are encrypted or not. .sp When generating keys and encrypting passwords use \-\-local when using salt\-call for extra security. Also consider using just the salt runner nacl when encrypting pillar passwords. -.sp -The nacl lib uses 32byte keys, these keys are base64 encoded to make your life more simple. -To generate your \fIkey\fP or \fIkeyfile\fP you can use: .INDENT 0.0 +.TP +.B configuration +The following configuration defaults can be +define (pillar or config files) Avoid storing private keys in pillars! Ensure master does not have \fIpillar_opts=True\fP: +.INDENT 7.0 .INDENT 3.5 .sp .nf .ft C -salt\-call \-\-local nacl.keygen keyfile=/root/.nacl +# cat /etc/salt/master.d/nacl.conf +nacl.config: + # NOTE: \(gakey\(ga and \(gakey_file\(ga have been renamed to \(gask\(ga, \(gask_file\(ga + # also \(gabox_type\(ga default changed from secretbox to sealedbox. + box_type: sealedbox (default) + sk_file: /etc/salt/pki/master/nacl (default) + pk_file: /etc/salt/pki/master/nacl.pub (default) + sk: None + pk: None .ft P .fi .UNINDENT .UNINDENT .sp -Now with your key, you can encrypt some data: +Usage can override the config defaults: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call nacl.enc sk_file=/etc/salt/pki/master/nacl pk_file=/etc/salt/pki/master/nacl.pub +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.sp +The nacl lib uses 32byte keys, these keys are base64 encoded to make your life more simple. +To generate your \fIsk_file\fP and \fIpk_file\fP use: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt\-call \-\-local nacl.enc mypass keyfile=/root/.nacl -DRB7Q6/X5gGSRCTpZyxS6hXO5LnlJIIJ4ivbmUlbWj0llUA+uaVyvou3vJ4= +salt\-call \-\-local nacl.keygen sk_file=/etc/salt/pki/master/nacl +# or if you want to work without files. +salt\-call \-\-local nacl.keygen +local: + \-\-\-\-\-\-\-\-\-\- + pk: + /kfGX7PbWeu099702PBbKWLpG/9p06IQRswkdWHCDk0= + sk: + SVWut5SqNpuPeNzb1b9y6b2eXg2PLIog43GBzp48Sow= +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Now with your keypair, you can encrypt data: +.sp +You have two option, \fIsealedbox\fP or \fIsecretbox\fP\&. +.sp +SecretBox is data encrypted using private key \fIpk\fP\&. Sealedbox is encrypted using public key \fIpk\fP\&. +.sp +Recommend using Sealedbox because the one way encryption permits developers to encrypt data for source control but not decrypt. +Sealedbox only has one key that is for both encryption and decryption. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.enc asecretpass pk=/kfGX7PbWeu099702PBbKWLpG/9p06IQRswkdWHCDk0= +tqXzeIJnTAM9Xf0mdLcpEdklMbfBGPj2oTKmlgrm3S1DTVVHNnh9h8mU1GKllGq/+cYsk6m5WhGdk58= .ft P .fi .UNINDENT @@ -177817,42 +189834,64 @@ To decrypt the data: .sp .nf .ft C -salt\-call \-\-local nacl.dec data=\(aqDRB7Q6/X5gGSRCTpZyxS6hXO5LnlJIIJ4ivbmUlbWj0llUA+uaVyvou3vJ4=\(aq keyfile=/root/.nacl -mypass +salt\-call \-\-local nacl.dec data=\(aqtqXzeIJnTAM9Xf0mdLcpEdklMbfBGPj2oTKmlgrm3S1DTVVHNnh9h8mU1GKllGq/+cYsk6m5WhGdk58=\(aq sk=\(aqSVWut5SqNpuPeNzb1b9y6b2eXg2PLIog43GBzp48Sow=\(aq .ft P .fi .UNINDENT .UNINDENT .sp -The following optional configurations can be defined in the -minion or master config. Avoid storing the config in pillars! +When the keys are defined in the master config you can use them from the nacl runner +without extra parameters: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -cat /etc/salt/master.d/nacl.conf +# cat /etc/salt/master.d/nacl.conf nacl.config: - key: \(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k=\(aq - keyfile: /root/.nacl + sk_file: /etc/salt/pki/master/nacl + pk: \(aqcTIqXwnUiD1ulg4kXsbeCE7/NoeKEzd4nLeYcCFpd9k=\(aq .ft P .fi .UNINDENT .UNINDENT -.sp -When the key is defined in the master config you can use it from the nacl runner: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt\-run nacl.enc \(aqmyotherpass\(aq +salt\-run nacl.enc \(aqasecretpass\(aq +salt\-run nacl.dec \(aqtqXzeIJnTAM9Xf0mdLcpEdklMbfBGPj2oTKmlgrm3S1DTVVHNnh9h8mU1GKllGq/+cYsk6m5WhGdk58=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# a salt developers minion could have pillar data that includes a nacl public key +nacl.config: + pk: \(aq/kfGX7PbWeu099702PBbKWLpG/9p06IQRswkdWHCDk0=\(aq .ft P .fi .UNINDENT .UNINDENT .sp -Now you can create a pillar with protected data like: +The developer can then use a less\-secure system to encrypt data. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.enc apassword +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Pillar files can include protected data that the salt master decrypts: .INDENT 0.0 .INDENT 3.5 .sp @@ -177860,81 +189899,98 @@ Now you can create a pillar with protected data like: .ft C pillarexample: user: root - password: {{ salt.nacl.dec(\(aqDRB7Q6/X5gGSRCTpZyxS6hXO5LnlJIIJ4ivbmUlbWj0llUA+uaVyvou3vJ4=\(aq) }} + password1: {{salt.nacl.dec(\(aqDRB7Q6/X5gGSRCTpZyxS6hlbWj0llUA+uaVyvou3vJ4=\(aq)|json}} + cert_key: {{salt.nacl.dec_file(\(aq/srv/salt/certs/example.com/key.nacl\(aq)|json}} + cert_key2: {{salt.nacl.dec_file(\(aqsalt:///certs/example.com/key.nacl\(aq)|json}} .ft P .fi .UNINDENT .UNINDENT .sp -Or do something interesting with grains like: +Larger files like certificates can be encrypted with: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt\-call nacl.enc minionname:dbrole -AL24Z2C5OlkReer3DuQTFdrNLchLuz3NGIhGjZkLtKRYry/b/CksWM8O9yskLwH2AGVLoEXI5jAa - -salt minionname grains.setval role \(aqAL24Z2C5OlkReer3DuQTFdrNLchLuz3NGIhGjZkLtKRYry/b/CksWM8O9yskLwH2AGVLoEXI5jAa\(aq - -{%\- set r = grains.get(\(aqrole\(aq) %} -{%\- set role = None %} -{%\- if r and \(aqnacl.dec\(aq in salt %} - {%\- set r = salt[\(aqnacl.dec\(aq](r,keyfile=\(aq/root/.nacl\(aq).split(\(aq:\(aq) %} - {%\- if opts[\(aqid\(aq] == r[0] %} - {%\- set role = r[1] %} - {%\- endif %} -{%\- endif %} -base: - {%\- if role %} - \(aq{{ opts[\(aqid\(aq] }}\(aq: - \- {{ role }} - {%\- endif %} +salt\-call nacl.enc_file /tmp/cert.crt out=/tmp/cert.nacl +# or more advanced +cert=$(cat /tmp/cert.crt) +salt\-call \-\-out=newline_values_only nacl.enc_pub data="$cert" > /tmp/cert.nacl .ft P .fi .UNINDENT .UNINDENT .sp -Multi\-line text items like certificates require a bit of extra work. You have to strip the new lines -and replace them with \(aq/n\(aq characters. Certificates specifically require some leading white space when -calling nacl.enc so that the \(aq\-\-\(aq in the first line (commonly \-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\-) doesn\(aqt get -interpreted as an argument to nacl.enc. For instance if you have a certificate file that lives in cert.crt: +In pillars rended with jinja be sure to include \fI|json\fP so line breaks are encoded: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -cert=$(cat cert.crt |awk \(aq{printf "%s\en",$0} END {print ""}\(aq); salt\-run nacl.enc " $cert" +cert: "{{salt.nacl.dec(\(aqS2uogToXkgENz9...085KYt\(aq)|json}}" .ft P .fi .UNINDENT .UNINDENT .sp -Pillar data should look the same, even though the secret will be quite long. However, when calling -multiline encrypted secrets from pillar in a state, use the following format to avoid issues with /n -creating extra whitespace at the beginning of each line in the cert file: +In states rendered with jinja it is also good pratice to include \fI|json\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -secret.txt: +{{sls}} private key: file.managed: - \- template: jinja - \- user: user - \- group: group + \- name: /etc/ssl/private/cert.key \- mode: 700 - \- contents: "{{\- salt[\(aqpillar.get\(aq](\(aqsecret\(aq) }}" + \- contents: "{{pillar[\(aqpillarexample\(aq][\(aqcert_key\(aq]|json}}" .ft P .fi .UNINDENT .UNINDENT .sp -The \(aq{{\-\(aq will tell jinja to strip the whitespace from the beginning of each of the new lines. +Optional small program to encrypt data without needing salt modules. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +#!/bin/python3 +import sys, base64, libnacl.sealed +pk = base64.b64decode(\(aqYOURPUBKEY\(aq) +b = libnacl.sealed.SealedBox(pk) +data = sys.stdin.buffer.read() +print(base64.b64encode(b.encrypt(data)).decode()) +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +echo \(aqapassword\(aq | nacl_enc.py +.ft P +.fi +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.modules.nacl.dec(data, **kwargs) -Takes a key generated from \fInacl.keygen\fP and decrypt some data. +Alias to \fI{box_type}_decrypt\fP +.sp +box_type: secretbox, sealedbox(default) +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nacl.dec_file(name, out=None, **kwargs) +This is a helper function to decrypt a file and return its contents. +.sp +You can provide an optional output file using \fIout\fP +.sp +\fIname\fP can be a local file or when not using \fIsalt\-run\fP can be a url like \fIsalt://\fP, \fIhttps://\fP etc. .sp CLI Examples: .INDENT 7.0 @@ -177942,9 +189998,9 @@ CLI Examples: .sp .nf .ft C -salt\-call \-\-local nacl.dec pEXHQM6cuaF7A= -salt\-call \-\-local nacl.dec data=\(aqpEXHQM6cuaF7A=\(aq keyfile=/root/.nacl -salt\-call \-\-local nacl.dec data=\(aqpEXHQM6cuaF7A=\(aq key=\(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k=\(aq +salt\-run nacl.dec_file name=/tmp/id_rsa.nacl +salt\-call nacl.dec_file name=salt://crt/mycert.nacl out=/tmp/id_rsa +salt\-run nacl.dec_file name=/tmp/id_rsa.nacl box_type=secretbox sk_file=/etc/salt/pki/master/nacl.pub .ft P .fi .UNINDENT @@ -177953,7 +190009,18 @@ salt\-call \-\-local nacl.dec data=\(aqpEXHQM6cuaF7A=\(aq key=\(aqcKEzd4kXsbeCE7 .INDENT 0.0 .TP .B salt.modules.nacl.enc(data, **kwargs) -Takes a key generated from \fInacl.keygen\fP and encrypt some data. +Alias to \fI{box_type}_encrypt\fP +.sp +box_type: secretbox, sealedbox(default) +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nacl.enc_file(name, out=None, **kwargs) +This is a helper function to encrypt a file and return its contents. +.sp +You can provide an optional output file using \fIout\fP +.sp +\fIname\fP can be a local file or when not using \fIsalt\-run\fP can be a url like \fIsalt://\fP, \fIhttps://\fP etc. .sp CLI Examples: .INDENT 7.0 @@ -177961,9 +190028,9 @@ CLI Examples: .sp .nf .ft C -salt\-call \-\-local nacl.enc datatoenc -salt\-call \-\-local nacl.enc datatoenc keyfile=/root/.nacl -salt\-call \-\-local nacl.enc datatoenc key=\(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k=\(aq +salt\-run nacl.enc_file name=/tmp/id_rsa +salt\-call nacl.enc_file name=salt://crt/mycert out=/tmp/cert +salt\-run nacl.enc_file name=/tmp/id_rsa box_type=secretbox sk_file=/etc/salt/pki/master/nacl.pub .ft P .fi .UNINDENT @@ -177971,8 +190038,15 @@ salt\-call \-\-local nacl.enc datatoenc key=\(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4N .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nacl.keygen(keyfile=None) -Use libnacl to generate a private key +.B salt.modules.nacl.keygen(sk_file=None, pk_file=None) +Use libnacl to generate a keypair. +.sp +If no \fIsk_file\fP is defined return a keypair. +.sp +If only the \fIsk_file\fP is defined \fIpk_file\fP will use the same name with a postfix \fI\&.pub\fP\&. +.sp +When the \fIsk_file\fP is already existing, but \fIpk_file\fP is not. The \fIpk_file\fP will be generated +using the \fIsk_file\fP\&. .sp CLI Examples: .INDENT 7.0 @@ -177980,9 +190054,89 @@ CLI Examples: .sp .nf .ft C +salt\-call nacl.keygen +salt\-call nacl.keygen sk_file=/etc/salt/pki/master/nacl +salt\-call nacl.keygen sk_file=/etc/salt/pki/master/nacl pk_file=/etc/salt/pki/master/nacl.pub salt\-call \-\-local nacl.keygen -salt\-call \-\-local nacl.keygen keyfile=/root/.nacl -salt\-call \-\-local \-\-out=newline_values_only nacl.keygen > /root/.nacl +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nacl.sealedbox_decrypt(data, **kwargs) +Decrypt data using a secret key that was encrypted using a public key with \fInacl.sealedbox_encrypt\fP\&. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call nacl.sealedbox_decrypt pEXHQM6cuaF7A= +salt\-call \-\-local nacl.sealedbox_decrypt data=\(aqpEXHQM6cuaF7A=\(aq sk_file=/etc/salt/pki/master/nacl +salt\-call \-\-local nacl.sealedbox_decrypt data=\(aqpEXHQM6cuaF7A=\(aq sk=\(aqYmFkcGFzcwo=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nacl.sealedbox_encrypt(data, **kwargs) +Encrypt data using a public key generated from \fInacl.keygen\fP\&. +The encryptd data can be decrypted using \fInacl.sealedbox_decrypt\fP only with the secret key. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run nacl.sealedbox_encrypt datatoenc +salt\-call \-\-local nacl.sealedbox_encrypt datatoenc pk_file=/etc/salt/pki/master/nacl.pub +salt\-call \-\-local nacl.sealedbox_encrypt datatoenc pk=\(aqvrwQF7cNiNAVQVAiS3bvcbJUnF0cN6fU9YTZD9mBfzQ=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nacl.secretbox_decrypt(data, **kwargs) +Decrypt data that was encrypted using \fInacl.secretbox_encrypt\fP using the secret key +that was generated from \fInacl.keygen\fP\&. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call nacl.secretbox_decrypt pEXHQM6cuaF7A= +salt\-call \-\-local nacl.secretbox_decrypt data=\(aqpEXHQM6cuaF7A=\(aq sk_file=/etc/salt/pki/master/nacl +salt\-call \-\-local nacl.secretbox_decrypt data=\(aqpEXHQM6cuaF7A=\(aq sk=\(aqYmFkcGFzcwo=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nacl.secretbox_encrypt(data, **kwargs) +Encrypt data using a secret key generated from \fInacl.keygen\fP\&. +The same secret key can be used to decrypt the data using \fInacl.secretbox_decrypt\fP\&. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run nacl.secretbox_encrypt datatoenc +salt\-call \-\-local nacl.secretbox_encrypt datatoenc sk_file=/etc/salt/pki/master/nacl +salt\-call \-\-local nacl.secretbox_encrypt datatoenc sk=\(aqYmFkcGFzcwo=\(aq .ft P .fi .UNINDENT @@ -178010,7 +190164,7 @@ salt \(aq*\(aq nagios.list_plugins .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nagios.retcode(plugin, args=\(aq\(aq, key_name=None) +.B salt.modules.nagios.retcode(plugin, args=u\(aq\(aq, key_name=None) Run one nagios plugin and return retcode of the execution .UNINDENT .INDENT 0.0 @@ -178058,7 +190212,7 @@ salt \(aq*\(aq nagios.retcode webserver .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nagios.run(plugin, args=\(aq\(aq) +.B salt.modules.nagios.run(plugin, args=u\(aq\(aq) Run nagios plugin and return all the data execution with cmd.run .sp CLI Example: @@ -178076,7 +190230,7 @@ salt \(aq*\(aq nagios.run check_icmp \(aq8.8.8.8\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nagios.run_all(plugin, args=\(aq\(aq) +.B salt.modules.nagios.run_all(plugin, args=u\(aq\(aq) Run nagios plugin and return all the data execution with cmd.run_all .UNINDENT .INDENT 0.0 @@ -178244,6 +190398,8 @@ salt \(aq*\(aq nagios_rpc.service_status hostname=webserver.domain.com service=\ .UNINDENT .SS salt.modules.namecheap_dns module .sp +Namecheap dns management +.sp Use this module to manage dns through the namecheap api. The Namecheap settings will be set in grains. .INDENT 0.0 @@ -178449,15 +190605,14 @@ salt \(aqmy\-minion\(aq namecheap_domains_dns.set_hosts sld tld hosts .UNINDENT .SS salt.modules.namecheap_domains module .sp -Namecheap management -.sp +Namecheap domains management +.INDENT 0.0 +.INDENT 3.5 New in version 2017.7.0. -.SS General Notes .sp Use this module to manage domains through the namecheap api. The Namecheap settings will be set in grains. -.SS Installation Prerequisites .INDENT 0.0 .IP \(bu 2 This module uses the following python libraries to communicate to @@ -178483,7 +190638,6 @@ pip install requests .IP \(bu 2 As saltstack depends on \fBrequests\fP this shouldn\(aqt be a problem .UNINDENT -.SS Prerequisite Configuration .INDENT 0.0 .IP \(bu 2 The namecheap username, api key and url should be set in a minion @@ -178505,6 +190659,8 @@ namecheap.url: https://api.namecheap.com/xml.response .UNINDENT .UNINDENT .UNINDENT +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.modules.namecheap_domains.check(*domains_to_check) @@ -178665,6 +190821,16 @@ transactionid unique integer value for the transaction .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq namecheap_domains.reactivate my\-domain\-name +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -178701,6 +190867,8 @@ salt \(aqmy\-minion\(aq namecheap_domains.renew my\-domain\-name 5 .UNINDENT .SS salt.modules.namecheap_ns module .sp +Namecheap nameservers management +.sp Use this module to manage nameservers through the namecheap api. The Namecheap settings will be set in grains. .INDENT 0.0 @@ -178884,15 +191052,14 @@ salt \(aq*\(aq namecheap_domains_ns.update sld tld nameserver old_ip new_ip .UNINDENT .SS salt.modules.namecheap_ssl module .sp -Namecheap management -.sp +Namecheap ssl management +.INDENT 0.0 +.INDENT 3.5 New in version 2017.7.0. -.SS General Notes .sp Use this module to manage ssl certificates through the namecheap api. The Namecheap settings will be set in grains. -.SS Installation Prerequisites .INDENT 0.0 .IP \(bu 2 This module uses the following python libraries to communicate to @@ -178918,7 +191085,6 @@ pip install requests .IP \(bu 2 As saltstack depends on \fBrequests\fP this shouldn\(aqt be a problem .UNINDENT -.SS Prerequisite Configuration .INDENT 0.0 .IP \(bu 2 The namecheap username, api key and url should be set in a minion @@ -178940,6 +191106,8 @@ namecheap.url: https://api.namecheap.com/xml.response .UNINDENT .UNINDENT .UNINDENT +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.modules.namecheap_ssl.activate(csr_file, certificate_id, web_server_type, approver_email=None, http_dc_validation=False, **kwargs) @@ -178998,6 +191166,16 @@ please see \fI\%https://www.namecheap.com/support/api/methods/ssl/activate.aspx\ .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq namecheap_ssl.activate my\-csr\-file my\-cert\-id apachessl +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -179155,6 +191333,16 @@ Pro .INDENT 7.0 .INDENT 3.5 CLI Example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq namecheap_ssl.create 2 RapidSSL +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .UNINDENT .UNINDENT @@ -179188,6 +191376,16 @@ Required if returncertificate is True .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq namecheap_ssl.get_info my\-cert\-id +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -179245,6 +191443,16 @@ Host_Name,Host_Name_DESC .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq namecheap_ssl.get_list Processing +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -179300,6 +191508,16 @@ instead of emails and to return the info to do so .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq namecheap_ssl.parse_csr my\-csr\-file PremiumSSL +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -179359,6 +191577,16 @@ please see \fI\%https://www.namecheap.com/support/api/methods/ssl/reissue.aspx\f .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq namecheap_ssl.reissue my\-csr\-file my\-cert\-id apachessl +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -179415,18 +191643,27 @@ string Promotional (coupon) code for the certificate .UNINDENT .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqmy\-minion\(aq namecheap_ssl.renew 1 my\-cert\-id RapidSSL +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .SS salt.modules.namecheap_users module .sp -Namecheap management -.sp +Namecheap users management +.INDENT 0.0 +.INDENT 3.5 New in version 2017.7.0. -.SS General Notes .sp Use this module to manage users through the namecheap api. The Namecheap settings will be set in grains. -.SS Installation Prerequisites .INDENT 0.0 .IP \(bu 2 This module uses the following python libraries to communicate to @@ -179452,7 +191689,6 @@ pip install requests .IP \(bu 2 As saltstack depends on \fBrequests\fP this shouldn\(aqt be a problem .UNINDENT -.SS Prerequisite Configuration .INDENT 0.0 .IP \(bu 2 The namecheap username, api key and url should be set in a minion @@ -179474,6 +191710,8 @@ namecheap.url: https://api.namecheap.com/xml.response .UNINDENT .UNINDENT .UNINDENT +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.modules.namecheap_users.check_balances(minimum=100) @@ -179738,7 +191976,7 @@ it requires \fI\%NAPALM\fP library to be installed: \fBpip install napalm\fP\&. Please check \fI\%Installation\fP for complete details. .INDENT 0.0 .TP -.B salt.modules.napalm_acl.get_filter_pillar(filter_name, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None) +.B salt.modules.napalm_acl.get_filter_pillar(filter_name, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None) Helper that can be used inside a state SLS, in order to get the filter configuration given its name. .INDENT 7.0 @@ -179760,7 +191998,7 @@ Included only for compatibility with .UNINDENT .INDENT 0.0 .TP -.B salt.modules.napalm_acl.get_term_pillar(filter_name, term_name, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None) +.B salt.modules.napalm_acl.get_term_pillar(filter_name, term_name, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None) Helper that can be used inside a state SLS, in order to get the term configuration given its name, under a certain filter uniquely identified by its name. @@ -180366,6 +192604,8 @@ flattened_addr flattened_saddr .IP \(bu 2 flattened_daddr +.IP \(bu 2 +priority .UNINDENT .UNINDENT .UNINDENT @@ -180722,11 +192962,11 @@ Output Example: .ft C { \(aqPEERS\-GROUP\-NAME\(aq:{ - \(aqtype\(aq : u\(aqexternal\(aq, - \(aqdescription\(aq : u\(aqHere we should have a nice description\(aq, - \(aqapply_groups\(aq : [u\(aqBGP\-PREFIX\-LIMIT\(aq], - \(aqimport_policy\(aq : u\(aqPUBLIC\-PEER\-IN\(aq, - \(aqexport_policy\(aq : u\(aqPUBLIC\-PEER\-OUT\(aq, + \(aqtype\(aq : \(aqexternal\(aq, + \(aqdescription\(aq : \(aqHere we should have a nice description\(aq, + \(aqapply_groups\(aq : [\(aqBGP\-PREFIX\-LIMIT\(aq], + \(aqimport_policy\(aq : \(aqPUBLIC\-PEER\-IN\(aq, + \(aqexport_policy\(aq : \(aqPUBLIC\-PEER\-OUT\(aq, \(aqremove_private\(aq: True, \(aqmultipath\(aq : True, \(aqmultihop_ttl\(aq : 30, @@ -180887,23 +193127,23 @@ Output Example: \(aqup\(aq : True, \(aqlocal_as\(aq : 13335, \(aqremote_as\(aq : 8121, - \(aqlocal_address\(aq : u\(aq172.101.76.1\(aq, + \(aqlocal_address\(aq : \(aq172.101.76.1\(aq, \(aqlocal_address_configured\(aq : True, \(aqlocal_port\(aq : 179, - \(aqremote_address\(aq : u\(aq192.247.78.0\(aq, - \(aqrouter_id\(aq: : u\(aq192.168.0.1\(aq, + \(aqremote_address\(aq : \(aq192.247.78.0\(aq, + \(aqrouter_id\(aq : \(aq192.168.0.1\(aq, \(aqremote_port\(aq : 58380, \(aqmultihop\(aq : False, - \(aqimport_policy\(aq : u\(aq4\-NTT\-TRANSIT\-IN\(aq, - \(aqexport_policy\(aq : u\(aq4\-NTT\-TRANSIT\-OUT\(aq, + \(aqimport_policy\(aq : \(aq4\-NTT\-TRANSIT\-IN\(aq, + \(aqexport_policy\(aq : \(aq4\-NTT\-TRANSIT\-OUT\(aq, \(aqinput_messages\(aq : 123, \(aqoutput_messages\(aq : 13, \(aqinput_updates\(aq : 123, \(aqoutput_updates\(aq : 5, \(aqmessages_queued_out\(aq : 23, - \(aqconnection_state\(aq : u\(aqEstablished\(aq, - \(aqprevious_connection_state\(aq : u\(aqEstabSync\(aq, - \(aqlast_event\(aq : u\(aqRecvKeepAlive\(aq, + \(aqconnection_state\(aq : \(aqEstablished\(aq, + \(aqprevious_connection_state\(aq : \(aqEstabSync\(aq, + \(aqlast_event\(aq : \(aqRecvKeepAlive\(aq, \(aqsuppress_4byte_as\(aq : False, \(aqlocal_as_prepend\(aq : False, \(aqholdtime\(aq : 90, @@ -181018,11 +193258,177 @@ Example output: Returns a dictionary with the raw output of all commands passed as arguments. .INDENT 7.0 .TP -.B Parameters -\fBcommands\fP \-\- list of commands to be executed on the device +.B commands +List of commands to be executed on the device. .TP -.B Returns -a dictionary with the mapping between each command and its raw output +.B textfsm_parse: \fBFalse\fP +Try parsing the outputs using the TextFSM templates. +.sp +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBnapalm_cli_textfsm_parse\fP\&. +.UNINDENT +.UNINDENT +.TP +.B textfsm_path +The path where the TextFSM templates can be found. This option implies +the usage of the TextFSM index file. +\fBtextfsm_path\fP can be either absolute path on the server, +either specified using the following URL mschemes: \fBfile://\fP, +\fBsalt://\fP, \fBhttp://\fP, \fBhttps://\fP, \fBftp://\fP, +\fBs3://\fP, \fBswift://\fP\&. +.sp +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This needs to be a directory with a flat structure, having an +index file (whose name can be specified using the \fBindex_file\fP option) +and a number of TextFSM templates. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBtextfsm_path\fP\&. +.UNINDENT +.UNINDENT +.TP +.B textfsm_template +The path to a certain the TextFSM template. +This can be specified using the absolute path +to the file, or using one of the following URL schemes: +.INDENT 7.0 +.IP \(bu 2 +\fBsalt://\fP, to fetch the template from the Salt fileserver. +.IP \(bu 2 +\fBhttp://\fP or \fBhttps://\fP +.IP \(bu 2 +\fBftp://\fP +.IP \(bu 2 +\fBs3://\fP +.IP \(bu 2 +\fBswift://\fP +.UNINDENT +.sp +New in version 2018.3.0. + +.TP +.B textfsm_template_dict +A dictionary with the mapping between a command +and the corresponding TextFSM path to use to extract the data. +The TextFSM paths can be specified as in \fBtextfsm_template\fP\&. +.sp +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBnapalm_cli_textfsm_template_dict\fP\&. +.UNINDENT +.UNINDENT +.TP +.B platform_grain_name: \fBos\fP +The name of the grain used to identify the platform name +in the TextFSM index file. Default: \fBos\fP\&. +.sp +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBtextfsm_platform_grain\fP\&. +.UNINDENT +.UNINDENT +.TP +.B platform_column_name: \fBPlatform\fP +The column name used to identify the platform, +exactly as specified in the TextFSM index file. +Default: \fBPlatform\fP\&. +.sp +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This is field is case sensitive, make sure +to assign the correct value to this option, +exactly as defined in the index file. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBtextfsm_platform_column_name\fP\&. +.UNINDENT +.UNINDENT +.TP +.B index_file: \fBindex\fP +The name of the TextFSM index file, under the \fBtextfsm_path\fP\&. Default: \fBindex\fP\&. +.sp +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBtextfsm_index_file\fP\&. +.UNINDENT +.UNINDENT +.TP +.B saltenv: \fBbase\fP +Salt fileserver envrionment from which to retrieve the file. +Ignored if \fBtextfsm_path\fP is not a \fBsalt://\fP URL. +.sp +New in version 2018.3.0. + +.TP +.B include_empty: \fBFalse\fP +Include empty files under the \fBtextfsm_path\fP\&. +.sp +New in version 2018.3.0. + +.TP +.B include_pat +Glob or regex to narrow down the files cached from the given path. +If matching with a regex, the regex must be prefixed with \fBE@\fP, +otherwise the expression will be interpreted as a glob. +.sp +New in version 2018.3.0. + +.TP +.B exclude_pat +Glob or regex to exclude certain files from being cached from the given path. +If matching with a regex, the regex must be prefixed with \fBE@\fP, +otherwise the expression will be interpreted as a glob. +.sp +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +If used with \fBinclude_pat\fP, files matching this pattern will be +excluded from the subset of files defined by \fBinclude_pat\fP\&. +.UNINDENT +.UNINDENT .UNINDENT .sp CLI Example: @@ -181037,6 +193443,18 @@ salt \(aq*\(aq net.cli "show version" "show chassis fan" .UNINDENT .UNINDENT .sp +CLI Example with TextFSM template: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq net.cli textfsm_parse=True textfsm_path=salt://textfsm/ +.ft P +.fi +.UNINDENT +.UNINDENT +.sp Example output: .INDENT 7.0 .INDENT 3.5 @@ -181044,14 +193462,14 @@ Example output: .nf .ft C { - u\(aqshow version and haiku\(aq: u\(aqHostname: re0.edge01.arn01 + \(aqshow version and haiku\(aq: \(aqHostname: re0.edge01.arn01 Model: mx480 Junos: 13.3R6.5 Help me, Obi\-Wan I just saw Episode Two You\(aqre my only hope \(aq, - u\(aqshow chassis fan\(aq : u\(aqItem Status RPM Measurement + \(aqshow chassis fan\(aq : \(aqItem Status RPM Measurement Top Rear Fan OK 3840 Spinning at intermediate\-speed Bottom Rear Fan OK 3840 Spinning at intermediate\-speed Top Middle Fan OK 3900 Spinning at intermediate\-speed @@ -181064,6 +193482,35 @@ Example output: .fi .UNINDENT .UNINDENT +.sp +Example output with TextFSM parsing: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{ + "comment": "", + "result": true, + "out": { + "sh ver": [ + { + "kernel": "9.1S3.5", + "documentation": "9.1S3.5", + "boot": "9.1S3.5", + "crypto": "9.1S3.5", + "chassis": "", + "routing": "9.1S3.5", + "base": "9.1S3.5", + "model": "mx960" + } + ] + } +} +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -181369,7 +193816,7 @@ Example output: .nf .ft C { - \(aqos_version\(aq: u\(aq13.3R6.5\(aq, + \(aqos_version\(aq: \(aq13.3R6.5\(aq, \(aquptime\(aq: 10117140, \(aqinterface_list\(aq: [ \(aqlc\-0/0/0\(aq, @@ -181382,11 +193829,11 @@ Example output: \(aqgr\-0/0/10\(aq, \(aqip\-0/0/10\(aq ], - \(aqvendor\(aq: u\(aqJuniper\(aq, - \(aqserial_number\(aq: u\(aqJN131356FBFA\(aq, - \(aqmodel\(aq: u\(aqMX480\(aq, - \(aqhostname\(aq: u\(aqre0.edge05.syd01\(aq, - \(aqfqdn\(aq: u\(aqre0.edge05.syd01\(aq + \(aqvendor\(aq: \(aqJuniper\(aq, + \(aqserial_number\(aq: \(aqJN131356FBFA\(aq, + \(aqmodel\(aq: \(aqMX480\(aq, + \(aqhostname\(aq: \(aqre0.edge05.syd01\(aq, + \(aqfqdn\(aq: \(aqre0.edge05.syd01\(aq } .ft P .fi @@ -181422,21 +193869,21 @@ Example output: .nf .ft C { - u\(aqManagement1\(aq: { + \(aqManagement1\(aq: { \(aqis_up\(aq: False, \(aqis_enabled\(aq: False, - \(aqdescription\(aq: u\(aq\(aq, + \(aqdescription\(aq: \(aq\(aq, \(aqlast_flapped\(aq: \-1, \(aqspeed\(aq: 1000, - \(aqmac_address\(aq: u\(aqdead:beef:dead\(aq, + \(aqmac_address\(aq: \(aqdead:beef:dead\(aq, }, - u\(aqEthernet1\(aq:{ + \(aqEthernet1\(aq:{ \(aqis_up\(aq: True, \(aqis_enabled\(aq: True, - \(aqdescription\(aq: u\(aqfoo\(aq, + \(aqdescription\(aq: \(aqfoo\(aq, \(aqlast_flapped\(aq: 1429978575.1554043, \(aqspeed\(aq: 1000, - \(aqmac_address\(aq: u\(aqbeef:dead:beef\(aq, + \(aqmac_address\(aq: \(aqbeef:dead:beef\(aq, } } .ft P @@ -181473,28 +193920,28 @@ Example output: .nf .ft C { - u\(aqFastEthernet8\(aq: { - u\(aqipv4\(aq: { - u\(aq10.66.43.169\(aq: { + \(aqFastEthernet8\(aq: { + \(aqipv4\(aq: { + \(aq10.66.43.169\(aq: { \(aqprefix_length\(aq: 22 } } }, - u\(aqLoopback555\(aq: { - u\(aqipv4\(aq: { - u\(aq192.168.1.1\(aq: { + \(aqLoopback555\(aq: { + \(aqipv4\(aq: { + \(aq192.168.1.1\(aq: { \(aqprefix_length\(aq: 24 } }, - u\(aqipv6\(aq: { - u\(aq1::1\(aq: { + \(aqipv6\(aq: { + \(aq1::1\(aq: { \(aqprefix_length\(aq: 64 }, - u\(aq2001:DB8:1::1\(aq: { + \(aq2001:DB8:1::1\(aq: { \(aqprefix_length\(aq: 64 }, - u\(aqFE80::3\(aq: { - \(aqprefix_length\(aq: u\(aqN/A\(aq + \(aqFE80::3\(aq: { + \(aqprefix_length\(aq: \(aqN/A\(aq } } } @@ -181539,17 +193986,17 @@ Example output: { \(aqTenGigE0/0/0/8\(aq: [ { - \(aqparent_interface\(aq: u\(aqBundle\-Ether8\(aq, - \(aqinterface_description\(aq: u\(aqTenGigE0/0/0/8\(aq, - \(aqremote_chassis_id\(aq: u\(aq8c60.4f69.e96c\(aq, - \(aqremote_system_name\(aq: u\(aqswitch\(aq, - \(aqremote_port\(aq: u\(aqEth2/2/1\(aq, - \(aqremote_port_description\(aq: u\(aqEthernet2/2/1\(aq, - \(aqremote_system_description\(aq: u\(aqCisco Nexus Operating System (NX\-OS) Software 7.1(0)N1(1a) + \(aqparent_interface\(aq: \(aqBundle\-Ether8\(aq, + \(aqinterface_description\(aq: \(aqTenGigE0/0/0/8\(aq, + \(aqremote_chassis_id\(aq: \(aq8c60.4f69.e96c\(aq, + \(aqremote_system_name\(aq: \(aqswitch\(aq, + \(aqremote_port\(aq: \(aqEth2/2/1\(aq, + \(aqremote_port_description\(aq: \(aqEthernet2/2/1\(aq, + \(aqremote_system_description\(aq: \(aqCisco Nexus Operating System (NX\-OS) Software 7.1(0)N1(1a) TAC support: http://www.cisco.com/tac Copyright (c) 2002\-2015, Cisco Systems, Inc. All rights reserved.\(aq, - \(aqremote_system_capab\(aq: u\(aqB, R\(aq, - \(aqremote_system_enable_capab\(aq: u\(aqB\(aq + \(aqremote_system_capab\(aq: \(aqB, R\(aq, + \(aqremote_system_enable_capab\(aq: \(aqB\(aq } ] } @@ -181591,7 +194038,7 @@ or using one of the following URL schemes: \fBswift://\fP .UNINDENT .sp -Changed in version 2017.7.3. +Changed in version 2018.3.0. .TP .B text @@ -181621,7 +194068,7 @@ New in version 2016.11.2. .B saltenv: \fBbase\fP Specifies the Salt environment name. .sp -New in version 2017.7.3. +New in version 2018.3.0. .UNINDENT .INDENT 7.0 @@ -181658,6 +194105,21 @@ salt \(aq*\(aq net.load_config filename=\(aq/absolute/path/to/your/file\(aq comm .UNINDENT .sp Example output: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{ + \(aqcomment\(aq: \(aqConfiguration discarded.\(aq, + \(aqalready_configured\(aq: False, + \(aqresult\(aq: True, + \(aqdiff\(aq: \(aq[edit interfaces xe\-0/0/5]+ description "Adding a description";\(aq +} +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -181769,11 +194231,17 @@ Group owner of file. New in version 2016.11.2. .TP -.B template_user: 755 +.B template_mode: 755 Permissions of file. .sp New in version 2016.11.2. +.TP +.B template_attrs: "\-\-\-\-\-\-\-\-\-\-\-\-\-\-e\-\-\-\-" +attributes of file. (see \fIman lsattr\fP) +.sp +New in version 2018.3.0. + .TP .B saltenv: base Specifies the template environment. @@ -182388,6 +194856,23 @@ salt \(aq*\(aq ntp.servers .fi .UNINDENT .UNINDENT +.sp +Example output: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +[ + \(aq192.168.0.1\(aq, + \(aq172.17.17.1\(aq, + \(aq172.17.17.2\(aq, + \(aq2400:cb00:6:1024::c71b:840a\(aq +] +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -182521,12 +195006,12 @@ Example output: .ft C [ { - \(aqremote\(aq : u\(aq188.114.101.4\(aq, - \(aqreferenceid\(aq : u\(aq188.114.100.1\(aq, + \(aqremote\(aq : \(aq188.114.101.4\(aq, + \(aqreferenceid\(aq : \(aq188.114.100.1\(aq, \(aqsynchronized\(aq : True, \(aqstratum\(aq : 4, - \(aqtype\(aq : u\(aq\-\(aq, - \(aqwhen\(aq : u\(aq107\(aq, + \(aqtype\(aq : \(aq\-\(aq, + \(aqwhen\(aq : \(aq107\(aq, \(aqhostpoll\(aq : 256, \(aqreachability\(aq : 377, \(aqdelay\(aq : 164.228, @@ -182726,7 +195211,7 @@ Output example: \(aqlast_test_loss\(aq : 0, \(aqround_trip_jitter\(aq : \-59.0, \(aqtarget\(aq : \(aq192.168.0.1\(aq, - \(aqsource\(aq : \(aq192.168.0.2\(aq + \(aqsource\(aq : \(aq192.168.0.2\(aq, \(aqprobe_count\(aq : 15, \(aqcurrent_test_min_delay\(aq: 63.138 }, @@ -182744,7 +195229,7 @@ Output example: \(aqlast_test_loss\(aq : 0, \(aqround_trip_jitter\(aq : \-34.0, \(aqtarget\(aq : \(aq172.17.17.1\(aq, - \(aqsource\(aq : \(aq172.17.17.2\(aq + \(aqsource\(aq : \(aq172.17.17.2\(aq, \(aqprobe_count\(aq : 15, \(aqcurrent_test_min_delay\(aq: 176.402 } @@ -182994,7 +195479,7 @@ CLI Example: .sp .nf .ft C -salt \(aqmy_router\(aq route.show +salt \(aqmy_router\(aq route.show 172.16.0.0/25 salt \(aqmy_router\(aq route.show 172.16.0.0/25 bgp .ft P .fi @@ -183512,7 +195997,7 @@ Output Example: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.napalm_yang_mod.diff(candidate, running, models) +.B salt.modules.napalm_yang_mod.diff(candidate, running, *models) Returns the difference between two configuration entities structured according to the YANG model. .sp @@ -184123,7 +196608,7 @@ salt \(aq*\(aq sysctl.get hw.physmem .UNINDENT .INDENT 0.0 .TP -.B salt.modules.netbsd_sysctl.persist(name, value, config=\(aq/etc/sysctl.conf\(aq) +.B salt.modules.netbsd_sysctl.persist(name, value, config=u\(aq/etc/sysctl.conf\(aq) Assign and persist a simple sysctl parameter for this minion .sp CLI Example: @@ -184394,8 +196879,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.netbsdservice.status(name, sig=None) -Return the status for a service, returns a bool whether the service is -running. +Return the status for a service. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Signature to use to find the service via ps +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -184403,7 +196909,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq service.status +salt \(aq*\(aq service.status [service signature] .ft P .fi .UNINDENT @@ -184691,7 +197197,7 @@ salt \(aq*\(aq netscaler.service_up \(aqserviceName\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.netscaler.servicegroup_add(sg_name, sg_type=\(aqHTTP\(aq, **connection_args) +.B salt.modules.netscaler.servicegroup_add(sg_name, sg_type=u\(aqHTTP\(aq, **connection_args) Add a new service group If no service type is specified, HTTP will be used. Most common service types: HTTP, SSL, and SSL_BRIDGE @@ -185763,7 +198269,7 @@ salt \(aq*\(aq network.traceroute archlinux.org .UNINDENT .INDENT 0.0 .TP -.B salt.modules.network.wol(mac, bcast=\(aq255.255.255.255\(aq, destport=9) +.B salt.modules.network.wol(mac, bcast=u\(aq255.255.255.255\(aq, destport=9) Send Wake On Lan packet to a host .sp CLI Example: @@ -186348,7 +198854,7 @@ Created security group information .UNINDENT .INDENT 0.0 .TP -.B salt.modules.neutron.create_security_group_rule(security_group, remote_group_id=None, direction=\(aqingress\(aq, protocol=None, port_range_min=None, port_range_max=None, ethertype=\(aqIPv4\(aq, profile=None) +.B salt.modules.neutron.create_security_group_rule(security_group, remote_group_id=None, direction=u\(aqingress\(aq, protocol=None, port_range_min=None, port_range_max=None, ethertype=u\(aqIPv4\(aq, profile=None) Creates a new security group rule .sp CLI Example: @@ -188144,7 +200650,24 @@ Value of updated VPN service information Module for managing NFS version 3. .INDENT 0.0 .TP -.B salt.modules.nfs3.del_export(exports=\(aq/etc/exports\(aq, path=None) +.B salt.modules.nfs3.add_export(exports=u\(aq/etc/exports\(aq, path=None, hosts=None, options=None) +Add an export +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq nfs3.add_export path=\(aq/srv/test\(aq hosts=\(aq127.0.0.1\(aq options=[\(aqrw\(aq] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nfs3.del_export(exports=u\(aq/etc/exports\(aq, path=None) Remove an export .sp CLI Example: @@ -188161,7 +200684,7 @@ salt \(aq*\(aq nfs.del_export /media/storage .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nfs3.list_exports(exports=\(aq/etc/exports\(aq) +.B salt.modules.nfs3.list_exports(exports=u\(aq/etc/exports\(aq) List configured exports .sp CLI Example: @@ -188176,12 +200699,29 @@ salt \(aq*\(aq nfs.list_exports .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nfs3.reload_exports() +Trigger a reload of the exports file to apply changes +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq nfs3.reload_exports +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.nftables .sp Support for nftables .INDENT 0.0 .TP -.B salt.modules.nftables.append(table=\(aqfilter\(aq, chain=None, rule=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.append(table=u\(aqfilter\(aq, chain=None, rule=None, family=u\(aqipv4\(aq) Append a rule to the specified table & chain. .INDENT 7.0 .TP @@ -188211,7 +200751,7 @@ salt \(aq*\(aq nftables.append filter input \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.build_rule(table=None, chain=None, command=None, position=\(aq\(aq, full=None, family=\(aqipv4\(aq, **kwargs) +.B salt.modules.nftables.build_rule(table=None, chain=None, command=None, position=u\(aq\(aq, full=None, family=u\(aqipv4\(aq, **kwargs) Build a well\-formatted nftables rule based on kwargs. A \fItable\fP and \fIchain\fP are not required, unless \fIfull\fP is True. .sp @@ -188250,7 +200790,7 @@ salt \(aq*\(aq nftables.build_rule filter input command=insert position=3 \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.check(table=\(aqfilter\(aq, chain=None, rule=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.check(table=u\(aqfilter\(aq, chain=None, rule=None, family=u\(aqipv4\(aq) Check for the existence of a rule in the table and chain .INDENT 7.0 .TP @@ -188280,7 +200820,7 @@ salt \(aq*\(aq nftables.check filter input \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.check_chain(table=\(aqfilter\(aq, chain=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.check_chain(table=u\(aqfilter\(aq, chain=None, family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -188303,7 +200843,7 @@ salt \(aq*\(aq nftables.check_chain filter input family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.check_table(table=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.check_table(table=None, family=u\(aqipv4\(aq) Check for the existence of a table .sp CLI Example: @@ -188320,7 +200860,7 @@ salt \(aq*\(aq nftables.check_table nat .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.delete(table, chain=None, position=None, rule=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.delete(table, chain=None, position=None, rule=None, family=u\(aqipv4\(aq) .INDENT 7.0 .TP .B Delete a rule from the specified table & chain, specifying either the rule @@ -188356,7 +200896,7 @@ salt \(aq*\(aq nftables.delete filter input \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.delete_chain(table=\(aqfilter\(aq, chain=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.delete_chain(table=u\(aqfilter\(aq, chain=None, family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -188383,7 +200923,7 @@ salt \(aq*\(aq nftables.delete_chain filter foo family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.delete_table(table, family=\(aqipv4\(aq) +.B salt.modules.nftables.delete_table(table, family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -188406,7 +200946,7 @@ salt \(aq*\(aq nftables.delete_table filter family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.flush(table=\(aqfilter\(aq, chain=\(aq\(aq, family=\(aqipv4\(aq) +.B salt.modules.nftables.flush(table=u\(aqfilter\(aq, chain=u\(aq\(aq, family=u\(aqipv4\(aq) Flush the chain in the specified table, flush all chains in the specified table if chain is not specified. .sp @@ -188429,7 +200969,7 @@ salt \(aq*\(aq nftables.flush filter input family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.get_rule_handle(table=\(aqfilter\(aq, chain=None, rule=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.get_rule_handle(table=u\(aqfilter\(aq, chain=None, rule=None, family=u\(aqipv4\(aq) Get the handle for a particular rule .INDENT 7.0 .TP @@ -188459,7 +200999,7 @@ salt \(aq*\(aq nftables.get_rule_handle filter input \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.get_rules(family=\(aqipv4\(aq) +.B salt.modules.nftables.get_rules(family=u\(aqipv4\(aq) Return a data structure of the current, in\-memory rules .sp CLI Example: @@ -188478,7 +201018,7 @@ salt \(aq*\(aq nftables.get_rules family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.get_saved_rules(conf_file=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.get_saved_rules(conf_file=None, family=u\(aqipv4\(aq) Return a data structure of the rules in the conf file .sp CLI Example: @@ -188495,7 +201035,7 @@ salt \(aq*\(aq nftables.get_saved_rules .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.insert(table=\(aqfilter\(aq, chain=None, position=None, rule=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.insert(table=u\(aqfilter\(aq, chain=None, position=None, rule=None, family=u\(aqipv4\(aq) Insert a rule into the specified table & chain, at the specified position. .sp If position is not specified, rule will be inserted in first position. @@ -188534,7 +201074,7 @@ salt \(aq*\(aq nftables.insert filter input position=3 \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.new_chain(table=\(aqfilter\(aq, chain=None, table_type=None, hook=None, priority=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.new_chain(table=u\(aqfilter\(aq, chain=None, table_type=None, hook=None, priority=None, family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -188567,7 +201107,7 @@ salt \(aq*\(aq nftables.new_chain filter foo family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.new_table(table, family=\(aqipv4\(aq) +.B salt.modules.nftables.new_table(table, family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -188590,7 +201130,7 @@ salt \(aq*\(aq nftables.new_table filter family=ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nftables.save(filename=None, family=\(aqipv4\(aq) +.B salt.modules.nftables.save(filename=None, family=u\(aqipv4\(aq) Save the current in\-memory rules to disk .sp CLI Example: @@ -188678,7 +201218,7 @@ salt \(aq*\(aq nginx.signal reload .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nginx.status(url=\(aqhttp://127.0.0.1/status\(aq) +.B salt.modules.nginx.status(url=u\(aqhttp://127.0.0.1/status\(aq) Return the data from an Nginx status page as a dictionary. \fI\%http://wiki.nginx.org/HttpStubStatusModule\fP .INDENT 7.0 @@ -188919,7 +201459,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq ip.dhcp_linklocal_all interface\-label +salt \(aq*\(aq ip.set_dhcp_linklocal_all interface\-label .ft P .fi .UNINDENT @@ -188927,7 +201467,7 @@ salt \(aq*\(aq ip.dhcp_linklocal_all interface\-label .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nilrt_ip.set_static_all(interface, address, netmask, gateway, domains) +.B salt.modules.nilrt_ip.set_static_all(interface, address, netmask, gateway, nameservers) Configure specified adapter to use ipv4 manual settings .INDENT 7.0 .TP @@ -188942,7 +201482,7 @@ Configure specified adapter to use ipv4 manual settings .IP \(bu 2 \fBgateway\fP (\fI\%str\fP) \-\- ipv4 gateway .IP \(bu 2 -\fBdomains\fP (\fI\%str\fP) \-\- list of domains servers separated by spaces +\fBnameservers\fP (\fI\%str\fP) \-\- list of nameservers servers separated by spaces .UNINDENT .TP .B Returns @@ -188958,7 +201498,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq ip.dhcp_linklocal_all interface\-label address netmask gateway domains +salt \(aq*\(aq ip.set_static_all interface\-label address netmask gateway nameservers .ft P .fi .UNINDENT @@ -189736,7 +202276,7 @@ salt \(aq*\(aq nova.suspend 1138 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nova.volume_attach(name, server_name, device=\(aq/dev/xvdb\(aq, profile=None, timeout=300) +.B salt.modules.nova.volume_attach(name, server_name, device=u\(aq/dev/xvdb\(aq, profile=None, timeout=300) Attach a block storage volume .INDENT 7.0 .TP @@ -190645,7 +203185,7 @@ salt \(aq*\(aq nspawn.remove foo stop=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nspawn.retcode(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) +.B salt.modules.nspawn.retcode(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) Run \fBcmd.retcode\fP within a container .INDENT 7.0 .TP @@ -190700,7 +203240,7 @@ salt myminion nspawn.retcode mycontainer \(aqip addr show\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nspawn.run(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) +.B salt.modules.nspawn.run(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) Run \fBcmd.run\fP within a container .INDENT 7.0 .TP @@ -190754,7 +203294,7 @@ salt myminion nspawn.run mycontainer \(aqifconfig \-a\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nspawn.run_all(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) +.B salt.modules.nspawn.run_all(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) Run \fBcmd.run_all\fP within a container .sp \fBNOTE:\fP @@ -190818,7 +203358,7 @@ salt myminion nspawn.run_all mycontainer \(aqip addr show\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nspawn.run_stderr(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) +.B salt.modules.nspawn.run_stderr(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) Run \fBcmd.run_stderr\fP within a container .INDENT 7.0 .TP @@ -190873,7 +203413,7 @@ salt myminion nspawn.run_stderr mycontainer \(aqip addr show\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.nspawn.run_stdout(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) +.B salt.modules.nspawn.run_stdout(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=u\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=None) Run \fBcmd.run_stdout\fP within a container .INDENT 7.0 .TP @@ -191152,7 +203692,7 @@ salt \(aq*\(aq sysctl.get hw.physmem .UNINDENT .INDENT 0.0 .TP -.B salt.modules.openbsd_sysctl.persist(name, value, config=\(aq/etc/sysctl.conf\(aq) +.B salt.modules.openbsd_sysctl.persist(name, value, config=u\(aq/etc/sysctl.conf\(aq) Assign and persist a simple sysctl parameter for this minion .sp CLI Example: @@ -191191,7 +203731,8 @@ Package support for OpenBSD \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -The package repository is configured on each host using \fB/etc/pkg.conf\fP +The package repository is configured on each host using \fB/etc/installurl\fP +from OpenBSD 6.1 onwards. Earlier releases relied on \fB/etc/pkg.conf\fP\&. .UNINDENT .UNINDENT .sp @@ -191873,8 +204414,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.openbsdservice.status(name, sig=None) -Return the status for a service, returns a bool whether the service is -running. +Return the status for a service. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Signature to use to find the service via ps +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -191882,7 +204444,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq service.status +salt \(aq*\(aq service.status [service signature] .ft P .fi .UNINDENT @@ -191906,6 +204468,8 @@ salt \(aq*\(aq service.stop .UNINDENT .UNINDENT .SS salt.modules.openscap module +.sp +Module for OpenSCAP Management .INDENT 0.0 .TP .B salt.modules.openscap.xccdf(params) @@ -192984,7 +205548,7 @@ salt \(aq*\(aq pkg.purge pkgs=\(aq["foo", "bar"]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.opkg.refresh_db(**kwargs) +.B salt.modules.opkg.refresh_db(failhard=False, **kwargs) Updates the opkg database to latest packages based upon repositories .sp Returns a dict, with the keys being package databases and the values being @@ -192994,6 +205558,17 @@ the result of the update attempt. Values can be one of the following: \fBTrue\fP: Database updated successfully .IP \(bu 2 \fBFalse\fP: Problem updating database +.UNINDENT +.INDENT 7.0 +.TP +.B failhard +If False, return results of failed lines as \fBFalse\fP for the package +database that encountered the error. +If True, raise an error with a list of the package databases that +encountered errors. +.sp +New in version 2018.3.0. + .UNINDENT .sp CLI Example: @@ -193175,6 +205750,81 @@ salt \(aq*\(aq pkg.version_cmp \(aq0.2.4\-0\(aq \(aq0.2.4.1\-0\(aq .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.opsgenie +.sp +Module for sending data to OpsGenie +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B configuration +This module can be used in Reactor System for +posting data to OpsGenie as a remote\-execution function. +.sp +For example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +opsgenie_event_poster: + local.opsgenie.post_data: + \- tgt: \(aqsalt\-minion\(aq + \- kwarg: + name: event.reactor + api_key: XXXXXXXX\-XXXX\-XXXX\-XXXX\-XXXXXXXXXXXX + reason: {{ data[\(aqdata\(aq][\(aqreason\(aq] }} + action_type: Create +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.opsgenie.post_data(api_key=None, name=u\(aqOpsGenie Execution Module\(aq, reason=None, action_type=None) +Post data to OpsGenie. It\(aqs designed for Salt\(aqs Event Reactor. +.sp +After configuring the sls reaction file as shown above, you can trigger the +module with your designated tag (og\-tag in this case). +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call event.send \(aqog\-tag\(aq \(aq{"reason" : "Overheating CPU!"}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Required parameters: +.INDENT 7.0 +.TP +.B api_key +It\(aqs the API Key you\(aqve copied while adding integration in OpsGenie. +.TP +.B reason +It will be used as alert\(aqs default message in OpsGenie. +.TP +.B action_type +OpsGenie supports the default values Create/Close for action_type. You +can customize this field with OpsGenie\(aqs custom actions for other +purposes like adding notes or acknowledging alerts. +.UNINDENT +.sp +Optional parameters: +.INDENT 7.0 +.TP +.B name +It will be used as alert\(aqs alias. If you want to use the close +functionality you must provide name field for both states like in +this case. +.UNINDENT +.UNINDENT .SS salt.modules.oracle .sp Oracle DataBase connection module @@ -194547,6 +207197,134 @@ salt \(aq*\(aq osquery.xprotect_reports .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.out module +.SS Output Module +.sp +New in version 2018.3.0. + +.sp +Execution module that processes JSON serializable data +and returns string having the format as processed by the outputters. +.sp +Although this does not bring much value on the CLI, it turns very handy +in applications that require human readable data rather than Python objects. +.sp +For example, inside a Jinja template: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{{ salt.out.string_format(complex_object, out=\(aqhighstate\(aq) }} +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.out.html_format(data, out=u\(aqnested\(aq, opts=None, **kwargs) +Return the formatted string as HTML. +.INDENT 7.0 +.TP +.B data +The JSON serializable object. +.TP +.B out: \fBnested\fP +The name of the output to use to transform the data. Default: \fBnested\fP\&. +.TP +.B opts +Dictionary of configuration options. Default: \fB__opts__\fP\&. +.TP +.B +.nf +** +.fi +kwargs +Arguments to sent to the outputter module. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq out.html_format "{\(aqkey\(aq: \(aqvalue\(aq}" out=yaml +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.out.out_format(data, out=u\(aqnested\(aq, opts=None, **kwargs) +Return the formatted outputter string for the Python object. +.INDENT 7.0 +.TP +.B data +The JSON serializable object. +.TP +.B out: \fBnested\fP +The name of the output to use to transform the data. Default: \fBnested\fP\&. +.TP +.B opts +Dictionary of configuration options. Default: \fB__opts__\fP\&. +.TP +.B +.nf +** +.fi +kwargs +Arguments to sent to the outputter module. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq out.out_format "{\(aqkey\(aq: \(aqvalue\(aq}" +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.out.string_format(data, out=u\(aqnested\(aq, opts=None, **kwargs) +Return the outputter formatted string, removing the ANSI escape sequences. +.INDENT 7.0 +.TP +.B data +The JSON serializable object. +.TP +.B out: \fBnested\fP +The name of the output to use to transform the data. Default: \fBnested\fP\&. +.TP +.B opts +Dictionary of configuration options. Default: \fB__opts__\fP\&. +.TP +.B +.nf +** +.fi +kwargs +Arguments to sent to the outputter module. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq out.string_format "{\(aqkey\(aq: \(aqvalue\(aq}" out=table +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.pacman .sp A module to wrap pacman calls, since Arch is the best @@ -195328,7 +208106,7 @@ pagerduty: For PagerDuty API details, see \fI\%https://developer.pagerduty.com/documentation/rest\fP .INDENT 0.0 .TP -.B salt.modules.pagerduty_util.create_or_update_resource(resource_name, identifier_fields, data, diff=None, profile=\(aqpagerduty\(aq, subdomain=None, api_key=None) +.B salt.modules.pagerduty_util.create_or_update_resource(resource_name, identifier_fields, data, diff=None, profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None) create or update any pagerduty resource Helper method for present(). .sp @@ -195344,7 +208122,7 @@ create_or_update_resource("escalation_policies", ["id","name"], diff=my_diff_fun .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pagerduty_util.delete_resource(resource_name, key, identifier_fields, profile=\(aqpagerduty\(aq, subdomain=None, api_key=None) +.B salt.modules.pagerduty_util.delete_resource(resource_name, key, identifier_fields, profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None) delete any pagerduty resource .sp Helper method for absent() @@ -195354,7 +208132,7 @@ delete_resource("users", key, ["id","name","email"]) # delete by id or name or e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pagerduty_util.get_escalation_policies(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None) +.B salt.modules.pagerduty_util.get_escalation_policies(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None) List escalation_policies belonging to this account .sp CLI Example: @@ -195366,7 +208144,7 @@ salt myminion pagerduty.get_escalation_policies .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pagerduty_util.get_resource(resource_name, key, identifier_fields, profile=\(aqpagerduty\(aq, subdomain=None, api_key=None) +.B salt.modules.pagerduty_util.get_resource(resource_name, key, identifier_fields, profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None) Get any single pagerduty resource by key. .sp We allow flexible lookup by any of a list of identifier_fields. @@ -195388,7 +208166,7 @@ The __context__ cache is purged after any create, update or delete to the resour .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pagerduty_util.get_schedules(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None) +.B salt.modules.pagerduty_util.get_schedules(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None) List schedules belonging to this account .sp CLI Example: @@ -195400,7 +208178,7 @@ salt myminion pagerduty.get_schedules .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pagerduty_util.get_services(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None) +.B salt.modules.pagerduty_util.get_services(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None) List services belonging to this account .sp CLI Example: @@ -195412,7 +208190,7 @@ salt myminion pagerduty.get_services .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pagerduty_util.get_users(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None) +.B salt.modules.pagerduty_util.get_users(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None) List users belonging to this account .sp CLI Example: @@ -195424,7 +208202,7 @@ salt myminion pagerduty.get_users .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pagerduty_util.resource_absent(resource, identifier_fields, profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.modules.pagerduty_util.resource_absent(resource, identifier_fields, profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Generic resource.absent state method. Pagerduty state modules should be a thin wrapper over this method, with a custom diff function. .sp @@ -195435,7 +208213,7 @@ resource_absent("users", ["id","name","email"]) .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pagerduty_util.resource_present(resource, identifier_fields, diff=None, profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.modules.pagerduty_util.resource_present(resource, identifier_fields, diff=None, profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Generic resource.present state method. Pagerduty state modules should be a thin wrapper over this method, with a custom diff function. .sp @@ -195474,6 +208252,18 @@ see the \fI\%Parallels Desktop Reference Guide\fP\&. What has not been implemented yet can be accessed through \fBparallels.prlctl\fP and \fBparallels.prlsrvctl\fP (note the preceding double dash \fB\-\-\fP as necessary): +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq parallels.prlctl installtools macvm runas=macdev +salt \-\- \(aq*\(aq parallels.prlctl capture \(aqmacvm \-\-file macvm.display.png\(aq runas=macdev +salt \-\- \(aq*\(aq parallels.prlsrvctl set \(aq\-\-mem\-limit auto\(aq runas=macdev +.ft P +.fi +.UNINDENT +.UNINDENT .sp New in version 2016.3.0. @@ -196163,7 +208953,7 @@ salt \(aq*\(aq partition.cp /dev/sda 2 3 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.parted.exists(device=\(aq\(aq) +.B salt.modules.parted.exists(device=u\(aq\(aq) Check to see if the partition exists .sp CLI Example: @@ -196540,7 +209330,7 @@ New in version 2016.3.0. .INDENT 0.0 .TP -.B salt.modules.pcs.auth(nodes, pcsuser=\(aqhacluster\(aq, pcspasswd=\(aqhacluster\(aq, extra_args=None) +.B salt.modules.pcs.auth(nodes, pcsuser=u\(aqhacluster\(aq, pcspasswd=u\(aqhacluster\(aq, extra_args=None) Authorize nodes to the cluster .INDENT 7.0 .TP @@ -196574,7 +209364,7 @@ salt \(aq*\(aq pcs.auth nodes=\(aq[ node1.example.org node2.example.org ]\(aq \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pcs.cib_create(cibfile, scope=\(aqconfiguration\(aq, extra_args=None) +.B salt.modules.pcs.cib_create(cibfile, scope=u\(aqconfiguration\(aq, extra_args=None) Create a CIB\-file from the current CIB of the cluster .INDENT 7.0 .TP @@ -196603,7 +209393,7 @@ salt \(aq*\(aq pcs.cib_create cibfile=\(aq/tmp/VIP_apache_1.cib\(aq \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pcs.cib_push(cibfile, scope=\(aqconfiguration\(aq, extra_args=None) +.B salt.modules.pcs.cib_push(cibfile, scope=u\(aqconfiguration\(aq, extra_args=None) Push a CIB\-file as the new CIB to the cluster .INDENT 7.0 .TP @@ -196657,7 +209447,7 @@ salt \(aq*\(aq pcs.cluster_node_add node=node2.example.org\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pcs.cluster_setup(nodes, pcsclustername=\(aqpcscluster\(aq, extra_args=None) +.B salt.modules.pcs.cluster_setup(nodes, pcsclustername=u\(aqpcscluster\(aq, extra_args=None) Setup pacemaker cluster via pcs command .INDENT 7.0 .TP @@ -196730,7 +209520,7 @@ salt \(aq*\(aq pcs.is_auth nodes=\(aq[node1.example.org node2.example.org]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pcs.item_create(item, item_id, item_type, create=\(aqcreate\(aq, extra_args=None, cibfile=None) +.B salt.modules.pcs.item_create(item, item_id, item_type, create=u\(aqcreate\(aq, extra_args=None, cibfile=None) Create an item via pcs command (mainly for use with the pcs state module) .INDENT 7.0 @@ -196756,7 +209546,7 @@ use cibfile instead of the live CIB .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pcs.item_show(item, item_id=None, item_type=None, show=\(aqshow\(aq, extra_args=None, cibfile=None) +.B salt.modules.pcs.item_show(item, item_id=None, item_type=None, show=u\(aqshow\(aq, extra_args=None, cibfile=None) Show an item via pcs command (mainly for use with the pcs state module) .INDENT 7.0 @@ -197234,7 +210024,7 @@ salt \(aq*\(aq pdbedit.modify mal account_control=NX Manage PHP pecl extensions. .INDENT 0.0 .TP -.B salt.modules.pecl.install(pecls, defaults=False, force=False, preferred_state=\(aqstable\(aq) +.B salt.modules.pecl.install(pecls, defaults=False, force=False, preferred_state=u\(aqstable\(aq) New in version 0.17.0. .sp @@ -197357,8 +210147,8 @@ configuration into a dictionary, and figure out .sp .nf .ft C ->>> import yaml ->>> ext_pillar = yaml.safe_load(""" +>>> import salt.utils.yaml +>>> ext_pillar = salt.utils.yaml.safe_load(""" \&... ext_pillar: \&... \- git: \&... \- issue38440 https://github.com/terminalmage/git_pillar: @@ -197561,7 +210351,7 @@ salt \(aq*\(aq pillar.file_exists foo/bar.sls .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pillar.filter_by(lookup_dict, pillar, merge=None, default=\(aqdefault\(aq, base=None) +.B salt.modules.pillar.filter_by(lookup_dict, pillar, merge=None, default=u\(aqdefault\(aq, base=None) New in version 2017.7.0. .sp @@ -198121,7 +210911,7 @@ installed pip is new enough. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pip.install(pkgs=None, requirements=None, bin_env=None, use_wheel=False, no_use_wheel=False, log=None, proxy=None, timeout=None, editable=None, find_links=None, index_url=None, extra_index_url=None, no_index=False, mirrors=None, build=None, target=None, download=None, download_cache=None, source=None, upgrade=False, force_reinstall=False, ignore_installed=False, exists_action=None, no_deps=False, no_install=False, no_download=False, global_options=None, install_options=None, user=None, no_chown=False, cwd=None, pre_releases=False, cert=None, allow_all_external=False, allow_external=None, allow_unverified=None, process_dependency_links=False, saltenv=\(aqbase\(aq, env_vars=None, use_vt=False, trusted_host=None, no_cache_dir=False, cache_dir=None) +.B salt.modules.pip.install(pkgs=None, requirements=None, bin_env=None, use_wheel=False, no_use_wheel=False, log=None, proxy=None, timeout=None, editable=None, find_links=None, index_url=None, extra_index_url=None, no_index=False, mirrors=None, build=None, target=None, download=None, download_cache=None, source=None, upgrade=False, force_reinstall=False, ignore_installed=False, exists_action=None, no_deps=False, no_install=False, no_download=False, global_options=None, install_options=None, user=None, no_chown=False, cwd=None, pre_releases=False, cert=None, allow_all_external=False, allow_external=None, allow_unverified=None, process_dependency_links=False, saltenv=u\(aqbase\(aq, env_vars=None, use_vt=False, trusted_host=None, no_cache_dir=False, cache_dir=None) Install packages with pip .sp Install packages individually or from a pip requirements file. Install @@ -198327,6 +211117,39 @@ salt \(aq*\(aq pip.install markdown,django editable=git+https:// .fi .UNINDENT .UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.pip.is_installed(pkgname=None, bin_env=None, user=None, cwd=None) +Filter list of installed apps from \fBfreeze\fP and return True or False if +\fBpkgname\fP exists in the list of packages installed. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +If the version of pip available is older than 8.0.3, the packages +wheel, setuptools, and distribute will not be reported by this function +even if they are installed. Unlike +\fI\%pip.freeze\fP, this function always +reports the version of pip which is installed. +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq pip.is_installed salt +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0: The packages wheel, setuptools, and distribute are included if the +installed pip is new enough. + .UNINDENT .INDENT 0.0 .TP @@ -198428,7 +211251,7 @@ salt \(aq*\(aq pip.list_upgrades .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pip.uninstall(pkgs=None, requirements=None, bin_env=None, log=None, proxy=None, timeout=None, user=None, no_chown=False, cwd=None, saltenv=\(aqbase\(aq, use_vt=False) +.B salt.modules.pip.uninstall(pkgs=None, requirements=None, bin_env=None, log=None, proxy=None, timeout=None, user=None, no_chown=False, cwd=None, saltenv=u\(aqbase\(aq, use_vt=False) Uninstall packages with pip .sp Uninstall packages individually or from a pip requirements file. Uninstall @@ -198608,6 +211431,16 @@ salt \(aq*\(aq pkg_resource.check_extra_requirements postfix.set_main mailq_path /usr/bin/mailq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postfix.set_master(service, conn_type, private=\(aqy\(aq, unpriv=\(aqy\(aq, chroot=\(aqy\(aq, wakeup=\(aqn\(aq, maxproc=\(aq100\(aq, command=\(aq\(aq, write_conf=True, path=\(aq/etc/postfix/master.cf\(aq) +.B salt.modules.postfix.set_master(service, conn_type, private=u\(aqy\(aq, unpriv=u\(aqy\(aq, chroot=u\(aqy\(aq, wakeup=u\(aqn\(aq, maxproc=u\(aq100\(aq, command=u\(aq\(aq, write_conf=True, path=u\(aq/etc/postfix/master.cf\(aq) Set a single config value in the master.cf file. If the value does not already exist, it will be appended to the end. .sp @@ -201474,7 +214365,7 @@ salt postfix.set_master smtp inet n y n n 100 smtpd .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postfix.show_main(path=\(aq/etc/postfix/main.cf\(aq) +.B salt.modules.postfix.show_main(path=u\(aq/etc/postfix/main.cf\(aq) Return a dict of active config values. This does not include comments, spacing or order. Bear in mind that order is functionally important in the main.cf file, since keys can be referred to as variables. This means that @@ -201491,7 +214382,7 @@ salt postfix.show_main path=/path/to/main.cf .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postfix.show_master(path=\(aq/etc/postfix/master.cf\(aq) +.B salt.modules.postfix.show_master(path=u\(aq/etc/postfix/master.cf\(aq) Return a dict of active config values. This does not include comments, spacing or order. .sp @@ -201669,7 +214560,7 @@ Name of the directory to check .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.datadir_init(name, auth=\(aqpassword\(aq, user=None, password=None, encoding=\(aqUTF8\(aq, locale=None, runas=None) +.B salt.modules.postgres.datadir_init(name, auth=u\(aqpassword\(aq, user=None, password=None, encoding=u\(aqUTF8\(aq, locale=None, runas=None) New in version 2016.3.0. .sp @@ -201906,7 +214797,7 @@ salt \(aq*\(aq postgres.group_update \(aqusername\(aq user=\(aquser\(aq \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.has_privileges(name, object_name, object_type, privileges=None, grant_option=None, prepend=\(aqpublic\(aq, maintenance_db=None, user=None, host=None, port=None, password=None, runas=None) +.B salt.modules.postgres.has_privileges(name, object_name, object_type, privileges=None, grant_option=None, prepend=u\(aqpublic\(aq, maintenance_db=None, user=None, host=None, port=None, password=None, runas=None) New in version 2016.3.0. .sp @@ -202250,7 +215141,7 @@ salt \(aq*\(aq postgres.owner_to \(aqdbname\(aq \(aqusername\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.privileges_grant(name, object_name, object_type, privileges=None, grant_option=None, prepend=\(aqpublic\(aq, maintenance_db=None, user=None, host=None, port=None, password=None, runas=None) +.B salt.modules.postgres.privileges_grant(name, object_name, object_type, privileges=None, grant_option=None, prepend=u\(aqpublic\(aq, maintenance_db=None, user=None, host=None, port=None, password=None, runas=None) New in version 2016.3.0. .sp @@ -202357,7 +215248,7 @@ System user all operations should be performed on behalf of .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.privileges_list(name, object_type, prepend=\(aqpublic\(aq, maintenance_db=None, user=None, host=None, port=None, password=None, runas=None) +.B salt.modules.postgres.privileges_list(name, object_type, prepend=u\(aqpublic\(aq, maintenance_db=None, user=None, host=None, port=None, password=None, runas=None) New in version 2016.3.0. .sp @@ -202425,7 +215316,7 @@ System user all operations should be performed on behalf of .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.privileges_revoke(name, object_name, object_type, privileges=None, prepend=\(aqpublic\(aq, maintenance_db=None, user=None, host=None, port=None, password=None, runas=None) +.B salt.modules.postgres.privileges_revoke(name, object_name, object_type, privileges=None, prepend=u\(aqpublic\(aq, maintenance_db=None, user=None, host=None, port=None, password=None, runas=None) New in version 2016.3.0. .sp @@ -202611,7 +215502,7 @@ salt \(aq*\(aq postgres.schema_create dbname name owner=\(aqowner\(aq \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.schema_exists(dbname, name, db_user=None, db_password=None, db_host=None, db_port=None) +.B salt.modules.postgres.schema_exists(dbname, name, user=None, db_user=None, db_password=None, db_host=None, db_port=None) Checks if a schema exists on the Postgres server. .sp CLI Example: @@ -202633,6 +215524,9 @@ Database name we query on .B name Schema name we look for .TP +.B user +The system user the operation should be performed on behalf of +.TP .B db_user database username if different from config or default .TP @@ -202648,7 +215542,7 @@ Database port if different from config or default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.schema_get(dbname, name, db_user=None, db_password=None, db_host=None, db_port=None) +.B salt.modules.postgres.schema_get(dbname, name, user=None, db_user=None, db_password=None, db_host=None, db_port=None) Return a dict with information about schemas in a database. .sp CLI Example: @@ -202670,6 +215564,9 @@ Database name we query on .B name Schema name we look for .TP +.B user +The system user the operation should be performed on behalf of +.TP .B db_user database username if different from config or default .TP @@ -202685,7 +215582,7 @@ Database port if different from config or default .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.schema_list(dbname, db_user=None, db_password=None, db_host=None, db_port=None) +.B salt.modules.postgres.schema_list(dbname, user=None, db_user=None, db_password=None, db_host=None, db_port=None) Return a dict with information about schemas in a Postgres database. .sp CLI Example: @@ -202704,6 +215601,9 @@ salt \(aq*\(aq postgres.schema_list dbname .B dbname Database name we query on .TP +.B user +The system user the operation should be performed on behalf of +.TP .B db_user database username if different from config or default .TP @@ -202862,7 +215762,7 @@ New in version 2015.8.0. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.user_create(username, user=None, host=None, port=None, maintenance_db=None, password=None, createdb=None, createuser=None, createroles=None, inherit=None, login=None, connlimit=None, encrypted=None, superuser=None, replication=None, rolepassword=None, groups=None, runas=None) +.B salt.modules.postgres.user_create(username, user=None, host=None, port=None, maintenance_db=None, password=None, createdb=None, createuser=None, createroles=None, inherit=None, login=None, connlimit=None, encrypted=None, superuser=None, replication=None, rolepassword=None, valid_until=None, groups=None, runas=None) Creates a Postgres user. .sp CLI Examples: @@ -202873,7 +215773,7 @@ CLI Examples: .ft C salt \(aq*\(aq postgres.user_create \(aqusername\(aq user=\(aquser\(aq \e host=\(aqhostname\(aq port=\(aqport\(aq password=\(aqpassword\(aq \e - rolepassword=\(aqrolepassword\(aq + rolepassword=\(aqrolepassword\(aq valid_until=\(aqvalid_until\(aq .ft P .fi .UNINDENT @@ -202934,7 +215834,7 @@ salt \(aq*\(aq postgres.user_remove \(aqusername\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.postgres.user_update(username, user=None, host=None, port=None, maintenance_db=None, password=None, createdb=None, createuser=None, createroles=None, encrypted=None, superuser=None, inherit=None, login=None, connlimit=None, replication=None, rolepassword=None, groups=None, runas=None) +.B salt.modules.postgres.user_update(username, user=None, host=None, port=None, maintenance_db=None, password=None, createdb=None, createuser=None, createroles=None, encrypted=None, superuser=None, inherit=None, login=None, connlimit=None, replication=None, rolepassword=None, valid_until=None, groups=None, runas=None) Updates a Postgres user. .sp CLI Examples: @@ -202945,7 +215845,7 @@ CLI Examples: .ft C salt \(aq*\(aq postgres.user_update \(aqusername\(aq user=\(aquser\(aq \e host=\(aqhostname\(aq port=\(aqport\(aq password=\(aqpassword\(aq \e - rolepassword=\(aqrolepassword\(aq + rolepassword=\(aqrolepassword\(aq valid_until=\(aqvalid_until\(aq .ft P .fi .UNINDENT @@ -202992,7 +215892,7 @@ salt \-N buildbox_group poudriere.bulk_build 90amd64 /root/pkg_list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.poudriere.create_jail(name, arch, version=\(aq9.0\-RELEASE\(aq) +.B salt.modules.poudriere.create_jail(name, arch, version=u\(aq9.0\-RELEASE\(aq) Creates a new poudriere jail if one does not exist .sp \fINOTE\fP creating a new jail will take some time the master is not hanging @@ -203202,7 +216102,7 @@ salt \(aq*\(aq network.get_http_proxy .UNINDENT .INDENT 0.0 .TP -.B salt.modules.proxy.get_ftp_proxy(network_service=\(aqEthernet\(aq) +.B salt.modules.proxy.get_ftp_proxy(network_service=u\(aqEthernet\(aq) Returns the current ftp proxy settings .INDENT 7.0 .TP @@ -203225,7 +216125,7 @@ salt \(aq*\(aq proxy.get_ftp_proxy Ethernet .UNINDENT .INDENT 0.0 .TP -.B salt.modules.proxy.get_http_proxy(network_service=\(aqEthernet\(aq) +.B salt.modules.proxy.get_http_proxy(network_service=u\(aqEthernet\(aq) Returns the current http proxy settings .INDENT 7.0 .TP @@ -203248,7 +216148,7 @@ salt \(aq*\(aq proxy.get_http_proxy Ethernet .UNINDENT .INDENT 0.0 .TP -.B salt.modules.proxy.get_https_proxy(network_service=\(aqEthernet\(aq) +.B salt.modules.proxy.get_https_proxy(network_service=u\(aqEthernet\(aq) Returns the current https proxy settings .INDENT 7.0 .TP @@ -203271,7 +216171,7 @@ salt \(aq*\(aq proxy.get_https_proxy Ethernet .UNINDENT .INDENT 0.0 .TP -.B salt.modules.proxy.get_proxy_bypass(network_service=\(aqEthernet\(aq) +.B salt.modules.proxy.get_proxy_bypass(network_service=u\(aqEthernet\(aq) Returns the current domains that can bypass the proxy .INDENT 7.0 .TP @@ -203311,7 +216211,7 @@ salt \(aq*\(aq proxy.get_proxy_win .UNINDENT .INDENT 0.0 .TP -.B salt.modules.proxy.set_ftp_proxy(server, port, user=None, password=None, network_service=\(aqEthernet\(aq, bypass_hosts=None) +.B salt.modules.proxy.set_ftp_proxy(server, port, user=None, password=None, network_service=u\(aqEthernet\(aq, bypass_hosts=None) Sets the ftp proxy settings .INDENT 7.0 .TP @@ -203350,7 +216250,7 @@ salt \(aq*\(aq proxy.set_ftp_proxy example.com 1080 user=proxy_user password=pro .UNINDENT .INDENT 0.0 .TP -.B salt.modules.proxy.set_http_proxy(server, port, user=None, password=None, network_service=\(aqEthernet\(aq, bypass_hosts=None) +.B salt.modules.proxy.set_http_proxy(server, port, user=None, password=None, network_service=u\(aqEthernet\(aq, bypass_hosts=None) Sets the http proxy settings. Note: On Windows this will override any other proxy settings you have, the preferred method of updating proxies on windows is using set_proxy. .INDENT 7.0 @@ -203390,7 +216290,7 @@ salt \(aq*\(aq proxy.set_http_proxy example.com 1080 user=proxy_user password=pr .UNINDENT .INDENT 0.0 .TP -.B salt.modules.proxy.set_https_proxy(server, port, user=None, password=None, network_service=\(aqEthernet\(aq, bypass_hosts=None) +.B salt.modules.proxy.set_https_proxy(server, port, user=None, password=None, network_service=u\(aqEthernet\(aq, bypass_hosts=None) Sets the https proxy settings. Note: On Windows this will override any other proxy settings you have, the preferred method of updating proxies on windows is using set_proxy. .INDENT 7.0 @@ -203430,7 +216330,7 @@ salt \(aq*\(aq proxy.set_https_proxy example.com 1080 user=proxy_user password=p .UNINDENT .INDENT 0.0 .TP -.B salt.modules.proxy.set_proxy_bypass(domains, network_service=\(aqEthernet\(aq) +.B salt.modules.proxy.set_proxy_bypass(domains, network_service=u\(aqEthernet\(aq) Sets the domains that can bypass the proxy .INDENT 7.0 .TP @@ -204075,7 +216975,7 @@ salt \(aq*\(aq ps.virtual_memory Publish a command from a minion to a target .INDENT 0.0 .TP -.B salt.modules.publish.full_data(tgt, fun, arg=None, tgt_type=\(aqglob\(aq, returner=\(aq\(aq, timeout=5, expr_form=None) +.B salt.modules.publish.full_data(tgt, fun, arg=None, tgt_type=u\(aqglob\(aq, returner=u\(aq\(aq, timeout=5, expr_form=None) Return the full data about the publication, this is invoked in the same way as the publish function .sp @@ -204112,7 +217012,7 @@ salt \(aq*\(aq publish.full_data test.kwarg arg=\(aqcheese=spam\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.publish.publish(tgt, fun, arg=None, tgt_type=\(aqglob\(aq, returner=\(aq\(aq, timeout=5, via_master=None, expr_form=None) +.B salt.modules.publish.publish(tgt, fun, arg=None, tgt_type=u\(aqglob\(aq, returner=u\(aq\(aq, timeout=5, via_master=None, expr_form=None) Publish a command from the minion out to other minions. .sp Publications need to be enabled on the Salt master and the minion @@ -204421,6 +217321,885 @@ salt \(aq*\(aq puppet.summary .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.purefa +.sp +Management of Pure Storage FlashArray +.SS Installation Prerequisites +.INDENT 0.0 +.IP \(bu 2 +You will need the \fBpurestorage\fP python package in your python installation +path that is running salt. +.INDENT 2.0 +.INDENT 3.5 +.sp +.nf +.ft C +pip install purestorage +.ft P +.fi +.UNINDENT +.UNINDENT +.IP \(bu 2 +Configure Pure Storage FlashArray authentication. Use one of the following +three methods. +.INDENT 2.0 +.IP 1. 3 +From the minion config +.UNINDENT +.INDENT 2.0 +.INDENT 3.5 +.sp +.nf +.ft C +pure_tags: + fa: + san_ip: management vip or hostname for the FlashArray + api_token: A valid api token for the FlashArray being managed +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 2.0 +.IP 2. 3 +From environment (PUREFA_IP and PUREFA_API) +.IP 3. 3 +From the pillar (PUREFA_IP and PUREFA_API) +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B maintainer +Simon Dodsley (\fI\%simon@purestorage.com\fP) +.TP +.B maturity +new +.TP +.B requires +purestorage +.TP +.B platform +all +.UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B salt.modules.purefa.hg_create(name, host=None, volume=None) +Create a hostgroup on a Pure Storage FlashArray. +.sp +Will return False if hostgroup already exists, or if +named host or volume do not exist. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of hostgroup (truncated to 63 characters) +.TP +.B host +string +name of host to add to hostgroup +.TP +.B volume +string +name of volume to add to hostgroup +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.hg_create foo host=bar volume=vol +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.hg_delete(name) +Delete a hostgroup on a Pure Storage FlashArray (removes all volumes and hosts). +.sp +Will return False is hostgroup is already in a deleted state. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of hostgroup +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.hg_delete foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.hg_remove(name, volume=None, host=None) +Remove a host and/or volume from a hostgroup on a Pure Storage FlashArray. +.sp +Will return False is hostgroup does not exist, or named host or volume are +not in the hostgroup. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of hostgroup +.TP +.B volume +string +name of volume to remove from hostgroup +.TP +.B host +string +name of host to remove from hostgroup +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.hg_remove foo volume=test host=bar +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.hg_update(name, host=None, volume=None) +Adds entries to a hostgroup on a Pure Storage FlashArray. +.sp +Will return False is hostgroup doesn\(aqt exist, or host +or volume do not exist. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of hostgroup +.TP +.B host +string +name of host to add to hostgroup +.TP +.B volume +string +name of volume to add to hostgroup +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.hg_update foo host=bar volume=vol +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.host_create(name, iqn=None, wwn=None) +Add a host on a Pure Storage FlashArray. +.sp +Will return False if host already exists, or the iSCSI or +Fibre Channel parameters are not in a valid format. +See Pure Storage FlashArray documentation. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of host (truncated to 63 characters) +.TP +.B iqn +string +iSCSI IQN of host +.TP +.B wwn +string +Fibre Channel WWN of host +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.host_create foo iqn=\(aq\(aq wwn=\(aq\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.host_delete(name) +Delete a host on a Pure Storage FlashArray (detaches all volumes). +.sp +Will return False if the host doesn\(aqt exist. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of host +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.host_delete foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.host_update(name, iqn=None, wwn=None) +Update a hosts port definitions on a Pure Storage FlashArray. +.sp +Will return False if new port definitions are already in use +by another host, or are not in a valid format. +See Pure Storage FlashArray documentation. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of host +.TP +.B iqn +string +Additional iSCSI IQN of host +.TP +.B wwn +string +Additional Fibre Channel WWN of host +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.host_update foo iqn=\(aq\(aq wwn=\(aq\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.pg_create(name, hostgroup=None, host=None, volume=None, enabled=True) +Create a protection group on a Pure Storage FlashArray. +.INDENT 7.0 +.TP +.B Will return False is the following cases: +.INDENT 7.0 +.IP \(bu 2 +Protection Grop already exists +.IP \(bu 2 +Protection Group in a deleted state +.IP \(bu 2 +More than one type is specified \- protection groups are for only +hostgroups, hosts or volumes +.IP \(bu 2 +Named type for protection group does not exist +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of protection group +.TP +.B hostgroup +string +name of hostgroup to add to protection group +.TP +.B host +string +name of host to add to protection group +.TP +.B volume +string +name of volume to add to protection group +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.pg_create foo [hostgroup=foo | host=bar | volume=vol] enabled=[true | false] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.pg_delete(name, eradicate=False) +Delete a protecton group on a Pure Storage FlashArray. +.sp +Will return False if protection group is already in a deleted state. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of protection group +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.pg_delete foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.pg_eradicate(name) +Eradicate a deleted protecton group on a Pure Storage FlashArray. +.sp +Will return False if protection group is not in a deleted state. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of protection group +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.pg_eradicate foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.pg_remove(name, hostgroup=None, host=None, volume=None) +Remove a hostgroup, host or volume from a protection group on a Pure Storage FlashArray. +.INDENT 7.0 +.TP +.B Will return False in the following cases: +.INDENT 7.0 +.IP \(bu 2 +Protection group does not exist +.IP \(bu 2 +Specified type is not currently associated with the protection group +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of hostgroup +.TP +.B hostgroup +string +name of hostgroup to remove from protection group +.TP +.B host +string +name of host to remove from hostgroup +.TP +.B volume +string +name of volume to remove from hostgroup +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.pg_remove foo [hostgroup=bar | host=test | volume=bar] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.pg_update(name, hostgroup=None, host=None, volume=None) +Update a protection group on a Pure Storage FlashArray. +.INDENT 7.0 +.TP +.B Will return False in the following cases: +.INDENT 7.0 +.IP \(bu 2 +Protection group does not exist +.IP \(bu 2 +Incorrect type selected for current protection group type +.IP \(bu 2 +Specified type does not exist +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of protection group +.TP +.B hostgroup +string +name of hostgroup to add to protection group +.TP +.B host +string +name of host to add to protection group +.TP +.B volume +string +name of volume to add to protection group +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.pg_update foo [hostgroup=foo | host=bar | volume=vol] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.snap_create(name, suffix=None) +Create a volume snapshot on a Pure Storage FlashArray. +.sp +Will return False is volume selected to snap does not exist. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume to snapshot +.TP +.B suffix +string +if specificed forces snapshot name suffix. If not specified defaults to timestamp. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.snap_create foo +salt \(aq*\(aq purefa.snap_create foo suffix=bar +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.snap_delete(name, suffix=None, eradicate=False) +Delete a volume snapshot on a Pure Storage FlashArray. +.sp +Will return False if selected snapshot does not exist. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume +.TP +.B suffix +string +name of snapshot +.TP +.B eradicate +boolean +Eradicate snapshot after deletion if True. Default is False +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.snap_delete foo suffix=snap eradicate=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.snap_eradicate(name, suffix=None) +Eradicate a deleted volume snapshot on a Pure Storage FlashArray. +.sp +Will return False if snapshot is not in a deleted state. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume +.TP +.B suffix +string +name of snapshot +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.snap_eradicate foo suffix=snap +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.snap_volume_create(name, target, overwrite=False) +Create R/W volume from snapshot on a Pure Storage FlashArray. +.sp +Will return False if target volume already exists and +overwrite is not specified, or selected snapshot doesn\(aqt exist. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume snapshot +.TP +.B target +string +name of clone volume +.TP +.B overwrite +boolean +overwrite clone if already exists (default: False) +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.snap_volume_create foo.bar clone overwrite=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.volume_attach(name, host) +Attach a volume to a host on a Pure Storage FlashArray. +.sp +Host and volume must exist or else will return False. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume +.TP +.B host +string +name of host +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.volume_attach foo bar +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.volume_clone(name, target, overwrite=False) +Clone an existing volume on a Pure Storage FlashArray. +.sp +Will return False if source volume doesn\(aqt exist, or +target volume already exists and overwrite not specified. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume +.TP +.B target +string +name of clone volume +.TP +.B overwrite +boolean +overwrite clone if already exists (default: False) +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.volume_clone foo bar overwrite=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.volume_create(name, size=None) +Create a volume on a Pure Storage FlashArray. +.sp +Will return False if volume already exists. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume (truncated to 63 characters) +.TP +.B size +string +if specificed capacity of volume. If not specified default to 1G. +Refer to Pure Storage documentation for formatting rules. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.volume_create foo +salt \(aq*\(aq purefa.volume_create foo size=10T +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.volume_delete(name, eradicate=False) +Delete a volume on a Pure Storage FlashArray. +.sp +Will return False if volume doesn\(aqt exist is already in a deleted state. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume +.TP +.B eradicate +boolean +Eradicate volume after deletion if True. Default is False +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.volume_delete foo eradicate=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.volume_detach(name, host) +Detach a volume from a host on a Pure Storage FlashArray. +.sp +Will return False if either host or volume do not exist, or +if selected volume isn\(aqt already connected to the host. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume +.TP +.B host +string +name of host +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.volume_detach foo bar +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.volume_eradicate(name) +Eradicate a deleted volume on a Pure Storage FlashArray. +.sp +Will return False is volume is not in a deleted state. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.volume_eradicate foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.purefa.volume_extend(name, size) +Extend an existing volume on a Pure Storage FlashArray. +.sp +Will return False if new size is less than or equal to existing size. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B name +string +name of volume +.TP +.B size +string +New capacity of volume. +Refer to Pure Storage documentation for formatting rules. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq purefa.volume_extend foo 10T +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.pushbullet module .sp Module for sending messages to Pushbullet (\fI\%https://www.pushbullet.com\fP) @@ -204719,7 +218498,7 @@ minion, and it is using a different module (or gives an error similar to .UNINDENT .INDENT 0.0 .TP -.B salt.modules.pw_user.add(name, uid=None, gid=None, groups=None, home=None, shell=None, unique=True, fullname=\(aq\(aq, roomnumber=\(aq\(aq, workphone=\(aq\(aq, homephone=\(aq\(aq, createhome=True, loginclass=None, **kwargs) +.B salt.modules.pw_user.add(name, uid=None, gid=None, groups=None, home=None, shell=None, unique=True, fullname=u\(aq\(aq, roomnumber=u\(aq\(aq, workphone=u\(aq\(aq, homephone=u\(aq\(aq, createhome=True, loginclass=None, **kwargs) Add a user to the minion .sp CLI Example: @@ -205744,7 +219523,7 @@ salt \(aq*\(aq rabbitmq.force_reset .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rabbitmq.join_cluster(host, user=\(aqrabbit\(aq, ram_node=None, runas=None) +.B salt.modules.rabbitmq.join_cluster(host, user=u\(aqrabbit\(aq, ram_node=None, runas=None) Join a rabbit cluster .sp CLI Example: @@ -205812,7 +219591,7 @@ salt \(aq*\(aq rabbitmq.list_permissions \(aq/myvhost\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rabbitmq.list_policies(vhost=\(aq/\(aq, runas=None) +.B salt.modules.rabbitmq.list_policies(vhost=u\(aq/\(aq, runas=None) Return a dictionary of policies nested by vhost and name based on the data returned from rabbitmqctl list_policies. .sp @@ -205972,7 +219751,7 @@ salt \(aq*\(aq rabbitmq.reset .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rabbitmq.set_permissions(vhost, user, conf=\(aq.*\(aq, write=\(aq.*\(aq, read=\(aq.*\(aq, runas=None) +.B salt.modules.rabbitmq.set_permissions(vhost, user, conf=u\(aq.*\(aq, write=u\(aq.*\(aq, read=u\(aq.*\(aq, runas=None) Sets permissions for vhost via rabbitmqctl set_permissions .sp CLI Example: @@ -205989,7 +219768,7 @@ salt \(aq*\(aq rabbitmq.set_permissions \(aqmyvhost\(aq \(aqmyuser\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rabbitmq.set_policy(vhost, name, pattern, definition, priority=None, runas=None) +.B salt.modules.rabbitmq.set_policy(vhost, name, pattern, definition, priority=None, apply_to=None, runas=None) Set a policy based on rabbitmqctl set_policy. .sp Reference: \fI\%http://www.rabbitmq.com/ha.html\fP @@ -206113,7 +219892,7 @@ salt \(aq*\(aq rabbitmq.vhost_exists rabbit_host Publish a command from a minion to a target .INDENT 0.0 .TP -.B salt.modules.raet_publish.full_data(tgt, fun, arg=None, tgt_type=\(aqglob\(aq, returner=\(aq\(aq, timeout=5, expr_form=None) +.B salt.modules.raet_publish.full_data(tgt, fun, arg=None, tgt_type=u\(aqglob\(aq, returner=u\(aq\(aq, timeout=5, expr_form=None) Return the full data about the publication, this is invoked in the same way as the publish function .sp @@ -206150,7 +219929,7 @@ salt \(aq*\(aq publish.full_data test.kwarg arg=\(aqcheese=spam\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.raet_publish.publish(tgt, fun, arg=None, tgt_type=\(aqglob\(aq, returner=\(aq\(aq, timeout=5, expr_form=None) +.B salt.modules.raet_publish.publish(tgt, fun, arg=None, tgt_type=u\(aqglob\(aq, returner=u\(aq\(aq, timeout=5, expr_form=None) Publish a command from the minion out to other minions. .sp Publications need to be enabled on the Salt master and the minion @@ -206296,7 +220075,7 @@ salt myminion rallydev.list_users .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rallydev.query_item(name, query_string, order=\(aqRank\(aq) +.B salt.modules.rallydev.query_item(name, query_string, order=u\(aqRank\(aq) Query a type of record for one or more items. Requires a valid query string. See \fI\%https://rally1.rallydev.com/slm/doc/webservice/introduction.jsp\fP for information on query syntax. @@ -206317,7 +220096,7 @@ salt myminion rallydev.query_task \(aq(Name contains reactor)\(aq Rank .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rallydev.query_user(query_string, order=\(aqUserName\(aq) +.B salt.modules.rallydev.query_user(query_string, order=u\(aqUserName\(aq) Update a user .sp CLI Example: @@ -207541,7 +221320,7 @@ salt \(aq*\(aq redis.bgsave .UNINDENT .INDENT 0.0 .TP -.B salt.modules.redismod.config_get(pattern=\(aq*\(aq, host=None, port=None, db=None, password=None) +.B salt.modules.redismod.config_get(pattern=u\(aq*\(aq, host=None, port=None, db=None, password=None) Get redis server configuration values .sp CLI Example: @@ -208017,7 +221796,7 @@ salt \(aq*\(aq redis.type foo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.redismod.keys(pattern=\(aq*\(aq, host=None, port=None, db=None, password=None) +.B salt.modules.redismod.keys(pattern=u\(aq*\(aq, host=None, port=None, db=None, password=None) Get redis keys, supports glob style patterns .sp CLI Example: @@ -208259,7 +222038,8 @@ salt \(aq*\(aq redis.zrange foo_sorted 0 10 .UNINDENT .UNINDENT .SS salt.modules.reg -.SS Manage the Windows registry +.sp +Manage the Windows registry .SS Hives .sp Hives are the main sections of the registry and all begin with the word HKEY. @@ -208328,6 +222108,10 @@ HKEY_LOCAL_MACHINE or HKLM HKEY_CURRENT_USER or HKCU .IP \(bu 2 HKEY_USER or HKU +.IP \(bu 2 +HKEY_CLASSES_ROOT or HKCR +.IP \(bu 2 +HKEY_CURRENT_CONFIG or HKCC .UNINDENT .IP \(bu 2 @@ -208379,6 +222163,10 @@ HKEY_LOCAL_MACHINE or HKLM HKEY_CURRENT_USER or HKCU .IP \(bu 2 HKEY_USER or HKU +.IP \(bu 2 +HKEY_CLASSES_ROOT or HKCR +.IP \(bu 2 +HKEY_CURRENT_CONFIG or HKCC .UNINDENT .IP \(bu 2 @@ -208412,6 +222200,55 @@ salt \(aq*\(aq reg.delete_value HKEY_CURRENT_USER \(aqSOFTWARE\eSalt\(aq \(aqver .UNINDENT .INDENT 0.0 .TP +.B salt.modules.reg.import_file(source, use_32bit_registry=False) +Import registry settings from a Windows \fBREG\fP file by invoking \fBREG.EXE\fP\&. +.sp +New in version 2018.3.0. + +.sp +Usage: +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt machine1 reg.import_file salt://win/printer_config/110_Canon/postinstall_config.reg +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBsource\fP (\fI\%str\fP) \-\- The full path of the \fBREG\fP file. This +can be either a local file path or a URL type supported by salt +(e.g. \fBsalt://salt_master_path\fP). +.IP \(bu 2 +\fBuse_32bit_registry\fP (\fI\%bool\fP) \-\- If the value of this paramater is \fBTrue\fP +then the \fBREG\fP file will be imported into the Windows 32 bit registry. +Otherwise the Windows 64 bit registry will be used. +.UNINDENT +.TP +.B Returns +If the value of \fBsource\fP is an invalid path or otherwise +causes \fBcp.cache_file\fP to return \fBFalse\fP then +the function will not return and +a \fBValueError\fP exception will be raised. +If \fBreg.exe\fP exits with a non\-0 exit code, then +a \fBCommandExecutionError\fP exception will be +raised. On success this function will return +\fBTrue\fP\&. +.TP +.B Return type +\fI\%bool\fP +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.reg.list_keys(hive, key=None, use_32bit_registry=False) Enumerates the subkeys in a registry key or hive. .INDENT 7.0 @@ -208429,6 +222266,10 @@ HKEY_LOCAL_MACHINE or HKLM HKEY_CURRENT_USER or HKCU .IP \(bu 2 HKEY_USER or HKU +.IP \(bu 2 +HKEY_CLASSES_ROOT or HKCR +.IP \(bu 2 +HKEY_CURRENT_CONFIG or HKCC .UNINDENT .IP \(bu 2 @@ -208477,6 +222318,10 @@ HKEY_LOCAL_MACHINE or HKLM HKEY_CURRENT_USER or HKCU .IP \(bu 2 HKEY_USER or HKU +.IP \(bu 2 +HKEY_CLASSES_ROOT or HKCR +.IP \(bu 2 +HKEY_CURRENT_CONFIG or HKCC .UNINDENT .IP \(bu 2 @@ -208527,6 +222372,10 @@ HKEY_LOCAL_MACHINE or HKLM HKEY_CURRENT_USER or HKCU .IP \(bu 2 HKEY_USER or HKU +.IP \(bu 2 +HKEY_CLASSES_ROOT or HKCR +.IP \(bu 2 +HKEY_CURRENT_CONFIG or HKCC .UNINDENT .IP \(bu 2 @@ -208588,6 +222437,10 @@ HKEY_LOCAL_MACHINE or HKLM HKEY_CURRENT_USER or HKCU .IP \(bu 2 HKEY_USER or HKU +.IP \(bu 2 +HKEY_CLASSES_ROOT or HKCR +.IP \(bu 2 +HKEY_CURRENT_CONFIG or HKCC .UNINDENT .IP \(bu 2 @@ -208875,11 +222728,32 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.rest_service.status(name, sig=None) -Return the status for a service via rest_sample, returns a bool -whether the service is running. +Return the status for a service via rest_sample. +If the name contains globbing, a dict mapping service name to True/False +values is returned. .sp New in version 2015.8.0. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Not implemented +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -209238,7 +223112,7 @@ minion, and it is using a different module (or gives an error similar to .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rh_service.available(name, limit=\(aq\(aq) +.B salt.modules.rh_service.available(name, limit=u\(aq\(aq) Return True if the named service is available. Use the \fBlimit\fP param to restrict results to services of that type. .sp @@ -209346,7 +223220,7 @@ salt \(aq*\(aq service.enabled .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rh_service.get_all(limit=\(aq\(aq) +.B salt.modules.rh_service.get_all(limit=u\(aq\(aq) Return all installed services. Use the \fBlimit\fP param to restrict results to services of that type. .sp @@ -209366,7 +223240,7 @@ salt \(aq*\(aq service.get_all limit=sysvinit .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rh_service.get_disabled(limit=\(aq\(aq) +.B salt.modules.rh_service.get_disabled(limit=u\(aq\(aq) Return the disabled services. Use the \fBlimit\fP param to restrict results to services of that type. .sp @@ -209386,7 +223260,7 @@ salt \(aq*\(aq service.get_disabled limit=sysvinit .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rh_service.get_enabled(limit=\(aq\(aq) +.B salt.modules.rh_service.get_enabled(limit=u\(aq\(aq) Return the enabled services. Use the \fBlimit\fP param to restrict results to services of that type. .sp @@ -209406,7 +223280,7 @@ salt \(aq*\(aq service.get_enabled limit=sysvinit .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rh_service.missing(name, limit=\(aq\(aq) +.B salt.modules.rh_service.missing(name, limit=u\(aq\(aq) The inverse of service.available. Return True if the named service is not available. Use the \fBlimit\fP param to restrict results to services of that type. @@ -209479,8 +223353,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.rh_service.status(name, sig=None) -Return the status for a service, returns a bool whether the service is -running. +Return the status for a service. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Signature to use to find the service via ps +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -209488,7 +223383,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq service.status +salt \(aq*\(aq service.status [service signature] .ft P .fi .UNINDENT @@ -209722,7 +223617,7 @@ salt \(aq*\(aq riak.test Support for rpm .INDENT 0.0 .TP -.B salt.modules.rpm.bin_pkg_info(path, saltenv=\(aqbase\(aq) +.B salt.modules.rpm.bin_pkg_info(path, saltenv=u\(aqbase\(aq) New in version 2015.8.0. .sp @@ -210030,7 +223925,7 @@ environments. This also provides a function to generate yum repositories This module implements the pkgbuild interface .INDENT 0.0 .TP -.B salt.modules.rpmbuild.build(runas, tgt, dest_dir, spec, sources, deps, env, template, saltenv=\(aqbase\(aq, log_dir=\(aq/var/log/salt/pkgbuild\(aq) +.B salt.modules.rpmbuild.build(runas, tgt, dest_dir, spec, sources, deps, env, template, saltenv=u\(aqbase\(aq, log_dir=u\(aq/var/log/salt/pkgbuild\(aq) Given the package destination directory, the spec file source and package sources, use mock to safely build the rpm defined in the spec file .sp @@ -210051,7 +223946,7 @@ mock and place it in /var/www/html/ on the minion .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rpmbuild.make_repo(repodir, keyid=None, env=None, use_passphrase=False, gnupghome=\(aq/etc/salt/gpgkeys\(aq, runas=\(aqroot\(aq, timeout=15.0) +.B salt.modules.rpmbuild.make_repo(repodir, keyid=None, env=None, use_passphrase=False, gnupghome=u\(aq/etc/salt/gpgkeys\(aq, runas=u\(aqroot\(aq, timeout=15.0) Make a package repository and optionally sign packages present .sp Given the repodir, create a \fByum\fP repository out of the rpms therein @@ -210190,7 +224085,7 @@ salt \(aq*\(aq pkgbuild.make_repo /var/www/html/ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rpmbuild.make_src_pkg(dest_dir, spec, sources, env=None, template=None, saltenv=\(aqbase\(aq) +.B salt.modules.rpmbuild.make_src_pkg(dest_dir, spec, sources, env=None, template=None, saltenv=u\(aqbase\(aq) Create a source rpm from the given spec file and sources .sp CLI Example: @@ -210229,7 +224124,7 @@ This data can also be passed into pillar\&. Options passed into opts will overwrite options passed into pillar. .INDENT 0.0 .TP -.B salt.modules.rsync.config(conf_path=\(aq/etc/rsyncd.conf\(aq) +.B salt.modules.rsync.config(conf_path=u\(aq/etc/rsyncd.conf\(aq) Changed in version 2016.3.0: Return data now contains just the contents of the rsyncd.conf as a string, instead of a dictionary as returned from \fBcmd.run_all\fP\&. @@ -210256,12 +224151,74 @@ salt \(aq*\(aq rsync.config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rsync.rsync(src, dst, delete=False, force=False, update=False, passwordfile=None, exclude=None, excludefrom=None, dryrun=False, rsh=None) +.B salt.modules.rsync.rsync(src, dst, delete=False, force=False, update=False, passwordfile=None, exclude=None, excludefrom=None, dryrun=False, rsh=None, additional_opts=None, saltenv=u\(aqbase\(aq) +.INDENT 7.0 +.INDENT 3.5 Changed in version 2016.3.0: Return data now contains just the output of the rsync command, instead of a dictionary as returned from \fBcmd.run_all\fP\&. .sp Rsync files from src to dst +.INDENT 0.0 +.TP +.B src +The source location where files will be rsynced from. +.TP +.B dst +The destination location where files will be rsynced to. +.TP +.B delete +False +Whether to enable the rsync \fI\-\-delete\fP flag, which +will delete extraneous files from dest dirs +.TP +.B force +False +Whether to enable the rsync \fI\-\-force\fP flag, which +will force deletion of dirs even if not empty. +.TP +.B update +False +Whether to enable the rsync \fI\-\-update\fP flag, which +forces rsync to skip any files which exist on the +destination and have a modified time that is newer +than the source file. +.TP +.B passwordfile +A file that contains a password for accessing an +rsync daemon. The file should contain just the +password. +.TP +.B exclude +Whether to enable the rsync \fI\-\-exclude\fP flag, which +will exclude files matching a PATTERN. +.TP +.B excludefrom +Whether to enable the rsync \fI\-\-excludefrom\fP flag, which +will read exclude patterns from a file. +.TP +.B dryrun +False +Whether to enable the rsync \fI\-\-dry\-run\fP flag, which +will perform a trial run with no changes made. +.TP +.B rsh +Whether to enable the rsync \fI\-\-rsh\fP flag, to +specify the remote shell to use. +.TP +.B additional_opts +Any additional rsync options, should be specified as a list. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B saltenv +.INDENT 7.0 +.INDENT 3.5 +Specify a salt fileserver environment to be used. +.UNINDENT +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -210271,11 +224228,14 @@ CLI Example: .ft C salt \(aq*\(aq rsync.rsync {src} {dst} {delete=True} {update=True} {passwordfile=/etc/pass.crt} {exclude=xx} {rsh} salt \(aq*\(aq rsync.rsync {src} {dst} {delete=True} {excludefrom=/xx.ini} {rsh} + +salt \(aq*\(aq rsync.rsync {src} {dst} {delete=True} {excludefrom=/xx.ini} additional_opts=\(aq["\-\-partial", "\-\-bwlimit=5000"]\(aq .ft P .fi .UNINDENT .UNINDENT .UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.modules.rsync.version() @@ -210577,7 +224537,7 @@ Return list of paths that may contain available services .UNINDENT .INDENT 0.0 .TP -.B salt.modules.runit.get_svc_broken_path(name=\(aq*\(aq) +.B salt.modules.runit.get_svc_broken_path(name=u\(aq*\(aq) Return list of broken path(s) in SERVICE_DIR that match \fBname\fP .sp A path is broken if it is a broken symlink or can not be a runit service @@ -210806,7 +224766,7 @@ salt \(aq*\(aq runit.stop Manage ruby installations and gemsets with RVM, the Ruby Version Manager. .INDENT 0.0 .TP -.B salt.modules.rvm.do(ruby, command, runas=None, cwd=None) +.B salt.modules.rvm.do(ruby, command, runas=None, cwd=None, env=None) Execute a command in an RVM controlled environment. .INDENT 7.0 .TP @@ -210955,7 +224915,7 @@ salt \(aq*\(aq rvm.gemset_empty 2.0.0 foobar .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rvm.gemset_list(ruby=\(aqdefault\(aq, runas=None) +.B salt.modules.rvm.gemset_list(ruby=u\(aqdefault\(aq, runas=None) List all gemsets for the given ruby. .INDENT 7.0 .TP @@ -211007,7 +224967,7 @@ salt \(aq*\(aq rvm.gemset_list_all .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rvm.get(version=\(aqstable\(aq, runas=None) +.B salt.modules.rvm.get(version=u\(aqstable\(aq, runas=None) Update RVM .INDENT 7.0 .TP @@ -211053,7 +225013,7 @@ salt \(aq*\(aq rvm.install .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rvm.install_ruby(ruby, runas=None) +.B salt.modules.rvm.install_ruby(ruby, runas=None, opts=None, env=None) Install a ruby implementation. .INDENT 7.0 .TP @@ -211063,6 +225023,13 @@ The version of ruby to install .B runas The user under which to run rvm. If not specified, then rvm will be run as the user under which Salt is running. +.TP +.B env +Environment to set for the install command. Useful for exporting compilation +flags such as RUBY_CONFIGURE_OPTS +.TP +.B opts +List of options to pass to the RVM installer (ie \-C, \-\-patch, etc) .UNINDENT .sp CLI Example: @@ -211119,7 +225086,7 @@ salt \(aq*\(aq rvm.list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.rvm.reinstall_ruby(ruby, runas=None) +.B salt.modules.rvm.reinstall_ruby(ruby, runas=None, env=None) Reinstall a ruby implementation .INDENT 7.0 .TP @@ -211386,7 +225353,7 @@ salt myminion s3.delete mybucket remoteobject .UNINDENT .INDENT 0.0 .TP -.B salt.modules.s3.get(bucket=\(aq\(aq, path=\(aq\(aq, return_bin=False, action=None, local_file=None, key=None, keyid=None, service_url=None, verify_ssl=None, kms_keyid=None, location=None, role_arn=None, path_style=None, https_enable=None) +.B salt.modules.s3.get(bucket=u\(aq\(aq, path=u\(aq\(aq, return_bin=False, action=None, local_file=None, key=None, keyid=None, service_url=None, verify_ssl=None, kms_keyid=None, location=None, role_arn=None, path_style=None, https_enable=None) List the contents of a bucket, or return an object from a bucket. Set return_bin to True in order to retrieve an object wholesale. Otherwise, Salt will attempt to parse an XML response. @@ -211477,7 +225444,7 @@ salt myminion s3.get mybucket myfile.png action=acl .UNINDENT .INDENT 0.0 .TP -.B salt.modules.s3.head(bucket, path=\(aq\(aq, key=None, keyid=None, service_url=None, verify_ssl=None, kms_keyid=None, location=None, role_arn=None, path_style=None, https_enable=None) +.B salt.modules.s3.head(bucket, path=u\(aq\(aq, key=None, keyid=None, service_url=None, verify_ssl=None, kms_keyid=None, location=None, role_arn=None, path_style=None, https_enable=None) Return the metadata for a bucket, or an object in a bucket. .sp CLI Examples: @@ -211847,7 +225814,30 @@ salt \(aq*\(aq saltutil.clear_cache .UNINDENT .INDENT 0.0 .TP -.B salt.modules.saltutil.cmd(tgt, fun, arg=(), timeout=None, tgt_type=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, ssh=False, **kwargs) +.B salt.modules.saltutil.clear_job_cache(hours=24) +Forcibly removes job cache folders and files on a minion. +.sp +New in version 2018.3.0. + +.sp +WARNING: The safest way to clear a minion cache is by first stopping +the minion and then deleting the cache files before restarting it. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq saltutil.clear_job_cache hours=12 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.saltutil.cmd(tgt, fun, arg=(), timeout=None, tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, kwarg=None, ssh=False, **kwargs) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -211868,7 +225858,7 @@ salt \(aq*\(aq saltutil.cmd .UNINDENT .INDENT 0.0 .TP -.B salt.modules.saltutil.cmd_iter(tgt, fun, arg=(), timeout=None, tgt_type=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, ssh=False, **kwargs) +.B salt.modules.saltutil.cmd_iter(tgt, fun, arg=(), timeout=None, tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, kwarg=None, ssh=False, **kwargs) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -212193,7 +226183,7 @@ salt \(aq*\(aq saltutil.revoke_auth .UNINDENT .INDENT 0.0 .TP -.B salt.modules.saltutil.runner(name, arg=None, kwarg=None, full_return=False, saltenv=\(aqbase\(aq, jid=None, **kwargs) +.B salt.modules.saltutil.runner(name, arg=None, kwarg=None, full_return=False, saltenv=u\(aqbase\(aq, jid=None, **kwargs) Execute a runner function. This function must be run on the master, either by targeting a minion running on a master or by using salt\-call on a master. @@ -212379,7 +226369,7 @@ salt \(aq*\(aq saltutil.sync_beacons saltenv=base,dev New in version 2017.7.0. .sp -Sync utility modules from \fBsalt://_cloud\fP to the minion +Sync cloud modules from \fBsalt://_cloud\fP to the minion .INDENT 7.0 .TP .B saltenv @@ -212856,7 +226846,7 @@ salt \(aq*\(aq saltutil.sync_renderers saltenv=base,dev New in version 0.10.0. .sp -Sync beacons from \fBsalt://_returners\fP to the minion +Sync returners from \fBsalt://_returners\fP to the minion .INDENT 7.0 .TP .B saltenv @@ -212985,6 +226975,47 @@ salt \(aq*\(aq saltutil.sync_states saltenv=base,dev .UNINDENT .INDENT 0.0 .TP +.B salt.modules.saltutil.sync_thorium(saltenv=None, refresh=False, extmod_whitelist=None, extmod_blacklist=None) +New in version 2018.3.0. + +.sp +Sync Thorium modules from \fBsalt://_thorium\fP to the minion +.INDENT 7.0 +.TP +.B saltenv +The fileserver environment from which to sync. To sync from more than +one environment, pass a comma\-separated list. +.sp +If not passed, then all environments configured in the top files will be checked for engines to sync. If no top files are +found, then the \fBbase\fP environment will be synced. +.TP +.B refresh: \fBTrue\fP +If \fBTrue\fP, refresh the available execution modules on the minion. +This refresh will be performed even if no new Thorium modules are synced. +Set to \fBFalse\fP to prevent this refresh. +.TP +.B extmod_whitelist +comma\-seperated list of modules to sync +.TP +.B extmod_blacklist +comma\-seperated list of modules to blacklist based on type +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq saltutil.sync_thorium +salt \(aq*\(aq saltutil.sync_thorium saltenv=base,dev +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.saltutil.sync_utils(saltenv=None, refresh=True, extmod_whitelist=None, extmod_blacklist=None) New in version 2014.7.0. @@ -213363,6 +227394,31 @@ salt \(aq*\(aq schedule.move jobname target .UNINDENT .INDENT 0.0 .TP +.B salt.modules.schedule.postpone_job(name, current_time, new_time, **kwargs) +Postpone a job in the minion\(aqs schedule +.sp +Current time and new time should be in date string format, +default value is %Y\-%m\-%dT%H:%M:%S. +.sp +New in version 2018.3.0. + +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq schedule.postpone_job job current_time new_time + +salt \(aq*\(aq schedule.postpone_job job current_time new_time time_fmt=\(aq%Y\-%m\-%dT%H:%M:%S\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.schedule.purge(**kwargs) Purge all the jobs currently scheduled on the minion .sp @@ -213432,6 +227488,49 @@ salt \(aq*\(aq schedule.save .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.schedule.show_next_fire_time(name, **kwargs) +Show the next fire time for scheduled job +.sp +New in version 2018.3.0. + +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq schedule.show_next_fire_time job_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.schedule.skip_job(name, current_time, **kwargs) +Skip a job in the minion\(aqs schedule at specified time. +.sp +Time to skip should be specified as date string format, +default value is %Y\-%m\-%dT%H:%M:%S. +.sp +New in version 2018.3.0. + +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq schedule.skip_job job time +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.scsi .sp SCSI administration module @@ -213522,7 +227621,7 @@ salt \(aq*\(aq sdb.get sdb://mymemcached/foo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.sdb.get_or_set_hash(uri, length=8, chars=\(aqabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(\-_=+)\(aq) +.B salt.modules.sdb.get_or_set_hash(uri, length=8, chars=u\(aqabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(\-_=+)\(aq) Perform a one\-time generation of a hash and write it to sdb. If that value has already been set return the value instead. .sp @@ -213841,7 +227940,7 @@ salt \(aq*\(aq selinux.fcontext_policy_is_applied my\-policy .UNINDENT .INDENT 0.0 .TP -.B salt.modules.selinux.filetype_id_to_string(filetype=\(aqa\(aq) +.B salt.modules.selinux.filetype_id_to_string(filetype=u\(aqa\(aq) New in version 2017.7.0. .sp @@ -214105,8 +228204,8 @@ new sense_hat Python module .UNINDENT .sp -You can specify the rotation of the Pi in a pillar. -This is useful if it is used upside down or sideways to correct the orientation of the image being shown. +The rotation of the Pi can be specified in a pillar. +This is useful if the Pi is used upside down or sideways to correct the orientation of the image being shown. .sp Example: .INDENT 0.0 @@ -214150,30 +228249,30 @@ Returns the color of a single pixel on the LED matrix. .INDENT 7.0 .TP .B x -The x coodrinate of th pixel. Ranges from 0 on the left to 7 on the right. +The x coordinate of the pixel. Ranges from 0 on the left to 7 on the right. .TP .B y -The y coodrinate of th pixel. Ranges from 0 at the top to 7 at the bottom. +The y coordinate of the pixel. Ranges from 0 at the top to 7 at the bottom. .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -Please read the note for \fIget_pixels\fP +Please read the note for \fBget_pixels\fP .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B salt.modules.sensehat.get_pixels() -Returns a list of 64 smaller lists of \fI[R, G, B]\fP pixels representing the +Returns a list of 64 smaller lists of \fB[R, G, B]\fP pixels representing the the currently displayed image on the LED matrix. .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -When using \fIset_pixels\fP the pixel values can sometimes change when -you read them again using \fIget_pixels\fP\&. This is because we specify each +When using \fBset_pixels\fP the pixel values can sometimes change when +you read them again using \fBget_pixels\fP\&. This is because we specify each pixel element as 8 bit numbers (0 to 255) but when they\(aqre passed into the Linux frame buffer for the LED matrix the numbers are bit shifted down to fit into RGB 565. 5 bits for red, 6 bits for green and 5 bits for blue. @@ -214181,8 +228280,8 @@ The loss of binary precision when performing this conversion (3 bits lost for red, 2 for green and 3 for blue) accounts for the discrepancies you see. .sp -The \fIget_pixels\fP method provides an accurate representation of how the -pixels end up in frame buffer memory after you have called \fIset_pixels\fP\&. +The \fBget_pixels\fP method provides an accurate representation of how the +pixels end up in frame buffer memory after you have called \fBset_pixels\fP\&. .UNINDENT .UNINDENT .UNINDENT @@ -214195,9 +228294,9 @@ Gets the current pressure in Millibars from the pressure sensor. .TP .B salt.modules.sensehat.get_temperature() Gets the temperature in degrees Celsius from the humidity sensor. -Equivalent to calling \fIget_temperature_from_humidity\fP\&. +Equivalent to calling \fBget_temperature_from_humidity\fP\&. .sp -If you get strange results try using \(aqget_temperature_from_pressure\(aq. +If you get strange results try using \fBget_temperature_from_pressure\fP\&. .UNINDENT .INDENT 0.0 .TP @@ -214230,17 +228329,17 @@ salt \(aqraspberry\(aq sensehat.low_light False .INDENT 0.0 .TP .B salt.modules.sensehat.set_pixel(x, y, color) -Sets the a single pixel on the LED matrix to a specified color. +Sets a single pixel on the LED matrix to a specified color. .INDENT 7.0 .TP .B x -The x coodrinate of th pixel. Ranges from 0 on the left to 7 on the right. +The x coordinate of the pixel. Ranges from 0 on the left to 7 on the right. .TP .B y -The y coodrinate of th pixel. Ranges from 0 at the top to 7 at the bottom. +The y coordinate of the pixel. Ranges from 0 at the top to 7 at the bottom. .TP .B color -The new color of the pixel as a list of \fI[R, G, B]\fP values. +The new color of the pixel as a list of \fB[R, G, B]\fP values. .UNINDENT .sp CLI Example: @@ -214262,13 +228361,13 @@ Sets the entire LED matrix based on a list of 64 pixel values .INDENT 7.0 .TP .B pixels -A list of 64 color values [R, G, B]. +A list of 64 \fB[R, G, B]\fP color values. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B salt.modules.sensehat.show_image(image) -Displays a 8 x 8 image on the LED matrix. +Displays an 8 x 8 image on the LED matrix. .INDENT 7.0 .TP .B image @@ -214319,7 +228418,7 @@ salt \(aqraspberry\(aq sensehat.show_letter B \(aq[0, 0, 255]\(aq \(aq[255, 255, .UNINDENT .INDENT 0.0 .TP -.B salt.modules.sensehat.show_message(message, msg_type=None, text_color=None, back_color=None, scroll_speed=None) +.B salt.modules.sensehat.show_message(message, msg_type=None, text_color=None, back_color=None, scroll_speed=0.1) Displays a message on the LED matrix. .INDENT 7.0 .TP @@ -214443,7 +228542,7 @@ salt \(aq*\(aq serverdensity_device.delete 51f7eafcdba4bb235e000ae4 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.serverdensity_device.get_sd_auth(val, sd_auth_pillar_name=\(aqserverdensity\(aq) +.B salt.modules.serverdensity_device.get_sd_auth(val, sd_auth_pillar_name=u\(aqserverdensity\(aq) Returns requested Server Density authentication value from pillar. .sp CLI Example: @@ -214756,9 +228855,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.service.status(name, sig=None) -Return the status for a service, returns the PID or an empty string if the -service is running or not, pass a signature to use to find the service via -ps +Return the status for a service. +If the name contains globbing, a dict mapping service name to PID or empty +string is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Signature to use to find the service via ps +.UNINDENT +.TP +.B Returns +PID if running, empty otherwise +dict: Maps service name to PID if running, empty string otherwise +.TP +.B Return type +string +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -214879,7 +228998,7 @@ salt myminion servicenow.non_structured_query sys_computer role=web type=compute .UNINDENT .INDENT 0.0 .TP -.B salt.modules.servicenow.set_change_request_state(change_id, state=\(aqapproved\(aq) +.B salt.modules.servicenow.set_change_request_state(change_id, state=u\(aqapproved\(aq) Set the approval state of a change request/record .INDENT 7.0 .TP @@ -215029,7 +229148,7 @@ salt \(aq*\(aq shadow.del_password username .UNINDENT .INDENT 0.0 .TP -.B salt.modules.shadow.gen_password(password, crypt_salt=None, algorithm=\(aqsha512\(aq) +.B salt.modules.shadow.gen_password(password, crypt_salt=None, algorithm=u\(aqsha512\(aq) New in version 2014.7.0. .sp @@ -215098,11 +229217,31 @@ salt \(aq*\(aq shadow.info root .UNINDENT .INDENT 0.0 .TP +.B salt.modules.shadow.list_users() +New in version 2018.3.0. + +.sp +Return a list of all shadow users +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq shadow.list_users +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.shadow.lock_password(name) New in version 2016.11.0. .sp -Lock the password from name user +Lock the password from specified user .sp CLI Example: .INDENT 7.0 @@ -215302,7 +229441,7 @@ slack: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.slack_notify.call_hook(message, attachment=None, color=\(aqgood\(aq, short=False, identifier=None, channel=None, username=None, icon_emoji=None) +.B salt.modules.slack_notify.call_hook(message, attachment=None, color=u\(aqgood\(aq, short=False, identifier=None, channel=None, username=None, icon_emoji=None) Send message to Slack incoming webhook. .INDENT 7.0 .TP @@ -215337,7 +229476,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq slack.post_hook message=\(aqHello, from SaltStack\(aq +salt \(aq*\(aq slack.call_hook message=\(aqHello, from SaltStack\(aq .ft P .fi .UNINDENT @@ -215502,7 +229641,39 @@ salt \(aq*\(aq slack.post_message channel="Development Room" message="Build is d Utility functions for use with or in SLS files .INDENT 0.0 .TP -.B salt.modules.slsutil.merge(obj_a, obj_b, strategy=\(aqsmart\(aq, renderer=\(aqyaml\(aq, merge_lists=False) +.B salt.modules.slsutil.deserialize(serializer, stream_or_string, **mod_kwargs) +Deserialize a Python object using a \fBserializer module\fP +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq slsutil.deserialize \(aqjson\(aq \(aq{"foo": "Foo!"}\(aq +salt \(aq*\(aq \-\-no\-parse=stream_or_string slsutil.deserialize \(aqjson\(aq \e + stream_or_string=\(aq{"foo": "Foo!"}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Jinja Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{% set python_object = salt.slsutil.deserialize(\(aqjson\(aq, + \(aq{"foo": "Foo!"}\(aq) %} +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.slsutil.merge(obj_a, obj_b, strategy=u\(aqsmart\(aq, renderer=u\(aqyaml\(aq, merge_lists=False) Merge a data structure into another by choosing a merge strategy .sp Strategies: @@ -215533,8 +229704,11 @@ salt \(aq*\(aq slsutil.merge \(aq{foo: Foo}\(aq \(aq{bar: Bar}\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.slsutil.renderer(path=None, string=None, default_renderer=\(aqjinja|yaml\(aq, **kwargs) +.B salt.modules.slsutil.renderer(path=None, string=None, default_renderer=u\(aqjinja|yaml\(aq, **kwargs) Parse a string or file through Salt\(aqs renderer system +.sp +Changed in version 2018.3.0: Add support for Salt fileserver URIs. + .sp This is an open\-ended function and can be used for a variety of tasks. It makes use of Salt\(aqs "renderer pipes" system to run a string or file through @@ -215544,7 +229718,9 @@ a pipe of any of the loaded renderer modules. .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBpath\fP \-\- The path to a file on the filesystem. +\fBpath\fP \-\- The path to a file on Salt\(aqs fileserver (any URIs supported by +\fBcp.get_url\fP) or on the local file +system. .IP \(bu 2 \fBstring\fP \-\- An inline string to be used as the file to send through the renderer system. Note, not all renderer modules can work with strings; @@ -215620,6 +229796,7 @@ CLI Example: .sp .nf .ft C +salt \(aq*\(aq slsutil.renderer salt://path/to/file salt \(aq*\(aq slsutil.renderer /path/to/file salt \(aq*\(aq slsutil.renderer /path/to/file.jinja \(aqjinja\(aq salt \(aq*\(aq slsutil.renderer /path/to/file.sls \(aqjinja|yaml\(aq @@ -215632,6 +229809,36 @@ salt \(aq*\(aq slsutil.renderer string=\(aqHello, {{ name }}.\(aq name=\(aqworld .UNINDENT .INDENT 0.0 .TP +.B salt.modules.slsutil.serialize(serializer, obj, **mod_kwargs) +Serialize a Python object using a \fBserializer module\fP +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq \-\-no\-parse=obj slsutil.serialize \(aqjson\(aq obj="{\(aqfoo\(aq: \(aqFoo!\(aq} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Jinja Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{% set json_string = salt.slsutil.serialize(\(aqjson\(aq, + {\(aqfoo\(aq: \(aqFoo!\(aq}) %} +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.slsutil.update(dest, upd, recursive_update=True, merge_lists=False) Merge \fBupd\fP recursively into \fBdest\fP .sp @@ -215802,7 +230009,7 @@ salt \(aq*\(aq imgadm.show e42f8c84\-bbea\-11e2\-b920\-078fab2aab1f .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_imgadm.update(uuid=\(aq\(aq) +.B salt.modules.smartos_imgadm.update(uuid=u\(aq\(aq) Gather info on unknown image(s) (locally installed) .INDENT 7.0 .TP @@ -216278,7 +230485,7 @@ salt \(aq*\(aq vmadm.create image_uuid=\(aq...\(aq alias=\(aq...\(aq nics=\(aq[{ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.create_snapshot(vm, name, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.create_snapshot(vm, name, key=u\(aquuid\(aq) Create snapshot of a vm .INDENT 7.0 .TP @@ -216315,7 +230522,7 @@ salt \(aq*\(aq vmadm.create_snapshot nacl baseline key=alias .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.delete(vm, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.delete(vm, key=u\(aquuid\(aq) Delete a vm .INDENT 7.0 .TP @@ -216343,7 +230550,7 @@ salt \(aq*\(aq vmadm.delete nacl key=alias .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.delete_snapshot(vm, name, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.delete_snapshot(vm, name, key=u\(aquuid\(aq) Delete snapshot of a vm .INDENT 7.0 .TP @@ -216380,7 +230587,7 @@ salt \(aq*\(aq vmadm.delete_snapshot nacl baseline key=alias .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.get(vm, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.get(vm, key=u\(aquuid\(aq) Output the JSON object describing a VM .INDENT 7.0 .TP @@ -216408,7 +230615,7 @@ salt \(aq*\(aq vmadm.get nacl key=alias .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.info(vm, info_type=\(aqall\(aq, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.info(vm, info_type=u\(aqall\(aq, key=u\(aquuid\(aq) Lookup info on running kvm .INDENT 7.0 .TP @@ -216442,7 +230649,7 @@ salt \(aq*\(aq vmadm.info nacl vnc key=alias .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.list(search=None, sort=None, order=\(aquuid, type, ram, state, alias\(aq, keyed=True) +.B salt.modules.smartos_vmadm.list(search=None, sort=None, order=u\(aquuid, type, ram, state, alias\(aq, keyed=True) Return a list of VMs .INDENT 7.0 .TP @@ -216516,7 +230723,7 @@ salt \(aq*\(aq vmadm.lookup search=\(aqalias=nacl\(aq one=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.reboot(vm, force=False, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.reboot(vm, force=False, key=u\(aquuid\(aq) Reboot a vm .INDENT 7.0 .TP @@ -216577,7 +230784,7 @@ salt \(aq*\(aq vmadm.receive 186da9ab\-7392\-4f55\-91a5\-b8f1fe770543 /opt/backu .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.reprovision(vm, image, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.reprovision(vm, image, key=u\(aquuid\(aq) Reprovision a vm .INDENT 7.0 .TP @@ -216609,7 +230816,7 @@ salt \(aq*\(aq vmadm.reprovision nacl c02a2044\-c1bd\-11e4\-bd8c\-dfc1db8b0182 k .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.rollback_snapshot(vm, name, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.rollback_snapshot(vm, name, key=u\(aquuid\(aq) Rollback snapshot of a vm .INDENT 7.0 .TP @@ -216646,7 +230853,7 @@ salt \(aq*\(aq vmadm.rollback_snapshot nacl baseline key=alias .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.send(vm, target, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.send(vm, target, key=u\(aquuid\(aq) Send a vm to a directory .INDENT 7.0 .TP @@ -216678,7 +230885,7 @@ salt \(aq*\(aq vmadm.send vm=nacl target=/opt/backups key=alias .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.start(vm, options=None, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.start(vm, options=None, key=u\(aquuid\(aq) Start a vm .INDENT 7.0 .TP @@ -216712,7 +230919,7 @@ salt \(aq*\(aq vmadm.start vm=nina.example.org key=hostname .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.stop(vm, force=False, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.stop(vm, force=False, key=u\(aquuid\(aq) Stop a vm .INDENT 7.0 .TP @@ -216746,7 +230953,7 @@ salt \(aq*\(aq vmadm.stop vm=nina.example.org key=hostname .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.sysrq(vm, action=\(aqnmi\(aq, key=\(aquuid\(aq) +.B salt.modules.smartos_vmadm.sysrq(vm, action=u\(aqnmi\(aq, key=u\(aquuid\(aq) Send non\-maskable interrupt to vm or capture a screenshot .INDENT 7.0 .TP @@ -216779,7 +230986,7 @@ salt \(aq*\(aq vmadm.sysrq nacl nmi key=alias .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smartos_vmadm.update(vm, from_file=None, key=\(aquuid\(aq, **kwargs) +.B salt.modules.smartos_vmadm.update(vm, from_file=None, key=u\(aquuid\(aq, **kwargs) Update a new vm .INDENT 7.0 .TP @@ -217467,8 +231674,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.smf.status(name, sig=None) -Return the status for a service, returns a bool whether the service is -running. +Return the status for a service. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Not implemented +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -217562,7 +231790,7 @@ another\-smtp\-login: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.smtp.send_msg(recipient, message, subject=\(aqMessage from Salt\(aq, sender=None, server=None, use_ssl=\(aqTrue\(aq, username=None, password=None, profile=None) +.B salt.modules.smtp.send_msg(recipient, message, subject=u\(aqMessage from Salt\(aq, sender=None, server=None, use_ssl=u\(aqTrue\(aq, username=None, password=None, profile=None) Send a message to an SMTP recipient. Designed for use in states. .sp CLI Examples: @@ -218001,7 +232229,7 @@ salt \(aq*\(aq shadow.del_password username .UNINDENT .INDENT 0.0 .TP -.B salt.modules.solaris_shadow.gen_password(password, crypt_salt=None, algorithm=\(aqsha512\(aq) +.B salt.modules.solaris_shadow.gen_password(password, crypt_salt=None, algorithm=u\(aqsha512\(aq) New in version 2015.8.8. .sp @@ -218275,7 +232503,7 @@ minion, and it is using a different module (or gives an error similar to .UNINDENT .INDENT 0.0 .TP -.B salt.modules.solaris_user.add(name, uid=None, gid=None, groups=None, home=None, shell=None, unique=True, fullname=\(aq\(aq, roomnumber=\(aq\(aq, workphone=\(aq\(aq, homephone=\(aq\(aq, createhome=True, **kwargs) +.B salt.modules.solaris_user.add(name, uid=None, gid=None, groups=None, home=None, shell=None, unique=True, fullname=u\(aq\(aq, roomnumber=u\(aq\(aq, workphone=u\(aq\(aq, homephone=u\(aq\(aq, createhome=True, **kwargs) Add a user to the minion .sp CLI Example: @@ -219024,7 +233252,7 @@ minion, and it is using a different module (or gives an error similar to .UNINDENT .INDENT 0.0 .TP -.B salt.modules.solarispkg.install(name=None, sources=None, saltenv=\(aqbase\(aq, **kwargs) +.B salt.modules.solarispkg.install(name=None, sources=None, saltenv=u\(aqbase\(aq, **kwargs) Install the passed package. Can install packages from the following sources: .INDENT 7.0 @@ -219309,7 +233537,7 @@ salt \(aq*\(aq pkg.purge pkgs=\(aq["foo", "bar"]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.solarispkg.remove(name=None, pkgs=None, saltenv=\(aqbase\(aq, **kwargs) +.B salt.modules.solarispkg.remove(name=None, pkgs=None, saltenv=u\(aqbase\(aq, **kwargs) Remove packages with pkgrm .INDENT 7.0 .TP @@ -220317,13 +234545,13 @@ New in version 2017.7.0. For now, module is limited to http\-exposed API. It doesn\(aqt implement config upload via Solr zkCli .INDENT 0.0 .TP -.B salt.modules.solrcloud.BOOL_PROPS_LIST = [\(aqtransient\(aq, \(aqloadOnStartup\(aq] +.B salt.modules.solrcloud.BOOL_PROPS_LIST = [u\(aqtransient\(aq, u\(aqloadOnStartup\(aq] Collections options type definition Reference: \fI\%https://cwiki.apache.org/confluence/display/solr/Collections+API#CollectionsAPI\-api1\fP .UNINDENT .INDENT 0.0 .TP -.B salt.modules.solrcloud.DICT_OPTIONS_LIST = [\(aqproperties\(aq] +.B salt.modules.solrcloud.DICT_OPTIONS_LIST = [u\(aqproperties\(aq] Collection unmodifiable options Reference: \fI\%https://cwiki.apache.org/confluence/display/solr/Collections+API#CollectionsAPI\-modifycoll\fP .UNINDENT @@ -220660,7 +234888,7 @@ splunk: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk.create_user(email, profile=\(aqsplunk\(aq, **kwargs) +.B salt.modules.splunk.create_user(email, profile=u\(aqsplunk\(aq, **kwargs) create a splunk user by name/email .sp CLI Example: @@ -220672,7 +234900,7 @@ salt myminion splunk.create_user \fI\%user@example.com\fP roles=[\(aquser\(aq] r .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk.delete_user(email, profile=\(aqsplunk\(aq) +.B salt.modules.splunk.delete_user(email, profile=u\(aqsplunk\(aq) Delete a splunk user by email .sp CLI Example: @@ -220684,7 +234912,7 @@ salt myminion splunk_user.delete \fI\%\(aquser@example.com\fP\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk.get_user(email, profile=\(aqsplunk\(aq, **kwargs) +.B salt.modules.splunk.get_user(email, profile=u\(aqsplunk\(aq, **kwargs) Get a splunk user by name/email .sp CLI Example: @@ -220697,7 +234925,7 @@ salt myminion splunk.get_user \fI\%\(aquser@example.com\fP\(aq user_details=true .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk.list_users(profile=\(aqsplunk\(aq) +.B salt.modules.splunk.list_users(profile=u\(aqsplunk\(aq) List all users in the splunk DB .sp CLI Example: @@ -220709,7 +234937,7 @@ salt myminion splunk.list_users .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk.update_user(email, profile=\(aqsplunk\(aq, **kwargs) +.B salt.modules.splunk.update_user(email, profile=u\(aqsplunk\(aq, **kwargs) Create a splunk user by email .sp CLI Example: @@ -220756,7 +234984,7 @@ splunk: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk_search.create(name, profile=\(aqsplunk\(aq, **kwargs) +.B salt.modules.splunk_search.create(name, profile=u\(aqsplunk\(aq, **kwargs) Create a splunk search .sp CLI Example: @@ -220768,7 +234996,7 @@ splunk_search.create \(aqmy search name\(aq search=\(aqerror msg\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk_search.delete(name, profile=\(aqsplunk\(aq) +.B salt.modules.splunk_search.delete(name, profile=u\(aqsplunk\(aq) Delete a splunk search .sp CLI Example: @@ -220780,7 +235008,7 @@ splunk_search.delete \(aqmy search name\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk_search.get(name, profile=\(aqsplunk\(aq) +.B salt.modules.splunk_search.get(name, profile=u\(aqsplunk\(aq) Get a splunk search .sp CLI Example: @@ -220792,7 +235020,7 @@ splunk_search.get \(aqmy search name\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk_search.list(profile=\(aqsplunk\(aq) +.B salt.modules.splunk_search.list(profile=u\(aqsplunk\(aq) List splunk searches (names only) .INDENT 7.0 .TP @@ -220802,7 +235030,7 @@ splunk_search.list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk_search.list_all(prefix=None, app=None, owner=None, description_contains=None, name_not_contains=None, profile=\(aqsplunk\(aq) +.B salt.modules.splunk_search.list_all(prefix=None, app=None, owner=None, description_contains=None, name_not_contains=None, profile=u\(aqsplunk\(aq) Get all splunk search details. Produces results that can be used to create an sls file. .sp @@ -220856,7 +235084,7 @@ $ diff final_searches.sls managed_searches.sls .UNINDENT .INDENT 0.0 .TP -.B salt.modules.splunk_search.update(name, profile=\(aqsplunk\(aq, **kwargs) +.B salt.modules.splunk_search.update(name, profile=u\(aqsplunk\(aq, **kwargs) Update a splunk search .sp CLI Example: @@ -221003,7 +235231,7 @@ or removed. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ssh.auth_keys(user=None, config=\(aq.ssh/authorized_keys\(aq, fingerprint_hash_type=None) +.B salt.modules.ssh.auth_keys(user=None, config=u\(aq.ssh/authorized_keys\(aq, fingerprint_hash_type=None) Return the authorized keys for users .sp CLI Example: @@ -221023,7 +235251,7 @@ salt \(aq*\(aq ssh.auth_keys user="[user1, user2]" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ssh.check_key(user, key, enc, comment, options, config=\(aq.ssh/authorized_keys\(aq, cache_keys=None, fingerprint_hash_type=None) +.B salt.modules.ssh.check_key(user, key, enc, comment, options, config=u\(aq.ssh/authorized_keys\(aq, cache_keys=None, fingerprint_hash_type=None) Check to see if a key needs updating, returns "update", "add" or "exists" .sp CLI Example: @@ -221040,7 +235268,7 @@ salt \(aq*\(aq ssh.check_key .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ssh.check_key_file(user, source, config=\(aq.ssh/authorized_keys\(aq, saltenv=\(aqbase\(aq, fingerprint_hash_type=None) +.B salt.modules.ssh.check_key_file(user, source, config=u\(aq.ssh/authorized_keys\(aq, saltenv=u\(aqbase\(aq, fingerprint_hash_type=None) Check a keyfile from a source destination against the local keys and return the keys to change .sp @@ -221085,6 +235313,9 @@ salt \(aq*\(aq ssh.check_known_host key=\(aqAAAA...FAaQ==\(aq .INDENT 0.0 .TP .B salt.modules.ssh.get_known_host(user, hostname, config=None, port=None, fingerprint_hash_type=None) +Deprecated since version 2018.3.0: Use \fI\%ssh.get_known_host_entries\fP instead. + +.sp Return information about known host from the configfile, if any. If there is no such key, return None. .sp @@ -221102,6 +235333,27 @@ salt \(aq*\(aq ssh.get_known_host .UNINDENT .INDENT 0.0 .TP +.B salt.modules.ssh.get_known_host_entries(user, hostname, config=None, port=None, fingerprint_hash_type=None) +New in version 2018.3.0. + +.sp +Return information about known host entries from the configfile, if any. +If there are no entries for a matching hostname, return None. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq ssh.get_known_host_entries +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.ssh.hash_known_hosts(user=None, config=None) Hash all the hostnames in the known hosts file. .sp @@ -221131,7 +235383,7 @@ salt \(aq*\(aq ssh.hash_known_hosts .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ssh.host_keys(keydir=None, private=True) +.B salt.modules.ssh.host_keys(keydir=None, private=True, certs=True) Return the minion\(aqs host keys .sp CLI Example: @@ -221143,6 +235395,7 @@ CLI Example: salt \(aq*\(aq ssh.host_keys salt \(aq*\(aq ssh.host_keys keydir=/etc/ssh salt \(aq*\(aq ssh.host_keys keydir=/etc/ssh private=False +salt \(aq*\(aq ssh.host_keys keydir=/etc/ssh certs=False .ft P .fi .UNINDENT @@ -221176,6 +235429,9 @@ salt \(aq*\(aq ssh.key_is_encrypted /root/id_rsa .TP .B salt.modules.ssh.recv_known_host(hostname, enc=None, port=None, hash_known_hosts=True, timeout=5, fingerprint_hash_type=None) Retrieve information about host public key from remote server +.sp +Deprecated since version 2018.3.0: Use \fI\%ssh.recv_known_host_entries\fP instead. + .INDENT 7.0 .TP .B hostname @@ -221186,9 +235442,8 @@ Defines what type of key is being used, can be ed25519, ecdsa ssh\-rsa or ssh\-dss .TP .B port -optional parameter, denoting the port of the remote host, which will be -used in case, if the public key will be requested from it. By default -the port 22 is used. +Optional parameter, denoting the port of the remote host on which an +SSH daemon is running. By default the port 22 is used. .TP .B hash_known_hosts True @@ -221205,8 +235460,8 @@ New in version 2016.3.0. .TP .B fingerprint_hash_type -The public key fingerprint hash type that the public key fingerprint -was originally hashed with. This defaults to \fBsha256\fP if not specified. +The fingerprint hash type that the public key fingerprints were +originally hashed with. This defaults to \fBsha256\fP if not specified. .sp New in version 2016.11.4. @@ -221229,7 +235484,61 @@ salt \(aq*\(aq ssh.recv_known_host enc= port= .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ssh.rm_auth_key(user, key, config=\(aq.ssh/authorized_keys\(aq, fingerprint_hash_type=None) +.B salt.modules.ssh.recv_known_host_entries(hostname, enc=None, port=None, hash_known_hosts=True, timeout=5, fingerprint_hash_type=None) +New in version 2018.3.0. + +.sp +Retrieve information about host public keys from remote server +.INDENT 7.0 +.TP +.B hostname +The name of the remote host (e.g. "github.com") +.TP +.B enc +Defines what type of key is being used, can be ed25519, ecdsa ssh\-rsa +or ssh\-dss +.TP +.B port +Optional parameter, denoting the port of the remote host on which an +SSH daemon is running. By default the port 22 is used. +.TP +.B hash_known_hosts +True +Hash all hostnames and addresses in the known hosts file. +.TP +.B timeout +int +Set the timeout for connection attempts. If \fBtimeout\fP seconds have +elapsed since a connection was initiated to a host or since the last +time anything was read from that host, then the connection is closed +and the host in question considered unavailable. Default is 5 seconds. +.TP +.B fingerprint_hash_type +The fingerprint hash type that the public key fingerprints were +originally hashed with. This defaults to \fBsha256\fP if not specified. +.sp +New in version 2016.11.4. + +.sp +Changed in version 2017.7.0:: default changed from \fBmd5\fP to \fBsha256\fP + +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq ssh.recv_known_host_entries enc= port= +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ssh.rm_auth_key(user, key, config=u\(aq.ssh/authorized_keys\(aq, fingerprint_hash_type=None) Remove an authorized key from the specified user\(aqs authorized key file .sp CLI Example: @@ -221246,7 +235555,7 @@ salt \(aq*\(aq ssh.rm_auth_key .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ssh.rm_auth_key_from_file(user, source, config=\(aq.ssh/authorized_keys\(aq, saltenv=\(aqbase\(aq, fingerprint_hash_type=None) +.B salt.modules.ssh.rm_auth_key_from_file(user, source, config=u\(aq.ssh/authorized_keys\(aq, saltenv=u\(aqbase\(aq, fingerprint_hash_type=None) Remove an authorized key from the specified user\(aqs authorized key file, using a file as source .sp @@ -221281,7 +235590,7 @@ salt \(aq*\(aq ssh.rm_known_host .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ssh.set_auth_key(user, key, enc=\(aqssh\-rsa\(aq, comment=\(aq\(aq, options=None, config=\(aq.ssh/authorized_keys\(aq, cache_keys=None, fingerprint_hash_type=None) +.B salt.modules.ssh.set_auth_key(user, key, enc=u\(aqssh\-rsa\(aq, comment=u\(aq\(aq, options=None, config=u\(aq.ssh/authorized_keys\(aq, cache_keys=None, fingerprint_hash_type=None) Add a key to the authorized_keys file. The "key" parameter must only be the string of text that is the encoded key. If the key begins with "ssh\-rsa" or ends with \fI\%user@host\fP, remove those from the key before passing it to this @@ -221301,7 +235610,7 @@ salt \(aq*\(aq ssh.set_auth_key \(aq\(aq enc=\(aqdsa\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.ssh.set_auth_key_from_file(user, source, config=\(aq.ssh/authorized_keys\(aq, saltenv=\(aqbase\(aq, fingerprint_hash_type=None) +.B salt.modules.ssh.set_auth_key_from_file(user, source, config=u\(aq.ssh/authorized_keys\(aq, saltenv=u\(aqbase\(aq, fingerprint_hash_type=None) Add a key to the authorized_keys file, using a file as the source. .sp CLI Example: @@ -221490,7 +235799,7 @@ Return whether this service is running. .INDENT 0.0 .TP .B salt.modules.ssh_service.start(name, sig=None) -Start the specified service on the rest_sample +Start the specified service on the ssh_sample .sp CLI Example: .INDENT 7.0 @@ -221507,8 +235816,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.ssh_service.status(name, sig=None) -Return the status for a service via rest_sample, returns a bool -whether the service is running. +Return the status for a service via ssh_sample. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Not implemented +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -221567,7 +235897,7 @@ Linux .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.changed_files(config=\(aqroot\(aq, num_pre=None, num_post=None) +.B salt.modules.snapper.changed_files(config=u\(aqroot\(aq, num_pre=None, num_post=None) Returns the files changed between two snapshots .INDENT 7.0 .TP @@ -221596,7 +235926,7 @@ salt \(aq*\(aq snapper.changed_files num_pre=19 num_post=20 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.create_baseline(tag=\(aqbaseline\(aq, config=\(aqroot\(aq) +.B salt.modules.snapper.create_baseline(tag=u\(aqbaseline\(aq, config=u\(aqroot\(aq) Creates a snapshot marked as baseline .INDENT 7.0 .TP @@ -221659,7 +235989,7 @@ salt \(aq*\(aq snapper.create_config name=myconfig subvolume=/foo/bar/ fstype=bt .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.create_snapshot(config=\(aqroot\(aq, snapshot_type=\(aqsingle\(aq, pre_number=None, description=None, cleanup_algorithm=\(aqnumber\(aq, userdata=None, **kwargs) +.B salt.modules.snapper.create_snapshot(config=u\(aqroot\(aq, snapshot_type=u\(aqsingle\(aq, pre_number=None, description=None, cleanup_algorithm=u\(aqnumber\(aq, userdata=None, **kwargs) Creates an snapshot .INDENT 7.0 .TP @@ -221711,7 +236041,7 @@ salt \(aq*\(aq snapper.create_snapshot .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.delete_snapshot(snapshots_ids=None, config=\(aqroot\(aq) +.B salt.modules.snapper.delete_snapshot(snapshots_ids=None, config=u\(aqroot\(aq) Deletes an snapshot .INDENT 7.0 .TP @@ -221738,7 +236068,7 @@ salt \(aq*\(aq snapper.delete_snapshot config=root snapshots_ids=[54,55,56] .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.diff(config=\(aqroot\(aq, filename=None, num_pre=None, num_post=None) +.B salt.modules.snapper.diff(config=u\(aqroot\(aq, filename=None, num_pre=None, num_post=None) Returns the differences between two snapshots .INDENT 7.0 .TP @@ -221771,7 +236101,7 @@ salt \(aq*\(aq snapper.diff filename=/var/log/snapper.log num_pre=19 num_post=20 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.diff_jid(jid, config=\(aqroot\(aq) +.B salt.modules.snapper.diff_jid(jid, config=u\(aqroot\(aq) Returns the changes applied by a \fIjid\fP .INDENT 7.0 .TP @@ -221796,7 +236126,7 @@ salt \(aq*\(aq snapper.diff_jid jid=20160607130930720112 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.get_config(name=\(aqroot\(aq) +.B salt.modules.snapper.get_config(name=u\(aqroot\(aq) Retrieves all values from a given configuration .sp CLI example: @@ -221813,7 +236143,7 @@ salt \(aq*\(aq snapper.get_config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.get_snapshot(number=0, config=\(aqroot\(aq) +.B salt.modules.snapper.get_snapshot(number=0, config=u\(aqroot\(aq) Get detailed information about a given snapshot .sp CLI example: @@ -221847,7 +236177,7 @@ salt \(aq*\(aq snapper.list_configs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.list_snapshots(config=\(aqroot\(aq) +.B salt.modules.snapper.list_snapshots(config=u\(aqroot\(aq) List available snapshots .sp CLI example: @@ -221864,7 +236194,7 @@ salt \(aq*\(aq snapper.list_snapshots config=myconfig .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.modify_snapshot(snapshot_id=None, description=None, userdata=None, cleanup=None, config=\(aqroot\(aq) +.B salt.modules.snapper.modify_snapshot(snapshot_id=None, description=None, userdata=None, cleanup=None, config=u\(aqroot\(aq) Modify attributes of an existing snapshot. .INDENT 7.0 .TP @@ -221950,7 +236280,7 @@ salt \(aq*\(aq snapper.run file.append args=\(aq["/etc/motd", "some text"]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.set_config(name=\(aqroot\(aq, **kwargs) +.B salt.modules.snapper.set_config(name=u\(aqroot\(aq, **kwargs) Set configuration values .sp CLI example: @@ -221967,10 +236297,20 @@ salt \(aq*\(aq snapper.set_config SYNC_ACL=True .sp Keys are case insensitive as they will be always uppercased to snapper convention. The above example is equivalent to: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq snapper.set_config sync_acl=True +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.status(config=\(aqroot\(aq, num_pre=None, num_post=None) +.B salt.modules.snapper.status(config=u\(aqroot\(aq, num_pre=None, num_post=None) Returns a comparison between two snapshots .INDENT 7.0 .TP @@ -222016,7 +236356,7 @@ salt \(aq*\(aq snapper.status_to_string .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.undo(config=\(aqroot\(aq, files=None, num_pre=None, num_post=None) +.B salt.modules.snapper.undo(config=u\(aqroot\(aq, files=None, num_pre=None, num_post=None) Undo all file changes that happened between num_pre and num_post, leaving the files into the state of num_pre. .sp @@ -222046,7 +236386,7 @@ salt \(aq*\(aq snapper.undo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.snapper.undo_jid(jid, config=\(aqroot\(aq) +.B salt.modules.snapper.undo_jid(jid, config=u\(aqroot\(aq) Undo the changes applied by a salt job .INDENT 7.0 .TP @@ -222399,7 +236739,7 @@ salt \(aq*\(aq state.disable bind.config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.state.event(tagmatch=\(aq*\(aq, count=\-1, quiet=False, sock_dir=None, pretty=False, node=\(aqminion\(aq) +.B salt.modules.state.event(tagmatch=u\(aq*\(aq, count=\-1, quiet=False, sock_dir=None, pretty=False, node=u\(aqminion\(aq) Watch Salt\(aqs event bus and block until the given tag is matched .sp New in version 2016.3.0. @@ -222445,6 +236785,14 @@ salt\-call \-\-local state.event pretty=True .UNINDENT .INDENT 0.0 .TP +.B salt.modules.state.get_pauses(jid=None) +Get a report on all of the currently paused state runs and pause +run settings. +Optionally send in a jid if you only desire to see a single pause +data set. +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.state.high(data, test=None, queue=False, **kwargs) Execute the compound calls stored in a single set of high data .sp @@ -222623,7 +236971,7 @@ salt \(aq*\(aq state.low \(aq{"state": "pkg", "fun": "installed", "name": "vi"}\ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.state.orchestrate(mods, saltenv=\(aqbase\(aq, test=None, exclude=None, pillar=None, pillarenv=None) +.B salt.modules.state.orchestrate(mods, saltenv=u\(aqbase\(aq, test=None, exclude=None, pillar=None, pillarenv=None) New in version 2016.11.0. .sp @@ -222658,6 +237006,44 @@ salt\-call \-\-local state.orchestrate webserver saltenv=dev pillarenv=aws .UNINDENT .INDENT 0.0 .TP +.B salt.modules.state.pause(jid, state_id=None, duration=None) +Set up a state id pause, this instructs a running state to pause at a given +state id. This needs to pass in the jid of the running state and can +optionally pass in a duration in seconds. If a state_id is not passed then +the jid referenced will be paused at the begining of the next state run. +.sp +The given state id is the id got a given state execution, so given a state +that looks like this: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +vim: + pkg.installed: [] +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The state_id to pass to \fIpause\fP is \fIvim\fP +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq state.pause 20171130110407769519 +salt \(aq*\(aq state.pause 20171130110407769519 vim +salt \(aq*\(aq state.pause 20171130110407769519 vim 20 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.state.pkg(pkg_path, pkg_sum, hash_type, test=None, **kwargs) Execute a packaged state run, the packaged state run will exist in a tarball available locally. This packaged state @@ -222701,7 +237087,42 @@ salt \(aq*\(aq state.request test,pkgs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.state.run_request(name=\(aqdefault\(aq, **kwargs) +.B salt.modules.state.resume(jid, state_id=None) +Remove a pause from a jid, allowing it to continue. If the state_id is +not specified then the a general pause will be resumed. +.sp +The given state_id is the id got a given state execution, so given a state +that looks like this: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +vim: + pkg.installed: [] +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The state_id to pass to \fIrm_pause\fP is \fIvim\fP +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq state.resume 20171130110407769519 +salt \(aq*\(aq state.resume 20171130110407769519 vim +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.state.run_request(name=u\(aqdefault\(aq, **kwargs) New in version 2015.5.0. .sp @@ -222767,6 +237188,27 @@ Display the low data from a specific sls. The default environment is .B saltenv Specify a salt fileserver environment to be used when applying states .TP +.B pillar +Custom Pillar values, passed as a dictionary of key\-value pairs +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq state.show_low_sls test pillar=\(aq{"foo": "bar"}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Values passed this way will override Pillar values set via +\fBpillar_roots\fP or an external Pillar source. +.UNINDENT +.UNINDENT +.TP .B pillarenv Specify a Pillar environment to be used when applying states. This can also be set in the minion config file using the @@ -222835,7 +237277,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq state.show_sls core,edit.vim dev +salt \(aq*\(aq state.show_sls core,edit.vim saltenv=dev .ft P .fi .UNINDENT @@ -222925,8 +237367,9 @@ salt \(aq*\(aq state.apply test pillar=\(aq{"foo": "bar"}\(aq \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -Values passed this way will override Pillar values set via -\fBpillar_roots\fP or an external Pillar source. +Values passed this way will override existing Pillar values set via +\fBpillar_roots\fP or an external Pillar source. Pillar values that +are not included in the kwarg will not be overwritten. .UNINDENT .UNINDENT .sp @@ -223066,6 +237509,31 @@ can also be set in the minion config file using the \fBpillarenv\fP option. When neither the \fBpillarenv\fP minion config option nor this CLI argument is used, all Pillar environments will be merged together. +.TP +.B pillar +Custom Pillar values, passed as a dictionary of key\-value pairs +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq state.sls_id my_state my_module pillar=\(aq{"foo": "bar"}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Values passed this way will override existing Pillar values set via +\fBpillar_roots\fP or an external Pillar source. Pillar values that +are not included in the kwarg will not be overwritten. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + .UNINDENT .sp CLI Example: @@ -223084,6 +237552,44 @@ salt \(aq*\(aq state.sls_id my_state my_module,a_common_module .UNINDENT .INDENT 0.0 .TP +.B salt.modules.state.soft_kill(jid, state_id=None) +Set up a state run to die before executing the given state id, +this instructs a running state to safely exit at a given +state id. This needs to pass in the jid of the running state. +If a state_id is not passed then the jid referenced will be safely exited +at the begining of the next state run. +.sp +The given state id is the id got a given state execution, so given a state +that looks like this: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +vim: + pkg.installed: [] +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The state_id to pass to \fIsoft_kill\fP is \fIvim\fP +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq state.soft_kill 20171130110407769519 +salt \(aq*\(aq state.soft_kill 20171130110407769519 vim +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.state.template(tem, queue=False, **kwargs) Execute the information stored in a template file on the minion. .sp @@ -223193,6 +237699,9 @@ Changed in version 2016.3.2: Return the CPU info for this minion .sp Changed in version 2016.11.4: Added support for AIX +.sp +Changed in version 2018.3.0: Added support for NetBSD and OpenBSD + .sp CLI Example: .INDENT 7.0 @@ -223213,6 +237722,9 @@ Return the CPU stats for this minion .sp Changed in version 2016.11.4: Added support for AIX +.sp +Changed in version 2018.3.0: Added support for OpenBSD + .sp CLI Example: .INDENT 7.0 @@ -223372,6 +237884,9 @@ Return the memory info for this minion .sp Changed in version 2016.11.4: Added support for AIX +.sp +Changed in version 2018.3.0: Added support for OpenBSD + .sp CLI Example: .INDENT 7.0 @@ -223413,6 +237928,9 @@ Return the network stats for this minion .sp Changed in version 2016.11.4: Added support for AIX +.sp +Changed in version 2018.3.0: Added support for OpenBSD + .sp CLI Example: .INDENT 7.0 @@ -223433,6 +237951,9 @@ Return the number of processing units available on this system .sp Changed in version 2016.11.4: Added support for AIX +.sp +Changed in version 2018.3.0: Added support for Darwin, FreeBSD and OpenBSD + .sp CLI Example: .INDENT 7.0 @@ -223532,7 +238053,7 @@ salt \(aq*\(aq status.proxy_reconnect rest_sample .UNINDENT .INDENT 0.0 .TP -.B salt.modules.status.time(format=\(aq%A, %d. %B %Y %I:%M%p\(aq) +.B salt.modules.status.time(format=u\(aq%A, %d. %B %Y %I:%M%p\(aq) New in version 2016.3.0. .sp @@ -223590,6 +238111,9 @@ Return the system version for this minion .sp Changed in version 2016.11.4: Added support for AIX +.sp +Changed in version 2018.3.0: Added support for OpenBSD + .sp CLI Example: .INDENT 7.0 @@ -223664,7 +238188,7 @@ New in version 2017.7.0. .INDENT 0.0 .TP -.B salt.modules.statuspage.create(endpoint=\(aqincidents\(aq, api_url=None, page_id=None, api_key=None, api_version=None, **kwargs) +.B salt.modules.statuspage.create(endpoint=u\(aqincidents\(aq, api_url=None, page_id=None, api_key=None, api_version=None, **kwargs) Insert a new entry under a specific endpoint. .INDENT 7.0 .TP @@ -223741,7 +238265,7 @@ minion: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.statuspage.delete(endpoint=\(aqincidents\(aq, id=None, api_url=None, page_id=None, api_key=None, api_version=None) +.B salt.modules.statuspage.delete(endpoint=u\(aqincidents\(aq, id=None, api_url=None, page_id=None, api_key=None, api_version=None) Remove an entry from an endpoint. .INDENT 7.0 .TP @@ -223793,7 +238317,7 @@ minion: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.statuspage.retrieve(endpoint=\(aqincidents\(aq, api_url=None, page_id=None, api_key=None, api_version=None) +.B salt.modules.statuspage.retrieve(endpoint=u\(aqincidents\(aq, api_url=None, page_id=None, api_key=None, api_version=None) Retrieve a specific endpoint from the Statuspage API. .INDENT 7.0 .TP @@ -223917,7 +238441,7 @@ minion: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.statuspage.update(endpoint=\(aqincidents\(aq, id=None, api_url=None, page_id=None, api_key=None, api_version=None, **kwargs) +.B salt.modules.statuspage.update(endpoint=u\(aqincidents\(aq, id=None, api_url=None, page_id=None, api_key=None, api_version=None, **kwargs) Update attribute(s) of a specific endpoint. .INDENT 7.0 .TP @@ -223988,93 +238512,6 @@ minion: .UNINDENT .UNINDENT .UNINDENT -.SS salt.modules.stormpath -.sp -Support for Stormpath -.sp -New in version 2015.8.0. - -.INDENT 0.0 -.TP -.B salt.modules.stormpath.create_account(directory_id, email, password, givenName, surname, **kwargs) -Create an account -.sp -CLI Examples: -.INDENT 7.0 -.INDENT 3.5 -salt myminion stormpath.create_account \fI\%shemp@example.com\fP letmein Shemp Howard -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.stormpath.delete_account(account_id) -Delete an account. -.sp -CLI Examples: -.INDENT 7.0 -.INDENT 3.5 -salt myminion stormpath.delete_account -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.stormpath.list_accounts() -Show all accounts. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -salt myminion stormpath.list_accounts -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.stormpath.list_directories() -Show all directories. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -salt myminion stormpath.list_directories -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.stormpath.show_account(account_id=None, email=None, directory_id=None, application_id=None, group_id=None, **kwargs) -Show a specific account. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -salt myminion stormpath.show_account -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.stormpath.show_tenant() -Get the tenant for the login being used. -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.stormpath.update_account(account_id, key=None, value=None, items=None) -Update one or more items for this account. Specifying an empty value will -clear it for that account. -.sp -CLI Examples: -.INDENT 7.0 -.INDENT 3.5 -salt myminion stormpath.update_account givenName shemp -salt myminion stormpath.update_account middleName \(aq\(aq -salt myminion stormpath.update_account items=\(aq{"givenName": "Shemp"} -salt myminion stormpath.update_account items=\(aq{"middlename": ""} -.UNINDENT -.UNINDENT -.UNINDENT .SS salt.modules.supervisord .sp Provide the service module for system supervisord or supervisord in a @@ -224225,7 +238662,7 @@ salt \(aq*\(aq supervisord.reread .UNINDENT .INDENT 0.0 .TP -.B salt.modules.supervisord.restart(name=\(aqall\(aq, user=None, conf_file=None, bin_env=None) +.B salt.modules.supervisord.restart(name=u\(aqall\(aq, user=None, conf_file=None, bin_env=None) Restart the named service. Process group names should not include a trailing asterisk. .INDENT 7.0 @@ -224256,7 +238693,7 @@ salt \(aq*\(aq supervisord.restart : .UNINDENT .INDENT 0.0 .TP -.B salt.modules.supervisord.start(name=\(aqall\(aq, user=None, conf_file=None, bin_env=None) +.B salt.modules.supervisord.start(name=u\(aqall\(aq, user=None, conf_file=None, bin_env=None) Start the named service. Process group names should not include a trailing asterisk. .INDENT 7.0 @@ -224345,7 +238782,7 @@ salt \(aq*\(aq supervisord.status_raw .UNINDENT .INDENT 0.0 .TP -.B salt.modules.supervisord.stop(name=\(aqall\(aq, user=None, conf_file=None, bin_env=None) +.B salt.modules.supervisord.stop(name=u\(aqall\(aq, user=None, conf_file=None, bin_env=None) Stop the named service. Process group names should not include a trailing asterisk. .INDENT 7.0 @@ -224651,7 +239088,7 @@ salt \(aq*\(aq svn.diff /path/to/repo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.svn.export(cwd, remote, target=None, user=None, username=None, password=None, revision=\(aqHEAD\(aq, *opts) +.B salt.modules.svn.export(cwd, remote, target=None, user=None, username=None, password=None, revision=u\(aqHEAD\(aq, *opts) Create an unversioned copy of a tree. .INDENT 7.0 .TP @@ -224697,7 +239134,7 @@ salt \(aq*\(aq svn.export /path/to/repo svn://remote/repo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.svn.info(cwd, targets=None, user=None, username=None, password=None, fmt=\(aqstr\(aq) +.B salt.modules.svn.info(cwd, targets=None, user=None, username=None, password=None, fmt=u\(aqstr\(aq) Display the Subversion information from the checkout. .INDENT 7.0 .TP @@ -224920,6 +239357,7 @@ salt \(aq*\(aq svn.update /path/to/repo .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.swarm .SS salt.modules.swift .sp Module for handling OpenStack Swift calls @@ -225343,7 +239781,7 @@ salt \(aq*\(aq sysfs.interfaces block/bcache0/bcache .UNINDENT .INDENT 0.0 .TP -.B salt.modules.sysfs.read(key, root=\(aq\(aq) +.B salt.modules.sysfs.read(key, root=u\(aq\(aq) Read from SysFS .INDENT 7.0 .TP @@ -225453,7 +239891,7 @@ the module will use it. If it is not set, syslog\-ng uses the default configuration file. .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.Argument(value=\(aq\(aq) +.B class salt.modules.syslog_ng.Argument(value=u\(aq\(aq) A TypedParameterValue has one or more Arguments. For example this can be the value of key_file. .sp @@ -225461,7 +239899,7 @@ Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.Buildable(iterable, join_body_on=\(aq\(aq, append_extra_newline=True) +.B class salt.modules.syslog_ng.Buildable(iterable, join_body_on=u\(aq\(aq, append_extra_newline=True) Base class of most classes, which have a build method. .sp It contains a common build function. @@ -225502,14 +239940,14 @@ Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.NamedStatement(type, id=\(aq\(aq, options=None) +.B class salt.modules.syslog_ng.NamedStatement(type, id=u\(aq\(aq, options=None) It represents a configuration statement, which has a name, e.g. a source. .sp Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.Option(type=\(aq\(aq, params=None) +.B class salt.modules.syslog_ng.Option(type=u\(aq\(aq, params=None) A Statement class contains Option instances. .sp An instance of Option can represent a file(), tcp(), udp(), etc. option. @@ -225518,21 +239956,21 @@ Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.Parameter(iterable=None, join_body_on=\(aq\(aq) +.B class salt.modules.syslog_ng.Parameter(iterable=None, join_body_on=u\(aq\(aq) An Option has one or more Parameter instances. .sp Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.ParameterValue(iterable=None, join_body_on=\(aq\(aq) +.B class salt.modules.syslog_ng.ParameterValue(iterable=None, join_body_on=u\(aq\(aq) A TypedParameter can have one or more values. .sp Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.SimpleParameter(value=\(aq\(aq) +.B class salt.modules.syslog_ng.SimpleParameter(value=u\(aq\(aq) A Parameter is a SimpleParameter, if it\(aqs just a simple type, like a string. .sp @@ -225558,7 +239996,7 @@ Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.SimpleParameterValue(value=\(aq\(aq) +.B class salt.modules.syslog_ng.SimpleParameterValue(value=u\(aq\(aq) A ParameterValuem which holds a simple type, like a string or a number. .sp For example in ip(127.0.0.1) 127.0.0.1 is a SimpleParameterValue. @@ -225567,7 +240005,7 @@ Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.Statement(type, id=\(aq\(aq, options=None, has_name=True) +.B class salt.modules.syslog_ng.Statement(type, id=u\(aq\(aq, options=None, has_name=True) It represents a syslog\-ng configuration statement, e.g. source, destination, filter. .sp @@ -225575,7 +240013,7 @@ Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.TypedParameter(type=\(aq\(aq, values=None) +.B class salt.modules.syslog_ng.TypedParameter(type=u\(aq\(aq, values=None) A Parameter, which has a type: .INDENT 7.0 .INDENT 3.5 @@ -225598,7 +240036,7 @@ Does not need examples. .UNINDENT .INDENT 0.0 .TP -.B class salt.modules.syslog_ng.TypedParameterValue(type=\(aq\(aq, arguments=None) +.B class salt.modules.syslog_ng.TypedParameterValue(type=u\(aq\(aq, arguments=None) We have to go deeper... .sp A TypedParameter can have a \(aqparameter\(aq, which also have a type. For example @@ -225919,7 +240357,7 @@ salt \(aq*\(aq syslog_ng.write_version name="3.6" The sys module provides information about the available functions on the minion .INDENT 0.0 .TP -.B salt.modules.sysmod.argspec(module=\(aq\(aq) +.B salt.modules.sysmod.argspec(module=u\(aq\(aq) Return the argument specification of functions in Salt execution modules. .sp @@ -226398,7 +240836,7 @@ salt \(aq*\(aq sys.renderer_doc \(aqc*\(aq \(aqj*\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.sysmod.returner_argspec(module=\(aq\(aq) +.B salt.modules.sysmod.returner_argspec(module=u\(aq\(aq) Return the argument specification of functions in Salt returner modules. .sp @@ -226477,7 +240915,7 @@ salt \(aq*\(aq sys.returner_doc \(aqsqlite3.get_*\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.sysmod.runner_argspec(module=\(aq\(aq) +.B salt.modules.sysmod.runner_argspec(module=u\(aq\(aq) Return the argument specification of functions in Salt runner modules. .sp @@ -226556,7 +240994,7 @@ salt \(aq*\(aq sys.runner_doc \(aqcache.clear_*\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.sysmod.state_argspec(module=\(aq\(aq) +.B salt.modules.sysmod.state_argspec(module=u\(aq\(aq) Return the argument specification of functions in Salt state modules. .sp @@ -226635,7 +241073,7 @@ salt \(aq*\(aq sys.state_doc \(aqservice.*\(aq \(aqiptables.*\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.sysmod.state_schema(module=\(aq\(aq) +.B salt.modules.sysmod.state_schema(module=u\(aq\(aq) Return a JSON Schema for the given state function(s) .sp New in version 2016.3.0. @@ -226722,7 +241160,19 @@ salt \(aq*\(aq sysrc.set name=sshd_flags value="\-p 2222" .UNINDENT .SS salt.modules.system .sp -Support for reboot, shutdown, etc +Support for reboot, shutdown, etc on POSIX\-like systems. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +If you have configured a wrapper such as \fBmolly\-guard\fP to +intercept \fIinteractive\fP shutdown commands, be aware that calling +\fBsystem.halt\fP, \fBsystem.poweroff\fP, \fBsystem.reboot\fP, and +\fBsystem.shutdown\fP with \fBsalt\-call\fP will hang indefinitely +while the wrapper script waits for user input. Calling them with +\fBsalt\fP will work as expected. +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.modules.system.get_computer_desc() @@ -226975,7 +241425,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq system.set_conputer_name master.saltstack.com +salt \(aq*\(aq system.set_computer_name master.saltstack.com .ft P .fi .UNINDENT @@ -226984,7 +241434,7 @@ salt \(aq*\(aq system.set_conputer_name master.saltstack.com .INDENT 0.0 .TP .B salt.modules.system.set_system_date(newdate, utc_offset=None) -Set the Windows system date. Use format for the date. +Set the system date. Use format for the date. .INDENT 7.0 .TP .B Parameters @@ -227788,8 +242238,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.systemd.status(name, sig=None) -Return the status for a service via systemd, returns \fBTrue\fP if the -service is running and \fBFalse\fP if it is not. +Return the status for a service via systemd. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Not implemented +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -227797,7 +242268,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq service.status +salt \(aq*\(aq service.status [service signature] .ft P .fi .UNINDENT @@ -227902,6 +242373,59 @@ salt \(aq*\(aq service.unmask foo runtime=True .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.telegram +.sp +Module for sending messages via Telegram. +.INDENT 0.0 +.TP +.B configuration +In order to send a message via the Telegram, certain +configuration is required in /etc/salt/minion on the relevant minions or +in the pillar. Some sample configs might look like: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +telegram.chat_id: \(aq123456789\(aq +telegram.token: \(aq00000000:xxxxxxxxxxxxxxxxxxxxxxxx\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.telegram.post_message(message, chat_id=None, token=None) +Send a message to a Telegram chat. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmessage\fP \-\- The message to send to the Telegram chat. +.IP \(bu 2 +\fBchat_id\fP \-\- (optional) The Telegram chat id. +.IP \(bu 2 +\fBtoken\fP \-\- (optional) The Telegram API token. +.UNINDENT +.TP +.B Returns +Boolean if message was sent successfully. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq telegram.post_message message="Hello Telegram!" +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.telemetry .sp Connection module for Telemetry @@ -227938,7 +242462,7 @@ requests .UNINDENT .INDENT 0.0 .TP -.B salt.modules.telemetry.create_alarm(deployment_id, metric_name, data, api_key=None, profile=\(aqtelemetry\(aq) +.B salt.modules.telemetry.create_alarm(deployment_id, metric_name, data, api_key=None, profile=u\(aqtelemetry\(aq) create an telemetry alarms. .sp data is a dict of alert configuration data. @@ -227954,7 +242478,7 @@ salt myminion telemetry.create_alarm rs\-ds033197 {} profile=telemetry .UNINDENT .INDENT 0.0 .TP -.B salt.modules.telemetry.delete_alarms(deployment_id, alert_id=None, metric_name=None, api_key=None, profile=\(aqtelemetry\(aq) +.B salt.modules.telemetry.delete_alarms(deployment_id, alert_id=None, metric_name=None, api_key=None, profile=u\(aqtelemetry\(aq) .INDENT 7.0 .TP .B delete an alert specified by alert_id or if not specified blows away all the alerts @@ -227972,7 +242496,7 @@ salt myminion telemetry.delete_alarms rs\-ds033197 profile=telemetry .UNINDENT .INDENT 0.0 .TP -.B salt.modules.telemetry.get_alarms(deployment_id, profile=\(aqtelemetry\(aq) +.B salt.modules.telemetry.get_alarms(deployment_id, profile=u\(aqtelemetry\(aq) get all the alarms set up against the current deployment .sp Returns dictionary of alarm information @@ -227986,7 +242510,7 @@ salt myminion telemetry.get_alarms rs\-ds033197 profile=telemetry .UNINDENT .INDENT 0.0 .TP -.B salt.modules.telemetry.get_alert_config(deployment_id, metric_name=None, api_key=None, profile=\(aqtelemetry\(aq) +.B salt.modules.telemetry.get_alert_config(deployment_id, metric_name=None, api_key=None, profile=u\(aqtelemetry\(aq) Get all alert definitions associated with a given deployment or if metric_name is specified, obtain the specific alert config .sp @@ -228002,7 +242526,7 @@ salt myminion telemetry.get_alert_config rs\-ds033197 profile=telemetry .UNINDENT .INDENT 0.0 .TP -.B salt.modules.telemetry.get_notification_channel_id(notify_channel, profile=\(aqtelemetry\(aq) +.B salt.modules.telemetry.get_notification_channel_id(notify_channel, profile=u\(aqtelemetry\(aq) Given an email address, creates a notification\-channels if one is not found and also returns the corresponding notification channel id. @@ -228024,7 +242548,7 @@ salt myminion telemetry.get_notification_channel_id \fI\%userx@company.com\fP pr .UNINDENT .INDENT 0.0 .TP -.B salt.modules.telemetry.update_alarm(deployment_id, metric_name, data, api_key=None, profile=\(aqtelemetry\(aq) +.B salt.modules.telemetry.update_alarm(deployment_id, metric_name, data, api_key=None, profile=u\(aqtelemetry\(aq) update an telemetry alarms. data is a dict of alert configuration data. .sp Returns (bool success, str message) tuple. @@ -228046,7 +242570,7 @@ New in version 2015.8.0. .INDENT 0.0 .TP -.B salt.modules.temp.dir(suffix=\(aq\(aq, prefix=\(aqtmp\(aq, parent=None) +.B salt.modules.temp.dir(suffix=u\(aq\(aq, prefix=u\(aqtmp\(aq, parent=None) Create a temporary directory .sp CLI Example: @@ -228064,7 +242588,7 @@ salt \(aq*\(aq temp.dir prefix=\(aqmytemp\-\(aq parent=\(aq/var/run/\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.temp.file(suffix=\(aq\(aq, prefix=\(aqtmp\(aq, parent=None) +.B salt.modules.temp.file(suffix=u\(aq\(aq, prefix=u\(aqtmp\(aq, parent=None) Create a temporary file .sp CLI Example: @@ -228266,7 +242790,7 @@ salt \(aq*\(aq test.echo \(aqfoo bar baz quo qux\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.test.exception(message=\(aqTest Exception\(aq) +.B salt.modules.test.exception(message=u\(aqTest Exception\(aq) Raise an exception .sp Optionally provide an error message or output the full stack. @@ -228500,23 +243024,17 @@ salt \(aq*\(aq test.rand_sleep 60 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.test.rand_str(size=9999999999, hash_type=None) -Return a random string -.INDENT 7.0 -.INDENT 3.5 -.INDENT 0.0 -.TP -.B size -size of the string to generate -.TP -.B hash_type -hash type to use -.sp +.B salt.modules.test.random_hash(size=9999999999, hash_type=None) New in version 2015.5.2. -.UNINDENT -.UNINDENT -.UNINDENT +.sp +Changed in version 2018.3.0: Function has been renamed from \fBtest.rand_str\fP to +\fBtest.random_hash\fP + +.sp +Generates a random number between 1 and \fBsize\fP, then returns a hash of +that number. If no \fBhash_type\fP is passed, the hash_type specified by the +minion\(aqs \fBhash_type\fP config option is used. .sp CLI Example: .INDENT 7.0 @@ -228524,7 +243042,8 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq test.rand_str +salt \(aq*\(aq test.random_hash +salt \(aq*\(aq test.random_hash hash_type=sha512 .ft P .fi .UNINDENT @@ -228601,7 +243120,7 @@ salt \(aq*\(aq test.true .UNINDENT .INDENT 0.0 .TP -.B salt.modules.test.try_(module, return_try_exception=False, **kwargs) +.B salt.modules.test.try(module, return_try_exception=False, **kwargs) Try to run a module command. On an exception return None. If \fIreturn_try_exception\fP is set True return the exception. This can be helpful in templates where running a module might fail as expected. @@ -228724,6 +243243,386 @@ namespace. .SS salt.modules.test_virtual .sp Module for running arbitrary tests with a __virtual__ function +.SS salt.modules.textfsm_mod module +.SS TextFSM +.sp +New in version 2018.3.0. + +.sp +Execution module that processes plain text and extracts data +using TextFSM templates. The output is presented in JSON serializable +data, and can be easily re\-used in other modules, or directly +inside the renderer (Jinja, Mako, Genshi, etc.). +.INDENT 0.0 +.TP +.B depends +.INDENT 7.0 +.IP \(bu 2 +textfsm Python library +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +For Python 2/3 compatibility, it is more recommended to +install the \fBjtextfsm\fP library: \fBpip install jtextfsm\fP\&. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.textfsm_mod.extract(template_path, raw_text=None, raw_text_file=None, saltenv=\(aqbase\(aq) +Extracts the data entities from the unstructured +raw text sent as input and returns the data +mapping, processing using the TextFSM template. +.INDENT 7.0 +.TP +.B template_path +The path to the TextFSM template. +This can be specified using the absolute path +to the file, or using one of the following URL schemes: +.INDENT 7.0 +.IP \(bu 2 +\fBsalt://\fP, to fetch the template from the Salt fileserver. +.IP \(bu 2 +\fBhttp://\fP or \fBhttps://\fP +.IP \(bu 2 +\fBftp://\fP +.IP \(bu 2 +\fBs3://\fP +.IP \(bu 2 +\fBswift://\fP +.UNINDENT +.TP +.B raw_text: \fBNone\fP +The unstructured text to be parsed. +.TP +.B raw_text_file: \fBNone\fP +Text file to read, having the raw text to be parsed using the TextFSM template. +Supports the same URL schemes as the \fBtemplate_path\fP argument. +.TP +.B saltenv: \fBbase\fP +Salt fileserver envrionment from which to retrieve the file. +Ignored if \fBtemplate_path\fP is not a \fBsalt://\fP URL. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq textfsm.extract salt://textfsm/juniper_version_template raw_text_file=s3://junos_ver.txt +salt \(aq*\(aq textfsm.extract http://some\-server/textfsm/juniper_version_template raw_text=\(aqHostname: router.abc ... snip ...\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Jinja template example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{%\- set raw_text = \(aqHostname: router.abc ... snip ...\(aq \-%} +{%\- set textfsm_extract = salt.textfsm.extract(\(aqhttps://some\-server/textfsm/juniper_version_template\(aq, raw_text) \-%} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Raw text example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +Hostname: router.abc +Model: mx960 +JUNOS Base OS boot [9.1S3.5] +JUNOS Base OS Software Suite [9.1S3.5] +JUNOS Kernel Software Suite [9.1S3.5] +JUNOS Crypto Software Suite [9.1S3.5] +JUNOS Packet Forwarding Engine Support (M/T Common) [9.1S3.5] +JUNOS Packet Forwarding Engine Support (MX Common) [9.1S3.5] +JUNOS Online Documentation [9.1S3.5] +JUNOS Routing Software Suite [9.1S3.5] +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +TextFSM Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +Value Chassis (\eS+) +Value Required Model (\eS+) +Value Boot (.*) +Value Base (.*) +Value Kernel (.*) +Value Crypto (.*) +Value Documentation (.*) +Value Routing (.*) + +Start +# Support multiple chassis systems. + ^\eS+:$$ \-> Continue.Record + ^${Chassis}:$$ + ^Model: ${Model} + ^JUNOS Base OS boot \e[${Boot}\e] + ^JUNOS Software Release \e[${Base}\e] + ^JUNOS Base OS Software Suite \e[${Base}\e] + ^JUNOS Kernel Software Suite \e[${Kernel}\e] + ^JUNOS Crypto Software Suite \e[${Crypto}\e] + ^JUNOS Online Documentation \e[${Documentation}\e] + ^JUNOS Routing Software Suite \e[${Routing}\e] +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Output example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{ + "comment": "", + "result": true, + "out": [ + { + "kernel": "9.1S3.5", + "documentation": "9.1S3.5", + "boot": "9.1S3.5", + "crypto": "9.1S3.5", + "chassis": "", + "routing": "9.1S3.5", + "base": "9.1S3.5", + "model": "mx960" + } + ] +} +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.textfsm_mod.index(command, platform=None, platform_grain_name=None, platform_column_name=None, output=None, output_file=None, textfsm_path=None, index_file=None, saltenv=\(aqbase\(aq, include_empty=False, include_pat=None, exclude_pat=None) +Dynamically identify the template required to extract the +information from the unstructured raw text. +.sp +The output has the same structure as the \fBextract\fP execution +function, the difference being that \fBindex\fP is capable +to identify what template to use, based on the platform +details and the \fBcommand\fP\&. +.INDENT 7.0 +.TP +.B command +The command executed on the device, to get the output. +.TP +.B platform +The platform name, as defined in the TextFSM index file. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +For ease of use, it is recommended to define the TextFSM +indexfile with values that can be matches using the grains. +.UNINDENT +.UNINDENT +.TP +.B platform_grain_name +The name of the grain used to identify the platform name +in the TextFSM index file. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBtextfsm_platform_grain\fP\&. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option is ignored when \fBplatform\fP is specified. +.UNINDENT +.UNINDENT +.TP +.B platform_column_name: \fBPlatform\fP +The column name used to identify the platform, +exactly as specified in the TextFSM index file. +Default: \fBPlatform\fP\&. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This is field is case sensitive, make sure +to assign the correct value to this option, +exactly as defined in the index file. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBtextfsm_platform_column_name\fP\&. +.UNINDENT +.UNINDENT +.TP +.B output +The raw output from the device, to be parsed +and extract the structured data. +.TP +.B output_file +The path to a file that contains the raw output from the device, +used to extract the structured data. +This option supports the usual Salt\-specific schemes: \fBfile://\fP, +\fBsalt://\fP, \fBhttp://\fP, \fBhttps://\fP, \fBftp://\fP, \fBs3://\fP, \fBswift://\fP\&. +.TP +.B textfsm_path +The path where the TextFSM templates can be found. This can be either +absolute path on the server, either specified using the following URL +schemes: \fBfile://\fP, \fBsalt://\fP, \fBhttp://\fP, \fBhttps://\fP, \fBftp://\fP, +\fBs3://\fP, \fBswift://\fP\&. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This needs to be a directory with a flat structure, having an +index file (whose name can be specified using the \fBindex_file\fP option) +and a number of TextFSM templates. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBtextfsm_path\fP\&. +.UNINDENT +.UNINDENT +.TP +.B index_file: \fBindex\fP +The name of the TextFSM index file, under the \fBtextfsm_path\fP\&. Default: \fBindex\fP\&. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option can be also specified in the minion configuration +file or pillar as \fBtextfsm_index_file\fP\&. +.UNINDENT +.UNINDENT +.TP +.B saltenv: \fBbase\fP +Salt fileserver envrionment from which to retrieve the file. +Ignored if \fBtextfsm_path\fP is not a \fBsalt://\fP URL. +.TP +.B include_empty: \fBFalse\fP +Include empty files under the \fBtextfsm_path\fP\&. +.TP +.B include_pat +Glob or regex to narrow down the files cached from the given path. +If matching with a regex, the regex must be prefixed with \fBE@\fP, +otherwise the expression will be interpreted as a glob. +.TP +.B exclude_pat +Glob or regex to exclude certain files from being cached from the given path. +If matching with a regex, the regex must be prefixed with \fBE@\fP, +otherwise the expression will be interpreted as a glob. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +If used with \fBinclude_pat\fP, files matching this pattern will be +excluded from the subset of files defined by \fBinclude_pat\fP\&. +.UNINDENT +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq textfsm.index \(aqsh ver\(aq platform=Juniper output_file=salt://textfsm/juniper_version_example textfsm_path=salt://textfsm/ +salt \(aq*\(aq textfsm.index \(aqsh ver\(aq output_file=salt://textfsm/juniper_version_example textfsm_path=ftp://textfsm/ platform_column_name=Vendor +salt \(aq*\(aq textfsm.index \(aqsh ver\(aq output_file=salt://textfsm/juniper_version_example textfsm_path=https://some\-server/textfsm/ platform_column_name=Vendor platform_grain_name=vendor +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +TextFSM index file example: +.sp +\fBsalt://textfsm/index\fP +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +Template, Hostname, Vendor, Command +juniper_version_template, .*, Juniper, sh[[ow]] ve[[rsion]] +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The usage can be simplified, +by defining (some of) the following options: \fBtextfsm_platform_grain\fP, +\fBtextfsm_path\fP, \fBtextfsm_platform_column_name\fP, or \fBtextfsm_index_file\fP, +in the (proxy) minion configuration file or pillar. +.sp +Configuration example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +textfsm_platform_grain: vendor +textfsm_path: salt://textfsm/ +textfsm_platform_column_name: Vendor +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +And the CLI usage becomes as simple as: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq textfsm.index \(aqsh ver\(aq output_file=salt://textfsm/juniper_version_example +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Usgae inside a Jinja template: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{%\- set command = \(aqsh ver\(aq \-%} +{%\- set output = salt.net.cli(command) \-%} +{%\- set textfsm_extract = salt.textfsm.index(command, output=output) \-%} +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.timezone .sp Module for managing timezone on POSIX\-like systems. @@ -229096,7 +243995,7 @@ salt \(aq*\(aq tls.cert_base_path .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.cert_info(cert_path, digest=\(aqsha256\(aq) +.B salt.modules.tls.cert_info(cert_path, digest=u\(aqsha256\(aq) Return information for a particular certificate .INDENT 7.0 .TP @@ -229121,7 +244020,7 @@ salt \(aq*\(aq tls.cert_info /dir/for/certs/cert.pem .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_ca(ca_name, bits=2048, days=365, CN=\(aqlocalhost\(aq, C=\(aqUS\(aq, ST=\(aqUtah\(aq, L=\(aqSalt Lake City\(aq, O=\(aqSaltStack\(aq, OU=None, emailAddress=\(aqxyz@pdq.net\(aq, fixmode=False, cacert_path=None, ca_filename=None, digest=\(aqsha256\(aq, onlyif=None, unless=None, replace=False) +.B salt.modules.tls.create_ca(ca_name, bits=2048, days=365, CN=u\(aqlocalhost\(aq, C=u\(aqUS\(aq, ST=u\(aqUtah\(aq, L=u\(aqSalt Lake City\(aq, O=u\(aqSaltStack\(aq, OU=None, emailAddress=None, fixmode=False, cacert_path=None, ca_filename=None, digest=u\(aqsha256\(aq, onlyif=None, unless=None, replace=False) Create a Certificate Authority (CA) .INDENT 7.0 .TP @@ -229153,7 +244052,7 @@ organization, default is "SaltStack" organizational unit, default is None .TP .B emailAddress -email address for the CA owner, default is \fI\%\(aqxyz@pdq.net\fP\(aq +email address for the CA owner, default is None .TP .B cacert_path absolute path to ca certificates root directory @@ -229221,7 +244120,7 @@ salt \(aq*\(aq tls.create_ca test_ca .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_ca_signed_cert(ca_name, CN, days=365, cacert_path=None, ca_filename=None, cert_path=None, cert_filename=None, digest=\(aqsha256\(aq, cert_type=None, type_ext=False, replace=False) +.B salt.modules.tls.create_ca_signed_cert(ca_name, CN, days=365, cacert_path=None, ca_filename=None, cert_path=None, cert_filename=None, digest=u\(aqsha256\(aq, cert_type=None, type_ext=False, replace=False) Create a Certificate (CERT) signed by a named Certificate Authority (CA) .sp If the certificate file already exists, the function just returns assuming @@ -229343,7 +244242,7 @@ salt \(aq*\(aq tls.create_ca_signed_cert test localhost .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_csr(ca_name, bits=2048, CN=\(aqlocalhost\(aq, C=\(aqUS\(aq, ST=\(aqUtah\(aq, L=\(aqSalt Lake City\(aq, O=\(aqSaltStack\(aq, OU=None, emailAddress=\(aqxyz@pdq.net\(aq, subjectAltName=None, cacert_path=None, ca_filename=None, csr_path=None, csr_filename=None, digest=\(aqsha256\(aq, type_ext=False, cert_type=\(aqserver\(aq, replace=False) +.B salt.modules.tls.create_csr(ca_name, bits=2048, CN=u\(aqlocalhost\(aq, C=u\(aqUS\(aq, ST=u\(aqUtah\(aq, L=u\(aqSalt Lake City\(aq, O=u\(aqSaltStack\(aq, OU=None, emailAddress=None, subjectAltName=None, cacert_path=None, ca_filename=None, csr_path=None, csr_filename=None, digest=u\(aqsha256\(aq, type_ext=False, cert_type=u\(aqserver\(aq, replace=False) Create a Certificate Signing Request (CSR) for a particular Certificate Authority (CA) .INDENT 7.0 @@ -229374,7 +244273,7 @@ NOTE: Must the same as CA certificate or an error will be raised organizational unit, default is None .TP .B emailAddress -email address for the request, default is \fI\%\(aqxyz@pdq.net\fP\(aq +email address for the request, default is None .TP .B subjectAltName valid subjectAltNames in full form, e.g. to add DNS entry you would call @@ -229528,7 +244427,7 @@ salt \(aq*\(aq tls.create_empty_crl ca_name=\(aqkoji\(aq ca_file .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_pkcs12(ca_name, CN, passphrase=\(aq\(aq, cacert_path=None, replace=False) +.B salt.modules.tls.create_pkcs12(ca_name, CN, passphrase=u\(aq\(aq, cacert_path=None, replace=False) Create a PKCS#12 browser certificate for a particular Certificate (CN) .INDENT 7.0 .TP @@ -229592,7 +244491,7 @@ salt \(aq*\(aq tls.create_pkcs12 test localhost .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_self_signed_cert(tls_dir=\(aqtls\(aq, bits=2048, days=365, CN=\(aqlocalhost\(aq, C=\(aqUS\(aq, ST=\(aqUtah\(aq, L=\(aqSalt Lake City\(aq, O=\(aqSaltStack\(aq, OU=None, emailAddress=\(aqxyz@pdq.net\(aq, cacert_path=None, cert_filename=None, digest=\(aqsha256\(aq, replace=False) +.B salt.modules.tls.create_self_signed_cert(tls_dir=u\(aqtls\(aq, bits=2048, days=365, CN=u\(aqlocalhost\(aq, C=u\(aqUS\(aq, ST=u\(aqUtah\(aq, L=u\(aqSalt Lake City\(aq, O=u\(aqSaltStack\(aq, OU=None, emailAddress=None, cacert_path=None, cert_filename=None, digest=u\(aqsha256\(aq, replace=False) Create a Self\-Signed Certificate (CERT) .INDENT 7.0 .TP @@ -229622,7 +244521,7 @@ NOTE: Must the same as CA certificate or an error will be raised organizational unit, default is None .TP .B emailAddress -email address for the request, default is \fI\%\(aqxyz@pdq.net\fP\(aq +email address for the request, default is None .TP .B cacert_path absolute path to ca certificates root directory @@ -229724,7 +244623,7 @@ salt \(aq*\(aq tls.get_ca test_ca as_text=False cacert_path=/etc/certs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.get_ca_signed_cert(ca_name, CN=\(aqlocalhost\(aq, as_text=False, cacert_path=None, cert_filename=None) +.B salt.modules.tls.get_ca_signed_cert(ca_name, CN=u\(aqlocalhost\(aq, as_text=False, cacert_path=None, cert_filename=None) Get the certificate path or content .INDENT 7.0 .TP @@ -229761,7 +244660,7 @@ salt \(aq*\(aq tls.get_ca_signed_cert test_ca CN=localhost as_text=False cacert_ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.get_ca_signed_key(ca_name, CN=\(aqlocalhost\(aq, as_text=False, cacert_path=None, key_filename=None) +.B salt.modules.tls.get_ca_signed_key(ca_name, CN=u\(aqlocalhost\(aq, as_text=False, cacert_path=None, key_filename=None) Get the certificate path or content .INDENT 7.0 .TP @@ -230023,7 +244922,7 @@ Apache Tomcat/7.0.37 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.deploy_war(war, context, force=\(aqno\(aq, url=\(aqhttp://localhost:8080/manager\(aq, saltenv=\(aqbase\(aq, timeout=180, temp_war_location=None, version=True) +.B salt.modules.tomcat.deploy_war(war, context, force=u\(aqno\(aq, url=u\(aqhttp://localhost:8080/manager\(aq, saltenv=u\(aqbase\(aq, timeout=180, temp_war_location=None, version=True) Deploy a WAR file .INDENT 7.0 .TP @@ -230114,6 +245013,17 @@ Extract the version from the war file name. There does not seem to be a standard for encoding the version into the \fI\%war file name\fP\&. .sp Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +/path/salt\-2015.8.6.war \-> 2015.8.6 +/path/V6R2013xD5.war \-> None +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -230134,7 +245044,7 @@ salt \(aq*\(aq tomcat.fullversion .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.leaks(url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.leaks(url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) Find memory leaks in tomcat .INDENT 7.0 .TP @@ -230161,7 +245071,7 @@ salt \(aq*\(aq tomcat.leaks .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.ls(url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.ls(url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) list all the deployed webapps .INDENT 7.0 .TP @@ -230189,7 +245099,7 @@ salt \(aq*\(aq tomcat.ls http://localhost:8080/manager .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.passwd(passwd, user=\(aq\(aq, alg=\(aqsha1\(aq, realm=None) +.B salt.modules.tomcat.passwd(passwd, user=u\(aq\(aq, alg=u\(aqsha1\(aq, realm=None) This function replaces the $CATALINA_HOME/bin/digest.sh script convert a clear\-text password to the $CATALINA_BASE/conf/tomcat\-users.xml format @@ -230210,7 +245120,7 @@ salt \(aq*\(aq tomcat.passwd secret tomcat sha1 \(aqProtected Realm\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.reload(app, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.reload(app, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) Reload the webapp .INDENT 7.0 .TP @@ -230241,7 +245151,7 @@ salt \(aq*\(aq tomcat.reload /jenkins http://localhost:8080/manager .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.serverinfo(url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.serverinfo(url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) return details about the server .INDENT 7.0 .TP @@ -230269,7 +245179,7 @@ salt \(aq*\(aq tomcat.serverinfo http://localhost:8080/manager .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.sessions(app, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.sessions(app, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) return the status of the webapp sessions .INDENT 7.0 .TP @@ -230317,7 +245227,7 @@ salt \(aq*\(aq tomcat.signal start .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.start(app, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.start(app, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) Start the webapp .INDENT 7.0 .TP @@ -230347,7 +245257,7 @@ salt \(aq*\(aq tomcat.start /jenkins http://localhost:8080/manager .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.status(url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.status(url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) Used to test if the tomcat manager is up .INDENT 7.0 .TP @@ -230375,7 +245285,7 @@ salt \(aq*\(aq tomcat.status http://localhost:8080/manager .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.status_webapp(app, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.status_webapp(app, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) return the status of the webapp (stopped | running | missing) .INDENT 7.0 .TP @@ -230406,7 +245316,7 @@ salt \(aq*\(aq tomcat.status_webapp /jenkins http://localhost:8080/manager .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.stop(app, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.stop(app, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) Stop the webapp .INDENT 7.0 .TP @@ -230437,7 +245347,7 @@ salt \(aq*\(aq tomcat.stop /jenkins http://localhost:8080/manager .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tomcat.undeploy(app, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.modules.tomcat.undeploy(app, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) Undeploy a webapp .INDENT 7.0 .TP @@ -231108,6 +246018,16 @@ salt \(aq*\(aq udev.env /sys/class/net/eth0 Return all the udev database .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq udev.exportdb +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -231485,8 +246405,29 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.upstart.status(name, sig=None) -Return the status for a service, returns a bool whether the service is -running. +Return the status for a service. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the service to check +.IP \(bu 2 +\fBsig\fP (\fI\%str\fP) \-\- Signature to use to find the service via ps +.UNINDENT +.TP +.B Returns +True if running, False otherwise +dict: Maps service name to True if running, False otherwise +.TP +.B Return type +\fI\%bool\fP +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -231494,7 +246435,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq service.status +salt \(aq*\(aq service.status [service signature] .ft P .fi .UNINDENT @@ -231606,7 +246547,7 @@ minion, and it is using a different module (or gives an error similar to .UNINDENT .INDENT 0.0 .TP -.B salt.modules.useradd.add(name, uid=None, gid=None, groups=None, home=None, shell=None, unique=True, system=False, fullname=\(aq\(aq, roomnumber=\(aq\(aq, workphone=\(aq\(aq, homephone=\(aq\(aq, createhome=True, loginclass=None, root=None, nologinit=False) +.B salt.modules.useradd.add(name, uid=None, gid=None, groups=None, home=None, shell=None, unique=True, system=False, fullname=u\(aq\(aq, roomnumber=u\(aq\(aq, workphone=u\(aq\(aq, homephone=u\(aq\(aq, createhome=True, loginclass=None, root=None, nologinit=False) Add a user to the minion .sp CLI Example: @@ -231997,6 +246938,425 @@ salt \(aq*\(aq uwsgi.stats 127.0.0.1:5050 .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.vagrant +.sp +Work with virtual machines managed by Vagrant. +.sp +New in version 2018.3.0. + +.sp +Mapping between a Salt node id and the Vagrant machine name +(and the path to the Vagrantfile where it is defined) +is stored in a Salt sdb database on the Vagrant host (minion) machine. +In order to use this module, sdb must be configured. An SQLite +database is the recommended storage method. The URI used for +the sdb lookup is "sdb://vagrant_sdb_data". +.INDENT 0.0 +.TP +.B requirements: +.INDENT 7.0 +.IP \(bu 2 +the VM host machine must have salt\-minion, Vagrant and a vm provider installed. +.IP \(bu 2 +the VM host must have a valid definition for \fIsdb://vagrant_sdb_data\fP +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +Configuration example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# file /etc/salt/minion.d/vagrant_sdb.conf +vagrant_sdb_data: + driver: sqlite3 + database: /var/cache/salt/vagrant.sqlite + table: sdb + create_table: True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.destroy(name) +Destroy and delete a virtual machine. (vagrant destroy \-f) +.sp +This also removes the salt_id name defined by vagrant.init. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt vagrant.destroy +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.get_machine_id(machine, cwd) +returns the salt_id name of the Vagrant VM +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmachine\fP \-\- the Vagrant machine name +.IP \(bu 2 +\fBcwd\fP \-\- the path to Vagrantfile +.UNINDENT +.TP +.B Returns +salt_id name +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.get_ssh_config(name, network_mask=u\(aq\(aq, get_private_key=False) +Retrieve hints of how you might connect to a Vagrant VM. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP \-\- the salt_id of the machine +.IP \(bu 2 +\fBnetwork_mask\fP \-\- a CIDR mask to search for the VM\(aqs address +.IP \(bu 2 +\fBget_private_key\fP \-\- (default: False) return the key used for ssh login +.UNINDENT +.TP +.B Returns +a dict of ssh login information for the VM +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt vagrant.get_ssh_config +salt my_laptop vagrant.get_ssh_config quail1 network_mask=10.0.0.0/8 get_private_key=True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The returned dictionary contains: +.INDENT 7.0 +.IP \(bu 2 +key_filename: the name of the private key file on the VM host computer +.IP \(bu 2 +ssh_username: the username to be used to log in to the VM +.IP \(bu 2 +ssh_host: the IP address used to log in to the VM. (This will usually be \fI127.0.0.1\fP) +.IP \(bu 2 +ssh_port: the TCP port used to log in to the VM. (This will often be \fI2222\fP) +.IP \(bu 2 +[ip_address:] (if \fInetwork_mask\fP is defined. see below) +.IP \(bu 2 +[private_key:] (if \fIget_private_key\fP is True) the private key for ssh_username +.UNINDENT +.sp +About \fInetwork_mask\fP: +.sp +Vagrant usually uses a redirected TCP port on its host computer to log in to a VM using ssh. +This redirected port and its IP address are "ssh_port" and "ssh_host". The ssh_host is +usually the localhost (127.0.0.1). +This makes it impossible for a third machine (such as a salt\-cloud master) to contact the VM +unless the VM has another network interface defined. You will usually want a bridged network +defined by having a \fIconfig.vm.network "public_network"\fP statement in your \fIVagrantfile\fP\&. +.sp +The IP address of the bridged adapter will typically be assigned by DHCP and unknown to you, +but you should be able to determine what IP network the address will be chosen from. +If you enter a CIDR network mask, Salt will attempt to find the VM\(aqs address for you. +The host machine will send an "ifconfig" command to the VM (using ssh to \fIssh_host\fP:\fIssh_port\fP) +and return the IP address of the first interface it can find which matches your mask. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.get_vm_info(name) +get the information for a VM. +.INDENT 7.0 +.TP +.B Parameters +\fBname\fP \-\- salt_id name +.TP +.B Returns +dictionary of {\(aqmachine\(aq: x, \(aqcwd\(aq: y, ...}. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.init(name, cwd=None, machine=u\(aq\(aq, runas=None, start=False, vagrant_provider=u\(aq\(aq, vm=None) +Initialize a new Vagrant VM. +.sp +This inputs all the information needed to start a Vagrant VM. These settings are stored in +a Salt sdb database on the Vagrant host minion and used to start, control, and query the +guest VMs. The salt_id assigned here is the key field for that database and must be unique. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP \-\- The salt_id name you will use to control this VM +.IP \(bu 2 +\fBcwd\fP \-\- The path to the directory where the Vagrantfile is located +.IP \(bu 2 +\fBmachine\fP \-\- The machine name in the Vagrantfile. If blank, the primary machine will be used. +.IP \(bu 2 +\fBrunas\fP \-\- The username on the host who owns the Vagrant work files. +.IP \(bu 2 +\fBstart\fP \-\- (default: False) Start the virtual machine now. +.IP \(bu 2 +\fBvagrant_provider\fP \-\- The name of a Vagrant VM provider (if not the default). +.IP \(bu 2 +\fBvm\fP \-\- Optionally, all the above information may be supplied in this dictionary. +.UNINDENT +.TP +.B Returns +A string indicating success, or False. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt vagrant.init /path/to/Vagrantfile +salt my_laptop vagrant.init x1 /projects/bevy_master machine=quail1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.list_active_vms(cwd=None) +Return a list of machine names for active virtual machine on the host, +which are defined in the Vagrantfile at the indicated path. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vagrant.list_active_vms cwd=/projects/project_1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.list_domains() +Return a list of the salt_id names of all available Vagrant VMs on +this host without regard to the path where they are defined. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vagrant.list_domains \-\-log\-level=info +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The log shows information about all known Vagrant environments +on this machine. This data is cached and may not be completely +up\-to\-date. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.list_inactive_vms(cwd=None) +Return a list of machine names for inactive virtual machine on the host, +which are defined in the Vagrantfile at the indicated path. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq virt.list_inactive_vms cwd=/projects/project_1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.pause(name) +Pause (vagrant suspend) the named VM. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt vagrant.pause +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.reboot(name, provision=False) +Reboot a VM. (vagrant reload) +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt vagrant.reboot provision=True +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP \-\- The salt_id name you will use to control this VM +.IP \(bu 2 +\fBprovision\fP \-\- (False) also re\-run the Vagrant provisioning scripts. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.shutdown(name) +Send a soft shutdown (vagrant halt) signal to the named vm. +.sp +This does the same thing as vagrant.stop. Other\-VM control +modules use "stop" and "shutdown" to differentiate between +hard and soft shutdowns. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt vagrant.shutdown +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.start(name) +Start (vagrant up) a virtual machine defined by salt_id name. +The machine must have been previously defined using "vagrant.init". +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt vagrant.start +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.stop(name) +Hard shutdown the virtual machine. (vagrant halt) +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt vagrant.stop +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.version() +Return the version of Vagrant on the minion +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vagrant.version +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vagrant.vm_state(name=u\(aq\(aq, cwd=None) +Return list of information for all the vms indicating their state. +.sp +If you pass a VM name in as an argument then it will return info +for just the named VM, otherwise it will return all VMs defined by +the Vagrantfile in the \fIcwd\fP directory. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vagrant.vm_state cwd=/projects/project_1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +returns a list of dictionaries with machine name, state, provider, +and salt_id name. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +datum = {\(aqmachine\(aq: _, # Vagrant machine name, + \(aqstate\(aq: _, # string indicating machine state, like \(aqrunning\(aq + \(aqprovider\(aq: _, # the Vagrant VM provider + \(aqname\(aq: _} # salt_id name +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Known bug: if there are multiple machines in your Vagrantfile, and you request +the status of the \fBprimary\fP machine, which you defined by leaving the \fBmachine\fP +parameter blank, then you may receive the status of all of them. +Please specify the actual machine name for each VM if there are more than one. +.UNINDENT .SS salt.modules.varnish .sp Support for Varnish @@ -232114,6 +247474,8 @@ salt \(aq*\(aq varnish.version .UNINDENT .UNINDENT .SS salt.modules.vault module +.sp +Functions to interact with Hashicorp Vault. .INDENT 0.0 .TP .B maintainer @@ -232124,9 +247486,20 @@ new .TP .B platform all +.TP +.B note +If you see the following error, you\(aqll need to upgrade \fBrequests\fP to atleast 2.4.2 .UNINDENT +.INDENT 0.0 +.INDENT 3.5 .sp -Functions to interact with Hashicorp Vault. +.nf +.ft C + [salt.pillar][CRITICAL][14337] Pillar render error: Failed to load ext_pillar vault: {\(aqerror\(aq: "request() got an unexpected keyword argument \(aqjson\(aq"} +.ft P +.fi +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B configuration @@ -232142,6 +247515,7 @@ Add this segment to the master configuration file, or .ft C vault: url: https://vault.service.domain:8200 + verify: /etc/ssl/certs/ca\-certificates.crt auth: method: token token: 11111111\-2222\-3333\-4444\-555555555555 @@ -232157,10 +247531,22 @@ vault: .TP .B url Url to your Vault installation. Required. +.TP +.B verify +For details please see +\fI\%http://docs.python\-requests.org/en/master/user/advanced/#ssl\-cert\-verification\fP +.sp +New in version 2018.3.0. + .TP .B auth Currently only token auth is supported. The token must be able to create tokens with the policies that should be assigned to minions. Required. +.sp +You can still use the token via a OS environment variable via this +config example: +.sp +And then export the VAULT_TOKEN variable in your OS: .TP .B policies Policies that are assigned to minions when requesting a token. These can @@ -232204,6 +247590,16 @@ peer_run: Delete secret at the path in vault. The vault policy used must allow this. .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vault.delete_secret "secret/my/secret" +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -232212,6 +247608,16 @@ List secret keys at the path in vault. The vault policy used must allow this. The path should end with a trailing slash. .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vault.list_secrets "secret/my/" +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -232249,6 +247655,16 @@ secrets: Set secret at the path in vault. The vault policy used must allow this. .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vault.write_secret "secret/my/secret" user="foo" password="bar" +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .SS salt.modules.vbox_guest .sp @@ -232487,7 +247903,7 @@ salt \(aqhypervisor\(aq vboxmanage.clonemedium .UNINDENT .INDENT 0.0 .TP -.B salt.modules.vboxmanage.clonevm(name=None, uuid=None, new_name=None, snapshot_uuid=None, snapshot_name=None, mode=\(aqmachine\(aq, options=None, basefolder=None, new_uuid=None, register=False, groups=None, **kwargs) +.B salt.modules.vboxmanage.clonevm(name=None, uuid=None, new_name=None, snapshot_uuid=None, snapshot_name=None, mode=u\(aqmachine\(aq, options=None, basefolder=None, new_uuid=None, register=False, groups=None, **kwargs) Clone a new VM from an existing VM .sp CLI Example: @@ -232538,7 +247954,7 @@ salt \(aq*\(aq vboxmanage.destroy my_vm .UNINDENT .INDENT 0.0 .TP -.B salt.modules.vboxmanage.list_items(item, details=False, group_by=\(aqUUID\(aq) +.B salt.modules.vboxmanage.list_items(item, details=False, group_by=u\(aqUUID\(aq) Return a list of a specific type of item. The following items are available: .INDENT 7.0 .INDENT 3.5 @@ -232749,7 +248165,7 @@ New in version 2015.8.0. Requires an \fBapi_key\fP in \fB/etc/salt/minion\fP: .INDENT 0.0 .TP -.B salt.modules.victorops.create_event(message_type=None, routing_key=\(aqeverybody\(aq, **kwargs) +.B salt.modules.victorops.create_event(message_type=None, routing_key=u\(aqeverybody\(aq, **kwargs) Create an event in VictorOps. Designed for use in states. .sp The following parameters are required: @@ -232833,7 +248249,7 @@ libvirt Python module .UNINDENT .INDENT 0.0 .TP -.B salt.modules.virt.cpu_baseline(full=False, migratable=False, out=\(aqlibvirt\(aq) +.B salt.modules.virt.cpu_baseline(full=False, migratable=False, out=u\(aqlibvirt\(aq) Return the optimal \(aqcustom\(aq CPU baseline config for VM\(aqs on this minion .sp New in version 2016.3.0. @@ -233180,7 +248596,7 @@ salt \(aq*\(aq virt.get_xml .UNINDENT .INDENT 0.0 .TP -.B salt.modules.virt.init(name, cpu, mem, image=None, nic=\(aqdefault\(aq, hypervisor=\(aqkvm\(aq, start=True, disk=\(aqdefault\(aq, saltenv=\(aqbase\(aq, seed=True, install=True, pub_key=None, priv_key=None, seed_cmd=\(aqseed.apply\(aq, enable_vnc=False, enable_qcow=False, **kwargs) +.B salt.modules.virt.init(name, cpu, mem, image=None, nic=u\(aqdefault\(aq, hypervisor=u\(aqkvm\(aq, start=True, disk=u\(aqdefault\(aq, saltenv=u\(aqbase\(aq, seed=True, install=True, pub_key=None, priv_key=None, seed_cmd=u\(aqseed.apply\(aq, enable_vnc=False, enable_qcow=False, **kwargs) Initialize a new vm .sp CLI Example: @@ -233523,7 +248939,7 @@ salt \(aq*\(aq virt.seed_non_shared_migrate .UNINDENT .INDENT 0.0 .TP -.B salt.modules.virt.set_autostart(vm_, state=\(aqon\(aq) +.B salt.modules.virt.set_autostart(vm_, state=u\(aqon\(aq) Set the autostart flag on a VM so that the VM will start with the host system on reboot. .sp @@ -233893,7 +249309,7 @@ New in version 0.17.0. .INDENT 0.0 .TP -.B salt.modules.virtualenv_mod.create(path, venv_bin=None, system_site_packages=False, distribute=False, clear=False, python=None, extra_search_dir=None, never_download=None, prompt=None, pip=False, symlinks=None, upgrade=None, user=None, use_vt=False, saltenv=\(aqbase\(aq) +.B salt.modules.virtualenv_mod.create(path, venv_bin=None, system_site_packages=False, distribute=False, clear=False, python=None, extra_search_dir=None, never_download=None, prompt=None, pip=False, symlinks=None, upgrade=None, user=None, use_vt=False, saltenv=u\(aqbase\(aq) Create a virtualenv .INDENT 7.0 .TP @@ -234157,8 +249573,8 @@ pip install pyVmomi .INDENT 0.0 .INDENT 3.5 Version 6.0 of pyVmomi has some problems with SSL error handling on certain -versions of Python. If using version 6.0 of pyVmomi, Python 2.6, -Python 2.7.9, or newer must be present. This is due to an upstream dependency +versions of Python. If using version 6.0 of pyVmomi, Python 2.7.9, +or newer must be present. This is due to an upstream dependency in pyVmomi 6.0 that is not supported in Python versions 2.7 to 2.7.8. If the version of Python is not in the supported range, you will need to install an earlier version of pyVmomi. See \fI\%Issue #29537\fP for more information. @@ -234250,10 +249666,11 @@ my\-minion: .sp However, some functions should be used against ESXi hosts, not vCenter Servers. Functionality such as getting a host\(aqs coredump network configuration should be -performed against a host and not a vCenter server. If the authentication information -you\(aqre using is against a vCenter server and not an ESXi host, you can provide the -host name that is associated with the vCenter server in the command, as a list, using -the \fBhost_names\fP or \fBesxi_host\fP kwarg. For example: +performed against a host and not a vCenter server. If the authentication +information you\(aqre using is against a vCenter server and not an ESXi host, you +can provide the host name that is associated with the vCenter server in the +command, as a list, using the \fBhost_names\fP or \fBesxi_host\fP kwarg. For +example: .INDENT 0.0 .INDENT 3.5 .sp @@ -234315,6 +249732,191 @@ local: .UNINDENT .INDENT 0.0 .TP +.B salt.modules.vsphere.add_capacity_to_diskgroup(*args, **kwargs) +Adds capacity disks to the disk group with the specified cache disk. +.INDENT 7.0 +.TP +.B cache_disk_id +The canonical name of the cache disk. +.TP +.B capacity_disk_ids +A list containing canonical names of the capacity disks to add. +.TP +.B safety_checks +Specify whether to perform safety check or to skip the checks and try +performing the required task. Default value is True. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.add_capacity_to_diskgroup + cache_disk_id=\(aqnaa.000000000000001\(aq + capacity_disk_ids=\(aq[naa.000000000000002, naa.000000000000003]\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.add_license(*args, **kwargs) +Adds a license to the vCenter or ESXi host +.INDENT 7.0 +.TP +.B key +License key. +.TP +.B description +License description added in as a label. +.TP +.B safety_checks +Specify whether to perform safety check or to skip the checks and try +performing the required task +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.add_license key= desc=\(aqLicense desc\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.assign_default_storage_policy_to_datastore(*args, **kwargs) +Assigns a storage policy as the default policy to a datastore. +.INDENT 7.0 +.TP +.B policy +Name of the policy to assign. +.TP +.B datastore +Name of the datastore to assign. +The datastore needs to be visible to the VMware entity the proxy +points to. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.assign_storage_policy_to_datastore + policy=\(aqpolicy name\(aq datastore=ds1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.assign_license(*args, **kwargs) +Assigns a license to an entity +.INDENT 7.0 +.TP +.B license_key +Key of the license to assign +See \fB_get_entity\fP docstrings for format. +.TP +.B license_name +Display name of license +.TP +.B entity +Dictionary representation of an entity +.TP +.B entity_display_name +Entity name used in logging +.TP +.B safety_checks +Specify whether to perform safety check or to skip the checks and try +performing the required task. Default is False. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.assign_license license_key=00000:00000 + license name=test entity={type:cluster,datacenter:dc,cluster:cl} +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.compare_vm_configs(new_config, current_config) +Compares virtual machine current and new configuration, the current is the +one which is deployed now, and the new is the target config. Returns the +differences between the objects in a dictionary, the keys are the +configuration parameter keys and the values are differences objects: either +list or recursive difference +.INDENT 7.0 +.TP +.B new_config: +New config dictionary with every available parameter +.TP +.B current_config +Currently deployed configuration +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.configure_host_cache(*args, **kwargs) +Configures the host cache on the selected host. +.INDENT 7.0 +.TP +.B enabled +Boolean flag specifying whether the host cache is enabled. +.TP +.B datastore +Name of the datastore that contains the host cache. Must be set if +enabled is \fBtrue\fP\&. +.TP +.B swap_size_MiB +Swap size in Mibibytes. Needs to be set if enabled is \fBtrue\fP\&. Must be +smaller thant the datastore size. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.configure_host_cache enabled=False + +salt \(aq*\(aq vsphere.configure_host_cache enabled=True datastore=ds1 + swap_size_MiB=1024 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.vsphere.coredump_network_enable(host, username, password, enabled, protocol=None, port=None, esxi_hosts=None, credstore=None) Enable or disable ESXi core dump collection. Returns \fBTrue\fP if coredump is enabled and returns \fBFalse\fP if core dump is not enabled. If there was an error, the error @@ -234367,6 +249969,475 @@ salt \(aq*\(aq vsphere.coredump_network_enable my.vcenter.location root bad\-pas .UNINDENT .INDENT 0.0 .TP +.B salt.modules.vsphere.create_cluster(*args, **kwargs) +Creates a cluster. +.sp +Note: cluster_dict[\(aqname\(aq] will be overridden by the cluster param value +.INDENT 7.0 +.TP +.B config_dict +Dictionary with the config values of the new cluster. +.TP +.B datacenter +Name of datacenter containing the cluster. +Ignored if already contained by proxy details. +Default value is None. +.TP +.B cluster +Name of cluster. +Ignored if already contained by proxy details. +Default value is None. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# esxdatacenter proxy +salt \(aq*\(aq vsphere.create_cluster cluster_dict=$cluster_dict cluster=cl1 + +# esxcluster proxy +salt \(aq*\(aq vsphere.create_cluster cluster_dict=$cluster_dict +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.create_datacenter(*args, **kwargs) +Creates a datacenter. +.sp +Supported proxies: esxdatacenter +.INDENT 7.0 +.TP +.B datacenter_name +The datacenter name +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.create_datacenter dc1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.create_diskgroup(*args, **kwargs) +Creates disk group on an ESXi host with the specified cache and +capacity disks. +.INDENT 7.0 +.TP +.B cache_disk_id +The canonical name of the disk to be used as a cache. The disk must be +ssd. +.TP +.B capacity_disk_ids +A list containing canonical names of the capacity disks. Must contain at +least one id. Default is True. +.TP +.B safety_checks +Specify whether to perform safety check or to skip the checks and try +performing the required task. Default value is True. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.create_diskgroup cache_disk_id=\(aqnaa.000000000000001\(aq + capacity_disk_ids=\(aq[naa.000000000000002, naa.000000000000003]\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.create_dvportgroup(*args, **kwargs) +Creates a distributed virtual portgroup. +.sp +Note: The \fBportgroup_name\fP param will override any name already set +in \fBportgroup_dict\fP\&. +.INDENT 7.0 +.TP +.B portgroup_dict +Dictionary with the config values the portgroup should be created with +(exmaple in salt.states.dvs). +.TP +.B portgroup_name +Name of the portgroup to be created. +.TP +.B dvs +Name of the DVS that will contain the portgroup. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.create_dvportgroup portgroup_dict= + portgroup_name=pg1 dvs=dvs1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.create_dvs(*args, **kwargs) +Creates a distributed virtual switch (DVS). +.sp +Note: The \fBdvs_name\fP param will override any name set in \fBdvs_dict\fP\&. +.INDENT 7.0 +.TP +.B dvs_dict +Dict representation of the new DVS (exmaple in salt.states.dvs) +.TP +.B dvs_name +Name of the DVS to be created. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.create_dvs dvs dict=$dvs_dict dvs_name=dvs_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.create_storage_policy(*args, **kwargs) +Creates a storage policy. +.sp +Supported capability types: scalar, set, range. +.INDENT 7.0 +.TP +.B policy_name +Name of the policy to create. +The value of the argument will override any existing name in +\fBpolicy_dict\fP\&. +.TP +.B policy_dict +Dictionary containing the changes to apply to the policy. +(exmaple in salt.states.pbm) +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.create_storage_policy policy_name=\(aqpolicy name\(aq + policy_dict="$policy_dict" +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.create_vm(*args, **kwargs) +Creates a virtual machine container. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt vm_minion vsphere.create_vm vm_name=vmname cpu=\(aq{count: 2, nested: True}\(aq ... +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B vm_name +Name of the virtual machine +.TP +.B cpu +Properties of CPUs for freshly created machines +.TP +.B memory +Memory size for freshly created machines +.TP +.B image +Virtual machine guest OS version identifier +VirtualMachineGuestOsIdentifier +.TP +.B version +Virtual machine container hardware version +.TP +.B datacenter +Datacenter where the virtual machine will be deployed (mandatory) +.TP +.B datastore +Datastore where the virtual machine files will be placed +.TP +.B placement +Resource pool or cluster or host or folder where the virtual machine +will be deployed +.TP +.B devices +interfaces +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B interfaces: +adapter: \(aqNetwork adapter 1\(aq +name: vlan100 +switch_type: distributed or standard +adapter_type: vmxnet3 or vmxnet, vmxnet2, vmxnet3, e1000, e1000e +mac: \(aq00:11:22:33:44:55\(aq +connectable: +.INDENT 7.0 +.INDENT 3.5 +allow_guest_control: True +connected: True +start_connected: True +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +disks +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B disks: +adapter: \(aqHard disk 1\(aq +size: 16 +unit: GB +address: \(aq0:0\(aq +controller: \(aqSCSI controller 0\(aq +thin_provision: False +eagerly_scrub: False +datastore: \(aqmyshare\(aq +filename: \(aqvm/mydisk.vmdk\(aq +.UNINDENT +.UNINDENT +.UNINDENT +.sp +scsi_devices +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B scsi_devices: +controller: \(aqSCSI controller 0\(aq +type: paravirtual +bus_sharing: no_sharing +.UNINDENT +.UNINDENT +.UNINDENT +.sp +serial_ports +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B serial_ports: +adapter: \(aqSerial port 1\(aq +type: network +backing: +.INDENT 7.0 +.INDENT 3.5 +uri: \(aq\fI\%telnet://something:port\fP\(aq +direction: +filename: \(aqservice_uri\(aq +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B connectable: +allow_guest_control: True +connected: True +start_connected: True +.UNINDENT +.sp +yield: False +.UNINDENT +.UNINDENT +.UNINDENT +.sp +cd_drives +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B cd_drives: +adapter: \(aqCD/DVD drive 0\(aq +controller: \(aqIDE 0\(aq +device_type: datastore_iso_file +datastore_iso_file: +.INDENT 7.0 +.INDENT 3.5 +path: path_to_iso +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B connectable: +allow_guest_control: True +connected: True +start_connected: True +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.TP +.B advanced_config +Advanced config parameters to be set for the virtual machine +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.create_vmfs_datastore(*args, **kwargs) +Creates a ESXi host disk group with the specified cache and capacity disks. +.INDENT 7.0 +.TP +.B datastore_name +The name of the datastore to be created. +.TP +.B disk_id +The disk id (canonical name) on which the datastore is created. +.TP +.B vmfs_major_version +The VMFS major version. +.TP +.B safety_checks +Specify whether to perform safety check or to skip the checks and try +performing the required task. Default is True. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.create_vmfs_datastore datastore_name=ds1 disk_id= + vmfs_major_version=5 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.delete_advanced_configs(*args, **kwargs) +Removes extra config parameters from a virtual machine +.INDENT 7.0 +.TP +.B vm_name +Virtual machine name +.TP +.B datacenter +Datacenter name where the virtual machine is available +.TP +.B advanced_configs +List of advanced config values to be removed +.TP +.B service_instance +vCenter service instance for connection and configuration +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.delete_vm(*args, **kwargs) +Deletes a virtual machine defined by name and placement +.INDENT 7.0 +.TP +.B name +Name of the virtual machine +.TP +.B datacenter +Datacenter of the virtual machine +.TP +.B placement +Placement information of the virtual machine +.TP +.B service_instance +vCenter service instance for connection and configuration +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.delete_vm name=my_vm datacenter=my_datacenter +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.disconnect(*args, **kwargs) +Disconnects from a vCenter or ESXi host +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Should be used by state functions, not invoked directly. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B service_instance +Service instance (vim.ServiceInstance) +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +See note above. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.vsphere.enable_firewall_ruleset(host, username, password, ruleset_enable, ruleset_name, protocol=None, port=None, esxi_hosts=None, credstore=None) Enable or disable an ESXi firewall rule set. .INDENT 7.0 @@ -234425,6 +250496,41 @@ salt \(aq*\(aq vsphere.enable_firewall_ruleset my.vcenter.location root bad\-pas .UNINDENT .INDENT 0.0 .TP +.B salt.modules.vsphere.erase_disk_partitions(*args, **kwargs) +Erases the partitions on a disk. +The disk can be specified either by the canonical name, or by the +scsi_address. +.INDENT 7.0 +.TP +.B disk_id +Canonical name of the disk. +Either \fBdisk_id\fP or \fBscsi_address\fP needs to be specified +(\fBdisk_id\fP supersedes \fBscsi_address\fP\&. +.TP +.B scsi_address +Scsi address of the disk. +\fBdisk_id\fP or \fBscsi_address\fP needs to be specified +(\fBdisk_id\fP supersedes \fBscsi_address\fP\&. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.erase_disk_partitions scsi_address=\(aqvmhaba0:C0:T0:L0\(aq + +salt \(aq*\(aq vsphere.erase_disk_partitions disk_id=\(aqnaa.000000000000001\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.vsphere.esxcli_cmd(cmd_str, host=None, username=None, password=None, protocol=None, port=None, esxi_hosts=None, credstore=None) Run an ESXCLI command directly on the host or list of hosts. .INDENT 7.0 @@ -234478,6 +250584,22 @@ salt \(aq*\(aq vsphere.esxcli_cmd my.vcenter.location root bad\-password .UNINDENT .INDENT 0.0 .TP +.B salt.modules.vsphere.get_advanced_configs(*args, **kwargs) +Returns extra config parameters from a virtual machine advanced config list +.INDENT 7.0 +.TP +.B vm_name +Virtual machine name +.TP +.B datacenter +Datacenter name where the virtual machine is available +.TP +.B service_instance +vCenter service instance for connection and configuration +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.vsphere.get_coredump_network_config(host, username, password, protocol=None, port=None, esxi_hosts=None, credstore=None) Retrieve information on ESXi or vCenter network dump collection and format it into a dictionary. @@ -234588,8 +250710,30 @@ salt \(aq*\(aq vsphere.get_firewall_status my.vcenter.location root bad\-passwor .UNINDENT .INDENT 0.0 .TP +.B salt.modules.vsphere.get_host_cache(*args, **kwargs) +Returns the host cache configuration on the proxy host. +.INDENT 7.0 +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.get_host_cache +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.vsphere.get_proxy_type() -Returns the proxy type +Returns the proxy type retrieved either from the pillar of from the proxy +minion\(aqs config. Returns \fB\fP otherwise. .sp CLI Example: .INDENT 7.0 @@ -234605,6 +250749,29 @@ salt \(aq*\(aq vsphere.get_proxy_type .UNINDENT .INDENT 0.0 .TP +.B salt.modules.vsphere.get_service_instance_via_proxy(*args, **kwargs) +Returns a service instance to the proxied endpoint (vCenter/ESXi host). +.INDENT 7.0 +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Should be used by state functions not invoked directly. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B CLI Example: +See note above +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.vsphere.get_syslog_config(host, username, password, protocol=None, port=None, esxi_hosts=None, credstore=None) Retrieve the syslog configuration. .INDENT 7.0 @@ -234658,10 +250825,83 @@ salt \(aq*\(aq vsphere.get_syslog_config my.vcenter.location root bad\-password .UNINDENT .INDENT 0.0 .TP +.B salt.modules.vsphere.get_vm(*args, **kwargs) +Returns vm object properties. +.INDENT 7.0 +.TP +.B name +Name of the virtual machine. +.TP +.B datacenter +Datacenter name +.TP +.B vm_properties +List of vm properties. +.TP +.B traversal_spec +Traversal Spec object(s) for searching. +.TP +.B parent_ref +Container Reference object for searching under a given object. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.get_vm_config(*args, **kwargs) +Queries and converts the virtual machine properties to the available format +from the schema. If the objects attribute is True the config objects will +have extra properties, like \(aqobject\(aq which will include the +vim.vm.device.VirtualDevice, this is necessary for deletion and update +actions. +.INDENT 7.0 +.TP +.B name +Name of the virtual machine +.TP +.B datacenter +Datacenter\(aqs name where the virtual machine is available +.TP +.B objects +Indicates whether to return the vmware object properties +(eg. object, key) or just the properties which can be set +.TP +.B service_instance +vCenter service instance for connection and configuration +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.get_vm_config_file(*args, **kwargs) +Queries the virtual machine config file and returns +vim.host.DatastoreBrowser.SearchResults object on success None on failure +.INDENT 7.0 +.TP +.B name +Name of the virtual machine +.TP +.B datacenter +Datacenter name +.TP +.B datastore +Datastore where the virtual machine files are stored +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.vsphere.gets_service_instance_via_proxy(fn) Decorator that connects to a target system (vCenter or ESXi host) using the proxy details and passes the connection (vim.ServiceInstance) to the decorated function. +.sp +Supported proxies: esxi, esxcluster, esxdatacenter. Notes .sp 1. The decorated function must have a \fBservice_instance\fP parameter @@ -234679,6 +250919,718 @@ None, this is a decorator .UNINDENT .INDENT 0.0 .TP +.B salt.modules.vsphere.list_assigned_licenses(*args, **kwargs) +Lists the licenses assigned to an entity +.INDENT 7.0 +.TP +.B entity +Dictionary representation of an entity. +See \fB_get_entity\fP docstrings for format. +.TP +.B entity_display_name +Entity name used in logging +.TP +.B license_keys: +List of license keys to be retrieved. Default is None. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_assigned_licenses + entity={type:cluster,datacenter:dc,cluster:cl} + entiy_display_name=cl +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_capability_definitions(*args, **kwargs) +Returns a list of the metadata of all capabilities in the vCenter. +.INDENT 7.0 +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_capabilities +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_cluster(*args, **kwargs) +Returns a dict representation of an ESX cluster. +.INDENT 7.0 +.TP +.B datacenter +Name of datacenter containing the cluster. +Ignored if already contained by proxy details. +Default value is None. +.TP +.B cluster +Name of cluster. +Ignored if already contained by proxy details. +Default value is None. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# vcenter proxy +salt \(aq*\(aq vsphere.list_cluster datacenter=dc1 cluster=cl1 + +# esxdatacenter proxy +salt \(aq*\(aq vsphere.list_cluster cluster=cl1 + +# esxcluster proxy +salt \(aq*\(aq vsphere.list_cluster +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_datacenters_via_proxy(*args, **kwargs) +Returns a list of dict representations of VMware datacenters. +Connection is done via the proxy details. +.sp +Supported proxies: esxdatacenter +.INDENT 7.0 +.TP +.B datacenter_names +List of datacenter names. +Default is None. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_datacenters_via_proxy + +salt \(aq*\(aq vsphere.list_datacenters_via_proxy dc1 + +salt \(aq*\(aq vsphere.list_datacenters_via_proxy dc1,dc2 + +salt \(aq*\(aq vsphere.list_datacenters_via_proxy datacenter_names=[dc1, dc2] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_datastores_via_proxy(*args, **kwargs) +Returns a list of dict representations of the datastores visible to the +proxy object. The list of datastores can be filtered by datastore names, +backing disk ids (canonical names) or backing disk scsi addresses. +.sp +Supported proxy types: esxi, esxcluster, esxdatacenter +.INDENT 7.0 +.TP +.B datastore_names +List of the names of datastores to filter on +.TP +.B backing_disk_ids +List of canonical names of the backing disks of the datastores to filer. +Default is None. +.TP +.B backing_disk_scsi_addresses +List of scsi addresses of the backing disks of the datastores to filter. +Default is None. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_datastores_via_proxy + +salt \(aq*\(aq vsphere.list_datastores_via_proxy datastore_names=[ds1, ds2] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_default_storage_policy_of_datastore(*args, **kwargs) +Returns a list of datastores assign the the storage policies. +.INDENT 7.0 +.TP +.B datastore +Name of the datastore to assign. +The datastore needs to be visible to the VMware entity the proxy +points to. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_default_storage_policy_of_datastore datastore=ds1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_default_vsan_policy(*args, **kwargs) +Returns the default vsan storage policy. +.INDENT 7.0 +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_storage_policies + +salt \(aq*\(aq vsphere.list_storage_policy policy_names=[policy_name] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_disk_partitions(*args, **kwargs) +Lists the partitions on a disk. +The disk can be specified either by the canonical name, or by the +scsi_address. +.INDENT 7.0 +.TP +.B disk_id +Canonical name of the disk. +Either \fBdisk_id\fP or \fBscsi_address\fP needs to be specified +(\fBdisk_id\fP supersedes \fBscsi_address\fP\&. +.TP +.B scsi_address\(ga +Scsi address of the disk. +\fBdisk_id\fP or \fBscsi_address\fP needs to be specified +(\fBdisk_id\fP supersedes \fBscsi_address\fP\&. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_disk_partitions scsi_address=\(aqvmhaba0:C0:T0:L0\(aq + +salt \(aq*\(aq vsphere.list_disk_partitions disk_id=\(aqnaa.000000000000001\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_diskgroups(*args, **kwargs) +Returns a list of disk group dict representation on an ESXi host. +The list of disk groups can be filtered by the cache disks +canonical names. If no filtering is applied, all disk groups are returned. +.INDENT 7.0 +.TP +.B cache_disk_ids: +List of cache disk canonical names of the disk groups to be retrieved. +Default is None. +.TP +.B use_proxy_details +Specify whether to use the proxy minion\(aqs details instead of the +arguments +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_diskgroups + +salt \(aq*\(aq vsphere.list_diskgroups cache_disk_ids=\(aq[naa.000000000000001]\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_disks(*args, **kwargs) +Returns a list of dict representations of the disks in an ESXi host. +The list of disks can be filtered by disk canonical names or +scsi addresses. +.INDENT 7.0 +.TP +.B disk_ids: +List of disk canonical names to be retrieved. Default is None. +.TP +.B scsi_addresses +List of scsi addresses of disks to be retrieved. Default is None +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_disks + +salt \(aq*\(aq vsphere.list_disks disk_ids=\(aq[naa.00, naa.001]\(aq + +salt \(aq*\(aq vsphere.list_disks + scsi_addresses=\(aq[vmhba0:C0:T0:L0, vmhba1:C0:T0:L0]\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_dvportgroups(*args, **kwargs) +Returns a list of distributed virtual switch portgroups. +The list can be filtered by the portgroup names or by the DVS. +.INDENT 7.0 +.TP +.B dvs +Name of the DVS containing the portgroups. +Default value is None. +.TP +.B portgroup_names +List of portgroup names to look for. If None, all portgroups are +returned. +Default value is None +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_dvporgroups + +salt \(aq*\(aq vsphere.list_dvportgroups dvs=dvs1 + +salt \(aq*\(aq vsphere.list_dvportgroups portgroup_names=[pg1] + +salt \(aq*\(aq vsphere.list_dvportgroups dvs=dvs1 portgroup_names=[pg1] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_dvss(*args, **kwargs) +Returns a list of distributed virtual switches (DVSs). +The list can be filtered by the datacenter or DVS names. +.INDENT 7.0 +.TP +.B datacenter +The datacenter to look for DVSs in. +Default value is None. +.TP +.B dvs_names +List of DVS names to look for. If None, all DVSs are returned. +Default value is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_dvss + +salt \(aq*\(aq vsphere.list_dvss dvs_names=[dvs1,dvs2] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_hosts_via_proxy(*args, **kwargs) +Returns a list of hosts for the the specified VMware environment. The list +of hosts can be filtered by datacenter name and/or cluster name +.INDENT 7.0 +.TP +.B hostnames +Hostnames to filter on. +.TP +.B datacenter_name +Name of datacenter. Only hosts in this datacenter will be retrieved. +Default is None. +.TP +.B cluster_name +Name of cluster. Only hosts in this cluster will be retrieved. If a +datacenter is not specified the first cluster with this name will be +considerred. Default is None. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_hosts_via_proxy + +salt \(aq*\(aq vsphere.list_hosts_via_proxy hostnames=[esxi1.example.com] + +salt \(aq*\(aq vsphere.list_hosts_via_proxy datacenter=dc1 cluster=cluster1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_licenses(*args, **kwargs) +Lists all licenses on a vCenter. +.INDENT 7.0 +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_licenses +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_storage_policies(*args, **kwargs) +Returns a list of storage policies. +.INDENT 7.0 +.TP +.B policy_names +Names of policies to list. If None, all policies are listed. +Default is None. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_storage_policies + +salt \(aq*\(aq vsphere.list_storage_policy policy_names=[policy_name] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.list_uplink_dvportgroup(*args, **kwargs) +Returns the uplink portgroup of a distributed virtual switch. +.INDENT 7.0 +.TP +.B dvs +Name of the DVS containing the portgroup. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.list_uplink_dvportgroup dvs=dvs_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.power_off_vm(*args, **kwargs) +Powers off a virtual machine specified by it\(aqs name. +.INDENT 7.0 +.TP +.B name +Name of the virtual machine +.TP +.B datacenter +Datacenter of the virtual machine +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.power_off_vm name=my_vm +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.power_on_vm(*args, **kwargs) +Powers on a virtual machine specified by it\(aqs name. +.INDENT 7.0 +.TP +.B name +Name of the virtual machine +.TP +.B datacenter +Datacenter of the virtual machine +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.power_on_vm name=my_vm +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.register_vm(*args, **kwargs) +Registers a virtual machine to the inventory with the given vmx file. +Returns comments and change list +.INDENT 7.0 +.TP +.B name +Name of the virtual machine +.TP +.B datacenter +Datacenter of the virtual machine +.TP +.B placement +Placement dictionary of the virtual machine, host or cluster +.TP +.B vmx_path: +Full path to the vmx file, datastore name should be included +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.remove_capacity_from_diskgroup(*args, **kwargs) +Remove capacity disks from the disk group with the specified cache disk. +.INDENT 7.0 +.TP +.B cache_disk_id +The canonical name of the cache disk. +.TP +.B capacity_disk_ids +A list containing canonical names of the capacity disks to add. +.TP +.B data_evacuation +Specifies whether to gracefully evacuate the data on the capacity disks +before removing them from the disk group. Default value is True. +.TP +.B safety_checks +Specify whether to perform safety check or to skip the checks and try +performing the required task. Default value is True. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.remove_capacity_from_diskgroup + cache_disk_id=\(aqnaa.000000000000001\(aq + capacity_disk_ids=\(aq[naa.000000000000002, naa.000000000000003]\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.remove_datastore(*args, **kwargs) +Removes a datastore. If multiple datastores an error is raised. +.INDENT 7.0 +.TP +.B datastore +Datastore name +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.remove_datastore ds_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.remove_diskgroup(*args, **kwargs) +Remove the diskgroup with the specified cache disk. +.INDENT 7.0 +.TP +.B cache_disk_id +The canonical name of the cache disk. +.TP +.B data_accessibility +Specifies whether to ensure data accessibility. Default value is True. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.remove_diskgroup cache_disk_id=\(aqnaa.000000000000001\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.remove_dvportgroup(*args, **kwargs) +Removes a distributed virtual portgroup. +.INDENT 7.0 +.TP +.B portgroup +Name of the portgroup to be removed. +.TP +.B dvs +Name of the DVS containing the portgroups. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.remove_dvportgroup portgroup=pg1 dvs=dvs1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.rename_datastore(*args, **kwargs) +Renames a datastore. The datastore needs to be visible to the proxy. +.INDENT 7.0 +.TP +.B datastore_name +Current datastore name. +.TP +.B new_datastore_name +New datastore name. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter/ESXi host. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.rename_datastore old_name new_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.vsphere.reset_syslog_config(host, username, password, protocol=None, port=None, syslog_config=None, esxi_hosts=None, credstore=None) Reset the syslog service to its default settings. .sp @@ -234743,6 +251695,25 @@ salt \(aq*\(aq vsphere.reset_syslog_config my.vcenter.location root bad\-passwor .UNINDENT .INDENT 0.0 .TP +.B salt.modules.vsphere.set_advanced_configs(*args, **kwargs) +Appends extra config parameters to a virtual machine advanced config list +.INDENT 7.0 +.TP +.B vm_name +Virtual machine name +.TP +.B datacenter +Datacenter name where the virtual machine is available +.TP +.B advanced_configs +Dictionary with advanced parameter key value pairs +.TP +.B service_instance +vCenter service instance for connection and configuration +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.vsphere.set_coredump_network_config(host, username, password, dump_ip, protocol=None, port=None, host_vnic=\(aqvmk0\(aq, dump_port=6500, esxi_hosts=None, credstore=None) Set the network parameters for a network coredump collection. Note that ESXi requires that the dumps first be enabled (see @@ -234943,6 +251914,238 @@ salt \(aq*\(aq vsphere.syslog_service_reload my.vcenter.location root bad\-passw .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.test_vcenter_connection(*args, **kwargs) +Checks if a connection is to a vCenter +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.test_vcenter_connection +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.unregister_vm(*args, **kwargs) +Unregisters a virtual machine defined by name and placement +.INDENT 7.0 +.TP +.B name +Name of the virtual machine +.TP +.B datacenter +Datacenter of the virtual machine +.TP +.B placement +Placement information of the virtual machine +.TP +.B service_instance +vCenter service instance for connection and configuration +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.unregister_vm name=my_vm datacenter=my_datacenter +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.update_cluster(*args, **kwargs) +Updates a cluster. +.INDENT 7.0 +.TP +.B config_dict +Dictionary with the config values of the new cluster. +.TP +.B datacenter +Name of datacenter containing the cluster. +Ignored if already contained by proxy details. +Default value is None. +.TP +.B cluster +Name of cluster. +Ignored if already contained by proxy details. +Default value is None. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# esxdatacenter proxy +salt \(aq*\(aq vsphere.update_cluster cluster_dict=$cluster_dict cluster=cl1 + +# esxcluster proxy +salt \(aq*\(aq vsphere.update_cluster cluster_dict=$cluster_dict +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.update_dvportgroup(*args, **kwargs) +Updates a distributed virtual portgroup. +.INDENT 7.0 +.TP +.B portgroup_dict +Dictionary with the values the portgroup should be update with +(exmaple in salt.states.dvs). +.TP +.B portgroup +Name of the portgroup to be updated. +.TP +.B dvs +Name of the DVS containing the portgroups. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.update_dvportgroup portgroup_dict= + portgroup=pg1 + +salt \(aq*\(aq vsphere.update_dvportgroup portgroup_dict= + portgroup=pg1 dvs=dvs1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.update_dvs(*args, **kwargs) +Updates a distributed virtual switch (DVS). +.INDENT 7.0 +.TP +.B Note: Updating the product info, capability, uplinks of a DVS is not +supported so the corresponding entries in \fBdvs_dict\fP will be +ignored. +.TP +.B dvs_dict +Dictionary with the values the DVS should be update with +(exmaple in salt.states.dvs) +.TP +.B dvs +Name of the DVS to be updated. +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.update_dvs dvs_dict=$dvs_dict dvs=dvs1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.update_storage_policy(*args, **kwargs) +Updates a storage policy. +.sp +Supported capability types: scalar, set, range. +.INDENT 7.0 +.TP +.B policy +Name of the policy to update. +.TP +.B policy_dict +Dictionary containing the changes to apply to the policy. +(exmaple in salt.states.pbm) +.TP +.B service_instance +Service instance (vim.ServiceInstance) of the vCenter. +Default is None. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq vsphere.update_storage_policy policy=\(aqpolicy name\(aq + policy_dict="$policy_dict" +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.vsphere.update_vm(*args, **kwargs) +Updates the configuration of the virtual machine if the config differs +.INDENT 7.0 +.TP +.B vm_name +Virtual Machine name to be updated +.TP +.B cpu +CPU configuration options +.TP +.B memory +Memory configuration options +.TP +.B version +Virtual machine container hardware version +.TP +.B image +Virtual machine guest OS version identifier +VirtualMachineGuestOsIdentifier +.TP +.B interfaces +Network interfaces configuration options +.TP +.B disks +Disks configuration options +.TP +.B scsi_devices +SCSI devices configuration options +.TP +.B serial_ports +Serial ports configuration options +.TP +.B datacenter +Datacenter where the virtual machine is available +.TP +.B datastore +Datastore where the virtual machine config files are available +.TP +.B cd_dvd_drives +CD/DVD drives configuration options +.TP +.B advanced_config +Advanced config parameters to be set for the virtual machine +.TP +.B service_instance +vCenter service instance for connection and configuration +.UNINDENT +.UNINDENT .SS salt.modules.win_autoruns .sp Module for listing programs that automatically run on startup @@ -234980,7 +252183,7 @@ salt \(aq*\(aq certutil.add_store salt://cert.cer "TrustedPublisher" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_certutil.add_store(source, store, saltenv=\(aqbase\(aq) +.B salt.modules.win_certutil.add_store(source, store, saltenv=u\(aqbase\(aq) Add the given cert into the given Certificate Store .INDENT 7.0 .TP @@ -235010,7 +252213,7 @@ salt \(aq*\(aq certutil.add_store salt://cert.cer TrustedPublisher .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_certutil.del_store(source, store, saltenv=\(aqbase\(aq) +.B salt.modules.win_certutil.del_store(source, store, saltenv=u\(aqbase\(aq) Delete the given cert into the given Certificate Store .INDENT 7.0 .TP @@ -235970,7 +253173,7 @@ salt \(aq*\(aq dism.remove_package C:\epackages\epackage.cab Module for configuring DNS Client on Windows systems .INDENT 0.0 .TP -.B salt.modules.win_dns_client.add_dns(ip, interface=\(aqLocal Area Connection\(aq, index=1) +.B salt.modules.win_dns_client.add_dns(ip, interface=u\(aqLocal Area Connection\(aq, index=1) Add the DNS server to the network interface (index starts from 1) .sp @@ -235991,7 +253194,7 @@ salt \(aq*\(aq win_dns_client.add_dns .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_dns_client.dns_dhcp(interface=\(aqLocal Area Connection\(aq) +.B salt.modules.win_dns_client.dns_dhcp(interface=u\(aqLocal Area Connection\(aq) Configure the interface to get its DNS servers from the DHCP server .sp CLI Example: @@ -236008,7 +253211,7 @@ salt \(aq*\(aq win_dns_client.dns_dhcp .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_dns_client.get_dns_config(interface=\(aqLocal Area Connection\(aq) +.B salt.modules.win_dns_client.get_dns_config(interface=u\(aqLocal Area Connection\(aq) Get the type of DNS configuration (dhcp / static) .sp CLI Example: @@ -236025,7 +253228,7 @@ salt \(aq*\(aq win_dns_client.get_dns_config \(aqLocal Area Connection\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_dns_client.get_dns_servers(interface=\(aqLocal Area Connection\(aq) +.B salt.modules.win_dns_client.get_dns_servers(interface=u\(aqLocal Area Connection\(aq) Return a list of the configured DNS servers of the specified interface .sp CLI Example: @@ -236042,7 +253245,7 @@ salt \(aq*\(aq win_dns_client.get_dns_servers \(aqLocal Area Connection\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_dns_client.rm_dns(ip, interface=\(aqLocal Area Connection\(aq) +.B salt.modules.win_dns_client.rm_dns(ip, interface=u\(aqLocal Area Connection\(aq) Remove the DNS server from the network interface .sp CLI Example: @@ -236059,10 +253262,10 @@ salt \(aq*\(aq win_dns_client.rm_dns .UNINDENT .SS salt.modules.win_dsc .sp -This module is Alpha -.sp Module for working with Windows PowerShell DSC (Desired State Configuration) .sp +This module is Alpha +.sp This module applies DSC Configurations in the form of PowerShell scripts or MOF (Managed Object Format) schema files. .sp @@ -236080,7 +253283,7 @@ PowerShell 5.0 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_dsc.apply_config(path, source=None, salt_env=\(aqbase\(aq) +.B salt.modules.win_dsc.apply_config(path, source=None, salt_env=u\(aqbase\(aq) Run an compiled DSC configuration (a folder containing a .mof file). The folder can be cached from the salt master using the \fBsource\fP option. .INDENT 7.0 @@ -236136,7 +253339,7 @@ salt \(aq*\(aq dsc.run_config C:\e\eDSC\e\eWebSiteConfiguration salt://dsc/confi .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_dsc.compile_config(path, source=None, config_name=None, config_data=None, config_data_source=None, script_parameters=None, salt_env=\(aqbase\(aq) +.B salt.modules.win_dsc.compile_config(path, source=None, config_name=None, config_data=None, config_data_source=None, script_parameters=None, salt_env=u\(aqbase\(aq) Compile a config from a PowerShell script (\fB\&.ps1\fP) .INDENT 7.0 .TP @@ -236314,7 +253517,7 @@ salt \(aq*\(aq dsc.get_lcm_config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_dsc.run_config(path, source=None, config_name=None, config_data=None, config_data_source=None, script_parameters=None, salt_env=\(aqbase\(aq) +.B salt.modules.win_dsc.run_config(path, source=None, config_name=None, config_data=None, config_data_source=None, script_parameters=None, salt_env=u\(aqbase\(aq) Compile a DSC Configuration in the form of a PowerShell script (.ps1) and apply it. The PowerShell script can be cached from the master using the \fBsource\fP option. If there is more than one config within the PowerShell @@ -236563,9 +253766,9 @@ salt.utils.win_dacl .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_file.check_perms(path, ret=None, owner=None, grant_perms=None, deny_perms=None, inheritance=True) -Set owner and permissions for each directory created. Used mostly by the -state system. +.B salt.modules.win_file.check_perms(path, ret=None, owner=None, grant_perms=None, deny_perms=None, inheritance=True, reset=False) +Check owner and permissions for the passed directory. This function checks +the permissions and sets them, returning the changes made. .INDENT 7.0 .TP .B Parameters @@ -236576,58 +253779,28 @@ state system. \fBret\fP (\fI\%dict\fP) \-\- A dictionary to append changes to and return. If not passed, will create a new dictionary to return. .IP \(bu 2 -\fBowner\fP (\fI\%str\fP) \-\- The owner of the directory. If not passed, it will be the account -that created the directory, likely SYSTEM +\fBowner\fP (\fI\%str\fP) \-\- The owner to set for the directory. .IP \(bu 2 -\fBgrant_perms\fP (\fI\%dict\fP) \-\- -.sp -A dictionary containing the user/group and the basic permissions to -grant, ie: \fB{\(aquser\(aq: {\(aqperms\(aq: \(aqbasic_permission\(aq}}\fP\&. You can also -set the \fBapplies_to\fP setting here. The default is -\fBthis_folder_subfolders_files\fP\&. Specify another \fBapplies_to\fP -setting like this: -.INDENT 2.0 -.INDENT 3.5 -.sp -.nf -.ft C -{\(aquser\(aq: {\(aqperms\(aq: \(aqfull_control\(aq, \(aqapplies_to\(aq: \(aqthis_folder\(aq}} -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -To set advanced permissions use a list for the \fBperms\fP parameter, ie: -.INDENT 2.0 -.INDENT 3.5 -.sp -.nf -.ft C -{\(aquser\(aq: {\(aqperms\(aq: [\(aqread_attributes\(aq, \(aqread_ea\(aq], \(aqapplies_to\(aq: \(aqthis_folder\(aq}} -.ft P -.fi -.UNINDENT -.UNINDENT - +\fBgrant_perms\fP (\fI\%dict\fP) \-\- A dictionary containing the user/group and the basic permissions to +check/grant, ie: \fB{\(aquser\(aq: {\(aqperms\(aq: \(aqbasic_permission\(aq}}\fP\&. +Default is \fBNone\fP\&. .IP \(bu 2 -\fBdeny_perms\fP (\fI\%dict\fP) \-\- A dictionary containing the user/group and permissions to deny along -with the \fBapplies_to\fP setting. Use the same format used for the -\fBgrant_perms\fP parameter. Remember, deny permissions supersede -grant permissions. +\fBdeny_perms\fP (\fI\%dict\fP) \-\- A dictionary containing the user/group and permissions to +check/deny. Default is \fBNone\fP\&. .IP \(bu 2 -\fBinheritance\fP (\fI\%bool\fP) \-\- If True the object will inherit permissions from the parent, if -False, inheritance will be disabled. Inheritance setting will not -apply to parent directories if they must be created +\fBinheritance\fP (\fI\%bool\fP) \-\- \fBTrue will check if inheritance is enabled and enable it. \(ga\(gaFalse\fP +will check if inheritance is disabled and disable it. Defaultl is +\fBTrue\fP\&. +.IP \(bu 2 +\fBreset\fP (\fI\%bool\fP) \-\- \fBTrue\fP wil show what permisisons will be removed by resetting the +DACL. \fBFalse\fP will do nothing. Default is \fBFalse\fP\&. .UNINDENT .TP .B Returns -A dictionary of changes made to the object +A dictionary of changes that have been made .TP .B Return type \fI\%dict\fP -.TP -.B Raises -\fBCommandExecutionError\fP \-\- If the object does not exist .UNINDENT .sp CLI Example: @@ -236636,14 +253809,14 @@ CLI Example: .sp .nf .ft C -# To grant the \(aqUsers\(aq group \(aqread & execute\(aq permissions. -salt \(aq*\(aq file.check_perms C:\eTemp\e Administrators "{\(aqUsers\(aq: {\(aqperms\(aq: \(aqread_execute\(aq}}" +# To see changes to \(ga\(gaC:\eTemp\(ga\(ga if the \(aqUsers\(aq group is given \(aqread & execute\(aq permissions. +salt \(aq*\(aq file.check_perms C:\eTemp\e {} Administrators "{\(aqUsers\(aq: {\(aqperms\(aq: \(aqread_execute\(aq}}" # Locally using salt call -salt\-call file.check_perms C:\eTemp\e Administrators "{\(aqUsers\(aq: {\(aqperms\(aq: \(aqread_execute\(aq, \(aqapplies_to\(aq: \(aqthis_folder_only\(aq}}" +salt\-call file.check_perms C:\eTemp\e {} Administrators "{\(aqUsers\(aq: {\(aqperms\(aq: \(aqread_execute\(aq, \(aqapplies_to\(aq: \(aqthis_folder_only\(aq}}" # Specify advanced attributes with a list -salt \(aq*\(aq file.check_perms C:\eTemp\e Administrators "{\(aqjsnuffy\(aq: {\(aqperms\(aq: [\(aqread_attributes\(aq, \(aqread_ea\(aq], \(aqapplies_to\(aq: \(aqfiles_only\(aq}}" +salt \(aq*\(aq file.check_perms C:\eTemp\e {} Administrators "{\(aqjsnuffy\(aq: {\(aqperms\(aq: [\(aqread_attributes\(aq, \(aqread_ea\(aq], \(aqapplies_to\(aq: \(aqfiles_only\(aq}}" .ft P .fi .UNINDENT @@ -237269,17 +254442,32 @@ salt \(aq*\(aq file.lchown c:\etemp\etest.txt myusername "pgroup=\(aqNone\(aq" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_file.makedirs(path, owner=None, grant_perms=None, deny_perms=None, inheritance=True) +.B salt.modules.win_file.makedirs(path, owner=None, grant_perms=None, deny_perms=None, inheritance=True, reset=False) Ensure that the parent directory containing this path is available. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBpath\fP (\fI\%str\fP) \-\- The full path to the directory. +\fBpath\fP (\fI\%str\fP) \-\- +.sp +The full path to the directory. +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +The path must end with a trailing slash otherwise the +directory(s) will be created up to the parent directory. For +example if path is \fBC:\etemp\etest\fP, then it would be treated +as \fBC:\etemp\e\fP but if the path ends with a trailing slash +like \fBC:\etemp\etest\e\fP, then it would be treated as +\fBC:\etemp\etest\e\fP\&. +.UNINDENT +.UNINDENT + .IP \(bu 2 \fBowner\fP (\fI\%str\fP) \-\- The owner of the directory. If not passed, it will be the account -that created the directly, likely SYSTEM +that created the directory, likely SYSTEM. .IP \(bu 2 \fBgrant_perms\fP (\fI\%dict\fP) \-\- .sp @@ -237319,21 +254507,18 @@ grant permissions. .IP \(bu 2 \fBinheritance\fP (\fI\%bool\fP) \-\- If True the object will inherit permissions from the parent, if False, inheritance will be disabled. Inheritance setting will not -apply to parent directories if they must be created -.UNINDENT -.UNINDENT +apply to parent directories if they must be created. +.IP \(bu 2 +\fBreset\fP (\fI\%bool\fP) \-\- .sp -\fBNOTE:\fP -.INDENT 7.0 -.INDENT 3.5 -The path must end with a trailing slash otherwise the directory(s) will -be created up to the parent directory. For example if path is -\fBC:\etemp\etest\fP, then it would be treated as \fBC:\etemp\e\fP but if -the path ends with a trailing slash like \fBC:\etemp\etest\e\fP, then it -would be treated as \fBC:\etemp\etest\e\fP\&. +If \fBTrue\fP the existing DACL will be cleared and replaced with the +settings defined in this function. If \fBFalse\fP, new entries will be +appended to the existing DACL. Default is \fBFalse\fP\&. +.sp +New in version 2018.3.0. + + .UNINDENT -.UNINDENT -.INDENT 7.0 .TP .B Returns True if successful @@ -237366,7 +254551,7 @@ salt \(aq*\(aq file.makedirs C:\eTemp\e Administrators "{\(aqjsnuffy\(aq: {\(aqp .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_file.makedirs_perms(path, owner=None, grant_perms=None, deny_perms=None, inheritance=True) +.B salt.modules.win_file.makedirs_perms(path, owner=None, grant_perms=None, deny_perms=None, inheritance=True, reset=True) Set owner and permissions for each directory created. .INDENT 7.0 .TP @@ -237376,7 +254561,7 @@ Set owner and permissions for each directory created. \fBpath\fP (\fI\%str\fP) \-\- The full path to the directory. .IP \(bu 2 \fBowner\fP (\fI\%str\fP) \-\- The owner of the directory. If not passed, it will be the account -that created the directory, likely SYSTEM +that created the directory, likely SYSTEM. .IP \(bu 2 \fBgrant_perms\fP (\fI\%dict\fP) \-\- .sp @@ -237414,9 +254599,19 @@ with the \fBapplies_to\fP setting. Use the same format used for the \fBgrant_perms\fP parameter. Remember, deny permissions supersede grant permissions. .IP \(bu 2 -\fBinheritance\fP (\fI\%bool\fP) \-\- If True the object will inherit permissions from the parent, if -False, inheritance will be disabled. Inheritance setting will not -apply to parent directories if they must be created +\fBinheritance\fP (\fI\%bool\fP) \-\- If \fBTrue\fP the object will inherit permissions from the parent, if +\fBFalse\fP, inheritance will be disabled. Inheritance setting will +not apply to parent directories if they must be created +.IP \(bu 2 +\fBreset\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP the existing DACL will be cleared and replaced with the +settings defined in this function. If \fBFalse\fP, new entries will be +appended to the existing DACL. Default is \fBFalse\fP\&. +.sp +New in version 2018.3.0. + + .UNINDENT .TP .B Returns @@ -237447,7 +254642,7 @@ salt \(aq*\(aq file.makedirs_perms C:\eTemp\e Administrators "{\(aqjsnuffy\(aq: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_file.mkdir(path, owner=None, grant_perms=None, deny_perms=None, inheritance=True) +.B salt.modules.win_file.mkdir(path, owner=None, grant_perms=None, deny_perms=None, inheritance=True, reset=False) Ensure that the directory is available and permissions are set. .INDENT 7.0 .TP @@ -237477,7 +254672,8 @@ setting like this: .UNINDENT .UNINDENT .sp -To set advanced permissions use a list for the \fBperms\fP parameter, ie: +To set advanced permissions use a list for the \fBperms\fP parameter, +ie: .INDENT 2.0 .INDENT 3.5 .sp @@ -237496,8 +254692,18 @@ with the \fBapplies_to\fP setting. Use the same format used for the grant permissions. .IP \(bu 2 \fBinheritance\fP (\fI\%bool\fP) \-\- If True the object will inherit permissions from the parent, if -False, inheritance will be disabled. Inheritance setting will not -apply to parent directories if they must be created +\fBFalse\fP, inheritance will be disabled. Inheritance setting will +not apply to parent directories if they must be created. +.IP \(bu 2 +\fBreset\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP the existing DACL will be cleared and replaced with the +settings defined in this function. If \fBFalse\fP, new entries will be +appended to the existing DACL. Default is \fBFalse\fP\&. +.sp +New in version 2018.3.0. + + .UNINDENT .TP .B Returns @@ -237679,7 +254885,7 @@ salt \(aq*\(aq file.set_mode /etc/passwd 0644 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_file.set_perms(path, grant_perms=None, deny_perms=None, inheritance=True) +.B salt.modules.win_file.set_perms(path, grant_perms=None, deny_perms=None, inheritance=True, reset=False) Set permissions for the given path .INDENT 7.0 .TP @@ -237692,8 +254898,8 @@ Set permissions for the given path .sp A dictionary containing the user/group and the basic permissions to grant, ie: \fB{\(aquser\(aq: {\(aqperms\(aq: \(aqbasic_permission\(aq}}\fP\&. You can also -set the \fBapplies_to\fP setting here. The default is -\fBthis_folder_subfolders_files\fP\&. Specify another \fBapplies_to\fP +set the \fBapplies_to\fP setting here. The default for \fBapplise_to\fP +is \fBthis_folder_subfolders_files\fP\&. Specify another \fBapplies_to\fP setting like this: .INDENT 2.0 .INDENT 3.5 @@ -237720,24 +254926,47 @@ ie: .UNINDENT .sp To see a list of available attributes and applies to settings see -the documentation for salt.utils.win_dacl +the documentation for salt.utils.win_dacl. +.sp +A value of \fBNone\fP will make no changes to the \fBgrant\fP portion of +the DACL. Default is \fBNone\fP\&. .IP \(bu 2 -\fBdeny_perms\fP (\fI\%dict\fP) \-\- A dictionary containing the user/group and permissions to deny along +\fBdeny_perms\fP (\fI\%dict\fP) \-\- +.sp +A dictionary containing the user/group and permissions to deny along with the \fBapplies_to\fP setting. Use the same format used for the \fBgrant_perms\fP parameter. Remember, deny permissions supersede grant permissions. +.sp +A value of \fBNone\fP will make no changes to the \fBdeny\fP portion of +the DACL. Default is \fBNone\fP\&. + .IP \(bu 2 -\fBinheritance\fP (\fI\%bool\fP) \-\- If True the object will inherit permissions from the parent, if -False, inheritance will be disabled. Inheritance setting will not -apply to parent directories if they must be created +\fBinheritance\fP (\fI\%bool\fP) \-\- If \fBTrue\fP the object will inherit permissions from the parent, if +\fBFalse\fP, inheritance will be disabled. Inheritance setting will +not apply to parent directories if they must be created. Default is +\fBFalse\fP\&. +.IP \(bu 2 +\fBreset\fP (\fI\%bool\fP) \-\- +.sp +If \fBTrue\fP the existing DCL will be cleared and replaced with the +settings defined in this function. If \fBFalse\fP, new entries will be +appended to the existing DACL. Default is \fBFalse\fP\&. +.sp +New in version 2018.3.0. + + .UNINDENT .TP .B Returns -True if successful, otherwise raise an error +True if successful .TP .B Return type \fI\%bool\fP +.TP +.B Raises +\fBCommandExecutionError\fP \-\- If unsuccessful .UNINDENT .sp CLI Example: @@ -237761,7 +254990,7 @@ salt \(aq*\(aq file.set_perms C:\eTemp\e "{\(aqjsnuffy\(aq: {\(aqperms\(aq: [\(a .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_file.stats(path, hash_type=\(aqsha256\(aq, follow_symlinks=True) +.B salt.modules.win_file.stats(path, hash_type=u\(aqsha256\(aq, follow_symlinks=True) Return a dict containing the stats about a given file .sp Under Windows, \fIgid\fP will equal \fIuid\fP and \fIgroup\fP will equal \fIuser\fP\&. @@ -237907,7 +255136,7 @@ salt \(aq*\(aq file.user_to_uid myusername Module for configuring Windows Firewall using \fBnetsh\fP .INDENT 0.0 .TP -.B salt.modules.win_firewall.add_rule(name, localport, protocol=\(aqtcp\(aq, action=\(aqallow\(aq, dir=\(aqin\(aq, remoteip=\(aqany\(aq) +.B salt.modules.win_firewall.add_rule(name, localport, protocol=u\(aqtcp\(aq, action=u\(aqallow\(aq, dir=u\(aqin\(aq, remoteip=u\(aqany\(aq) New in version 2015.5.0. .sp @@ -238077,7 +255306,7 @@ salt \(aq*\(aq firewall.delete_rule allow80 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_firewall.disable(profile=\(aqallprofiles\(aq) +.B salt.modules.win_firewall.disable(profile=u\(aqallprofiles\(aq) Disable firewall profile .INDENT 7.0 .TP @@ -238122,7 +255351,7 @@ salt \(aq*\(aq firewall.disable .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_firewall.enable(profile=\(aqallprofiles\(aq) +.B salt.modules.win_firewall.enable(profile=u\(aqallprofiles\(aq) New in version 2015.5.0. .sp @@ -238198,7 +255427,7 @@ salt \(aq*\(aq firewall.get_config .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_firewall.get_rule(name=\(aqall\(aq) +.B salt.modules.win_firewall.get_rule(name=u\(aqall\(aq) New in version 2015.5.0. .sp @@ -240918,15 +258147,25 @@ Only the ones that listen to the WM_SETTINGCHANGE message \fI\%http://support.microsoft.com/kb/104011\fP .INDENT 0.0 .TP -.B salt.modules.win_path.add(path, index=0) -Add the directory to the SYSTEM path in the index location +.B salt.modules.win_path.add(path, index=None, **kwargs) +Add the directory to the SYSTEM path in the index location. Returns +\fBTrue\fP if successful, otherwise \fBFalse\fP\&. .INDENT 7.0 .TP -.B Returns -boolean True if successful, False if unsuccessful +.B path +Directory to add to path +.TP +.B index +Optionally specify an index at which to insert the directory +.TP +.B rehash +True +If the registry was updated, and this value is set to \fBTrue\fP, sends a +WM_SETTINGCHANGE broadcast to refresh the environment variables. Set +this to \fBFalse\fP to skip this broadcast. .UNINDENT .sp -CLI Example: +CLI Examples: .INDENT 7.0 .INDENT 3.5 .sp @@ -240987,26 +258226,38 @@ salt \(aq*\(aq win_path.get_path .INDENT 0.0 .TP .B salt.modules.win_path.rehash() -Send a WM_SETTINGCHANGE Broadcast to Windows to refresh the Environment variables +Send a WM_SETTINGCHANGE Broadcast to Windows to refresh the Environment +variables .sp CLI Example: -.sp -\&... code\-block:: bash .INDENT 7.0 .INDENT 3.5 +.sp +.nf +.ft C salt \(aq*\(aq win_path.rehash +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_path.remove(path) +.B salt.modules.win_path.remove(path, **kwargs) Remove the directory from the SYSTEM path .INDENT 7.0 .TP .B Returns boolean True if successful, False if unsuccessful .UNINDENT +.INDENT 7.0 +.TP +.B rehash +True +If the registry was updated, and this value is set to \fBTrue\fP, sends a +WM_SETTINGCHANGE broadcast to refresh the environment variables. Set +this to \fBFalse\fP to skip this broadcast. +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -241918,7 +259169,7 @@ New in version 2016.11.0. .INDENT 0.0 .TP -.B salt.modules.win_pki.export_cert(name, thumbprint, cert_format=\(aqcer\(aq, context=\(aqLocalMachine\(aq, store=\(aqMy\(aq, password=\(aq\(aq) +.B salt.modules.win_pki.export_cert(name, thumbprint, cert_format=u\(aqcer\(aq, context=u\(aqLocalMachine\(aq, store=u\(aqMy\(aq, password=u\(aq\(aq) Export the certificate to a file from the given certificate store. .INDENT 7.0 .TP @@ -241962,7 +259213,7 @@ salt \(aq*\(aq win_pki.export_cert name=\(aqC:\ecerts\eexample.cer\(aq thumbprin .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_pki.get_cert_file(name, cert_format=\(aqcer\(aq, password=\(aq\(aq) +.B salt.modules.win_pki.get_cert_file(name, cert_format=u\(aqcer\(aq, password=u\(aq\(aq) Get the details of the certificate file. .INDENT 7.0 .TP @@ -242000,7 +259251,7 @@ salt \(aq*\(aq win_pki.get_cert_file name=\(aqC:\ecerts\eexample.cer\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_pki.get_certs(context=\(aqLocalMachine\(aq, store=\(aqMy\(aq) +.B salt.modules.win_pki.get_certs(context=u\(aqLocalMachine\(aq, store=u\(aqMy\(aq) Get the available certificates in the given store. .INDENT 7.0 .TP @@ -242058,7 +259309,7 @@ salt \(aq*\(aq win_pki.get_stores .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_pki.import_cert(name, cert_format=\(aqcer\(aq, context=\(aqLocalMachine\(aq, store=\(aqMy\(aq, exportable=True, password=\(aq\(aq, saltenv=\(aqbase\(aq) +.B salt.modules.win_pki.import_cert(name, cert_format=u\(aqcer\(aq, context=u\(aqLocalMachine\(aq, store=u\(aqMy\(aq, exportable=True, password=u\(aq\(aq, saltenv=u\(aqbase\(aq) Import the certificate file into the given certificate store. .INDENT 7.0 .TP @@ -242105,7 +259356,7 @@ salt \(aq*\(aq win_pki.import_cert name=\(aqsalt://cert.cer\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_pki.remove_cert(thumbprint, context=\(aqLocalMachine\(aq, store=\(aqMy\(aq) +.B salt.modules.win_pki.remove_cert(thumbprint, context=u\(aqLocalMachine\(aq, store=u\(aqMy\(aq) Remove the certificate from the given certificate store. .INDENT 7.0 .TP @@ -242140,7 +259391,7 @@ salt \(aq*\(aq win_pki.remove_cert thumbprint=\(aqAAA000\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_pki.test_cert(thumbprint, context=\(aqLocalMachine\(aq, store=\(aqMy\(aq, untrusted_root=False, dns_name=\(aq\(aq, eku=\(aq\(aq) +.B salt.modules.win_pki.test_cert(thumbprint, context=u\(aqLocalMachine\(aq, store=u\(aqMy\(aq, untrusted_root=False, dns_name=u\(aq\(aq, eku=u\(aq\(aq) Check the certificate for validity. .INDENT 7.0 .TP @@ -242290,7 +259541,7 @@ The scheme to use, leave as None to use the current. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_powercfg.set_disk_timeout(timeout, power=\(aqac\(aq, scheme=None) +.B salt.modules.win_powercfg.set_disk_timeout(timeout, power=u\(aqac\(aq, scheme=None) Set the disk timeout in minutes for the given power scheme .sp CLI Example: @@ -242318,7 +259569,7 @@ The scheme to use, leave as None to use the current. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_powercfg.set_hibernate_timeout(timeout, power=\(aqac\(aq, scheme=None) +.B salt.modules.win_powercfg.set_hibernate_timeout(timeout, power=u\(aqac\(aq, scheme=None) Set the hibernate timeout in minutes for the given power scheme .sp CLI Example: @@ -242346,7 +259597,7 @@ The scheme to use, leave as None to use the current. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_powercfg.set_monitor_timeout(timeout, power=\(aqac\(aq, scheme=None) +.B salt.modules.win_powercfg.set_monitor_timeout(timeout, power=u\(aqac\(aq, scheme=None) Set the monitor timeout in minutes for the given power scheme .sp CLI Example: @@ -242374,7 +259625,7 @@ The scheme to use, leave as None to use the current. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_powercfg.set_standby_timeout(timeout, power=\(aqac\(aq, scheme=None) +.B salt.modules.win_powercfg.set_standby_timeout(timeout, power=u\(aqac\(aq, scheme=None) Set the standby timeout in minutes for the given power scheme .sp CLI Example: @@ -242536,27 +259787,6 @@ salt \(aqwin01\(aq psget.list_modules desc=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_psget.psversion() -Returns the Powershell version -.sp -This has been deprecated and has been replaced by \fBcmd.shell_info\fP Note -the minimum version return is 5 as \fBdsc\fP is not available for version -less than 5. This function will be removed in \(aqOxygen\(aq release. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aqwin01\(aq dsc.psversion -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP .B salt.modules.win_psget.register_repository(name, location, installation_policy=None) Register a PSGet repository on the local machine .INDENT 7.0 @@ -242662,7 +259892,7 @@ salt\-call winrepo.genrepo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_repo.show_sls(name, saltenv=\(aqbase\(aq) +.B salt.modules.win_repo.show_sls(name, saltenv=u\(aqbase\(aq) New in version 2015.8.0. .sp @@ -242781,7 +260011,19 @@ salt\-call winrepo.update_git_repos .UNINDENT .SS salt.modules.win_servermanager .sp -Manage Windows features via the ServerManager powershell module +Manage Windows features via the ServerManager powershell module. Can list +available and installed roles/features. Can install and remove roles/features. +.INDENT 0.0 +.TP +.B maintainer +Shane Lee <\fI\%slee@saltstack.com\fP> +.TP +.B platform +Windows Server 2008R2 or greater +.TP +.B depends +PowerShell module \fBServerManager\fP +.UNINDENT .INDENT 0.0 .TP .B salt.modules.win_servermanager.install(feature, recurse=False, restart=False, source=None, exclude=None) @@ -242807,33 +260049,45 @@ a long timeout .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBfeature\fP (\fI\%str\fP) \-\- The name of the feature to install -.IP \(bu 2 -\fBrecurse\fP (\fI\%bool\fP) \-\- Install all sub\-features. Default is False -.IP \(bu 2 -\fBsource\fP (\fI\%str\fP) \-\- Path to the source files if missing from the target -system. None means that the system will use windows update services to -find the required files. Default is None -.IP \(bu 2 -\fBrestart\fP (\fI\%bool\fP) \-\- Restarts the computer when installation is complete, if -required by the role/feature installed. Default is False -.IP \(bu 2 -\fBexclude\fP (\fI\%str\fP) \-\- +\fBfeature\fP (\fIstr, list\fP) \-\- .sp -The name of the feature to exclude when installing the -named feature. +The name of the feature(s) to install. This can be a single feature, +a string of features in a comma delimited list (no spaces), or a +list of features. .sp -\fBNOTE:\fP +New in version 2018.3.0: Added the ability to pass a list of features to be installed. + + +.IP \(bu 2 +\fBrecurse\fP (\fIOptions[bool]\fP) \-\- Install all sub\-features. Default is False +.IP \(bu 2 +\fBrestart\fP (\fIOptional[bool]\fP) \-\- Restarts the computer when installation is complete, if required by +the role/feature installed. Will also trigger a reboot if an item +in \fBexclude\fP requires a reboot to be properly removed. Default is +False +.IP \(bu 2 +\fBsource\fP (\fIOptional[str]\fP) \-\- Path to the source files if missing from the target system. None +means that the system will use windows update services to find the +required files. Default is None +.IP \(bu 2 +\fBexclude\fP (\fIOptional[str]\fP) \-\- +.sp +The name of the feature to exclude when installing the named +feature. This can be a single feature, a string of features in a +comma\-delimited list (no spaces), or a list of features. +.sp +\fBWARNING:\fP .INDENT 2.0 .INDENT 3.5 As there is no exclude option for the \fBAdd\-WindowsFeature\fP -command, the feature will be installed with other sub\-features and -will then be removed. +or \fBInstall\-WindowsFeature\fP PowerShell commands the features +named in \fBexclude\fP will be installed with other sub\-features +and will then be removed. \fBIf the feature named in \(ga\(gaexclude\(ga\(ga +is not a sub\-feature of one of the installed items it will still +be removed.\fP .UNINDENT .UNINDENT -.IP \(bu 2 -\fBrestart\fP \-\- Restarts the computer when installation is complete, if required by the role feature installed. .UNINDENT .TP .B Returns @@ -242849,9 +260103,19 @@ CLI Example: .sp .nf .ft C +# Install the Telnet Client passing a single string salt \(aq*\(aq win_servermanager.install Telnet\-Client -salt \(aq*\(aq win_servermanager.install SNMP\-Service True -salt \(aq*\(aq win_servermanager.install TFTP\-Client source=d:\eside\-by\-side + +# Install the TFTP Client and the SNMP Service passing a comma\-delimited +# string. Install all sub\-features +salt \(aq*\(aq win_servermanager.install TFTP\-Client,SNMP\-Service recurse=True + +# Install the TFTP Client from d:\eside\-by\-side +salt \(aq*\(aq win_servermanager.install TFTP\-Client source=d:\e\eside\-by\-side + +# Install the XPS Viewer, SNMP Service, and Remote Access passing a +# list. Install all sub\-features, but exclude the Web Server +salt \(aq*\(aq win_servermanager.install "[\(aqXPS\-Viewer\(aq, \(aqSNMP\-Service\(aq, \(aqRemoteAccess\(aq]" True recurse=True exclude="Web\-Server" .ft P .fi .UNINDENT @@ -242864,10 +260128,11 @@ List available features to install .INDENT 7.0 .TP .B Returns -A list of available features +A list of available features as returned by the +\fBGet\-WindowsFeature\fP PowerShell command .TP .B Return type -list +\fI\%str\fP .UNINDENT .sp CLI Example: @@ -242890,10 +260155,10 @@ newer. .INDENT 7.0 .TP .B Returns -A list of installed features +A dictionary of installed features .TP .B Return type -list +\fI\%dict\fP .UNINDENT .sp CLI Example: @@ -242928,14 +260193,21 @@ idea to use the \fB\-t\fP option to set a longer timeout. .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBfeature\fP (\fI\%str\fP) \-\- The name of the feature to remove +\fBfeature\fP (\fIstr, list\fP) \-\- +.sp +The name of the feature(s) to remove. This can be a single feature, +a string of features in a comma delimited list (no spaces), or a +list of features. +.sp +New in version 2018.3.0: Added the ability to pass a list of features to be removed. + + .IP \(bu 2 -\fBremove_payload\fP (\fI\%bool\fP) \-\- True will cause the feature to be removed from -the side\-by\-side store (\fB%SystemDrive%:\eWindows\eWinSxS\fP). Default is -False +\fBremove_payload\fP (\fIOptional[bool]\fP) \-\- True will cause the feature to be removed from the side\-by\-side +store (\fB%SystemDrive%:\eWindows\eWinSxS\fP). Default is False .IP \(bu 2 -\fBrestart\fP (\fI\%bool\fP) \-\- Restarts the computer when uninstall is complete, if -required by the role/feature removed. Default is False +\fBrestart\fP (\fIOptional[bool]\fP) \-\- Restarts the computer when uninstall is complete, if required by the +role/feature removed. Default is False .UNINDENT .TP .B Returns @@ -242993,132 +260265,7 @@ salt \(aq*\(aq service.available .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_service.config(name, bin_path=None, display_name=None, svc_type=None, start_type=None, error=None, group=None, tag=None, depend=None, obj=None, password=None, **kwargs) -Deprecated since version 2016.11.0: Use \fBservice.modify\fP instead - -.sp -Modify the named service. Because this is deprecated it will use the passed -parameters to run \fBservice.modify\fP instead. -.INDENT 7.0 -.TP -.B Parameters -.INDENT 7.0 -.IP \(bu 2 -\fBname\fP (\fI\%str\fP) \-\- Specifies the service name. This is not the display_name -.IP \(bu 2 -\fBbin_path\fP (\fI\%str\fP) \-\- Specifies the path to the service binary file. -Backslashes must be escaped, eg: C:\epath\eto\ebinary.exe -.IP \(bu 2 -\fBdisplay_name\fP (\fI\%str\fP) \-\- the name to be displayed in the service manager -.IP \(bu 2 -\fBsvc_type\fP (\fI\%str\fP) \-\- -.sp -Specifies the service type. Default is \fBown\fP\&. -Valid options are as follows: -.INDENT 2.0 -.IP \(bu 2 -kernel: Driver service -.IP \(bu 2 -filesystem: File system driver service -.IP \(bu 2 -adapter: Adapter driver service (reserved) -.IP \(bu 2 -recognizer: Recognizer driver service (reserved) -.IP \(bu 2 -own (default): Service runs in its own process -.IP \(bu 2 -share: Service shares a process with one or more other services -.UNINDENT - -.IP \(bu 2 -\fBstart_type\fP (\fI\%str\fP) \-\- -.sp -Specifies the service start type. Valid options are as -follows: -.INDENT 2.0 -.IP \(bu 2 -boot: Device driver that is loaded by the boot loader -.IP \(bu 2 -system: Device driver that is started during kernel initialization -.IP \(bu 2 -auto: Service that automatically starts -.IP \(bu 2 -manual (default): Service must be started manually -.IP \(bu 2 -disabled: Service cannot be started -.UNINDENT - -.IP \(bu 2 -\fBerror\fP (\fI\%str\fP) \-\- -.sp -The severity of the error, and action taken, if this -service fails to start. Valid options are as follows: -.INDENT 2.0 -.IP \(bu 2 -normal (normal): Error is logged and a message box is displayed -.IP \(bu 2 -severe: Error is logged and computer attempts a restart with the -last known good configuration -.IP \(bu 2 -critical: Error is logged, computer attempts to restart with the -last known good configuration, system halts on failure -.IP \(bu 2 -ignore: Error is logged and startup continues, no notification is -given to the user -.UNINDENT - -.IP \(bu 2 -\fBgroup\fP \-\- The name of the load order group to which this service -belongs -.IP \(bu 2 -\fBdepend\fP (\fIlist\fP) \-\- A list of services or load ordering groups that -must start before this service -.IP \(bu 2 -\fBobj\fP (\fI\%str\fP) \-\- -.sp -The name of the account under which the service should run. -For \fBown\fP type services this should be in the \fBdomain\eusername\fP -format. The following are examples of valid built\-in service -accounts: -.INDENT 2.0 -.IP \(bu 2 -NT Authority\eLocalService -.IP \(bu 2 -NT Authority\eNetworkService -.IP \(bu 2 -NT Authority\eLocalSystem -.IP \(bu 2 -\&.\eLocalSystem -.UNINDENT - -.IP \(bu 2 -\fBpassword\fP (\fI\%str\fP) \-\- The password for the account name specified in -\fBaccount_name\fP\&. For the above built\-in accounts, this can be None. -Otherwise a password must be specified. -.UNINDENT -.TP -.B Returns -a dictionary of changes made -.TP -.B Return type -\fI\%dict\fP -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq service.config display_name=\(aq\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.win_service.create(name, bin_path, exe_args=None, display_name=None, description=None, service_type=\(aqown\(aq, start_type=\(aqmanual\(aq, start_delayed=False, error_control=\(aqnormal\(aq, load_order_group=None, dependencies=None, account_name=\(aq.\e\eLocalSystem\(aq, account_password=None, run_interactive=False, **kwargs) +.B salt.modules.win_service.create(name, bin_path, exe_args=None, display_name=None, description=None, service_type=u\(aqown\(aq, start_type=u\(aqmanual\(aq, start_delayed=False, error_control=u\(aqnormal\(aq, load_order_group=None, dependencies=None, account_name=u\(aq.\e\eLocalSystem\(aq, account_password=None, run_interactive=False, **kwargs) Create the named service. .sp New in version 2015.8.0. @@ -243131,7 +260278,7 @@ New in version 2015.8.0. \fBname\fP (\fI\%str\fP) \-\- Specifies the service name. This is not the display_name .IP \(bu 2 \fBbin_path\fP (\fI\%str\fP) \-\- Specifies the path to the service binary file. -Backslashes must be escaped, eg: C:\epath\eto\ebinary.exe +Backslashes must be escaped, eg: C:pathtobinary.exe .IP \(bu 2 \fBexe_args\fP (\fI\%str\fP) \-\- Any additional arguments required by the service binary. .IP \(bu 2 @@ -243216,13 +260363,13 @@ should run. For \fBown\fP type services this should be in the built\-in service accounts: .INDENT 2.0 .IP \(bu 2 -NT Authority\eLocalService +NT AuthorityLocalService .IP \(bu 2 -NT Authority\eNetworkService +NT AuthorityNetworkService .IP \(bu 2 -NT Authority\eLocalSystem +NT AuthorityLocalSystem .IP \(bu 2 -\&.\eLocalSystem +\&.LocalSystem .UNINDENT .IP \(bu 2 @@ -243365,12 +260512,38 @@ salt \(aq*\(aq service.disabled .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_service.enable(name, **kwargs) +.B salt.modules.win_service.enable(name, start_type=u\(aqauto\(aq, start_delayed=False, **kwargs) Enable the named service to start at boot .INDENT 7.0 .TP .B Parameters +.INDENT 7.0 +.IP \(bu 2 \fBname\fP (\fI\%str\fP) \-\- The name of the service to enable. +.IP \(bu 2 +\fBstart_type\fP (\fI\%str\fP) \-\- +.sp +Specifies the service start type. Valid options are as +follows: +.INDENT 2.0 +.IP \(bu 2 +boot: Device driver that is loaded by the boot loader +.IP \(bu 2 +system: Device driver that is started during kernel initialization +.IP \(bu 2 +auto: Service that automatically starts +.IP \(bu 2 +manual: Service must be started manually +.IP \(bu 2 +disabled: Service cannot be started +.UNINDENT + +.IP \(bu 2 +\fBstart_delayed\fP (\fI\%bool\fP) \-\- Set the service to Auto(Delayed Start). Only valid +if the start_type is set to \fBAuto\fP\&. If service_type is not passed, +but the service is already set to \fBAuto\fP, then the flag will be +set. +.UNINDENT .TP .B Returns \fBTrue\fP if successful, \fBFalse\fP otherwise @@ -243658,7 +260831,7 @@ New in version 2016.11.0. \fBservice.get_service_name\fP function .IP \(bu 2 \fBbin_path\fP (\fI\%str\fP) \-\- The path to the service executable. Backslashes must be -escaped, eg: C:\epath\eto\ebinary.exe +escaped, eg: C:pathtobinary.exe .IP \(bu 2 \fBexe_args\fP (\fI\%str\fP) \-\- Any arguments required by the service executable .IP \(bu 2 @@ -243742,11 +260915,11 @@ should run. For \fBown\fP type services this should be in the built\-in service accounts: .INDENT 2.0 .IP \(bu 2 -NT Authority\eLocalService +NT AuthorityLocalService .IP \(bu 2 -NT Authority\eNetworkService +NT AuthorityNetworkService .IP \(bu 2 -NT Authority\eLocalSystem +NT AuthorityLocalSystem .IP \(bu 2 \&.LocalSystem .UNINDENT @@ -243857,7 +261030,12 @@ salt \(aq*\(aq service.start .INDENT 0.0 .TP .B salt.modules.win_service.status(name, sig=None) -Return the status for a service +Return the status for a service. +If the name contains globbing, a dict mapping service name to True/False +values is returned. +.sp +Changed in version 2018.3.0: The service name can now be a glob (e.g. \fBsalt*\fP) + .INDENT 7.0 .TP .B Parameters @@ -243870,6 +261048,7 @@ Return the status for a service .TP .B Returns True if running, False otherwise +dict: Maps service name to True if running, False otherwise .TP .B Return type \fI\%bool\fP @@ -243881,7 +261060,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq service.status [service signature] +salt \(aq*\(aq service.status .ft P .fi .UNINDENT @@ -244083,7 +261262,7 @@ wmi .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_smtp_server.get_connection_ip_list(as_wmi_format=False, server=\(aqSmtpSvc/1\(aq) +.B salt.modules.win_smtp_server.get_connection_ip_list(as_wmi_format=False, server=u\(aqSmtpSvc/1\(aq) Get the IPGrant list for the SMTP virtual server. .INDENT 7.0 .TP @@ -244116,7 +261295,7 @@ salt \(aq*\(aq win_smtp_server.get_connection_ip_list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_smtp_server.get_log_format(server=\(aqSmtpSvc/1\(aq) +.B salt.modules.win_smtp_server.get_log_format(server=u\(aqSmtpSvc/1\(aq) Get the active log format for the SMTP virtual server. .INDENT 7.0 .TP @@ -244169,7 +261348,7 @@ salt \(aq*\(aq win_smtp_server.get_log_format_types .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_smtp_server.get_relay_ip_list(server=\(aqSmtpSvc/1\(aq) +.B salt.modules.win_smtp_server.get_relay_ip_list(server=u\(aqSmtpSvc/1\(aq) Get the RelayIpList list for the SMTP virtual server. .INDENT 7.0 .TP @@ -244206,7 +261385,7 @@ salt \(aq*\(aq win_smtp_server.get_relay_ip_list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_smtp_server.get_server_setting(settings, server=\(aqSmtpSvc/1\(aq) +.B salt.modules.win_smtp_server.get_server_setting(settings, server=u\(aqSmtpSvc/1\(aq) Get the value of the setting for the SMTP virtual server. .INDENT 7.0 .TP @@ -244264,7 +261443,7 @@ salt \(aq*\(aq win_smtp_server.get_servers .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_smtp_server.set_connection_ip_list(addresses=None, grant_by_default=False, server=\(aqSmtpSvc/1\(aq) +.B salt.modules.win_smtp_server.set_connection_ip_list(addresses=None, grant_by_default=False, server=u\(aqSmtpSvc/1\(aq) Set the IPGrant list for the SMTP virtual server. .INDENT 7.0 .TP @@ -244299,7 +261478,7 @@ salt \(aq*\(aq win_smtp_server.set_connection_ip_list addresses="{\(aq127.0.0.1\ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_smtp_server.set_log_format(log_format, server=\(aqSmtpSvc/1\(aq) +.B salt.modules.win_smtp_server.set_log_format(log_format, server=u\(aqSmtpSvc/1\(aq) Set the active log format for the SMTP virtual server. .INDENT 7.0 .TP @@ -244332,7 +261511,7 @@ salt \(aq*\(aq win_smtp_server.set_log_format \(aqMicrosoft IIS Log File Format\ .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_smtp_server.set_relay_ip_list(addresses=None, server=\(aqSmtpSvc/1\(aq) +.B salt.modules.win_smtp_server.set_relay_ip_list(addresses=None, server=u\(aqSmtpSvc/1\(aq) Set the RelayIpList list for the SMTP virtual server. .sp Due to the unusual way that Windows stores the relay IPs, it is advisable to retrieve @@ -244393,7 +261572,7 @@ salt \(aq*\(aq win_smtp_server.set_relay_ip_list addresses="[\(aq192.168.1.1\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_smtp_server.set_server_setting(settings, server=\(aqSmtpSvc/1\(aq) +.B salt.modules.win_smtp_server.set_server_setting(settings, server=u\(aqSmtpSvc/1\(aq) Set the value of the setting for the SMTP virtual server. .sp \fBNOTE:\fP @@ -245973,7 +263152,7 @@ salt \(aq*\(aq system.stop_time_service .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_system.unjoin_domain(username=None, password=None, domain=None, workgroup=\(aqWORKGROUP\(aq, disable=False, restart=False) +.B salt.modules.win_system.unjoin_domain(username=None, password=None, domain=None, workgroup=u\(aqWORKGROUP\(aq, disable=False, restart=False) Unjoin a computer from an Active Directory Domain. Requires a restart. .INDENT 7.0 .TP @@ -246027,8 +263206,8 @@ CLI Example: .ft C salt \(aqminion\-id\(aq system.unjoin_domain restart=True -salt \(aqminion\-id\(aq system.unjoin_domain username=\(aqunjoinuser\(aq \e\e - password=\(aqunjoinpassword\(aq disable=True \e\e +salt \(aqminion\-id\(aq system.unjoin_domain username=\(aqunjoinuser\(aq \e + password=\(aqunjoinpassword\(aq disable=True \e restart=True .ft P .fi @@ -246046,7 +263225,7 @@ You can add and clear triggers and actions. You can list all tasks, folders, triggers, and actions. .INDENT 0.0 .TP -.B salt.modules.win_task.add_action(name=None, location=\(aq\e\e\(aq, action_type=\(aqExecute\(aq, **kwargs) +.B salt.modules.win_task.add_action(name=None, location=u\(aq\e\e\(aq, action_type=u\(aqExecute\(aq, **kwargs) Add an action to a task. .INDENT 7.0 .TP @@ -246173,7 +263352,7 @@ salt \(aqminion\-id\(aq task.add_action cmd=\(aqdel /Q /S C:\e\eTemp .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.add_trigger(name=None, location=\(aq\e\e\(aq, trigger_type=None, trigger_enabled=True, start_date=None, start_time=None, end_date=None, end_time=None, random_delay=None, repeat_interval=None, repeat_duration=None, repeat_stop_at_duration_end=False, execution_time_limit=None, **kwargs) +.B salt.modules.win_task.add_trigger(name=None, location=u\(aq\e\e\(aq, trigger_type=None, trigger_enabled=True, start_date=None, start_time=None, end_date=None, end_time=None, random_delay=None, repeat_interval=None, repeat_duration=None, repeat_stop_at_duration_end=False, execution_time_limit=None, **kwargs) .INDENT 7.0 .TP .B Parameters @@ -246464,7 +263643,7 @@ salt \(aqminion\-id\(aq task.add_trigger trigger_type=Once trigger_e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.clear_triggers(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.clear_triggers(name, location=u\(aq\e\e\(aq) Remove all triggers from the task. .INDENT 7.0 .TP @@ -246502,7 +263681,7 @@ salt \(aqminion\-id\(aq task.clear_trigger .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.create_folder(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.create_folder(name, location=u\(aq\e\e\(aq) Create a folder in which to create tasks. .INDENT 7.0 .TP @@ -246542,7 +263721,7 @@ salt \(aqminion\-id\(aq task.create_folder .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.create_task(name, location=\(aq\e\e\(aq, user_name=\(aqSystem\(aq, password=None, force=False, **kwargs) +.B salt.modules.win_task.create_task(name, location=u\(aq\e\e\(aq, user_name=u\(aqSystem\(aq, password=None, force=False, **kwargs) Create a new task in the designated location. This function has many keyword arguments that are not listed here. For additional arguments see: .INDENT 7.0 @@ -246609,7 +263788,7 @@ salt \(aqminion\-id\(aq task.create_task user_name=System force=True .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.create_task_from_xml(name, location=\(aq\e\e\(aq, xml_text=None, xml_path=None, user_name=\(aqSystem\(aq, password=None) +.B salt.modules.win_task.create_task_from_xml(name, location=u\(aq\e\e\(aq, xml_text=None, xml_path=None, user_name=u\(aqSystem\(aq, password=None) Create a task based on XML. Source can be a file or a string of XML. .INDENT 7.0 .TP @@ -246678,7 +263857,7 @@ salt \(aqminion\-id\(aq task.create_task_from_xml xml_path=C:\etask. .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.delete_folder(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.delete_folder(name, location=u\(aq\e\e\(aq) Delete a folder from the task scheduler. .INDENT 7.0 .TP @@ -246716,7 +263895,7 @@ salt \(aqminion\-id\(aq task.delete_folder .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.delete_task(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.delete_task(name, location=u\(aq\e\e\(aq) Delete a task from the task scheduler. .INDENT 7.0 .TP @@ -246754,7 +263933,7 @@ salt \(aqminion\-id\(aq task.delete_task .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.edit_task(name=None, location=\(aq\e\e\(aq, user_name=None, password=None, description=None, enabled=None, hidden=None, run_if_idle=None, idle_duration=None, idle_wait_timeout=None, idle_stop_on_end=None, idle_restart=None, ac_only=None, stop_if_on_batteries=None, wake_to_run=None, run_if_network=None, network_id=None, network_name=None, allow_demand_start=None, start_when_available=None, restart_every=None, restart_count=3, execution_time_limit=None, force_stop=None, delete_after=None, multiple_instances=None, **kwargs) +.B salt.modules.win_task.edit_task(name=None, location=u\(aq\e\e\(aq, user_name=None, password=None, description=None, enabled=None, hidden=None, run_if_idle=None, idle_duration=None, idle_wait_timeout=None, idle_stop_on_end=None, idle_restart=None, ac_only=None, stop_if_on_batteries=None, wake_to_run=None, run_if_network=None, network_id=None, network_name=None, allow_demand_start=None, start_when_available=None, restart_every=None, restart_count=3, execution_time_limit=None, force_stop=None, delete_after=None, multiple_instances=None, **kwargs) Edit the parameters of a task. Triggers and Actions cannot be edited yet. .INDENT 7.0 .TP @@ -247021,7 +264200,7 @@ salt \(aqminion\-id\(aq task.edit_task description=\(aqThis task is .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.info(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.info(name, location=u\(aq\e\e\(aq) Get the details about a task in the task scheduler. .INDENT 7.0 .TP @@ -247059,7 +264238,7 @@ salt \(aqminion\-id\(aq task.info .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.list_actions(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.list_actions(name, location=u\(aq\e\e\(aq) List all actions that pertain to a task in the specified location. .INDENT 7.0 .TP @@ -247097,7 +264276,7 @@ salt \(aqminion\-id\(aq task.list_actions .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.list_folders(location=\(aq\e\e\(aq) +.B salt.modules.win_task.list_folders(location=u\(aq\e\e\(aq) List all folders located in a specific location in the task scheduler. .INDENT 7.0 .TP @@ -247130,7 +264309,7 @@ salt \(aqminion\-id\(aq task.list_folders .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.list_tasks(location=\(aq\e\e\(aq) +.B salt.modules.win_task.list_tasks(location=u\(aq\e\e\(aq) List all tasks located in a specific location in the task scheduler. .INDENT 7.0 .TP @@ -247163,7 +264342,7 @@ salt \(aqminion\-id\(aq task.list_tasks .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.list_triggers(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.list_triggers(name, location=u\(aq\e\e\(aq) List all triggers that pertain to a task in the specified location. .INDENT 7.0 .TP @@ -247201,7 +264380,7 @@ salt \(aqminion\-id\(aq task.list_triggers .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.run(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.run(name, location=u\(aq\e\e\(aq) Run a scheduled task manually. .INDENT 7.0 .TP @@ -247239,7 +264418,7 @@ salt \(aqminion\-id\(aq task.list_run .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.run_wait(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.run_wait(name, location=u\(aq\e\e\(aq) Run a scheduled task and return when the task finishes .INDENT 7.0 .TP @@ -247277,7 +264456,7 @@ salt \(aqminion\-id\(aq task.list_run_wait .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.status(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.status(name, location=u\(aq\e\e\(aq) Determine the status of a task. Is it Running, Queued, Ready, etc. .INDENT 7.0 .TP @@ -247329,7 +264508,7 @@ salt \(aqminion\-id\(aq task.list_status .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_task.stop(name, location=\(aq\e\e\(aq) +.B salt.modules.win_task.stop(name, location=u\(aq\e\e\(aq) Stop a scheduled task. .INDENT 7.0 .TP @@ -248461,7 +265640,7 @@ CLI Example: .nf .ft C salt \(aq*\(aq user.update bob password=secret profile=C:\eUsers\eBob - home=\e\eserver\ehomeshare\ebob homedrive=U: + home=\eserver\ehomeshareob homedrive=U: .ft P .fi .UNINDENT @@ -249987,7 +267166,7 @@ signing_private_key=\(aq/etc/pki/myca.key\(aq csr=\(aq/etc/pki/myca.csr\(aq} .UNINDENT .INDENT 0.0 .TP -.B salt.modules.x509.create_crl(path=None, text=False, signing_private_key=None, signing_private_key_passphrase=None, signing_cert=None, revoked=None, include_expired=False, days_valid=100, digest=\(aq\(aq) +.B salt.modules.x509.create_crl(path=None, text=False, signing_private_key=None, signing_private_key_passphrase=None, signing_cert=None, revoked=None, include_expired=False, days_valid=100, digest=u\(aq\(aq) Create a CRL .INDENT 7.0 .TP @@ -250105,7 +267284,7 @@ salt \(aq*\(aq x509.create_csr path=/etc/pki/myca.csr \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.x509.create_private_key(path=None, text=False, bits=2048, passphrase=None, cipher=\(aqaes_128_cbc\(aq, verbose=True) +.B salt.modules.x509.create_private_key(path=None, text=False, bits=2048, passphrase=None, cipher=u\(aqaes_128_cbc\(aq, verbose=True) Creates a private key in PEM format. .INDENT 7.0 .TP @@ -251122,7 +268301,7 @@ New in version 2016.11.0. .INDENT 0.0 .TP -.B salt.modules.xbpspkg.add_repo(repo, conffile=\(aq/usr/share/xbps.d/15\-saltstack.conf\(aq) +.B salt.modules.xbpspkg.add_repo(repo, conffile=u\(aq/usr/share/xbps.d/15\-saltstack.conf\(aq) Add an XBPS repository to the system. .INDENT 7.0 .TP @@ -251798,7 +268977,7 @@ xmpp.send_msg \(aqadmins@xmpp.example.com\(aq \(aqThis is a salt module test\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.xmpp.send_msg_multi(message, recipients=None, rooms=None, jid=None, password=None, nick=\(aqSaltStack Bot\(aq, profile=None) +.B salt.modules.xmpp.send_msg_multi(message, recipients=None, rooms=None, jid=None, password=None, nick=u\(aqSaltStack Bot\(aq, profile=None) Send a message to an XMPP recipient, support send message to multiple recipients or chat room. .sp @@ -252244,7 +269423,7 @@ salt \(aq*\(aq pkg.info_installed ... .UNINDENT .INDENT 0.0 .TP -.B salt.modules.yumpkg.install(name=None, refresh=False, skip_verify=False, pkgs=None, sources=None, downloadonly=False, reinstall=False, normalize=True, update_holds=False, **kwargs) +.B salt.modules.yumpkg.install(name=None, refresh=False, skip_verify=False, pkgs=None, sources=None, downloadonly=False, reinstall=False, normalize=True, update_holds=False, ignore_epoch=False, saltenv=u\(aqbase\(aq, **kwargs) Changed in version 2015.8.12,2016.3.3,2016.11.0: On minions running systemd>=205, \fI\%systemd\-run(1)\fP is now used to isolate commands which modify installed packages from the \fBsalt\-minion\fP daemon\(aqs control group. This is done to keep systemd @@ -252308,6 +269487,10 @@ Only download the packages, do not install. .B version Install a specific version of the package, e.g. 1.2.3\-4.el5. Ignored if "pkgs" or "sources" is passed. +.sp +Changed in version 2018.3.0: version can now contain comparison operators (e.g. \fB>1.2.3\fP, +\fB<=2.0\fP, etc.) + .TP .B update_holds False @@ -252342,6 +269525,16 @@ Disable exclude from main, for a repo or for everything. .sp New in version 2014.7.0. +.TP +.B ignore_epoch +False +Only used when the version of a package is specified using a comparison +operator (e.g. \fB>4.1\fP). If set to \fBTrue\fP, then the epoch will be +ignored when comparing the currently\-installed version to the desired +version. +.sp +New in version 2018.3.0. + .UNINDENT .sp Multiple Package Installation Options: @@ -252402,6 +269595,35 @@ salt \-G role:nsd pkg.install gpfs.gplbin\-2.6.32\-279.31.1.el6.x86_64 normalize .sp New in version 2014.7.0. +.TP +.B diff_attr: +If a list of package attributes is specified, returned value will +contain them, eg.: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{\(aq\(aq: { + \(aqold\(aq: { + \(aqversion\(aq: \(aq\(aq, + \(aqarch\(aq: \(aq\(aq}, + + \(aqnew\(aq: { + \(aqversion\(aq: \(aq\(aq, + \(aqarch\(aq: \(aq\(aq}}} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Valid attributes are: \fBepoch\fP, \fBversion\fP, \fBrelease\fP, \fBarch\fP, +\fBinstall_date\fP, \fBinstall_date_time_t\fP\&. +.sp +If \fBall\fP is specified, all valid attributes will be returned. +.sp +New in version 2018.3.0. + .UNINDENT .sp Returns a dict containing the new package names and versions: @@ -252416,6 +269638,26 @@ Returns a dict containing the new package names and versions: .fi .UNINDENT .UNINDENT +.sp +If an attribute list in diff_attr is specified, the dict will also contain +any specified attribute, eg.: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{\(aq\(aq: { + \(aqold\(aq: { + \(aqversion\(aq: \(aq\(aq, + \(aqarch\(aq: \(aq\(aq}, + + \(aqnew\(aq: { + \(aqversion\(aq: \(aq\(aq, + \(aqarch\(aq: \(aq\(aq}}} +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -252470,7 +269712,7 @@ salt \(aq*\(aq pkg.list_downloaded .UNINDENT .INDENT 0.0 .TP -.B salt.modules.yumpkg.list_holds(pattern=\(aq\e\ew+(?:[.\-][^\-]+)*\(aq, full=True) +.B salt.modules.yumpkg.list_holds(pattern=u\(aq[\e\ew+]+(?:[.\-][^\-]+)*\(aq, full=True) Changed in version 2016.3.0,2015.8.4,2015.5.10: Function renamed from \fBpkg.get_locked_pkgs\fP to \fBpkg.list_holds\fP\&. .sp @@ -252565,17 +269807,50 @@ salt \(aq*\(aq pkg.list_patches .INDENT 0.0 .TP .B salt.modules.yumpkg.list_pkgs(versions_as_list=False, **kwargs) -List the packages currently installed in a dict: +List the packages currently installed as a dict. By default, the dict +contains versions as a comma separated string: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C -{\(aq\(aq: \(aq\(aq} +{\(aq\(aq: \(aq[,...]\(aq} .ft P .fi .UNINDENT .UNINDENT +.INDENT 7.0 +.TP +.B versions_as_list: +If set to true, the versions are provided as a list +.sp +{\(aq\(aq: [\(aq\(aq, \(aq\(aq]} +.TP +.B attr: +If a list of package attributes is specified, returned value will +contain them in addition to version, eg.: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{\(aq\(aq: [{\(aqversion\(aq : \(aqversion\(aq, \(aqarch\(aq : \(aqarch\(aq}]} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Valid attributes are: \fBepoch\fP, \fBversion\fP, \fBrelease\fP, \fBarch\fP, +\fBinstall_date\fP, \fBinstall_date_time_t\fP\&. +.sp +If \fBall\fP is specified, all valid attributes will be returned. +.INDENT 7.0 +.INDENT 3.5 +New in version 2018.3.0. + +.UNINDENT +.UNINDENT +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -252584,6 +269859,8 @@ CLI Example: .nf .ft C salt \(aq*\(aq pkg.list_pkgs +salt \(aq*\(aq pkg.list_pkgs attr=version,arch +salt \(aq*\(aq pkg.list_pkgs attr=\(aq["version", "arch"]\(aq .ft P .fi .UNINDENT @@ -253257,7 +270534,7 @@ New in version 2016.3.0. .INDENT 7.0 .INDENT 3.5 To add extra arguments to the \fByum upgrade\fP command, pass them as key -word arguments. For arguments without assignments, pass \fBTrue\fP +word arguments. For arguments without assignments, pass \fBTrue\fP .UNINDENT .UNINDENT .INDENT 7.0 @@ -253897,7 +271174,7 @@ salt \(aq*\(aq zabbix.hostgroup_update 24 name=\(aqRenamed Name\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zabbix.hostinterface_create(hostid, ip, dns=\(aq\(aq, main=1, type=1, useip=1, port=None, **connection_args) +.B salt.modules.zabbix.hostinterface_create(hostid, ip, dns=u\(aq\(aq, main=1, type=1, useip=1, port=None, **connection_args) Create new host interface NOTE: This function accepts all standard host group interface: keyword argument names differ depending on your zabbix version, see: \fI\%https://www.zabbix.com/documentation/3.0/manual/api/reference/hostinterface/object\fP @@ -254804,6 +272081,252 @@ salt \(aq*\(aq zabbix.usergroup_update 8 name=guestsRenamed .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zabbix.usermacro_create(macro, value, hostid, **connection_args) +Create new host usermacro. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmacro\fP \-\- name of the host usermacro +.IP \(bu 2 +\fBvalue\fP \-\- value of the host usermacro +.IP \(bu 2 +\fBhostid\fP \-\- hostid or templateid +.IP \(bu 2 +\fB_connection_user\fP \-\- Optional \- zabbix user (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_password\fP \-\- Optional \- zabbix password (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_url\fP \-\- Optional \- url of zabbix frontend (can also be set in opts, pillar, see module\(aqs docstring) +.UNINDENT +.UNINDENT +.sp +return: ID of the created host usermacro. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq zabbix.usermacro_create \(aq{$SNMP_COMMUNITY}\(aq \(aqpublic\(aq 1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zabbix.usermacro_createglobal(macro, value, **connection_args) +Create new global usermacro. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmacro\fP \-\- name of the global usermacro +.IP \(bu 2 +\fBvalue\fP \-\- value of the global usermacro +.IP \(bu 2 +\fB_connection_user\fP \-\- Optional \- zabbix user (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_password\fP \-\- Optional \- zabbix password (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_url\fP \-\- Optional \- url of zabbix frontend (can also be set in opts, pillar, see module\(aqs docstring) +.UNINDENT +.UNINDENT +.sp +return: ID of the created global usermacro. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq zabbix.usermacro_createglobal \(aq{$SNMP_COMMUNITY}\(aq \(aqpublic\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zabbix.usermacro_delete(macroids, **connection_args) +Delete host usermacros. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmacroids\fP \-\- macroids of the host usermacros +.IP \(bu 2 +\fB_connection_user\fP \-\- Optional \- zabbix user (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_password\fP \-\- Optional \- zabbix password (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_url\fP \-\- Optional \- url of zabbix frontend (can also be set in opts, pillar, see module\(aqs docstring) +.UNINDENT +.UNINDENT +.sp +return: IDs of the deleted host usermacro. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq zabbix.usermacro_delete 21 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zabbix.usermacro_deleteglobal(macroids, **connection_args) +Delete global usermacros. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmacroids\fP \-\- macroids of the global usermacros +.IP \(bu 2 +\fB_connection_user\fP \-\- Optional \- zabbix user (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_password\fP \-\- Optional \- zabbix password (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_url\fP \-\- Optional \- url of zabbix frontend (can also be set in opts, pillar, see module\(aqs docstring) +.UNINDENT +.UNINDENT +.sp +return: IDs of the deleted global usermacro. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq zabbix.usermacro_deleteglobal 21 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zabbix.usermacro_get(macro=None, hostids=None, templateids=None, hostmacroids=None, globalmacroids=None, globalmacro=False, **connection_args) +Retrieve user macros according to the given parameters. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBmacro\fP \-\- name of the usermacro +.IP \(bu 2 +\fBhostids\fP \-\- Return macros for the given hostids +.IP \(bu 2 +\fBtemplateids\fP \-\- Return macros for the given templateids +.IP \(bu 2 +\fBhostmacroids\fP \-\- Return macros with the given hostmacroids +.IP \(bu 2 +\fBglobalmacroids\fP \-\- Return macros with the given globalmacroids (implies globalmacro=True) +.IP \(bu 2 +\fBglobalmacro\fP \-\- if True, returns only global macros +.IP \(bu 2 +\fBconnection_args\fP (\fIoptional\fP) \-\- _connection_user: zabbix user (can also be set in opts or pillar, see module\(aqs docstring) +_connection_password: zabbix password (can also be set in opts or pillar, see module\(aqs docstring) +_connection_url: url of zabbix frontend (can also be set in opts or pillar, see module\(aqs docstring) +.UNINDENT +.TP +.B Returns +Array with usermacro details, False if no usermacro found or on failure. +.UNINDENT +.sp +CLI Example: +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +salt \(aq*\(aq zabbix.usermacro_get macro=\(aq{$SNMP_COMMUNITY}\(aq +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zabbix.usermacro_update(hostmacroid, value, **connection_args) +Update existing host usermacro. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBhostmacroid\fP \-\- id of the host usermacro +.IP \(bu 2 +\fBvalue\fP \-\- new value of the host usermacro +.IP \(bu 2 +\fB_connection_user\fP \-\- Optional \- zabbix user (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_password\fP \-\- Optional \- zabbix password (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_url\fP \-\- Optional \- url of zabbix frontend (can also be set in opts, pillar, see module\(aqs docstring) +.UNINDENT +.UNINDENT +.sp +return: ID of the update host usermacro. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq zabbix.usermacro_update 1 \(aqpublic\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zabbix.usermacro_updateglobal(globalmacroid, value, **connection_args) +Update existing global usermacro. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBglobalmacroid\fP \-\- id of the host usermacro +.IP \(bu 2 +\fBvalue\fP \-\- new value of the host usermacro +.IP \(bu 2 +\fB_connection_user\fP \-\- Optional \- zabbix user (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_password\fP \-\- Optional \- zabbix password (can also be set in opts or pillar, see module\(aqs docstring) +.IP \(bu 2 +\fB_connection_url\fP \-\- Optional \- url of zabbix frontend (can also be set in opts, pillar, see module\(aqs docstring) +.UNINDENT +.UNINDENT +.sp +return: ID of the update global usermacro. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq zabbix.usermacro_updateglobal 1 \(aqpublic\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.zcbuildout .sp Management of zc.buildout @@ -255080,7 +272603,7 @@ zenoss: .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zenoss.add_device(device=None, device_class=None, collector=\(aqlocalhost\(aq, prod_state=1000) +.B salt.modules.zenoss.add_device(device=None, device_class=None, collector=u\(aqlocalhost\(aq, prod_state=1000) A function to connect to a zenoss server and add a new device entry. .INDENT 7.0 .TP @@ -255450,6 +272973,9 @@ salt \(aq*\(aq zfs.exists myzpool/myvolume type=volume .B salt.modules.zfs.get(*dataset, **kwargs) New in version 2016.3.0. +.sp +Changed in version 2018.3.0. + .sp Displays properties for the given datasets. .INDENT 7.0 @@ -255487,6 +273013,11 @@ filesystem, snapshot, volume, bookmark, or all. string comma\-separated list of sources to display. Must be one of the following: local, default, inherited, temporary, and none. The default value is all sources. +.TP +.B parsable +boolean +display numbers in parsable (exact) values +.. versionadded:: 2018.3.0 .UNINDENT .sp \fBNOTE:\fP @@ -255646,7 +273177,7 @@ salt \(aq*\(aq zfs.inherit canmount myzpool/mydataset [recursive=True|False] New in version 2015.5.0. .sp -Changed in version 2016.3.0. +Changed in version 2018.3.0. .sp Return a list of all datasets or a specified dataset on the system and the @@ -255681,6 +273212,11 @@ property to sort on (default = name) .B order string [ascending|descending] sort order (default = ascending) +.TP +.B parsable +boolean +display numbers in parsable (exact) values +.. versionadded:: 2018.3.0 .UNINDENT .sp CLI Example: @@ -255699,7 +273235,7 @@ salt \(aq*\(aq zfs.list myzpool/mydataset properties="sharenfs,mountpoint" .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zfs.mount(name=\(aq\-a\(aq, **kwargs) +.B salt.modules.zfs.mount(name=u\(aq\-a\(aq, **kwargs) New in version 2016.3.0. .sp @@ -256102,13 +273638,21 @@ salt \(aq*\(aq zfs.unmount myzpool/mydataset [force=True|False] .UNINDENT .SS salt.modules.zk_concurrency .SS Concurrency controls in zookeeper +.INDENT 0.0 +.TP +.B depends +kazoo +.TP +.B configuration +See \fBsalt.modules.zookeeper\fP for setup instructions. +.UNINDENT .sp This module allows you to acquire and release a slot. This is primarily useful for ensureing that no more than N hosts take a specific action at once. This can also be used to coordinate between masters. .INDENT 0.0 .TP -.B salt.modules.zk_concurrency.lock(path, zk_hosts, identifier=None, max_concurrency=1, timeout=None, ephemeral_lease=False, force=False) +.B salt.modules.zk_concurrency.lock(path, zk_hosts=None, identifier=None, max_concurrency=1, timeout=None, ephemeral_lease=False, force=False, profile=None, scheme=None, username=None, password=None, default_acl=None) Get lock (with optional timeout) .INDENT 7.0 .TP @@ -256135,17 +273679,10 @@ Forcibly acquire the lock regardless of available slots .UNINDENT .sp Example: -.sp -\&... code\-block: bash -.INDENT 7.0 -.INDENT 3.5 -salt minion zk_concurrency.lock /lock/path host1:1234,host2:1234 -.UNINDENT -.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zk_concurrency.lock_holders(path, zk_hosts, identifier=None, max_concurrency=1, timeout=None, ephemeral_lease=False) +.B salt.modules.zk_concurrency.lock_holders(path, zk_hosts=None, identifier=None, max_concurrency=1, timeout=None, ephemeral_lease=False, profile=None, scheme=None, username=None, password=None, default_acl=None) Return an un\-ordered list of lock holders .INDENT 7.0 .TP @@ -256169,17 +273706,10 @@ Whether the locks in zookeper should be ephemeral .UNINDENT .sp Example: -.sp -\&... code\-block: bash -.INDENT 7.0 -.INDENT 3.5 -salt minion zk_concurrency.lock_holders /lock/path host1:1234,host2:1234 -.UNINDENT -.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zk_concurrency.party_members(path, zk_hosts, min_nodes=1, blocking=False) +.B salt.modules.zk_concurrency.party_members(path, zk_hosts=None, min_nodes=1, blocking=False, profile=None, scheme=None, username=None, password=None, default_acl=None) Get the List of identifiers in a particular party, optionally waiting for the specified minimum number of nodes (min_nodes) to appear .INDENT 7.0 @@ -256198,18 +273728,10 @@ The boolean indicating if we need to block until min_nodes are available .UNINDENT .sp Example: -.sp -\&... code\-block: bash -.INDENT 7.0 -.INDENT 3.5 -salt minion zk_concurrency.party_members /lock/path host1:1234,host2:1234 -salt minion zk_concurrency.party_members /lock/path host1:1234,host2:1234 min_nodes=3 blocking=True -.UNINDENT -.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zk_concurrency.unlock(path, zk_hosts=None, identifier=None, max_concurrency=1, ephemeral_lease=False) +.B salt.modules.zk_concurrency.unlock(path, zk_hosts=None, identifier=None, max_concurrency=1, ephemeral_lease=False, scheme=None, profile=None, username=None, password=None, default_acl=None) Remove lease from semaphore .INDENT 7.0 .TP @@ -256233,13 +273755,6 @@ Whether the locks in zookeper should be ephemeral .UNINDENT .sp Example: -.sp -\&... code\-block: bash -.INDENT 7.0 -.INDENT 3.5 -salt minion zk_concurrency.unlock /lock/path host1:1234,host2:1234 -.UNINDENT -.UNINDENT .UNINDENT .SS salt.modules.znc .sp @@ -257137,27 +274652,20 @@ Nitin Madhok <\fI\%nmadhok@clemson.edu\fP> .INDENT 0.0 .TP .B salt.modules.zpool.add(zpool, *vdevs, **kwargs) -Changed in version 2016.3.0. - -.sp Add the specified vdev\(aqs to the given storage pool .INDENT 7.0 .TP .B zpool string -name of storage pool +Name of storage pool .TP -.B -.nf -* -.fi -vdevs +.B vdevs string -one or more devices +One or more devices .TP .B force boolean -forces use of device +Forces use of device .UNINDENT .sp CLI Example: @@ -257175,27 +274683,24 @@ salt \(aq*\(aq zpool.add myzpool /path/to/vdev1 /path/to/vdev2 [...] .INDENT 0.0 .TP .B salt.modules.zpool.attach(zpool, device, new_device, force=False) -Changed in version 2016.3.0. - -.sp Attach specified device to zpool .INDENT 7.0 .TP .B zpool string -name of storage pool +Name of storage pool .TP .B device string -device to attach too +Existing device name too .TP .B new_device string -device to attach +New device name (to be attached to \fBdevice\fP) .TP .B force boolean -forces use of device +Forces use of device .UNINDENT .sp CLI Example: @@ -257215,47 +274720,48 @@ salt \(aq*\(aq zpool.attach myzpool /path/to/vdev1 /path/to/vdev2 [...] .B salt.modules.zpool.create(zpool, *vdevs, **kwargs) New in version 2015.5.0. -.sp -Changed in version 2016.3.0. - .sp Create a simple zpool, a mirrored zpool, a zpool having nested VDEVs, a hybrid zpool with cache, spare and log drives or a zpool with RAIDZ\-1, RAIDZ\-2 or RAIDZ\-3 .INDENT 7.0 .TP .B zpool string -name of storage pool +Name of storage pool .TP -.B -.nf -* -.fi -vdevs +.B vdevs string -one or move devices +One or move devices .TP .B force boolean -forces use of vdevs, even if they appear in use or specify a conflicting replication level. +Forces use of vdevs, even if they appear in use or specify a +conflicting replication level. .TP .B mountpoint string -sets the mount point for the root dataset +Sets the mount point for the root dataset .TP .B altroot string -equivalent to "\-o cachefile=none,altroot=root" +Equivalent to "\-o cachefile=none,altroot=root" .TP .B properties dict -additional pool properties +Additional pool properties .TP .B filesystem_properties dict -additional filesystem properties +Additional filesystem properties +.TP +.B createboot +boolean +create a boot partition +.sp +New in version 2018.3.0. + .UNINDENT .sp -CLI Example: +CLI Examples: .INDENT 7.0 .INDENT 3.5 .sp @@ -257274,9 +274780,10 @@ salt \(aq*\(aq zpool.create myhybridzpool mirror /tmp/file1 [...] log mirror /pa \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -Zpool properties can be specified at the time of creation of the pool by -passing an additional argument called "properties" and specifying the properties -with their respective values in the form of a python dictionary: +Zpool properties can be specified at the time of creation of the pool +by passing an additional argument called "properties" and specifying +the properties with their respective values in the form of a python +dictionary: .INDENT 0.0 .INDENT 3.5 .sp @@ -257288,9 +274795,10 @@ properties="{\(aqproperty1\(aq: \(aqvalue1\(aq, \(aqproperty2\(aq: \(aqvalue2\(a .UNINDENT .UNINDENT .sp -Filesystem properties can be specified at the time of creation of the pool by -passing an additional argument called "filesystem_properties" and specifying the properties -with their respective values in the form of a python dictionary: +Filesystem properties can be specified at the time of creation of the +pool by passing an additional argument called "filesystem_properties" +and specifying the properties with their respective values in the form +of a python dictionary: .INDENT 0.0 .INDENT 3.5 .sp @@ -257319,12 +274827,7 @@ salt \(aq*\(aq zpool.create myzpool /path/to/vdev1 [...] properties="{\(aqproper .INDENT 0.0 .TP .B salt.modules.zpool.create_file_vdev(size, *vdevs) -Changed in version 2016.3.0. - -.sp -Creates file based \fBvirtual devices\fP for a zpool -.sp -\fB*vdevs\fP is a list of full paths for mkfile to create +Creates file based virtual devices for a zpool .sp CLI Example: .INDENT 7.0 @@ -257348,19 +274851,16 @@ Depending on file size, the above command may take a while to return. .INDENT 0.0 .TP .B salt.modules.zpool.destroy(zpool, force=False) -Changed in version 2016.3.0. - -.sp Destroys a storage pool .INDENT 7.0 .TP .B zpool string -name of storage pool +Name of storage pool .TP .B force boolean -force destroy of pool +Force destroy of pool .UNINDENT .sp CLI Example: @@ -257378,19 +274878,16 @@ salt \(aq*\(aq zpool.destroy myzpool .INDENT 0.0 .TP .B salt.modules.zpool.detach(zpool, device) -Changed in version 2016.3.0. - -.sp Detach specified device to zpool .INDENT 7.0 .TP .B zpool string -name of storage pool +Name of storage pool .TP .B device string -device to detach +Device to detach .UNINDENT .sp CLI Example: @@ -257413,7 +274910,7 @@ Check if a ZFS storage pool is active .TP .B zpool string -name of storage pool +Name of storage pool .UNINDENT .sp CLI Example: @@ -257433,24 +274930,17 @@ salt \(aq*\(aq zpool.exists myzpool .B salt.modules.zpool.export(*pools, **kwargs) New in version 2015.5.0. -.sp -Changed in version 2016.3.0. - .sp Export storage pools .INDENT 7.0 .TP -.B -.nf -* -.fi -pools +.B pools string -one or more storage pools to export +One or more storage pools to export .TP .B force boolean -force export of storage pools +Force export of storage pools .UNINDENT .sp CLI Example: @@ -257468,7 +274958,7 @@ salt \(aq*\(aq zpool.export myzpool2 myzpool2 ... [force=True|False] .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zpool.get(zpool, prop=None, show_source=False) +.B salt.modules.zpool.get(zpool, prop=None, show_source=False, parsable=False) New in version 2016.3.0. .sp @@ -257477,15 +274967,22 @@ Retrieves the given list of properties .TP .B zpool string -name of storage pool +Name of storage pool .TP .B prop string -optional name of property to retrieve +Optional name of property to retrieve .TP .B show_source boolean -show source of property +Show source of property +.TP +.B parsable +boolean +Display numbers in parsable (exact) values +.sp +New in version 2018.3.0. + .UNINDENT .sp CLI Example: @@ -257526,20 +275023,22 @@ salt \(aq*\(aq zpool.healthy New in version 2016.3.0. .sp -Displays the command history of the specified pools or all pools if no pool is specified +Displays the command history of the specified pools, or all pools if no +pool is specified .INDENT 7.0 .TP .B zpool string -optional storage pool +Optional storage pool .TP .B internal boolean -toggle display of internally logged ZFS events +Toggle display of internally logged ZFS events .TP .B verbose boolean -toggle display of the user name, the hostname, and the zone in which the operation was performed +Toggle display of the user name, the hostname, and the zone in which +the operation was performed .UNINDENT .sp CLI Example: @@ -257559,56 +275058,56 @@ salt \(aq*\(aq zpool.upgrade myzpool .B salt.modules.zpool.import(zpool=None, new_name=None, **kwargs) New in version 2015.5.0. -.sp -Changed in version 2016.3.0. - .sp Import storage pools or list pools available for import .INDENT 7.0 .TP .B zpool string -optional name of storage pool +Optional name of storage pool .TP .B new_name string -optional new name for the storage pool +Optional new name for the storage pool .TP .B mntopts string -comma\-separated list of mount options to use when mounting datasets within the pool. +Comma\-separated list of mount options to use when mounting datasets +within the pool. .TP .B force boolean -forces import, even if the pool appears to be potentially active. +Forces import, even if the pool appears to be potentially active. .TP .B altroot string -equivalent to "\-o cachefile=none,altroot=root" +Equivalent to "\-o cachefile=none,altroot=root" .TP .B dir string -searches for devices or files in dir, multiple dirs can be specified as follows:: dir="dir1,dir2" +Searches for devices or files in dir, multiple dirs can be specified as +follows: \fBdir="dir1,dir2"\fP .TP .B no_mount boolean -import the pool without mounting any file systems. +Import the pool without mounting any file systems. .TP .B only_destroyed boolean -imports destroyed pools only. this also sets force=True. +Imports destroyed pools only. this also sets force=True. .TP .B properties dict -additional pool properties +Additional pool properties .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -Zpool properties can be specified at the time of creation of the pool by -passing an additional argument called "properties" and specifying the properties -with their respective values in the form of a python dictionary: +Zpool properties can be specified at the time of creation of the pool +by passing an additional argument called "properties" and specifying +the properties with their respective values in the form of a python +dictionary: .INDENT 0.0 .INDENT 3.5 .sp @@ -257639,9 +275138,6 @@ salt \(aq*\(aq zpool.import myzpool dir=\(aq/tmp\(aq .INDENT 0.0 .TP .B salt.modules.zpool.iostat(zpool=None, sample_time=0) -Changed in version 2016.3.0. - -.sp Display I/O statistics for the given pools .INDENT 7.0 .TP @@ -257668,11 +275164,45 @@ salt \(aq*\(aq zpool.iostat myzpool .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zpool.list(properties=\(aqsize, alloc, free, cap, frag, health\(aq, zpool=None) -New in version 2015.5.0. +.B salt.modules.zpool.labelclear(device, force=False) +New in version 2018.3.0. .sp -Changed in version 2016.3.0. +Removes ZFS label information from the specified device +.sp +\fBWARNING:\fP +.INDENT 7.0 +.INDENT 3.5 +The device must not be part of an active pool configuration. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B device +string +Device name +.TP +.B force +boolean +Treat exported or foreign devices as inactive +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq zpool.labelclear /path/to/dev +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zpool.list(properties=u\(aqsize, alloc, free, cap, frag, health\(aq, zpool=None, parsable=False) +New in version 2015.5.0. .sp Return information about (all) storage pools @@ -257685,12 +275215,20 @@ optional name of storage pool .B properties string comma\-separated list of properties to list +.TP +.B parsable +boolean +display numbers in parsable (exact) values +.sp +New in version 2018.3.0. + .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -the \(aqname\(aq property will always be included, the \(aqfrag\(aq property will get removed if not available +The \fBname\fP property will always be included, while the \fBfrag\fP +property will get removed if not available .UNINDENT .UNINDENT .INDENT 7.0 @@ -257703,7 +275241,7 @@ optional zpool \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -multiple storage pool can be provded as a space separated list +Multiple storage pool can be provded as a space separated list .UNINDENT .UNINDENT .sp @@ -257714,6 +275252,9 @@ CLI Example: .nf .ft C salt \(aq*\(aq zpool.list +salt \(aq*\(aq zpool.list zpool=tank +salt \(aq*\(aq zpool.list \(aqsize,free\(aq +salt \(aq*\(aq zpool.list \(aqsize,free\(aq tank .ft P .fi .UNINDENT @@ -257724,17 +275265,15 @@ salt \(aq*\(aq zpool.list .B salt.modules.zpool.offline(zpool, *vdevs, **kwargs) New in version 2015.5.0. -.sp -Changed in version 2016.3.0. - .sp Ensure that the specified devices are offline .sp \fBWARNING:\fP .INDENT 7.0 .INDENT 3.5 -By default, the OFFLINE state is persistent. The device remains offline when -the system is rebooted. To temporarily take a device offline, use \fBtemporary=True\fP\&. +By default, the \fBOFFLINE\fP state is persistent. The device remains +offline when the system is rebooted. To temporarily take a device +offline, use \fBtemporary=True\fP\&. .UNINDENT .UNINDENT .INDENT 7.0 @@ -257743,17 +275282,13 @@ the system is rebooted. To temporarily take a device offline, use \fBtemporary=T string name of storage pool .TP -.B -.nf -* -.fi -vdevs +.B vdevs string -one or more devices +One or more devices .TP .B temporary boolean -enable temporarily offline +Enable temporarily offline .UNINDENT .sp CLI Example: @@ -257773,9 +275308,6 @@ salt \(aq*\(aq zpool.offline myzpool /path/to/vdev1 [...] [temporary=True|False] .B salt.modules.zpool.online(zpool, *vdevs, **kwargs) New in version 2015.5.0. -.sp -Changed in version 2016.3.0. - .sp Ensure that the specified devices are online .INDENT 7.0 @@ -257784,11 +275316,7 @@ Ensure that the specified devices are online string name of storage pool .TP -.B -.nf -* -.fi -vdevs +.B vdevs string one or more devices .TP @@ -257828,8 +275356,8 @@ Generates a new unique identifier for the pool \fBWARNING:\fP .INDENT 7.0 .INDENT 3.5 -You must ensure that all devices in this pool are online -and healthy before performing this action. +You must ensure that all devices in this pool are online and healthy +before performing this action. .UNINDENT .UNINDENT .INDENT 7.0 @@ -257880,18 +275408,15 @@ salt \(aq*\(aq zpool.reopen myzpool .INDENT 0.0 .TP .B salt.modules.zpool.replace(zpool, old_device, new_device=None, force=False) -Changed in version 2016.3.0. - -.sp -Replaces old_device with new_device. +Replaces \fBold_device\fP with \fBnew_device\fP .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -This is equivalent to attaching new_device, -waiting for it to resilver, and then detaching old_device. +This is equivalent to attaching \fBnew_device\fP, +waiting for it to resilver, and then detaching \fBold_device\fP\&. .sp -The size of new_device must be greater than or equal to the minimum +The size of \fBnew_device\fP must be greater than or equal to the minimum size of all the devices in a mirror or raidz configuration. .UNINDENT .UNINDENT @@ -257899,15 +275424,15 @@ size of all the devices in a mirror or raidz configuration. .TP .B zpool string -name of storage pool +Name of storage pool .TP .B old_device string -old device to replace +Old device to replace .TP .B new_device string -optional new device +Optional new device .TP .B force boolean @@ -257928,20 +275453,32 @@ salt \(aq*\(aq zpool.replace myzpool /path/to/vdev1 /path/to/vdev2 .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zpool.scrub(zpool, stop=False) -Changed in version 2016.3.0. - -.sp +.B salt.modules.zpool.scrub(zpool, stop=False, pause=False) Scrub a storage pool .INDENT 7.0 .TP .B zpool string -name of storage pool +Name of storage pool .TP .B stop boolean -if true, cancel ongoing scrub +If \fBTrue\fP, cancel ongoing scrub +.TP +.B pause +boolean +If \fBTrue\fP, pause ongoing scrub +.sp +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +If both \fBpause\fP and \fBstop\fP are \fBTrue\fP, then \fBstop\fP will +win. +.UNINDENT +.UNINDENT .UNINDENT .sp CLI Example: @@ -257967,15 +275504,15 @@ Sets the given property on the specified pool .TP .B zpool string -name of storage pool +Name of storage pool .TP .B prop string -name of property +Name of property to set .TP .B value string -value to set property to +Value to set for the specified property .UNINDENT .sp CLI Example: @@ -257992,10 +275529,90 @@ salt \(aq*\(aq zpool.set myzpool readonly yes .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zpool.status(zpool=None) -Changed in version 2016.3.0. +.B salt.modules.zpool.split(zpool, newzpool, **kwargs) +New in version 2018.3.0. .sp +Splits devices off pool creating newpool. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +All vdevs in pool must be mirrors. At the time of the split, +\fBnewzpool\fP will be a replica of \fBzpool\fP\&. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B zpool +string +Name of storage pool +.TP +.B newzpool +string +Name of new storage pool +.TP +.B mountpoint +string +Sets the mount point for the root dataset +.TP +.B altroot +string +Sets altroot for newzpool +.TP +.B properties +dict +Additional pool properties for newzpool +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq zpool.split datamirror databackup +salt \(aq*\(aq zpool.split datamirror databackup altroot=/backup +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Zpool properties can be specified at the time of creation of the pool +by passing an additional argument called "properties" and specifying +the properties with their respective values in the form of a python +dictionary: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +properties="{\(aqproperty1\(aq: \(aqvalue1\(aq, \(aqproperty2\(aq: \(aqvalue2\(aq}" +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq zpool.split datamirror databackup properties="{\(aqreadonly\(aq: \(aqon\(aq}" +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zpool.status(zpool=None) Return the status of the named zpool .INDENT 7.0 .TP @@ -258027,20 +275644,21 @@ Enables all supported features on the given pool \fBWARNING:\fP .INDENT 7.0 .INDENT 3.5 -Once this is done, the pool will no longer be accessible on systems that do not -support feature flags. See zpool\-features(5) for details on compatibility with -systems that support feature flags, but do not support all features enabled on the pool. +Once this is done, the pool will no longer be accessible on systems +that do not support feature flags. See \fBzpool\-features(5)\fP for +details on compatibility with systems that support feature flags, but +do not support all features enabled on the pool. .UNINDENT .UNINDENT .INDENT 7.0 .TP .B zpool string -optional storage pool, applies to all otherwize +Optional storage pool, applies to all otherwize .TP .B version int -version to upgrade to, if unspecified upgrade to the highest possible +Version to upgrade to, if unspecified upgrade to the highest possible .UNINDENT .sp CLI Example: @@ -258393,6 +276011,11 @@ Skip the GPG verification check (e.g., \fB\-\-no\-gpg\-checks\fP) Can be either a version number, or the combination of a comparison operator (<, >, <=, >=, =) and a version number (ex. \(aq>1.2.3\-4\(aq). This parameter is ignored if \fBpkgs\fP or \fBsources\fP is passed. +.TP +.B resolve_capabilities +If this option is set to True zypper will take capabilites into +account. In this case names which are just provided by a package +will get installed. Default is False. .UNINDENT .sp Multiple Package Installation Options: @@ -258439,6 +276062,35 @@ salt \(aq*\(aq pkg.install sources=\(aq[{"foo": "salt://foo.rpm"},{"bar": "salt: .B ignore_repo_failure Zypper returns error code 106 if one of the repositories are not available for various reasons. In case to set strict check, this parameter needs to be set to True. Default: False. +.TP +.B diff_attr: +If a list of package attributes is specified, returned value will +contain them, eg.: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{\(aq\(aq: { + \(aqold\(aq: { + \(aqversion\(aq: \(aq\(aq, + \(aqarch\(aq: \(aq\(aq}, + + \(aqnew\(aq: { + \(aqversion\(aq: \(aq\(aq, + \(aqarch\(aq: \(aq\(aq}}} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Valid attributes are: \fBepoch\fP, \fBversion\fP, \fBrelease\fP, \fBarch\fP, +\fBinstall_date\fP, \fBinstall_date_time_t\fP\&. +.sp +If \fBall\fP is specified, all valid attributes will be returned. +.sp +New in version 2018.3.0. + .UNINDENT .sp Returns a dict containing the new package names and versions: @@ -258453,6 +276105,26 @@ Returns a dict containing the new package names and versions: .fi .UNINDENT .UNINDENT +.sp +If an attribute list is specified in \fBdiff_attr\fP, the dict will also contain +any specified attribute, eg.: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{\(aq\(aq: { + \(aqold\(aq: { + \(aqversion\(aq: \(aq\(aq, + \(aqarch\(aq: \(aq\(aq}, + + \(aqnew\(aq: { + \(aqversion\(aq: \(aq\(aq, + \(aqarch\(aq: \(aq\(aq}}} +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -258626,8 +276298,8 @@ salt \(aq*\(aq pkg.list_patterns .INDENT 0.0 .TP .B salt.modules.zypper.list_pkgs(versions_as_list=False, **kwargs) -List the packages currently installed as a dict with versions -as a comma separated string: +List the packages currently installed as a dict. By default, the dict +contains versions as a comma separated string: .INDENT 7.0 .INDENT 3.5 .sp @@ -258645,6 +276317,31 @@ If set to true, the versions are provided as a list .sp {\(aq\(aq: [\(aq\(aq, \(aq\(aq]} .TP +.B attr: +If a list of package attributes is specified, returned value will +contain them in addition to version, eg.: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{\(aq\(aq: [{\(aqversion\(aq : \(aqversion\(aq, \(aqarch\(aq : \(aqarch\(aq}]} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Valid attributes are: \fBepoch\fP, \fBversion\fP, \fBrelease\fP, \fBarch\fP, +\fBinstall_date\fP, \fBinstall_date_time_t\fP\&. +.sp +If \fBall\fP is specified, all valid attributes will be returned. +.INDENT 7.0 +.INDENT 3.5 +New in version 2018.3.0. + +.UNINDENT +.UNINDENT +.TP .B removed: not supported .TP @@ -258659,6 +276356,8 @@ CLI Example: .nf .ft C salt \(aq*\(aq pkg.list_pkgs +salt \(aq*\(aq pkg.list_pkgs attr=version,arch +salt \(aq*\(aq pkg.list_pkgs attr=\(aq["version", "arch"]\(aq .ft P .fi .UNINDENT @@ -258697,6 +276396,27 @@ salt \(aq*\(aq pkg.list_products all=True .UNINDENT .INDENT 0.0 .TP +.B salt.modules.zypper.list_provides(**kwargs) +New in version 2018.3.0. + +.sp +List package provides of installed packages as a dict. +{\(aq\(aq: [\(aq\(aq, \(aq\(aq, ...]} +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq pkg.list_provides +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.zypper.list_repos() Lists all repos. .sp @@ -258750,17 +276470,17 @@ alias by which the zypper refers to the repo the URL for zypper to reference .TP .B enabled -enable or disable (True or False) repository, +Enable or disable (True or False) repository, but do not remove if disabled. .TP .B refresh -enable or disable (True or False) auto\-refresh of the repository. +Enable or disable (True or False) auto\-refresh of the repository. .TP .B cache Enable or disable (True or False) RPM files caching. .TP .B gpgcheck -Enable or disable (True or False) GOG check for this repository. +Enable or disable (True or False) GPG check for this repository. .TP .B gpgautoimport Automatically trust and import new repository. @@ -259005,7 +276725,45 @@ salt \(aq*\(aq pkg.remove_lock pkgs=\(aq["foo", "bar"]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.zypper.search(criteria, refresh=False) +.B salt.modules.zypper.resolve_capabilities(pkgs, refresh, **kwargs) +New in version 2018.3.0. + +.sp +Convert name provides in \fBpkgs\fP into real package names if +\fBresolve_capabilities\fP parameter is set to True. In case of +\fBresolve_capabilities\fP is set to False the package list +is returned unchanged. +.INDENT 7.0 +.TP +.B refresh +force a refresh if set to True. +If set to False (default) it depends on zypper if a refresh is +executed. +.TP +.B resolve_capabilities +If this option is set to True the input will be checked if +a package with this name exists. If not, this function will +search for a package which provides this name. If one is found +the output is exchanged with the real package name. +In case this option is set to False (Default) the input will +be returned unchanged. +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq pkg.resolve_capabilities resolve_capabilities=True w3m_ssl +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.zypper.search(criteria, refresh=False, **kwargs) List known packags, available to the system. .INDENT 7.0 .TP @@ -259013,6 +276771,47 @@ List known packags, available to the system. force a refresh if set to True. If set to False (default) it depends on zypper if a refresh is executed. +.TP +.B match (str) +One of \fIexact\fP, \fIwords\fP, \fIsubstrings\fP\&. Search for an \fIexact\fP match +or for the whole \fIwords\fP only. Default to \fIsubstrings\fP to patch +partial words. +.TP +.B provides (bool) +Search for packages which provide the search strings. +.TP +.B recommends (bool) +Search for packages which recommend the search strings. +.TP +.B requires (bool) +Search for packages which require the search strings. +.TP +.B suggests (bool) +Search for packages which suggest the search strings. +.TP +.B conflicts (bool) +Search packages conflicting with search strings. +.TP +.B obsoletes (bool) +Search for packages which obsolete the search strings. +.TP +.B file_list (bool) +Search for a match in the file list of packages. +.TP +.B search_descriptions (bool) +Search also in package summaries and descriptions. +.TP +.B case_sensitive (bool) +Perform case\-sensitive search. +.TP +.B installed_only (bool) +Show only installed packages. +.TP +.B not_installed_only (bool) +Show only packages which are not installed. +.TP +.B details (bool) +Show version and repository .UNINDENT .sp CLI Examples: @@ -259192,22 +276991,77 @@ salt \(aq*\(aq pkg.version_cmp \(aq0.2\-001\(aq \(aq0.2.0.1\-002\(aq .UNINDENT .SS netapi modules .SS rest_cherrypy +.INDENT 0.0 +.IP \(bu 2 +\fI\%A REST API for Salt\fP +.INDENT 2.0 +.IP \(bu 2 +\fI\%Authentication\fP +.IP \(bu 2 +\fI\%Usage\fP +.IP \(bu 2 +\fI\%Content negotiation\fP +.UNINDENT +.IP \(bu 2 +\fI\%Performance Expectations and Recommended Usage\fP +.INDENT 2.0 +.IP \(bu 2 +\fI\%Long\-Running HTTP Connections\fP +.IP \(bu 2 +\fI\%Timeouts\fP +.IP \(bu 2 +\fI\%Best Practices\fP +.IP \(bu 2 +\fI\%Performance Tuning\fP +.IP \(bu 2 +\fI\%Future Plans\fP +.UNINDENT +.IP \(bu 2 +\fI\%Deployment\fP +.INDENT 2.0 +.IP \(bu 2 +\fI\%salt\-api using the CherryPy server\fP +.IP \(bu 2 +\fI\%Using a WSGI\-compliant web server\fP +.UNINDENT +.IP \(bu 2 +\fI\%REST URI Reference\fP +.INDENT 2.0 +.IP \(bu 2 +\fI\%/\fP +.IP \(bu 2 +\fI\%/login\fP +.IP \(bu 2 +\fI\%/logout\fP +.IP \(bu 2 +\fI\%/minions\fP +.IP \(bu 2 +\fI\%/jobs\fP +.IP \(bu 2 +\fI\%/run\fP +.IP \(bu 2 +\fI\%/events\fP +.IP \(bu 2 +\fI\%/hook\fP +.IP \(bu 2 +\fI\%/keys\fP +.IP \(bu 2 +\fI\%/ws\fP +.IP \(bu 2 +\fI\%/stats\fP +.UNINDENT +.UNINDENT .SS A REST API for Salt -.sp -New in version 2014.7.0. - .INDENT 0.0 .TP .B depends .INDENT 7.0 .IP \(bu 2 -CherryPy Python module. Version 3.2.3 is currently recommended when -SSL is enabled, since this version worked the best with SSL in -internal testing. Versions 3.2.3 \- 4.x can be used if SSL is not enabled. -Be aware that there is a known -\fI\%SSL error\fP -introduced in version 3.2.5. The issue was reportedly resolved with -CherryPy milestone 3.3, but the patch was committed for version 3.6.1. +CherryPy Python module. +.sp +Note: there is a \fI\%known SSL traceback for CherryPy versions 3.2.5 through +3.7.x\fP\&. Please use +version 3.2.3 or the latest 10.x version instead. .UNINDENT .TP .B optdepends @@ -259306,9 +277160,15 @@ the underlying code is changed and will output more debugging info. .TP .B log_access_file Path to a file to write HTTP access logs. +.sp +New in version 2016.11.0. + .TP .B log_error_file Path to a file to write HTTP error logs. +.sp +New in version 2016.11.0. + .TP .B ssl_crt The path to a SSL certificate. (See below) @@ -259348,9 +277208,7 @@ True Whether to check for and kill HTTP responses that have exceeded the default timeout. .sp -Deprecated since version 2016.11.9,: 2017.7.3, Oxygen -.sp -The "expire_responses" configuration setting, which corresponds +Deprecated since version 2016.11.9,2017.7.3,2018.3.0: The "expire_responses" configuration setting, which corresponds to the \fBtimeout_monitor\fP setting in CherryPy, is no longer supported in CherryPy versions >= 12.0.0. @@ -259364,6 +277222,13 @@ False Collect and report statistics about the CherryPy server .sp Reports are available via the \fI\%Stats\fP URL. +.TP +.B stats_disable_auth +False +Do not require authentication to access the \fB/stats\fP endpoint. +.sp +New in version 2018.3.0. + .TP .B static A filesystem path to static HTML/JavaScript/CSS/image assets. @@ -259778,6 +277643,94 @@ curl \-ksi http://localhost:8000/login \e .UNINDENT .UNINDENT .UNINDENT +.SS Performance Expectations and Recommended Usage +.sp +This module provides a thin wrapper around Salt\(aqs Python API\&. Executing a Salt command via rest_cherrypy is directly analogous +to executing a Salt command via Salt\(aqs CLI (which also uses the Python API) \-\- +they share the same semantics, performance characteristics, and 98% of the same +code. As a rule\-of\-thumb: if you wouldn\(aqt do it at the CLI don\(aqt do it via this +API. +.SS Long\-Running HTTP Connections +.sp +The CherryPy server is a production\-ready, threading HTTP server written in +Python. Because it makes use of a thread pool to process HTTP requests it is +not ideally suited to maintaining large numbers of concurrent, synchronous +connections. On moderate hardware with default settings it should top\-out at +around 30 to 50 concurrent connections. +.sp +That number of long\-running, synchronous Salt processes is also not ideal. Like +at the CLI, each Salt command run will start a process that instantiates its +own \fBLocalClient\fP, which instantiates its own listener to the Salt event bus, +and sends out its own periodic \fBsaltutil.find_job\fP queries to determine if a +Minion is still running the command. Not exactly a lightweight operation. +.SS Timeouts +.sp +In addition to the above resource overhead for long\-running connections, there +are the usual HTTP timeout semantics for the CherryPy server, any HTTP client +being used, as well as any hardware in between such as proxies, gateways, or +load balancers. rest_cherrypy can be configured not to time\-out long responses +via the \fBexpire_responses\fP setting, and both \fBLocalClient\fP and \fBRunnerClient\fP have their own timeout parameters that may be +passed as top\-level keywords: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +curl \-b /tmp/cookies.txt \-sSi localhost:8000 \-H \(aqContent\-type: application/json\(aq \-d \(aq +[ + { + "client": "local", + "tgt": "*", + "fun": "test.sleep", + "kwarg": {"length": 30}, + "timeout": 60 + }, + { + "client": "runner", + "fun": "test.sleep", + "kwarg": {"s_time": 30}, + "timeout": 60 + } +] +\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Best Practices +.sp +Given the performance overhead and HTTP timeouts for long\-running operations +described above, the most effective and most scalable way to use both Salt and +salt\-api is to run commands asynchronously using the \fBlocal_async\fP, +\fBrunner_async\fP, and \fBwheel_async\fP clients. +.sp +Running async jobs results in being able to process 3x more commands per second +for \fBLocalClient\fP and 17x more commands per second for \fBRunnerClient\fP, in +addition to much less network traffic and memory requirements. Job returns can +be fetched from Salt\(aqs job cache via the \fB/jobs/\fP endpoint, or they can +be collected into a data store using Salt\(aqs Returner system\&. +.sp +The \fB/events\fP endpoint is specifically designed to handle long\-running HTTP +connections and it exposes Salt\(aqs event bus which includes job returns. +Watching this endpoint first, then executing asynchronous Salt commands second, +is the most lightweight and scalable way to use \fBrest_cherrypy\fP while still +receiving job returns in real\-time. But this requires clients that can properly +handle the inherent asynchronicity of that workflow. +.SS Performance Tuning +.sp +The \fBthread_pool\fP and \fBsocket_queue_size\fP settings can be used to increase +the capacity of rest_cherrypy to handle incoming requests. Keep an eye on RAM +usage as well as available file handles while testing changes to these +settings. As salt\-api is a thin wrapper around Salt\(aqs Python API, also keep an +eye on the performance of Salt when testing. +.SS Future Plans +.sp +Now that Salt uses the Tornado concurrency library internally, we plan to +improve performance in the API by taking advantage of existing processes and +event listeners and to use lightweight coroutines to facilitate more +simultaneous HTTP connections and better support for synchronous operations. +That effort can be tracked in \fI\%issue 26505\fP, but until that issue is closed +rest_cherrypy will remain the officially recommended REST API. .SS Deployment .sp The \fBrest_cherrypy\fP netapi module is a standard Python WSGI app. It can be @@ -259787,6 +277740,7 @@ deployed one of two ways. The default configuration is to run this module using \fBsalt\-api\fP to start the Python\-based CherryPy server. This server is lightweight, multi\-threaded, encrypted with SSL, and should be considered production\-ready. +See the section above for performance expectations. .SS Using a WSGI\-compliant web server .sp This module may be deployed on any WSGI\-compliant server such as Apache with @@ -259822,30 +277776,6 @@ An example Apache virtual host configuration: .UNINDENT .UNINDENT .SS REST URI Reference -.INDENT 0.0 -.IP \(bu 2 -\fI\%/\fP -.IP \(bu 2 -\fI\%/login\fP -.IP \(bu 2 -\fI\%/logout\fP -.IP \(bu 2 -\fI\%/minions\fP -.IP \(bu 2 -\fI\%/jobs\fP -.IP \(bu 2 -\fI\%/run\fP -.IP \(bu 2 -\fI\%/events\fP -.IP \(bu 2 -\fI\%/hook\fP -.IP \(bu 2 -\fI\%/keys\fP -.IP \(bu 2 -\fI\%/ws\fP -.IP \(bu 2 -\fI\%/stats\fP -.UNINDENT .SS \fB/\fP .INDENT 0.0 .TP @@ -260731,8 +278661,8 @@ Note, the SSE stream is fast and completely asynchronous and Salt is very fast. If a job is created using a regular POST request, it is possible that the job return will be available on the SSE stream before the response for the POST request arrives. It is important to take that -asynchronity into account when designing an application. Below are some -general guidelines. +asynchronicity into account when designing an application. Below are +some general guidelines. .INDENT 7.0 .IP \(bu 2 Subscribe to the SSE stream _before_ creating any events. @@ -261028,6 +278958,14 @@ New in version 2014.7.0. List all keys or show a specific key .INDENT 7.0 .TP +.B Request Headers +.INDENT 7.0 +.IP \(bu 2 +\fBX\-Auth\-Token\fP \-\- a session token from \fI\%Login\fP\&. +.IP \(bu 2 +\fBAccept\fP \-\- the desired response format. +.UNINDENT +.TP .B Status Codes .INDENT 7.0 .IP \(bu 2 @@ -261768,12 +279706,15 @@ instruct the highstate outputter to omit displaying anything in green, this means that nothing with a result of True and no changes will not be printed .TP .B state_output: -The highstate outputter has six output modes, \fBfull\fP, \fBterse\fP, -\fBmixed\fP, \fBmixed_id\fP, \fBchanges\fP and \fBfilter\fP\&. +The highstate outputter has six output modes, +\fBfull\fP, \fBterse\fP, \fBmixed\fP, \fBchanges\fP and \fBfilter\fP +* The default is set to \fBfull\fP, which will display many lines of detailed .INDENT 7.0 -.IP \(bu 2 -The default is set to \fBfull\fP, which will display many lines of detailed +.INDENT 3.5 information for each executed chunk. +.UNINDENT +.UNINDENT +.INDENT 7.0 .IP \(bu 2 If \fBterse\fP is used, then the output is greatly simplified and shown in only one line. @@ -261781,32 +279722,34 @@ only one line. If \fBmixed\fP is used, then terse output will be used unless a state failed, in which case full output will be used. .IP \(bu 2 -If \fBmixed_id\fP is used, then the mixed form will be used, but the value for \fBname\fP -will be drawn from the state ID. This is useful for cases where the name -value might be very long and hard to read. -.IP \(bu 2 If \fBchanges\fP is used, then terse output will be used if there was no error and no changes, otherwise full output will be used. .IP \(bu 2 If \fBfilter\fP is used, then either or both of two different filters can be used: \fBexclude\fP or \fBterse\fP\&. -* for \fBexclude\fP, state.highstate expects a list of states to be excluded .INDENT 2.0 .INDENT 3.5 -(or \fBNone\fP) +.INDENT 0.0 +.IP \(bu 2 +for \fBexclude\fP, state.highstate expects a list of states to be excluded (or \fBNone\fP) followed by \fBTrue\fP for terse output or \fBFalse\fP for regular output. Because of parsing nuances, if only one of these is used, it must still contain a comma. For instance: \fIexclude=True,\fP\&. -.UNINDENT -.UNINDENT -.INDENT 2.0 .IP \(bu 2 for \fBterse\fP, state.highstate expects simply \fBTrue\fP or \fBFalse\fP\&. .UNINDENT +.UNINDENT +.UNINDENT .sp These can be set as such from the command line, or in the Salt config as \fIstate_output_exclude\fP or \fIstate_output_terse\fP, respectively. .UNINDENT +.sp +The output modes have one modifier: +\fBfull_id\fP, \fBterse_id\fP, \fBmixed_id\fP, \fBchanges_id\fP and \fBfilter_id\fP +If \fB_id\fP is used, then the corresponding form will be used, but the value for \fBname\fP +will be drawn from the state ID. This is useful for cases where the name +value might be very long and hard to read. .TP .B state_tabular: If \fIstate_output\fP uses the terse output, set this to \fITrue\fP for an aligned @@ -261986,7 +279929,7 @@ myminion: .UNINDENT .INDENT 0.0 .TP -.B class salt.output.nested.NestDisplay +.B class salt.output.nested.NestDisplay(retcode=0) Manage the nested display contents .INDENT 7.0 .TP @@ -262304,7 +280247,7 @@ edge01.bjm01: .UNINDENT .INDENT 0.0 .TP -.B class salt.output.table_out.TableDisplay(has_header=True, row_delimiter=\(aq\-\(aq, delim=\(aq | \(aq, justify=\(aqcenter\(aq, separate_rows=True, prefix=\(aq| \(aq, suffix=\(aq |\(aq, width=50, wrapfunc=None) +.B class salt.output.table_out.TableDisplay(has_header=True, row_delimiter=u\(aq\-\(aq, delim=u\(aq | \(aq, justify=u\(aqcenter\(aq, separate_rows=True, prefix=u\(aq| \(aq, suffix=u\(aq |\(aq, width=50, wrapfunc=None) Manage the table display content. .INDENT 7.0 .TP @@ -262323,7 +280266,7 @@ Prepare rows content to be displayed. .UNINDENT .INDENT 7.0 .TP -.B ustring(indent, color, msg, prefix=\(aq\(aq, suffix=\(aq\(aq, endc=None) +.B ustring(indent, color, msg, prefix=u\(aq\(aq, suffix=u\(aq\(aq, endc=None) Build the unicode string to be displayed. .UNINDENT .INDENT 7.0 @@ -263027,6 +280970,9 @@ merge it with the current pillar data .SS salt.pillar.csvpillar module .sp Store key/value pairs in a CSV file +.sp +New in version 2016.11.0. + .sp Example configuration: .INDENT 0.0 @@ -263132,7 +281078,7 @@ Will produce the following Pillar values for a minion named "jerry": .UNINDENT .INDENT 0.0 .TP -.B salt.pillar.csvpillar.ext_pillar(mid, pillar, path, idkey=\(aqid\(aq, namespace=None, fieldnames=None, restkey=None, restval=None, dialect=\(aqexcel\(aq) +.B salt.pillar.csvpillar.ext_pillar(mid, pillar, path, idkey=u\(aqid\(aq, namespace=None, fieldnames=None, restkey=None, restval=None, dialect=u\(aqexcel\(aq) Read a CSV into Pillar .INDENT 7.0 .TP @@ -263491,6 +281437,13 @@ Be careful when using \fBfollow_dir_links\fP, as a recursive symlink chain will result in unexpected results. .UNINDENT .UNINDENT +.sp +Changed in version 2018.3.0: If \fBroot_dir\fP is a relative path, it will be treated as relative to the +\fBpillar_roots\fP of the environment specified by +\fBpillarenv\fP\&. If an environment specifies multiple +roots, this module will search for files relative to all of them, in order, +merging the results. + .sp If \fBkeep_newline\fP is set to \fBTrue\fP, then the pillar values for files ending in newlines will keep that newline. The default behavior is to remove the @@ -263735,15 +281688,6 @@ Read pillar data from Foreman via its API. .SS salt.pillar.git_pillar .SS Use a git repository as a Pillar source .sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -This external pillar has been rewritten for the 2015.8.0 release. The old method of configuring this -external pillar will be maintained for a couple releases, allowing time for -configurations to be updated to reflect the new usage. -.UNINDENT -.UNINDENT -.sp This external pillar allows for a Pillar top file and Pillar SLS files to be sourced from a git repository. .sp @@ -263789,7 +281733,7 @@ qa: .UNINDENT .sp Additionally, while git_pillar allows for the branch/tag to be overridden -(see \fI\%here\fP, or \fI\%here\fP for Salt releases before 2015.8.0), keep in +(see \fI\%here\fP), keep in mind that the top file must reference the actual environment name. It is common practice to make the environment in a git_pillar top file match the branch/tag name, but when remapping, the environment of course no longer @@ -263799,157 +281743,7 @@ common misconfiguration that may be to blame, and is a good first step in troubleshooting. .UNINDENT .UNINDENT -.SS Configuring git_pillar for Salt releases before 2015.8.0 -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -This legacy configuration for git_pillar will no longer be supported as of -the \fBOxygen\fP release of Salt. -.UNINDENT -.UNINDENT -.sp -For Salt releases earlier than 2015.8.0, -GitPython is the only supported provider for git_pillar. Individual -repositories can be configured under the \fBext_pillar\fP -configuration parameter like so: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -ext_pillar: - \- git: master https://gitserver/git\-pillar.git root=subdirectory -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -The repository is specified in the format \fB \fP, with an -optional \fBroot\fP parameter (added in the 2014.7.0 release) which allows the pillar SLS files to be -served up from a subdirectory (similar to \fBgitfs_root\fP in gitfs). -.sp -To use more than one branch from the same repo, multiple lines must be -specified under \fBext_pillar\fP: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -ext_pillar: - \- git: master https://gitserver/git\-pillar.git - \- git: dev https://gitserver/git\-pillar.git -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -To remap a specific branch to a specific Pillar environment, use the format -\fB:\fP: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -ext_pillar: - \- git: develop:dev https://gitserver/git\-pillar.git - \- git: master:prod https://gitserver/git\-pillar.git -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -In this case, the \fBdevelop\fP branch would need its own \fBtop.sls\fP with a -\fBdev\fP section in it, like this: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -dev: - \(aq*\(aq: - \- bar -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -The \fBmaster\fP branch would need its own \fBtop.sls\fP with a \fBprod\fP section in -it: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -prod: - \(aq*\(aq: - \- bar -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -If \fB__env__\fP is specified as the branch name, then git_pillar will first look -at the minion\(aqs \fBenvironment\fP option. If unset, it will fall back -to using branch specified by the master\(aqs \fBgitfs_base\fP: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -ext_pillar: - \- git: __env__ https://gitserver/git\-pillar.git root=pillar -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -The corresponding Pillar top file would look like this: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -{{saltenv}}: - \(aq*\(aq: - \- bar -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -This feature was unintentionally omitted when git_pillar was rewritten for -the 2015.8.0 release. It was added again in the 2016.3.4 release, but it -has changed slightly in that release. On Salt masters running 2015.8.0 -through 2016.3.3, this feature can only be accessed using the legacy config -described above. For 2016.3.4 and later, refer to explanation of the -\fB__env__\fP parameter in the below section. -.sp -Versions 2016.3.0 through 2016.3.4 incorrectly check the \fImaster\(aqs\fP -\fBenvironment\fP config option (instead of the minion\(aqs) before falling back -to \fBgitfs_base\fP\&. This has been fixed in the 2016.3.5 and -2016.11.1 releases (2016.11.0 contains the incorrect behavior). -.sp -Additionally, in releases before 2016.11.0, both \fB{{env}}\fP and -\fB{{saltenv}}\fP could be used as a placeholder for the environment. -Starting in 2016.11.0, \fB{{env}}\fP is no longer supported. -.UNINDENT -.UNINDENT -.SS Configuring git_pillar for Salt releases 2015.8.0 and later -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -In version 2015.8.0, the method of configuring git external pillars has -changed, and now more closely resembles that of the Git Fileserver -Backend\&. If Salt detects the old configuration schema, it -will use the pre\-2015.8.0 code to compile the external pillar. A warning -will also be logged. -.UNINDENT -.UNINDENT +.SS Configuring git_pillar for Salt .sp Beginning with Salt version 2015.8.0, \fI\%pygit2\fP is now supported in addition to \fI\%GitPython\fP\&. The requirements for \fI\%GitPython\fP and \fI\%pygit2\fP are the same as for @@ -264083,36 +281877,6 @@ The corresponding Pillar top file would look like this: .UNINDENT .UNINDENT .sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -This feature was unintentionally omitted when git_pillar was rewritten for -the 2015.8.0 release. It was added again in the 2016.3.4 release, but it -has changed slightly in that release. The fallback value replaced by -\fB{{env}}\fP is :conf_master: is \fBgit_pillar_base\fP, while the -legacy config\(aqs version of this feature replaces \fB{{env}}\fP with -\fBgitfs_base\fP\&. -.sp -On Salt masters running 2015.8.0 through 2016.3.3, this feature can only be -accessed using the legacy config in the previous section of this page. -.sp -The same issue which affected the behavior of the minion\(aqs -\fBenvironment\fP config value using the legacy configuration -syntax (see the documentation in the pre\-2015.8.0 section above for the -legacy support of this feature) also affects the new\-style git_pillar -syntax in version 2016.3.4. This has been corrected in version 2016.3.5 and -2016.11.1 (2016.11.0 contains the incorrect behavior). -.sp -2016.3.4 incorrectly checks the \fImaster\(aqs\fP \fBenvironment\fP config option -(instead of the minion\(aqs) before falling back to the master\(aqs -\fBgit_pillar_base\fP\&. -.sp -Additionally, in releases before 2016.11.0, both \fB{{env}}\fP and -\fB{{saltenv}}\fP could be used as a placeholder for the environment. -Starting in 2016.11.0, \fB{{env}}\fP is no longer supported. -.UNINDENT -.UNINDENT -.sp With the addition of \fI\%pygit2\fP support, git_pillar can now interact with authenticated remotes. Authentication works just like in gitfs (as outlined in the Git Fileserver Backend Walkthrough), only @@ -264326,7 +282090,7 @@ file in the same pillar environment. .UNINDENT .INDENT 0.0 .TP -.B salt.pillar.git_pillar.ext_pillar(minion_id, repo, pillar_dirs) +.B salt.pillar.git_pillar.ext_pillar(minion_id, pillar, *repos) Checkout the ext_pillar sources and compile the resulting pillar SLS .UNINDENT .SS salt.pillar.gpg module @@ -264388,13 +282152,13 @@ Cleanup mercurial command server .UNINDENT .INDENT 7.0 .TP -.B update(branch=\(aqdefault\(aq) +.B update(branch=u\(aqdefault\(aq) Ensure we are using the latest revision in the hg repository .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.pillar.hg_pillar.ext_pillar(minion_id, pillar, repo, branch=\(aqdefault\(aq, root=None) +.B salt.pillar.hg_pillar.ext_pillar(minion_id, pillar, repo, branch=u\(aqdefault\(aq, root=None) Extract pillar from an hg repository .UNINDENT .INDENT 0.0 @@ -264415,7 +282179,7 @@ Execute hiera and return the data A module that adds data to the Pillar structure retrieved by an http request .SS Configuring the HTTP_JSON ext_pillar .sp -Set the following Salt config to setup Foreman as external pillar source: +Set the following Salt config to setup http json result as external pillar source: .INDENT 0.0 .INDENT 3.5 .sp @@ -264431,15 +282195,58 @@ ext_pillar: .fi .UNINDENT .UNINDENT +.sp +If the with_grains parameter is set, grain keys wrapped in can be provided (wrapped +in <> brackets) in the url in order to populate pillar data based on the grain value. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ext_pillar: + \- http_json: + url: http://example.com/api/ + with_grains: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Changed in version 2018.3.0: If %s is present in the url, it will be automaticaly replaced by the minion_id: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ext_pillar: + \- http_json: + url: http://example.com/api/%s +.ft P +.fi +.UNINDENT +.UNINDENT + .SS Module Documentation .INDENT 0.0 .TP -.B salt.pillar.http_json.ext_pillar(minion_id, pillar, url=None) +.B salt.pillar.http_json.ext_pillar(minion_id, pillar, url, with_grains=False) Read pillar data from HTTP response. -.sp -:param url String to make request -:returns dict with pillar data to add -:returns empty if error +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBurl\fP (\fI\%str\fP) \-\- Url to request. +.IP \(bu 2 +\fBwith_grains\fP (\fI\%bool\fP) \-\- Whether to substitute strings in the url with their grain values. +.UNINDENT +.TP +.B Returns +A dictionary of the pillar data to add. +.TP +.B Return type +\fI\%dict\fP +.UNINDENT .UNINDENT .SS salt.pillar.http_yaml module .sp @@ -264462,15 +282269,58 @@ ext_pillar: .fi .UNINDENT .UNINDENT +.sp +If the with_grains parameter is set, grain keys wrapped in can be provided (wrapped +in <> brackets) in the url in order to populate pillar data based on the grain value. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ext_pillar: + \- http_yaml: + url: http://example.com/api/ + with_grains: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Changed in version 2018.3.0: If %s is present in the url, it will be automaticaly replaced by the minion_id: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ext_pillar: + \- http_json: + url: http://example.com/api/%s +.ft P +.fi +.UNINDENT +.UNINDENT + .SS Module Documentation .INDENT 0.0 .TP -.B salt.pillar.http_yaml.ext_pillar(minion_id, pillar, url) +.B salt.pillar.http_yaml.ext_pillar(minion_id, pillar, url, with_grains=False) Read pillar data from HTTP response. -.sp -:param url String to make request -:returns dict with pillar data to add -:returns empty if error +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBurl\fP (\fI\%str\fP) \-\- Url to request. +.IP \(bu 2 +\fBwith_grains\fP (\fI\%bool\fP) \-\- Whether to substitute strings in the url with their grain values. +.UNINDENT +.TP +.B Returns +A dictionary of the pillar data to add. +.TP +.B Return type +\fI\%dict\fP +.UNINDENT .UNINDENT .SS salt.pillar.libvirt .sp @@ -264488,7 +282338,7 @@ Read in the generated libvirt keys .UNINDENT .INDENT 0.0 .TP -.B salt.pillar.libvirt.gen_hyper_keys(minion_id, country=\(aqUS\(aq, state=\(aqUtah\(aq, locality=\(aqSalt Lake City\(aq, organization=\(aqSalted\(aq) +.B salt.pillar.libvirt.gen_hyper_keys(minion_id, country=u\(aqUS\(aq, state=u\(aqUtah\(aq, locality=u\(aqSalt Lake City\(aq, organization=u\(aqSalted\(aq, expiration_days=u\(aq365\(aq) Generate the keys to be used by libvirt hypervisors, this routine gens the keys and applies them to the pillar for the hypervisor minions .UNINDENT @@ -265361,7 +283211,7 @@ dict in your SLS templates. .SS Module Documentation .INDENT 0.0 .TP -.B salt.pillar.mongo.ext_pillar(minion_id, pillar, collection=\(aqpillar\(aq, id_field=\(aq_id\(aq, re_pattern=None, re_replace=\(aq\(aq, fields=None) +.B salt.pillar.mongo.ext_pillar(minion_id, pillar, collection=u\(aqpillar\(aq, id_field=u\(aq_id\(aq, re_pattern=None, re_replace=u\(aq\(aq, fields=None) Connect to a mongo database and read per\-node pillar information. .INDENT 7.0 .TP @@ -265556,6 +283406,22 @@ which contains a list of nodegroups which match for a given minion. New in version 2016.11.0. .SS Command Line +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call pillar.get nodegroups +local: + \- class_infra + \- colo_sj + \- state_active + \- country_US + \- type_saltmaster +.ft P +.fi +.UNINDENT +.UNINDENT .SS Configuring Nodegroups Pillar .INDENT 0.0 .INDENT 3.5 @@ -266260,7 +284126,7 @@ Pillar key to return data into .UNINDENT .INDENT 0.0 .TP -.B salt.pillar.redismod.key_value(minion_id, pillar, pillar_key=\(aqredis_pillar\(aq) +.B salt.pillar.redismod.key_value(minion_id, pillar, pillar_key=u\(aqredis_pillar\(aq) Looks for key in redis matching minion_id, returns a structure based on the data type of the redis key. String for string type, dict for hash type and lists for lists, sets and sorted sets. @@ -266378,7 +284244,7 @@ for each environment rather than specifying multiple_env. This is due to issue #22471 (\fI\%https://github.com/saltstack/salt/issues/22471\fP) .INDENT 0.0 .TP -.B salt.pillar.s3.ext_pillar(minion_id, pillar, bucket, key=None, keyid=None, verify_ssl=True, location=None, multiple_env=False, environment=\(aqbase\(aq, prefix=\(aq\(aq, service_url=None, kms_keyid=None, s3_cache_expire=30, s3_sync_on_update=True, path_style=False, https_enable=True) +.B salt.pillar.s3.ext_pillar(minion_id, pillar, bucket, key=None, keyid=None, verify_ssl=True, location=None, multiple_env=False, environment=u\(aqbase\(aq, prefix=u\(aq\(aq, service_url=None, kms_keyid=None, s3_cache_expire=30, s3_sync_on_update=True, path_style=False, https_enable=True) Execute a command and read the output as YAML .UNINDENT .SS salt.pillar.sql_base module @@ -267780,6 +285646,7 @@ Multiple Vault sources may also be used: ext_pillar: \- vault: path=secret/salt \- vault: path=secret/root + \- vault: path=secret/minions/{minion}/pass .ft P .fi .UNINDENT @@ -268949,6 +286816,11 @@ works. .UNINDENT .INDENT 0.0 .TP +.B salt.proxy.esxi.get_details() +Return the proxy details +.UNINDENT +.INDENT 0.0 +.TP .B salt.proxy.esxi.grains() Get the grains from the proxy device. .UNINDENT @@ -268967,8 +286839,9 @@ the protocol and port are cached. .INDENT 0.0 .TP .B salt.proxy.esxi.ping() -Check to see if the host is responding. Returns False if the host didn\(aqt -respond, True otherwise. +Returns True if connection is to be done via a vCenter (no connection is attempted). +Check to see if the host is responding when connecting directly via an ESXi +host. .sp CLI Example: .INDENT 7.0 @@ -269340,6 +287213,14 @@ salt\-proxy \-\-proxyid=vmx .ft P .fi .UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.proxy.junos.alive(opts) +Validate and return the connection status with the remote device. +.sp +New in version 2018.3.0. + .UNINDENT .INDENT 0.0 .TP @@ -269885,7 +287766,7 @@ Run command through switch\(aqs cli .UNINDENT .INDENT 0.0 .TP -.B salt.proxy.nxos.set_password(username, password, encrypted=False, role=None, crypt_salt=None, algorithm=\(aqsha256\(aq) +.B salt.proxy.nxos.set_password(username, password, encrypted=False, role=None, crypt_salt=None, algorithm=u\(aqsha256\(aq) Set users password on switch .INDENT 7.0 .INDENT 3.5 @@ -269987,6 +287868,24 @@ Philips HUE lamps module for proxy. .sp New in version 2015.8.3. +.sp +First create a new user on the Hue bridge by following the +\fI\%Meet hue\fP instructions. +.sp +To configure the proxy minion: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +proxy: + proxytype: philips_hue + host: [hostname or ip] + user: [username] +.ft P +.fi +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B class salt.proxy.philips_hue.Const @@ -270621,7 +288520,7 @@ Return a list of Salt Queues on the Salt Master .UNINDENT .INDENT 0.0 .TP -.B salt.queues.pgjsonb_queue.pop(queue, quantity=1) +.B salt.queues.pgjsonb_queue.pop(queue, quantity=1, is_runner=False) Pop one or more or all items from the queue return them. .UNINDENT .SS salt.queues.sqlite_queue module @@ -270681,7 +288580,7 @@ Return a list of Salt Queues on the Salt Master .UNINDENT .INDENT 0.0 .TP -.B salt.queues.sqlite_queue.pop(queue, quantity=1) +.B salt.queues.sqlite_queue.pop(queue, quantity=1, is_runner=False) Pop one or more or all items from the queue return them. .UNINDENT .SS roster modules @@ -270846,17 +288745,17 @@ salt.gtmanfred.com: Any of the [groups] or direct hostnames will return. The \(aqall\(aq is special, and returns everything. .INDENT 0.0 .TP -.B class salt.roster.ansible.Inventory(tgt, tgt_type=\(aqglob\(aq, inventory_file=\(aq/etc/salt/roster\(aq) +.B class salt.roster.ansible.Inventory(tgt, tgt_type=u\(aqglob\(aq, inventory_file=u\(aq/etc/salt/roster\(aq) Matcher for static inventory files .UNINDENT .INDENT 0.0 .TP -.B class salt.roster.ansible.Script(tgt, tgt_type=\(aqglob\(aq, inventory_file=\(aq/etc/salt/roster\(aq) +.B class salt.roster.ansible.Script(tgt, tgt_type=u\(aqglob\(aq, inventory_file=u\(aq/etc/salt/roster\(aq) Matcher for Inventory scripts .UNINDENT .INDENT 0.0 .TP -.B salt.roster.ansible.targets(tgt, tgt_type=\(aqglob\(aq, **kwargs) +.B salt.roster.ansible.targets(tgt, tgt_type=u\(aqglob\(aq, **kwargs) Return the targets from the ansible inventory_file Default: /etc/salt/roster .UNINDENT @@ -270894,16 +288793,12 @@ overriding the one in \fBroster_defaults\fP: .sp .nf .ft C - +roster_order: + host: id # use the minion id as hostname .ft P .fi .UNINDENT .UNINDENT -.INDENT 0.0 -.TP -.B roster_order: -host: id # use the minion id as hostname -.UNINDENT .sp You can define lists of parameters as well, the first result from the list will become the value. .SS Selecting a host @@ -270912,32 +288807,16 @@ You can define lists of parameters as well, the first result from the list will .sp .nf .ft C - -.ft P -.fi -.UNINDENT -.UNINDENT -.sp # default roster_order: -.INDENT 0.0 -.INDENT 3.5 -.INDENT 0.0 -.TP -.B host: -.INDENT 7.0 -.IP \(bu 2 -ipv6\-private # IPv6 addresses in private ranges -.IP \(bu 2 -ipv6\-global # IPv6 addresses in global ranges -.IP \(bu 2 -ipv4\-private # IPv4 addresses in private ranges -.IP \(bu 2 -ipv4\-public # IPv4 addresses in public ranges -.IP \(bu 2 -ipv4\-local # loopback addresses -.UNINDENT -.UNINDENT + host: + \- ipv6\-private # IPv6 addresses in private ranges + \- ipv6\-global # IPv6 addresses in global ranges + \- ipv4\-private # IPv4 addresses in private ranges + \- ipv4\-public # IPv4 addresses in public ranges + \- ipv4\-local # loopback addresses +.ft P +.fi .UNINDENT .UNINDENT .sp @@ -270951,25 +288830,14 @@ Other address selection parameters are also possible: .sp .nf .ft C - +roster_order: + host: + \- global|public|private|local # Both IPv6 and IPv4 addresses in that range + \- 2000::/3 # CIDR networks, both IPv4 and IPv6 are supported .ft P .fi .UNINDENT .UNINDENT -.INDENT 0.0 -.TP -.B roster_order: -.INDENT 7.0 -.TP -.B host: -.INDENT 7.0 -.IP \(bu 2 -global|public|private|local # Both IPv6 and IPv4 addresses in that range -.IP \(bu 2 -2000::/3 # CIDR networks, both IPv4 and IPv6 are supported -.UNINDENT -.UNINDENT -.UNINDENT .SS Using cached data .sp Several cached libraries can be selected using the \fBlibrary: \(ga\(ga prefix, followed by the library key. @@ -270982,55 +288850,28 @@ This should be especially useful for the other roster keys: .sp .nf .ft C +roster_order: + host: + \- grain: fqdn_ip4 # Lookup this grain + \- mine: network.ip_addrs # Mine data lookup works the same + password: sdb://vault/ssh_pass # Salt SDB URLs are also supported + + user: + \- pillar: ssh:auth:user # Lookup this pillar key + \- sdb://osenv/USER # Lookup this env var through sdb + + priv: + \- pillar: # Lists are also supported + \- salt:ssh:private_key + \- ssh:auth:private_key .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B roster_order: -.INDENT 7.0 -.TP -.B host: -.INDENT 7.0 -.IP \(bu 2 -grain: fqdn_ip4 # Lookup this grain -.IP \(bu 2 -mine: network.ip_addrs # Mine data lookup works the same -.UNINDENT -.UNINDENT -.sp -password: sdb://vault/ssh_pass # Salt SDB URLs are also supported -.INDENT 7.0 -.TP -.B user: -.INDENT 7.0 -.IP \(bu 2 -pillar: \fI\%ssh:auth:user\fP # Lookup this pillar key -.IP \(bu 2 -sdb://osenv/USER # Lookup this env var through sdb -.UNINDENT -.TP -.B priv: -.INDENT 7.0 -.IP \(bu 2 -.INDENT 2.0 -.TP -.B pillar: # Lists are also supported -.INDENT 7.0 -.IP \(bu 2 -salt:ssh:private_key -.IP \(bu 2 -\fI\%ssh:auth:private_key\fP -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.roster.cache.targets(tgt, tgt_type=\(aqglob\(aq, **kwargs) +.B salt.roster.cache.targets(tgt, tgt_type=u\(aqglob\(aq, **kwargs) Return the targets from the Salt Masters\(aq minion cache. All targets and matchers are supported. .sp @@ -271067,7 +288908,7 @@ Extract the preferred IP address from the ipv4 grain .UNINDENT .INDENT 0.0 .TP -.B salt.roster.cloud.targets(tgt, tgt_type=\(aqglob\(aq, **kwargs) +.B salt.roster.cloud.targets(tgt, tgt_type=u\(aqglob\(aq, **kwargs) Return the targets from the flat yaml file, checks opts for location but defaults to /etc/salt/roster .UNINDENT @@ -271093,7 +288934,7 @@ salt\-ssh \-\-roster clustershell \(aqserver_[1\-10,21\-30],test_server[5,7,9]\( .UNINDENT .INDENT 0.0 .TP -.B salt.roster.clustershell.targets(tgt, tgt_type=\(aqglob\(aq, **kwargs) +.B salt.roster.clustershell.targets(tgt, tgt_type=u\(aqglob\(aq, **kwargs) Return the targets .UNINDENT .SS salt.roster.flat @@ -271101,7 +288942,7 @@ Return the targets Read in the roster from a flat file using the renderer system .INDENT 0.0 .TP -.B class salt.roster.flat.RosterMatcher(raw, tgt, tgt_type, ipv=\(aqipv4\(aq) +.B class salt.roster.flat.RosterMatcher(raw, tgt, tgt_type, ipv=u\(aqipv4\(aq) Matcher for the roster data structure .INDENT 7.0 .TP @@ -271142,7 +288983,7 @@ Execute the correct tgt_type routine and return .UNINDENT .INDENT 0.0 .TP -.B salt.roster.flat.targets(tgt, tgt_type=\(aqglob\(aq, **kwargs) +.B salt.roster.flat.targets(tgt, tgt_type=u\(aqglob\(aq, **kwargs) Return the targets from the flat yaml file, checks opts for location but defaults to /etc/salt/roster .UNINDENT @@ -271168,7 +289009,7 @@ salt\-ssh \-\-roster range \(aq%%%example.range.cluster\(aq test.ping .UNINDENT .INDENT 0.0 .TP -.B salt.roster.range.targets(tgt, tgt_type=\(aqrange\(aq, **kwargs) +.B salt.roster.range.targets(tgt, tgt_type=u\(aqrange\(aq, **kwargs) Return the targets from a range query .UNINDENT .SS salt.roster.scan @@ -271187,7 +289028,7 @@ it is the default .UNINDENT .INDENT 0.0 .TP -.B salt.roster.scan.targets(tgt, tgt_type=\(aqglob\(aq, **kwargs) +.B salt.roster.scan.targets(tgt, tgt_type=u\(aqglob\(aq, **kwargs) Return the targets from the flat yaml file, checks opts for location but defaults to /etc/salt/roster .UNINDENT @@ -271325,7 +289166,7 @@ _ T{ \fBnacl\fP T} T{ -This runner helps create encrypted passwords that can be included in pillars. +This module helps include encrypted passwords in pillars, grains and salt state files. T} _ T{ @@ -271379,7 +289220,7 @@ _ T{ \fBsaltutil\fP T} T{ -Sync custom types to the Master +The Saltutil runner is used to sync custom types to the Master. T} _ T{ @@ -271395,12 +289236,6 @@ Runner for SmartOS minions control vmadm T} _ T{ -\fBsearch\fP -T} T{ -Runner frontend to search system -T} -_ -T{ \fBspacewalk\fP T} T{ Spacewalk Runner @@ -271858,7 +289693,7 @@ ________________________________________________________________________________ Return cached data from minions .INDENT 0.0 .TP -.B salt.runners.cache.clear_all(tgt=None, tgt_type=\(aqglob\(aq, expr_form=None) +.B salt.runners.cache.clear_all(tgt=None, tgt_type=u\(aqglob\(aq, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -271908,25 +289743,29 @@ have their lock cleared. For example, a \fBremote\fP value of \fBgithub\fP will remove the lock from all github.com remotes. .TP .B type -update,checkout -The types of lock to clear. Can be \fBupdate\fP, \fBcheckout\fP, or both of -.UNINDENT +update,checkout,mountpoint +The types of lock to clear. Can be one or more of \fBupdate\fP, +\fBcheckout\fP, and \fBmountpoint\fP, and can be passed either as a +comma\-separated or Python list. .sp -et (either comma\-separated or as a Python list). -.INDENT 7.0 -.INDENT 3.5 New in version 2015.8.8. -.UNINDENT +.sp +Changed in version 2018.3.0: \fBmountpoint\fP lock type added + .UNINDENT .sp -CLI Example: +CLI Examples: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C +salt\-run cache.clear_git_lock gitfs salt\-run cache.clear_git_lock git_pillar +salt\-run cache.clear_git_lock git_pillar type=update +salt\-run cache.clear_git_lock git_pillar type=update,checkout +salt\-run cache.clear_git_lock git_pillar type=\(aq["update", "mountpoint"]\(aq .ft P .fi .UNINDENT @@ -271934,7 +289773,7 @@ salt\-run cache.clear_git_lock git_pillar .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cache.clear_grains(tgt=None, tgt_type=\(aqglob\(aq, expr_form=None) +.B salt.runners.cache.clear_grains(tgt=None, tgt_type=u\(aqglob\(aq, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -271955,7 +289794,7 @@ salt\-run cache.clear_grains .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cache.clear_mine(tgt=None, tgt_type=\(aqglob\(aq, expr_form=None) +.B salt.runners.cache.clear_mine(tgt=None, tgt_type=u\(aqglob\(aq, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -271976,7 +289815,7 @@ salt\-run cache.clear_mine .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cache.clear_mine_func(tgt=None, tgt_type=\(aqglob\(aq, clear_mine_func_flag=None, expr_form=None) +.B salt.runners.cache.clear_mine_func(tgt=None, tgt_type=u\(aqglob\(aq, clear_mine_func_flag=None, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -271997,7 +289836,7 @@ salt\-run cache.clear_mine_func tgt=\(aq*\(aq clear_mine_func_flag=\(aqnetwork.i .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cache.clear_pillar(tgt=None, tgt_type=\(aqglob\(aq, expr_form=None) +.B salt.runners.cache.clear_pillar(tgt=None, tgt_type=u\(aqglob\(aq, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -272087,7 +289926,7 @@ salt\-run cache.flush cloud/active/ec2/myec2 myminion cachedir=/var/cache/salt/ .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cache.grains(tgt=None, tgt_type=\(aqglob\(aq, **kwargs) +.B salt.runners.cache.grains(tgt=None, tgt_type=u\(aqglob\(aq, **kwargs) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -272125,7 +289964,7 @@ salt\-run cache.list cloud/active/ec2/myec2 cachedir=/var/cache/salt/ .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cache.mine(tgt=None, tgt_type=\(aqglob\(aq, **kwargs) +.B salt.runners.cache.mine(tgt=None, tgt_type=u\(aqglob\(aq, **kwargs) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -272146,7 +289985,7 @@ salt\-run cache.mine .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cache.pillar(tgt=None, tgt_type=\(aqglob\(aq, **kwargs) +.B salt.runners.cache.pillar(tgt=None, tgt_type=u\(aqglob\(aq, **kwargs) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -272189,7 +290028,7 @@ This runner wraps the functionality of salt cloud making salt cloud routines available to all internal apis via the runner system .INDENT 0.0 .TP -.B salt.runners.cloud.action(func=None, cloudmap=None, instances=None, provider=None, instance=None, **kwargs) +.B salt.runners.cloud.action(func=None, cloudmap=None, instances=None, provider=None, instance=None, opts=None, **kwargs) Execute a single action on the given map/provider/instance .sp CLI Example: @@ -272223,32 +290062,32 @@ salt\-run cloud.create my\-ec2\-config myinstance image=ami\-1624987 .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cloud.destroy(instances) +.B salt.runners.cloud.destroy(instances, opts=None) Destroy the named vm(s) .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cloud.full_query(query_type=\(aqlist_nodes_full\(aq) +.B salt.runners.cloud.full_query(query_type=u\(aqlist_nodes_full\(aq) List all available cloud provider data .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cloud.list_images(provider=\(aqall\(aq) +.B salt.runners.cloud.list_images(provider=u\(aqall\(aq) List cloud provider images for the given providers .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cloud.list_locations(provider=\(aqall\(aq) +.B salt.runners.cloud.list_locations(provider=u\(aqall\(aq) List cloud provider sizes for the given providers .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cloud.list_sizes(provider=\(aqall\(aq) +.B salt.runners.cloud.list_sizes(provider=u\(aqall\(aq) List cloud provider sizes for the given providers .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cloud.map_run(path=None, **kwargs) +.B salt.runners.cloud.map_run(path=None, opts=None, **kwargs) Execute a salt cloud map file .UNINDENT .INDENT 0.0 @@ -272271,12 +290110,12 @@ salt\-run cloud.profile prof=my\-ec2 instances=node1,node2,node3 .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cloud.query(query_type=\(aqlist_nodes\(aq) +.B salt.runners.cloud.query(query_type=u\(aqlist_nodes\(aq) List cloud provider data for all providers .UNINDENT .INDENT 0.0 .TP -.B salt.runners.cloud.select_query(query_type=\(aqlist_nodes_select\(aq) +.B salt.runners.cloud.select_query(query_type=u\(aqlist_nodes_select\(aq) List selected nodes .UNINDENT .SS salt.runners.ddns @@ -272293,7 +290132,7 @@ Nitin Madhok <\fI\%nmadhok@clemson.edu\fP> .UNINDENT .INDENT 0.0 .TP -.B salt.runners.ddns.add_host(zone, name, ttl, ip, keyname, keyfile, nameserver, timeout, port=53, keyalgorithm=\(aqhmac\-md5\(aq) +.B salt.runners.ddns.add_host(zone, name, ttl, ip, keyname, keyfile, nameserver, timeout, port=53, keyalgorithm=u\(aqhmac\-md5\(aq) Create both A and PTR (reverse) records for a host. .sp CLI Example: @@ -272310,7 +290149,7 @@ salt\-run ddns.add_host domain.com my\-test\-vm 3600 10.20.30.40 my\-tsig\-key / .UNINDENT .INDENT 0.0 .TP -.B salt.runners.ddns.create(zone, name, ttl, rdtype, data, keyname, keyfile, nameserver, timeout, port=53, keyalgorithm=\(aqhmac\-md5\(aq) +.B salt.runners.ddns.create(zone, name, ttl, rdtype, data, keyname, keyfile, nameserver, timeout, port=53, keyalgorithm=u\(aqhmac\-md5\(aq) Create a DNS record. The nameserver must be an IP address and the master running this runner must have create privileges on that server. .sp @@ -272328,7 +290167,7 @@ salt\-run ddns.create domain.com my\-test\-vm 3600 A 10.20.30.40 my\-tsig\-key / .UNINDENT .INDENT 0.0 .TP -.B salt.runners.ddns.delete(zone, name, keyname, keyfile, nameserver, timeout, rdtype=None, data=None, port=53, keyalgorithm=\(aqhmac\-md5\(aq) +.B salt.runners.ddns.delete(zone, name, keyname, keyfile, nameserver, timeout, rdtype=None, data=None, port=53, keyalgorithm=u\(aqhmac\-md5\(aq) Delete a DNS record. .sp CLI Example: @@ -272345,7 +290184,7 @@ salt\-run ddns.delete domain.com my\-test\-vm my\-tsig\-key /etc/salt/tsig.keyri .UNINDENT .INDENT 0.0 .TP -.B salt.runners.ddns.delete_host(zone, name, keyname, keyfile, nameserver, timeout, port=53, keyalgorithm=\(aqhmac\-md5\(aq) +.B salt.runners.ddns.delete_host(zone, name, keyname, keyfile, nameserver, timeout, port=53, keyalgorithm=u\(aqhmac\-md5\(aq) Delete both forward (A) and reverse (PTR) records for a host only if the forward (A) record exists. .sp @@ -272363,7 +290202,7 @@ salt\-run ddns.delete_host domain.com my\-test\-vm my\-tsig\-key /etc/salt/tsig. .UNINDENT .INDENT 0.0 .TP -.B salt.runners.ddns.update(zone, name, ttl, rdtype, data, keyname, keyfile, nameserver, timeout, replace=False, port=53, keyalgorithm=\(aqhmac\-md5\(aq) +.B salt.runners.ddns.update(zone, name, ttl, rdtype, data, keyname, keyfile, nameserver, timeout, replace=False, port=53, keyalgorithm=u\(aqhmac\-md5\(aq) Replace, or update a DNS record. The nameserver must be an IP address and the master running this runner must have update privileges on that server. .sp @@ -272452,7 +290291,7 @@ salt\-run digicert.del_cached_domain domain1.example.com,domain2.example.com .UNINDENT .INDENT 0.0 .TP -.B salt.runners.digicertapi.gen_csr(minion_id, dns_name, organization_id, ou_name=None, key_len=2048, shatype=\(aqsha256\(aq, password=None) +.B salt.runners.digicertapi.gen_csr(minion_id, dns_name, organization_id, ou_name=None, key_len=2048, shatype=u\(aqsha256\(aq, password=None) CLI Example: .INDENT 7.0 .INDENT 3.5 @@ -272485,7 +290324,7 @@ salt\-run digicert.gen_key [dns_name] [password] .UNINDENT .INDENT 0.0 .TP -.B salt.runners.digicertapi.get_certificate(order_id=None, certificate_id=None, minion_id=None, cert_format=\(aqpem_all\(aq, filename=None) +.B salt.runners.digicertapi.get_certificate(order_id=None, certificate_id=None, minion_id=None, cert_format=u\(aqpem_all\(aq, filename=None) Retrieve a certificate by order_id or certificate_id and write it to stdout or a filename. .INDENT 7.0 .TP @@ -272851,7 +290690,7 @@ salt\-run drac.version example.com Error generator to enable integration testing of salt runner error handling .INDENT 0.0 .TP -.B salt.runners.error.error(name=None, message=\(aq\(aq) +.B salt.runners.error.error(name=None, message=u\(aq\(aq) If name is None Then return empty dict .sp Otherwise raise an exception with __name__ from name, message from message @@ -273062,7 +290901,7 @@ salt\-run f5.check_virtualserver load_balancer virtual_server .UNINDENT .INDENT 0.0 .TP -.B salt.runners.f5.create_pool(lb, name, method=\(aqROUND_ROBIN\(aq) +.B salt.runners.f5.create_pool(lb, name, method=u\(aqROUND_ROBIN\(aq) Create a pool on the F5 load balancer .sp CLI Examples: @@ -273292,7 +291131,7 @@ salt\-run fileserver.clear_lock remote=bitbucket .UNINDENT .INDENT 0.0 .TP -.B salt.runners.fileserver.dir_list(saltenv=\(aqbase\(aq, backend=None) +.B salt.runners.fileserver.dir_list(saltenv=u\(aqbase\(aq, backend=None) Return a list of directories in the given environment .INDENT 7.0 .TP @@ -273330,7 +291169,7 @@ salt\-run fileserver.dir_list \-git .UNINDENT .INDENT 0.0 .TP -.B salt.runners.fileserver.empty_dir_list(saltenv=\(aqbase\(aq, backend=None) +.B salt.runners.fileserver.empty_dir_list(saltenv=u\(aqbase\(aq, backend=None) New in version 2015.5.0. .sp @@ -273412,7 +291251,7 @@ salt\-run fileserver.envs git .UNINDENT .INDENT 0.0 .TP -.B salt.runners.fileserver.file_list(saltenv=\(aqbase\(aq, backend=None) +.B salt.runners.fileserver.file_list(saltenv=u\(aqbase\(aq, backend=None) Return a list of files from the salt fileserver .INDENT 7.0 .TP @@ -273491,7 +291330,7 @@ salt\-run fileserver.lock remote=bitbucket .UNINDENT .INDENT 0.0 .TP -.B salt.runners.fileserver.symlink_list(saltenv=\(aqbase\(aq, backend=None) +.B salt.runners.fileserver.symlink_list(saltenv=u\(aqbase\(aq, backend=None) Return a list of symlinked files and dirs .INDENT 7.0 .TP @@ -273571,18 +291410,18 @@ Runner module to directly manage the git external pillar New in version 2014.1.0. .sp -Changed in version 2015.8.4: This runner function now supports the new git_pillar +Changed in version 2015.8.4: This runner function now supports the git_pillar configuration schema introduced in 2015.8.0. Additionally, the branch and repo can now be omitted to -update all git_pillar remotes. The return data has also changed. For -releases 2015.8.3 and earlier, there is no value returned. Starting -with 2015.8.4, the return data is a dictionary. If using the old -git_pillar configuration schema, then the -dictionary values will be \fBTrue\fP if the update completed without -error, and \fBFalse\fP if an error occurred. If using the new -git_pillar configuration schema, the -values will be \fBTrue\fP only if new commits were fetched, and \fBFalse\fP -if there were errors or no new commits were fetched. +update all git_pillar remotes. The return data has also changed to +a dictionary. The values will be \fBTrue\fP only if new commits were +fetched, and \fBFalse\fP if there were errors or no new commits were +fetched. + +.sp +Changed in version 2018.3.0: The return for a given git_pillar remote will now be \fBNone\fP when no +changes were fetched. \fBFalse\fP now is reserved only for instances in +which there were errors. .sp Fetch one or all configured git_pillar remotes. @@ -273612,7 +291451,7 @@ CLI Example: .ft C # Update specific branch and repo salt\-run git_pillar.update branch=\(aqbranch\(aq repo=\(aqhttps://foo.com/bar.git\(aq -# Update all repos (2015.8.4 and later) +# Update all repos salt\-run git_pillar.update # Run with debug logging salt\-run git_pillar.update \-l debug @@ -273732,10 +291571,14 @@ The external job cache to use. Default: \fINone\fP\&. .UNINDENT .sp CLI Example: -.. code\-block:: bash .INDENT 7.0 .INDENT 3.5 +.sp +.nf +.ft C salt\-run jobs.exit_success 20160520145827701627 +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT @@ -274418,7 +292261,7 @@ salt\-run manage.allowed .UNINDENT .INDENT 0.0 .TP -.B salt.runners.manage.bootstrap(version=\(aqdevelop\(aq, script=None, hosts=\(aq\(aq, root_user=False, script_args=\(aq\(aq, roster=\(aqflat\(aq, ssh_user=None, ssh_password=None, ssh_priv_key=None, tmp_dir=\(aq/tmp/.bootstrap\(aq, http_backend=\(aqtornado\(aq) +.B salt.runners.manage.bootstrap(version=u\(aqdevelop\(aq, script=None, hosts=u\(aq\(aq, script_args=u\(aq\(aq, roster=u\(aqflat\(aq, ssh_user=None, ssh_password=None, ssh_priv_key=None, tmp_dir=u\(aq/tmp/.bootstrap\(aq, http_backend=u\(aqtornado\(aq) Bootstrap minions with salt\-bootstrap .INDENT 7.0 .TP @@ -274433,17 +292276,6 @@ URL containing the script to execute .B hosts Comma\-separated hosts [example: hosts=\(aqhost1.local,host2.local\(aq]. These hosts need to exist in the specified roster. -.TP -.B root_user -False -Prepend \fBroot@\fP to each host. Default changed in Salt 2016.11.0 from \fBTrue\fP -to \fBFalse\fP\&. -.sp -Changed in version 2016.11.0. - -.sp -Deprecated since version Oxygen. - .TP .B script_args Any additional arguments that you want to pass to the script. @@ -274513,7 +292345,6 @@ CLI Example: salt\-run manage.bootstrap hosts=\(aqhost1,host2\(aq salt\-run manage.bootstrap hosts=\(aqhost1,host2\(aq version=\(aqv0.17\(aq salt\-run manage.bootstrap hosts=\(aqhost1,host2\(aq version=\(aqv0.17\(aq script=\(aqhttps://bootstrap.saltstack.com/develop\(aq -salt\-run manage.bootstrap hosts=\(aqec2\-user@host1,ec2\-user@host2\(aq root_user=False .ft P .fi .UNINDENT @@ -274521,7 +292352,7 @@ salt\-run manage.bootstrap hosts=\(aqec2\-user@host1,ec2\-user@host2\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.runners.manage.bootstrap_psexec(hosts=\(aq\(aq, master=None, version=None, arch=\(aqwin32\(aq, installer_url=None, username=None, password=None) +.B salt.runners.manage.bootstrap_psexec(hosts=u\(aq\(aq, master=None, version=None, arch=u\(aqwin32\(aq, installer_url=None, username=None, password=None) Bootstrap Windows minions via PsExec. .INDENT 7.0 .TP @@ -274565,7 +292396,7 @@ salt\-run manage.bootstrap_psexec hosts=\(aqhost1,host2\(aq installer_url=\(aqht .UNINDENT .INDENT 0.0 .TP -.B salt.runners.manage.down(removekeys=False, tgt=\(aq*\(aq, tgt_type=\(aqglob\(aq, expr_form=None) +.B salt.runners.manage.down(removekeys=False, tgt=u\(aq*\(aq, tgt_type=u\(aqglob\(aq, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -274589,7 +292420,7 @@ salt\-run manage.down tgt="webservers" tgt_type="nodegroup" .UNINDENT .INDENT 0.0 .TP -.B salt.runners.manage.get_stats(estate=None, stack=\(aqroad\(aq) +.B salt.runners.manage.get_stats(estate=None, stack=u\(aqroad\(aq) Print the stack stats .INDENT 7.0 .TP @@ -275012,7 +292843,7 @@ salt\-run manage.road_stats [estate=alpha_minion] .UNINDENT .INDENT 0.0 .TP -.B salt.runners.manage.safe_accept(target, tgt_type=\(aqglob\(aq, expr_form=None) +.B salt.runners.manage.safe_accept(target, tgt_type=u\(aqglob\(aq, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -275034,7 +292865,7 @@ salt\-run manage.safe_accept minion1,minion2 tgt_type=list .UNINDENT .INDENT 0.0 .TP -.B salt.runners.manage.status(output=True, tgt=\(aq*\(aq, tgt_type=\(aqglob\(aq, expr_form=None, timeout=None, gather_job_timeout=None) +.B salt.runners.manage.status(output=True, tgt=u\(aq*\(aq, tgt_type=u\(aqglob\(aq, expr_form=None, timeout=None, gather_job_timeout=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -275057,7 +292888,7 @@ salt\-run manage.status timeout=5 gather_job_timeout=10 .UNINDENT .INDENT 0.0 .TP -.B salt.runners.manage.up(tgt=\(aq*\(aq, tgt_type=\(aqglob\(aq, expr_form=None, timeout=None, gather_job_timeout=None) +.B salt.runners.manage.up(tgt=u\(aq*\(aq, tgt_type=u\(aqglob\(aq, expr_form=None, timeout=None, gather_job_timeout=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -275160,7 +292991,7 @@ salt\-run mattermost.post_message message=\(aqBuild is done\(aq A runner to access data from the salt mine .INDENT 0.0 .TP -.B salt.runners.mine.get(tgt, fun, tgt_type=\(aqglob\(aq) +.B salt.runners.mine.get(tgt, fun, tgt_type=u\(aqglob\(aq) Gathers the data from the specified minions\(aq mine, pass in the target, function to look up and the target type .sp @@ -275178,7 +293009,7 @@ salt\-run mine.get \(aq*\(aq network.interfaces .UNINDENT .INDENT 0.0 .TP -.B salt.runners.mine.update(tgt, tgt_type=\(aqglob\(aq, clear=False, mine_functions=None) +.B salt.runners.mine.update(tgt, tgt_type=u\(aqglob\(aq, clear=False, mine_functions=None) New in version 2017.7.0. .sp @@ -275218,7 +293049,7 @@ salt\-run mine.update \(aqjuniper\-edges\(aq tgt_type=\(aqnodegroup\(aq .UNINDENT .SS salt.runners.nacl .sp -This runner helps create encrypted passwords that can be included in pillars. +This module helps include encrypted passwords in pillars, grains and salt state files. .INDENT 0.0 .TP .B depends @@ -275229,29 +293060,230 @@ This is often useful if you wish to store your pillars in source control or share your pillar data with others that you trust. I don\(aqt advise making your pillars public regardless if they are encrypted or not. .sp -The following configurations can be defined in the master config -so your users can create encrypted passwords using the runner nacl: +When generating keys and encrypting passwords use \-\-local when using salt\-call for extra +security. Also consider using just the salt runner nacl when encrypting pillar passwords. .INDENT 0.0 +.TP +.B configuration +The following configuration defaults can be +define (pillar or config files) Avoid storing private keys in pillars! Ensure master does not have \fIpillar_opts=True\fP: +.INDENT 7.0 .INDENT 3.5 .sp .nf .ft C -cat /etc/salt/master.d/nacl.conf +# cat /etc/salt/master.d/nacl.conf nacl.config: - key: \(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k=\(aq - keyfile: /root/.nacl + # NOTE: \(gakey\(ga and \(gakey_file\(ga have been renamed to \(gask\(ga, \(gask_file\(ga + # also \(gabox_type\(ga default changed from secretbox to sealedbox. + box_type: sealedbox (default) + sk_file: /etc/salt/pki/master/nacl (default) + pk_file: /etc/salt/pki/master/nacl.pub (default) + sk: None + pk: None .ft P .fi .UNINDENT .UNINDENT .sp -Now with the config in the master you can use the runner nacl like: +Usage can override the config defaults: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call nacl.enc sk_file=/etc/salt/pki/master/nacl pk_file=/etc/salt/pki/master/nacl.pub +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.sp +The nacl lib uses 32byte keys, these keys are base64 encoded to make your life more simple. +To generate your \fIsk_file\fP and \fIpk_file\fP use: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -salt\-run nacl.enc \(aqdata\(aq +salt\-call \-\-local nacl.keygen sk_file=/etc/salt/pki/master/nacl +# or if you want to work without files. +salt\-call \-\-local nacl.keygen +local: + \-\-\-\-\-\-\-\-\-\- + pk: + /kfGX7PbWeu099702PBbKWLpG/9p06IQRswkdWHCDk0= + sk: + SVWut5SqNpuPeNzb1b9y6b2eXg2PLIog43GBzp48Sow= +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Now with your keypair, you can encrypt data: +.sp +You have two option, \fIsealedbox\fP or \fIsecretbox\fP\&. +.sp +SecretBox is data encrypted using private key \fIpk\fP\&. Sealedbox is encrypted using public key \fIpk\fP\&. +.sp +Recommend using Sealedbox because the one way encryption permits developers to encrypt data for source control but not decrypt. +Sealedbox only has one key that is for both encryption and decryption. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.enc asecretpass pk=/kfGX7PbWeu099702PBbKWLpG/9p06IQRswkdWHCDk0= +tqXzeIJnTAM9Xf0mdLcpEdklMbfBGPj2oTKmlgrm3S1DTVVHNnh9h8mU1GKllGq/+cYsk6m5WhGdk58= +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To decrypt the data: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.dec data=\(aqtqXzeIJnTAM9Xf0mdLcpEdklMbfBGPj2oTKmlgrm3S1DTVVHNnh9h8mU1GKllGq/+cYsk6m5WhGdk58=\(aq sk=\(aqSVWut5SqNpuPeNzb1b9y6b2eXg2PLIog43GBzp48Sow=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +When the keys are defined in the master config you can use them from the nacl runner +without extra parameters: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# cat /etc/salt/master.d/nacl.conf +nacl.config: + sk_file: /etc/salt/pki/master/nacl + pk: \(aqcTIqXwnUiD1ulg4kXsbeCE7/NoeKEzd4nLeYcCFpd9k=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run nacl.enc \(aqasecretpass\(aq +salt\-run nacl.dec \(aqtqXzeIJnTAM9Xf0mdLcpEdklMbfBGPj2oTKmlgrm3S1DTVVHNnh9h8mU1GKllGq/+cYsk6m5WhGdk58=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# a salt developers minion could have pillar data that includes a nacl public key +nacl.config: + pk: \(aq/kfGX7PbWeu099702PBbKWLpG/9p06IQRswkdWHCDk0=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The developer can then use a less\-secure system to encrypt data. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.enc apassword +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Pillar files can include protected data that the salt master decrypts: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pillarexample: + user: root + password1: {{salt.nacl.dec(\(aqDRB7Q6/X5gGSRCTpZyxS6hlbWj0llUA+uaVyvou3vJ4=\(aq)|json}} + cert_key: {{salt.nacl.dec_file(\(aq/srv/salt/certs/example.com/key.nacl\(aq)|json}} + cert_key2: {{salt.nacl.dec_file(\(aqsalt:///certs/example.com/key.nacl\(aq)|json}} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Larger files like certificates can be encrypted with: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call nacl.enc_file /tmp/cert.crt out=/tmp/cert.nacl +# or more advanced +cert=$(cat /tmp/cert.crt) +salt\-call \-\-out=newline_values_only nacl.enc_pub data="$cert" > /tmp/cert.nacl +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +In pillars rended with jinja be sure to include \fI|json\fP so line breaks are encoded: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +cert: "{{salt.nacl.dec(\(aqS2uogToXkgENz9...085KYt\(aq)|json}}" +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +In states rendered with jinja it is also good pratice to include \fI|json\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +{{sls}} private key: + file.managed: + \- name: /etc/ssl/private/cert.key + \- mode: 700 + \- contents: "{{pillar[\(aqpillarexample\(aq][\(aqcert_key\(aq]|json}}" +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Optional small program to encrypt data without needing salt modules. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +#!/bin/python3 +import sys, base64, libnacl.sealed +pk = base64.b64decode(\(aqYOURPUBKEY\(aq) +b = libnacl.sealed.SealedBox(pk) +data = sys.stdin.buffer.read() +print(base64.b64encode(b.encrypt(data)).decode()) +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +echo \(aqapassword\(aq | nacl_enc.py .ft P .fi .UNINDENT @@ -275259,7 +293291,18 @@ salt\-run nacl.enc \(aqdata\(aq .INDENT 0.0 .TP .B salt.runners.nacl.dec(data, **kwargs) -Takes a key generated from \fInacl.keygen\fP and decrypt some data. +Alias to \fI{box_type}_decrypt\fP +.sp +box_type: secretbox, sealedbox(default) +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.nacl.dec_file(name, out=None, **kwargs) +This is a helper function to decrypt a file and return its contents. +.sp +You can provide an optional output file using \fIout\fP +.sp +\fIname\fP can be a local file or when not using \fIsalt\-run\fP can be a url like \fIsalt://\fP, \fIhttps://\fP etc. .sp CLI Examples: .INDENT 7.0 @@ -275267,9 +293310,9 @@ CLI Examples: .sp .nf .ft C -salt\-run nacl.dec pEXHQM6cuaF7A= -salt\-run nacl.dec data=\(aqpEXHQM6cuaF7A=\(aq keyfile=/root/.nacl -salt\-run nacl.dec data=\(aqpEXHQM6cuaF7A=\(aq key=\(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k=\(aq +salt\-run nacl.dec_file name=/tmp/id_rsa.nacl +salt\-call nacl.dec_file name=salt://crt/mycert.nacl out=/tmp/id_rsa +salt\-run nacl.dec_file name=/tmp/id_rsa.nacl box_type=secretbox sk_file=/etc/salt/pki/master/nacl.pub .ft P .fi .UNINDENT @@ -275278,7 +293321,18 @@ salt\-run nacl.dec data=\(aqpEXHQM6cuaF7A=\(aq key=\(aqcKEzd4kXsbeCE7/nLTIqXwnUi .INDENT 0.0 .TP .B salt.runners.nacl.enc(data, **kwargs) -Takes a key generated from \fInacl.keygen\fP and encrypt some data. +Alias to \fI{box_type}_encrypt\fP +.sp +box_type: secretbox, sealedbox(default) +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.nacl.enc_file(name, out=None, **kwargs) +This is a helper function to encrypt a file and return its contents. +.sp +You can provide an optional output file using \fIout\fP +.sp +\fIname\fP can be a local file or when not using \fIsalt\-run\fP can be a url like \fIsalt://\fP, \fIhttps://\fP etc. .sp CLI Examples: .INDENT 7.0 @@ -275286,9 +293340,9 @@ CLI Examples: .sp .nf .ft C -salt\-run nacl.enc datatoenc -salt\-run nacl.enc datatoenc keyfile=/root/.nacl -salt\-run nacl.enc datatoenc key=\(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k=\(aq +salt\-run nacl.enc_file name=/tmp/id_rsa +salt\-call nacl.enc_file name=salt://crt/mycert out=/tmp/cert +salt\-run nacl.enc_file name=/tmp/id_rsa box_type=secretbox sk_file=/etc/salt/pki/master/nacl.pub .ft P .fi .UNINDENT @@ -275296,8 +293350,15 @@ salt\-run nacl.enc datatoenc key=\(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k .UNINDENT .INDENT 0.0 .TP -.B salt.runners.nacl.keygen(keyfile=None) -Use libnacl to generate a private key +.B salt.runners.nacl.keygen(sk_file=None, pk_file=None) +Use libnacl to generate a keypair. +.sp +If no \fIsk_file\fP is defined return a keypair. +.sp +If only the \fIsk_file\fP is defined \fIpk_file\fP will use the same name with a postfix \fI\&.pub\fP\&. +.sp +When the \fIsk_file\fP is already existing, but \fIpk_file\fP is not. The \fIpk_file\fP will be generated +using the \fIsk_file\fP\&. .sp CLI Examples: .INDENT 7.0 @@ -275305,9 +293366,89 @@ CLI Examples: .sp .nf .ft C -salt\-run nacl.keygen -salt\-run nacl.keygen keyfile=/root/.nacl -salt\-run \-\-out=newline_values_only nacl.keygen > /root/.nacl +salt\-call nacl.keygen +salt\-call nacl.keygen sk_file=/etc/salt/pki/master/nacl +salt\-call nacl.keygen sk_file=/etc/salt/pki/master/nacl pk_file=/etc/salt/pki/master/nacl.pub +salt\-call \-\-local nacl.keygen +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.nacl.sealedbox_decrypt(data, **kwargs) +Decrypt data using a secret key that was encrypted using a public key with \fInacl.sealedbox_encrypt\fP\&. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call nacl.sealedbox_decrypt pEXHQM6cuaF7A= +salt\-call \-\-local nacl.sealedbox_decrypt data=\(aqpEXHQM6cuaF7A=\(aq sk_file=/etc/salt/pki/master/nacl +salt\-call \-\-local nacl.sealedbox_decrypt data=\(aqpEXHQM6cuaF7A=\(aq sk=\(aqYmFkcGFzcwo=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.nacl.sealedbox_encrypt(data, **kwargs) +Encrypt data using a public key generated from \fInacl.keygen\fP\&. +The encryptd data can be decrypted using \fInacl.sealedbox_decrypt\fP only with the secret key. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run nacl.sealedbox_encrypt datatoenc +salt\-call \-\-local nacl.sealedbox_encrypt datatoenc pk_file=/etc/salt/pki/master/nacl.pub +salt\-call \-\-local nacl.sealedbox_encrypt datatoenc pk=\(aqvrwQF7cNiNAVQVAiS3bvcbJUnF0cN6fU9YTZD9mBfzQ=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.nacl.secretbox_decrypt(data, **kwargs) +Decrypt data that was encrypted using \fInacl.secretbox_encrypt\fP using the secret key +that was generated from \fInacl.keygen\fP\&. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call nacl.secretbox_decrypt pEXHQM6cuaF7A= +salt\-call \-\-local nacl.secretbox_decrypt data=\(aqpEXHQM6cuaF7A=\(aq sk_file=/etc/salt/pki/master/nacl +salt\-call \-\-local nacl.secretbox_decrypt data=\(aqpEXHQM6cuaF7A=\(aq sk=\(aqYmFkcGFzcwo=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.nacl.secretbox_encrypt(data, **kwargs) +Encrypt data using a secret key generated from \fInacl.keygen\fP\&. +The same secret key can be used to decrypt the data using \fInacl.secretbox_decrypt\fP\&. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run nacl.secretbox_encrypt datatoenc +salt\-call \-\-local nacl.secretbox_encrypt datatoenc sk_file=/etc/salt/pki/master/nacl +salt\-call \-\-local nacl.secretbox_encrypt datatoenc sk=\(aqYmFkcGFzcwo=\(aq .ft P .fi .UNINDENT @@ -275820,7 +293961,7 @@ LLDP Neighbors for interface xe\-0/1/2 Network tools to run from the Master .INDENT 0.0 .TP -.B salt.runners.network.wol(mac, bcast=\(aq255.255.255.255\(aq, destport=9) +.B salt.runners.network.wol(mac, bcast=u\(aq255.255.255.255\(aq, destport=9) Send a "Magic Packet" to wake up a Minion .sp CLI Example: @@ -275839,7 +293980,7 @@ salt\-run network.wol 08:00:27:13:69:77 255.255.255.255 7 .UNINDENT .INDENT 0.0 .TP -.B salt.runners.network.wollist(maclist, bcast=\(aq255.255.255.255\(aq, destport=9) +.B salt.runners.network.wollist(maclist, bcast=u\(aq255.255.255.255\(aq, destport=9) Send a "Magic Packet" to wake up a list of Minions. This list must contain one MAC hardware address per line .sp @@ -275857,6 +293998,24 @@ salt\-run network.wollist \(aq/path/to/maclist\(aq 255.255.255.255 7 .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.network.wolmatch(tgt, tgt_type=u\(aqglob\(aq, bcast=u\(aq255.255.255.255\(aq, destport=9) +Send a "Magic Packet" to wake up Minions that are matched in the grains cache +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run network.wolmatch minion_id +salt\-run network.wolmatch 192.168.0.0/16 tgt_type=\(aqipcidr\(aq bcast=255.255.255.255 destport=7 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.runners.pagerduty .sp Runner Module for Firing Events via PagerDuty @@ -276032,7 +294191,7 @@ salt\-run pagerduty.list_maintenance_windows my\-pagerduty\-account Functions to interact with the pillar compiler on the master .INDENT 0.0 .TP -.B salt.runners.pillar.show_pillar(minion=\(aq*\(aq, **kwargs) +.B salt.runners.pillar.show_pillar(minion=u\(aq*\(aq, **kwargs) Returns the compiled pillar either of a specific minion or just the global available pillars. This function assumes that no minion has the id \fB*\fP\&. @@ -276109,7 +294268,7 @@ print(pillar) .UNINDENT .INDENT 0.0 .TP -.B salt.runners.pillar.show_top(minion=None, saltenv=\(aqbase\(aq) +.B salt.runners.pillar.show_top(minion=None, saltenv=u\(aqbase\(aq) Returns the compiled top data for pillar for a specific minion. If no minion is specified, we use the first minion we find. .sp @@ -276133,7 +294292,7 @@ New in version 2015.8.0. .INDENT 0.0 .TP -.B salt.runners.pkg.list_upgrades(jid, style=\(aqgroup\(aq, outputter=\(aqnested\(aq, ext_source=None) +.B salt.runners.pkg.list_upgrades(jid, style=u\(aqgroup\(aq, outputter=u\(aqnested\(aq, ext_source=None) Show list of available pkg upgrades using a specified format style .sp CLI Example: @@ -276225,7 +294384,7 @@ run them. And it will do this every minute, unless there are any jobs that are still running from the last time the process_runner task was executed. .INDENT 0.0 .TP -.B salt.runners.queue.delete(queue, items, backend=\(aqsqlite\(aq) +.B salt.runners.queue.delete(queue, items, backend=u\(aqsqlite\(aq) Delete an item or items from a queue .sp CLI Example: @@ -276244,7 +294403,7 @@ salt\-run queue.delete myqueue "[\(aqitem1\(aq, \(aqitem2\(aq, \(aqitem3\(aq]" .UNINDENT .INDENT 0.0 .TP -.B salt.runners.queue.insert(queue, items, backend=\(aqsqlite\(aq) +.B salt.runners.queue.insert(queue, items, backend=u\(aqsqlite\(aq) Add an item or items to a queue .sp CLI Example: @@ -276299,7 +294458,7 @@ salt\-run queue.insert_runner event.send test_insert_runner kwargs=\(aq{"data": .UNINDENT .INDENT 0.0 .TP -.B salt.runners.queue.list_items(queue, backend=\(aqsqlite\(aq) +.B salt.runners.queue.list_items(queue, backend=u\(aqsqlite\(aq) List contents of a queue .sp CLI Example: @@ -276317,7 +294476,7 @@ salt\-run queue.list_items myqueue backend=sqlite .UNINDENT .INDENT 0.0 .TP -.B salt.runners.queue.list_length(queue, backend=\(aqsqlite\(aq) +.B salt.runners.queue.list_length(queue, backend=u\(aqsqlite\(aq) Provide the number of items in a queue .sp CLI Example: @@ -276335,7 +294494,7 @@ salt\-run queue.list_length myqueue backend=sqlite .UNINDENT .INDENT 0.0 .TP -.B salt.runners.queue.list_queues(backend=\(aqsqlite\(aq) +.B salt.runners.queue.list_queues(backend=u\(aqsqlite\(aq) Return a list of Salt Queues on the backend .sp CLI Example: @@ -276353,7 +294512,7 @@ salt\-run queue.list_queues backend=sqlite .UNINDENT .INDENT 0.0 .TP -.B salt.runners.queue.pop(queue, quantity=1, backend=\(aqsqlite\(aq) +.B salt.runners.queue.pop(queue, quantity=1, backend=u\(aqsqlite\(aq, is_runner=False) Pop one or more or all items from a queue .sp CLI Example: @@ -276374,7 +294533,7 @@ salt\-run queue.pop myqueue all backend=sqlite .UNINDENT .INDENT 0.0 .TP -.B salt.runners.queue.process_queue(queue, quantity=1, backend=\(aqsqlite\(aq) +.B salt.runners.queue.process_queue(queue, quantity=1, backend=u\(aqsqlite\(aq, is_runner=False) Pop items off a queue and create an event on the Salt event bus to be processed by a Reactor. .sp @@ -276426,7 +294585,7 @@ salt\-run queue.process_runner 5 A convenience system to manage reactors .INDENT 0.0 .TP -.B salt.runners.reactor.add(event, reactors, saltenv=\(aqbase\(aq, test=None) +.B salt.runners.reactor.add(event, reactors, saltenv=u\(aqbase\(aq, test=None) Add a new reactor .sp CLI Example: @@ -276443,7 +294602,7 @@ salt\-run reactor.add \(aqsalt/cloud/*/destroyed\(aq reactors=\(aq/srv/reactor/d .UNINDENT .INDENT 0.0 .TP -.B salt.runners.reactor.delete(event, saltenv=\(aqbase\(aq, test=None) +.B salt.runners.reactor.delete(event, saltenv=u\(aqbase\(aq, test=None) Delete a reactor .sp CLI Example: @@ -276460,7 +294619,7 @@ salt\-run reactor.delete \(aqsalt/cloud/*/destroyed\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.runners.reactor.list(saltenv=\(aqbase\(aq, test=None) +.B salt.runners.reactor.list(saltenv=u\(aqbase\(aq, test=None) List currently configured reactors .sp CLI Example: @@ -276518,12 +294677,39 @@ __salt__[\(aqsalt.cmd\(aq](fun=fun, args=args, kwargs=kwargs) .INDENT 0.0 .TP .B salt.runners.salt.cmd(fun, *args, **kwargs) -Execute \fBfun\fP with the given \fBargs\fP and \fBkwargs\fP\&. -Parameter \fBfun\fP should be the string name -of the execution module to call. +Changed in version 2018.3.0: Added \fBwith_pillar\fP argument + .sp -Note that execution modules will be \fIloaded every time\fP -this function is called. +Execute \fBfun\fP with the given \fBargs\fP and \fBkwargs\fP\&. Parameter \fBfun\fP +should be the string name of the execution module +to call. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Execution modules will be loaded \fIevery time\fP this function is called. +Additionally, keep in mind that since runners execute on the master, +custom execution modules will need to be synced to the master using +\fBsalt\-run saltutil.sync_modules\fP, otherwise they will not be +available. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B with_pillar +False +If \fBTrue\fP, pillar data will be compiled for the master +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +To target the master in the pillar top file, keep in mind that the +default \fBid\fP for the master is \fB_master\fP\&. This can be +overridden by setting an \fBid\fP configuration parameter in the +master config file. +.UNINDENT +.UNINDENT +.UNINDENT .sp CLI example: .INDENT 7.0 @@ -276534,6 +294720,7 @@ CLI example: salt\-run salt.cmd test.ping # call functions with arguments and keyword arguments salt\-run salt.cmd test.arg 1 2 3 a=1 +salt\-run salt.cmd mymod.myfunc with_pillar=True .ft P .fi .UNINDENT @@ -276541,7 +294728,7 @@ salt\-run salt.cmd test.arg 1 2 3 a=1 .UNINDENT .INDENT 0.0 .TP -.B salt.runners.salt.execute(tgt, fun, arg=(), timeout=None, tgt_type=\(aqglob\(aq, ret=\(aq\(aq, jid=\(aq\(aq, kwarg=None, **kwargs) +.B salt.runners.salt.execute(tgt, fun, arg=(), timeout=None, tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, jid=u\(aq\(aq, kwarg=None, **kwargs) New in version 2017.7.0. .sp @@ -276587,13 +294774,15 @@ schedule: .UNINDENT .SS salt.runners.saltutil .sp -Sync custom types to the Master +The Saltutil runner is used to sync custom types to the Master. See the +\fBsaltutil module\fP for documentation on +managing updates to minions. .sp New in version 2016.3.0. .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_all(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_all(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync all custom types .INDENT 7.0 .TP @@ -276626,11 +294815,11 @@ salt\-run saltutil.sync_all extmod_whitelist={\(aqrunners\(aq: [\(aqcustom_runne .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_cache(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_cache(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) New in version 2017.7.0. .sp -Sync utils modules from \fBsalt://_cache\fP to the master +Sync cache modules from \fBsalt://_cache\fP to the master .INDENT 7.0 .TP .B saltenv @@ -276661,11 +294850,11 @@ salt\-run saltutil.sync_cache .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_clouds(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_clouds(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) New in version 2017.7.0. .sp -Sync utils modules from \fBsalt://_clouds\fP to the master +Sync cloud modules from \fBsalt://_clouds\fP to the master .INDENT 7.0 .TP .B saltenv @@ -276696,7 +294885,42 @@ salt\-run saltutil.sync_clouds .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_engines(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_eauth_tokens(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +New in version 2018.3.0. + +.sp +Sync eauth token modules from \fBsalt://_tokens\fP to the master +.INDENT 7.0 +.TP +.B saltenv +base +The fileserver environment from which to sync. To sync from more than +one environment, pass a comma\-separated list. +.TP +.B extmod_whitelist +None +comma\-seperated list of modules to sync +.TP +.B extmod_blacklist +None +comma\-seperated list of modules to blacklist based on type +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run saltutil.sync_eauth_tokens +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.saltutil.sync_engines(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync engines from \fBsalt://_engines\fP to the master .INDENT 7.0 .TP @@ -276728,7 +294952,42 @@ salt\-run saltutil.sync_engines .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_grains(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_fileserver(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +New in version 2018.3.0. + +.sp +Sync fileserver modules from \fBsalt://_fileserver\fP to the master +.INDENT 7.0 +.TP +.B saltenv +base +The fileserver environment from which to sync. To sync from more than +one environment, pass a comma\-separated list. +.TP +.B extmod_whitelist +None +comma\-seperated list of modules to sync +.TP +.B extmod_blacklist +None +comma\-seperated list of modules to blacklist based on type +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run saltutil.sync_fileserver +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.saltutil.sync_grains(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync grains modules from \fBsalt://_grains\fP to the master .INDENT 7.0 .TP @@ -276760,7 +295019,7 @@ salt\-run saltutil.sync_grains .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_modules(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_modules(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync execution modules from \fBsalt://_modules\fP to the master .INDENT 7.0 .TP @@ -276792,7 +295051,7 @@ salt\-run saltutil.sync_modules .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_output(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_output(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync output modules from \fBsalt://_output\fP to the master .INDENT 7.0 .TP @@ -276824,7 +295083,7 @@ salt\-run saltutil.sync_output .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_pillar(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_pillar(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync pillar modules from \fBsalt://_pillar\fP to the master .INDENT 7.0 .TP @@ -276856,7 +295115,7 @@ salt\-run saltutil.sync_pillar .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_proxymodules(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_proxymodules(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync proxy modules from \fBsalt://_proxy\fP to the master .INDENT 7.0 .TP @@ -276888,7 +295147,7 @@ salt\-run saltutil.sync_proxy .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_queues(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_queues(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync queue modules from \fBsalt://_queues\fP to the master .INDENT 7.0 .TP @@ -276920,7 +295179,7 @@ salt\-run saltutil.sync_queues .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_renderers(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_renderers(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync renderer modules from from \fBsalt://_renderers\fP to the master .INDENT 7.0 .TP @@ -276952,7 +295211,7 @@ salt\-run saltutil.sync_renderers .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_returners(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_returners(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync returner modules from \fBsalt://_returners\fP to the master .INDENT 7.0 .TP @@ -276984,11 +295243,11 @@ salt\-run saltutil.sync_returners .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_roster(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_roster(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) New in version 2017.7.0. .sp -Sync utils modules from \fBsalt://_roster\fP to the master +Sync roster modules from \fBsalt://_roster\fP to the master .INDENT 7.0 .TP .B saltenv @@ -277019,7 +295278,7 @@ salt\-run saltutil.sync_roster .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_runners(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_runners(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync runners from \fBsalt://_runners\fP to the master .INDENT 7.0 .TP @@ -277051,11 +295310,11 @@ salt\-run saltutil.sync_runners .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_sdb(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_sdb(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) New in version 2017.7.0. .sp -Sync utils modules from \fBsalt://_sdb\fP to the master +Sync sdb modules from \fBsalt://_sdb\fP to the master .INDENT 7.0 .TP .B saltenv @@ -277086,7 +295345,7 @@ salt\-run saltutil.sync_sdb .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_states(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_states(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync state modules from \fBsalt://_states\fP to the master .INDENT 7.0 .TP @@ -277118,7 +295377,39 @@ salt\-run saltutil.sync_states .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_tops(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_thorium(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +New in version 2018.3.0. + +.sp +Sync Thorium from \fBsalt://_thorium\fP to the master +.INDENT 7.0 +.TP +.B saltenv: \fBbase\fP +The fileserver environment from which to sync. To sync from more than +one environment, pass a comma\-separated list. +.TP +.B extmod_whitelist +comma\-seperated list of modules to sync +.TP +.B extmod_blacklist +comma\-seperated list of modules to blacklist based on type +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run saltutil.sync_thorium +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.saltutil.sync_tops(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) New in version 2016.3.7,2016.11.4,2017.7.0. .sp @@ -277145,7 +295436,7 @@ salt\-run saltutil.sync_tops .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_utils(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_utils(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) New in version 2016.11.0. .sp @@ -277180,7 +295471,7 @@ salt\-run saltutil.sync_utils .UNINDENT .INDENT 0.0 .TP -.B salt.runners.saltutil.sync_wheel(saltenv=\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) +.B salt.runners.saltutil.sync_wheel(saltenv=u\(aqbase\(aq, extmod_whitelist=None, extmod_blacklist=None) Sync wheel modules from \fBsalt://_wheel\fP to the master .INDENT 7.0 .TP @@ -277226,7 +295517,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq sdb.delete sdb://mymemcached/foo +salt\-run sdb.delete sdb://mymemcached/foo .ft P .fi .UNINDENT @@ -277244,7 +295535,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq sdb.get sdb://mymemcached/foo +salt\-run sdb.get sdb://mymemcached/foo .ft P .fi .UNINDENT @@ -277252,7 +295543,7 @@ salt \(aq*\(aq sdb.get sdb://mymemcached/foo .UNINDENT .INDENT 0.0 .TP -.B salt.runners.sdb.get_or_set_hash(uri, length=8, chars=\(aqabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(\-_=+)\(aq) +.B salt.runners.sdb.get_or_set_hash(uri, length=8, chars=u\(aqabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(\-_=+)\(aq) Perform a one\-time generation of a hash and write it to sdb. If that value has already been set return the value instead. .sp @@ -277294,7 +295585,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq sdb.set sdb://mymemcached/foo bar +salt\-run sdb.set sdb://mymemcached/foo bar .ft P .fi .UNINDENT @@ -277547,26 +295838,6 @@ salt\-run vmadm.stop search=\(aqtype=KVM\(aq one=False .UNINDENT .UNINDENT .UNINDENT -.SS salt.runners.search -.sp -Runner frontend to search system -.INDENT 0.0 -.TP -.B salt.runners.search.query(term) -Query the search system -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt\-run search.query foo -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT .SS salt.runners.spacewalk .SS Spacewalk Runner .sp @@ -277726,7 +295997,7 @@ A Runner module interface on top of the salt\-ssh Python API. This allows for programmatic use from salt\-api, the Reactor, Orchestrate, etc. .INDENT 0.0 .TP -.B salt.runners.ssh.cmd(tgt, fun, arg=(), timeout=None, tgt_type=\(aqglob\(aq, kwarg=None, expr_form=None) +.B salt.runners.ssh.cmd(tgt, fun, arg=(), timeout=None, tgt_type=u\(aqglob\(aq, kwarg=None, expr_form=None) New in version 2015.5.0. .sp @@ -277744,7 +296015,7 @@ A wrapper around the \fBSSHClient.cmd\fP method. Execute orchestration functions .INDENT 0.0 .TP -.B salt.runners.state.event(tagmatch=\(aq*\(aq, count=\-1, quiet=False, sock_dir=None, pretty=False, node=\(aqmaster\(aq) +.B salt.runners.state.event(tagmatch=u\(aq*\(aq, count=\-1, quiet=False, sock_dir=None, pretty=False, node=u\(aqmaster\(aq) Watch Salt\(aqs event bus and block until the given tag is matched .sp New in version 2014.7.0. @@ -277813,7 +296084,7 @@ script. .UNINDENT .INDENT 0.0 .TP -.B salt.runners.state.orchestrate(mods, saltenv=\(aqbase\(aq, test=None, exclude=None, pillar=None, pillarenv=None, pillar_enc=None, orchestration_jid=None) +.B salt.runners.state.orchestrate(mods, saltenv=u\(aqbase\(aq, test=None, exclude=None, pillar=None, pillarenv=None, pillar_enc=None, orchestration_jid=None) New in version 0.17.0. .sp @@ -277906,6 +296177,29 @@ salt\-run state.orchestrate_high \(aq{ .UNINDENT .INDENT 0.0 .TP +.B salt.runners.state.orchestrate_show_sls(mods, saltenv=u\(aqbase\(aq, test=None, exclude=None, pillar=None, pillarenv=None, pillar_enc=None) +Display the state data from a specific sls, or list of sls files, after +being render using the master minion. +.sp +Note, the master minion adds a "_master" suffix to it\(aqs minion id. +.sp +\fBSEE ALSO:\fP +.INDENT 7.0 +.INDENT 3.5 +The state.show_sls module function +.UNINDENT +.UNINDENT +.sp +CLI Example: +.. code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +salt\-run state.orch_show_sls my\-orch\-formula.my\-orch\-state \(aqpillar={ nodegroup: ng1 }\(aq +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.runners.state.orchestrate_single(fun, name, test=None, queue=False, pillar=None, **kwargs) Execute a single state orchestration routine .sp @@ -277924,6 +296218,18 @@ salt\-run state.orchestrate_single fun=salt.wheel name=key.list_all .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.state.rm_pause(jid, state_id, duration=None) +Remove a pause from a jid, allowing it to continue +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.state.set_pause(jid, state_id, duration=None) +Set up a state id pause, this instructs a running state to pause at a given +state id. This needs to pass in the jid of the running state and can +optionally pass in a duration in seconds. +.UNINDENT .SS salt.runners.survey .sp A general map/reduce style salt runner for aggregating results @@ -278045,7 +296351,27 @@ Kwargs will be filtered for \(aqprivate\(aq keynames. .UNINDENT .INDENT 0.0 .TP -.B salt.runners.test.metasyntactic(locality=\(aqus\(aq) +.B salt.runners.test.get_opts() +New in version 2018.3.0. + +.sp +Return the configuration options of the master. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run test.get_opts +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.runners.test.metasyntactic(locality=u\(aqus\(aq) Return common metasyntactic variables for the given locality .UNINDENT .INDENT 0.0 @@ -278077,7 +296403,7 @@ in a standalone way. This runner has tools which generate the standalone salt system for easy consumption. .INDENT 0.0 .TP -.B salt.runners.thin.generate(extra_mods=\(aq\(aq, overwrite=False, so_mods=\(aq\(aq, python2_bin=\(aqpython2\(aq, python3_bin=\(aqpython3\(aq, absonly=True, compress=\(aqgzip\(aq) +.B salt.runners.thin.generate(extra_mods=u\(aq\(aq, overwrite=False, so_mods=u\(aq\(aq, python2_bin=u\(aqpython2\(aq, python3_bin=u\(aqpython3\(aq, absonly=True, compress=u\(aqgzip\(aq) Generate the salt\-thin tarball and print the location of the tarball Optional additional mods to include (e.g. mako) can be supplied as a comma delimited string. Permits forcing an overwrite of the output file as well. @@ -278099,7 +296425,7 @@ salt\-run thin.generate overwrite=1 .UNINDENT .INDENT 0.0 .TP -.B salt.runners.thin.generate_min(extra_mods=\(aq\(aq, overwrite=False, so_mods=\(aq\(aq, python2_bin=\(aqpython2\(aq, python3_bin=\(aqpython3\(aq) +.B salt.runners.thin.generate_min(extra_mods=u\(aq\(aq, overwrite=False, so_mods=u\(aq\(aq, python2_bin=u\(aqpython2\(aq, python3_bin=u\(aqpython3\(aq) Generate the salt\-thin tarball and print the location of the tarball Optional additional mods to include (e.g. mako) can be supplied as a comma delimited string. Permits forcing an overwrite of the output file as well. @@ -278238,7 +296564,7 @@ salt\-run venafi.del_cached_domain domain1.example.com,domain2.example.com .UNINDENT .INDENT 0.0 .TP -.B salt.runners.venafiapi.gen_csr(minion_id, dns_name, zone=\(aqdefault\(aq, country=None, state=None, loc=None, org=None, org_unit=None, password=None) +.B salt.runners.venafiapi.gen_csr(minion_id, dns_name, zone=u\(aqdefault\(aq, country=None, state=None, loc=None, org=None, org_unit=None, password=None) Generate a csr using the host\(aqs private_key. Analogous to: .INDENT 7.0 @@ -278266,7 +296592,7 @@ salt\-run venafi.gen_csr .UNINDENT .INDENT 0.0 .TP -.B salt.runners.venafiapi.gen_key(minion_id, dns_name=None, zone=\(aqdefault\(aq, password=None) +.B salt.runners.venafiapi.gen_key(minion_id, dns_name=None, zone=u\(aqdefault\(aq, password=None) Generate and return an private_key. If a \fBdns_name\fP is passed in, the private_key will be cached under that name. The type of key and the parameters used to generate the key are based on the default certificate @@ -278354,7 +296680,7 @@ salt\-run venafi.register email@example.com .UNINDENT .INDENT 0.0 .TP -.B salt.runners.venafiapi.renew(minion_id, dns_name=None, zone=\(aqdefault\(aq, request_id=None, country=\(aqUS\(aq, state=\(aqCalifornia\(aq, loc=\(aqPalo Alto\(aq, org=\(aqBeta Organization\(aq, org_unit=\(aqBeta Group\(aq, password=None, zone_id=None) +.B salt.runners.venafiapi.renew(minion_id, dns_name=None, zone=u\(aqdefault\(aq, request_id=None, country=u\(aqUS\(aq, state=u\(aqCalifornia\(aq, loc=u\(aqPalo Alto\(aq, org=u\(aqBeta Organization\(aq, org_unit=u\(aqBeta Group\(aq, password=None, zone_id=None) Request a new certificate .sp Uses the following command: @@ -278383,7 +296709,7 @@ salt\-run venafi.request .UNINDENT .INDENT 0.0 .TP -.B salt.runners.venafiapi.request(minion_id, dns_name=None, zone=\(aqdefault\(aq, request_id=None, country=\(aqUS\(aq, state=\(aqCalifornia\(aq, loc=\(aqPalo Alto\(aq, org=\(aqBeta Organization\(aq, org_unit=\(aqBeta Group\(aq, password=None, zone_id=None) +.B salt.runners.venafiapi.request(minion_id, dns_name=None, zone=u\(aqdefault\(aq, request_id=None, country=u\(aqUS\(aq, state=u\(aqCalifornia\(aq, loc=u\(aqPalo Alto\(aq, org=u\(aqBeta Organization\(aq, org_unit=u\(aqBeta Group\(aq, password=None, zone_id=None) Request a new certificate .sp Uses the following command: @@ -278527,7 +296853,7 @@ Return information about the host connected to this master .UNINDENT .INDENT 0.0 .TP -.B salt.runners.virt.init(name, cpu, mem, image, hypervisor=\(aqkvm\(aq, host=None, seed=True, nic=\(aqdefault\(aq, install=True, start=True, disk=\(aqdefault\(aq, saltenv=\(aqbase\(aq, enable_vnc=False) +.B salt.runners.virt.init(name, cpu, mem, image, hypervisor=u\(aqkvm\(aq, host=None, seed=True, nic=u\(aqdefault\(aq, install=True, start=True, disk=u\(aqdefault\(aq, saltenv=u\(aqbase\(aq, enable_vnc=False) This routine is used to create a new virtual machine. This routines takes a number of options to determine what the newly created virtual machine will look like. @@ -278584,7 +296910,7 @@ to list. .UNINDENT .INDENT 0.0 .TP -.B salt.runners.virt.migrate(name, target=\(aq\(aq) +.B salt.runners.virt.migrate(name, target=u\(aq\(aq) Migrate a VM from one host to another. This routine will just start the migration and display information on how to look up the progress. .UNINDENT @@ -278820,7 +297146,7 @@ _ T{ \fBtism\fP T} T{ -tISM \- the Immutalbe Secrets Manager SDB Module +tISM \- the Immutable Secrets Manager SDB Module T} _ T{ @@ -279009,6 +297335,24 @@ This module allows access to Consul using an \fBsdb://\fP URI Like all sdb modules, the Consul module requires a configuration profile to be configured in either the minion or master configuration file. This profile requires very little. For example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +myconsul: + driver: consul + host: 127.0.0.1 + port: 8500 + token: b6376760\-a8bb\-edd5\-fcda\-33bc13bfc556 + scheme: http + consistency: default + dc: dev + verify: True +.ft P +.fi +.UNINDENT +.UNINDENT .sp The \fBdriver\fP refers to the Consul module, all other options are optional. For option details see: \fI\%https://python\-consul.readthedocs.io/en/latest/#consul\fP @@ -279556,7 +297900,7 @@ Set a key/value pair in sqlite3 .UNINDENT .SS salt.sdb.tism module .sp -tISM \- the Immutalbe Secrets Manager SDB Module +tISM \- the Immutable Secrets Manager SDB Module .INDENT 0.0 .TP .B maintainer @@ -279586,7 +297930,9 @@ sdb://tism/hQEMAzJ+GfdAB3KqAQf9E3cyvrPEWR1sf1tMvH0nrJ0bZa9kDFLPxvtwAOqlRiNp0F7Ip .UNINDENT .UNINDENT .sp -A profile must be setup in the minion configuration or pillar. If you want to use sdb in a runner or pillar you must also place a profile in the master configuration. +A profile must be setup in the minion configuration or pillar. If you want to +use sdb in a runner or pillar you must also place a profile in the master +configuration. .INDENT 0.0 .INDENT 3.5 .sp @@ -279732,14 +298078,18 @@ my\-yaml\-file: merge: strategy: smart merge_list: false + gpg: true .ft P .fi .UNINDENT .UNINDENT +.sp +Setting the \fBgpg\fP option to \fBtrue\fP (default is \fBfalse\fP) will decrypt embedded +GPG\-encrypted data using the \fBGPG renderer\fP\&. .INDENT 0.0 .TP .B salt.sdb.yaml.get(key, profile=None) -Get a value from the REST interface +Get a value from the dictionary .UNINDENT .INDENT 0.0 .TP @@ -280285,6 +298635,12 @@ Connection module for Amazon Cloud Formation T} _ T{ +\fBboto_cloudfront\fP +T} T{ +Manage CloudFront distributions +T} +_ +T{ \fBboto_cloudtrail\fP T} T{ Manage CloudTrail Objects @@ -280503,6 +298859,7 @@ _ T{ \fBcsf\fP T} T{ +CSF Ip tables management T} _ T{ @@ -280634,7 +298991,7 @@ _ T{ \fBfirewall\fP T} T{ -State to check firewall configurations .. +State to check firewall configurations T} _ T{ @@ -280832,7 +299189,6 @@ _ T{ \fBinfoblox\fP T} T{ -states for infoblox stuff T} _ T{ @@ -280890,6 +299246,12 @@ Kapacitor state module. T} _ T{ +\fBkernelpkg\fP +T} T{ +Manage kernel packages and active kernel version +T} +_ +T{ \fBkeyboard\fP T} T{ Management of keyboard layouts @@ -280932,6 +299294,18 @@ Manage DNS records and zones using libcloud T} _ T{ +\fBlibcloud_loadbalancer\fP +T} T{ +Apache Libcloud Load Balancer State +T} +_ +T{ +\fBlibcloud_storage\fP +T} T{ +Apache Libcloud Storage State +T} +_ +T{ \fBlinux_acl\fP T} T{ Linux File Access Control Lists @@ -280944,6 +299318,12 @@ Management of languages/locales T} _ T{ +\fBlogadm\fP +T} T{ +Management of logs using Solaris logadm. +T} +_ +T{ \fBlogrotate\fP T} T{ Module for managing logrotate. @@ -281078,7 +299458,7 @@ _ T{ \fBmsteams\fP T} T{ -Send a message card to Microsoft Teams ======================= This state is useful for sending messages to Teams during state runs. +Send a message card to Microsoft Teams T} _ T{ @@ -281148,6 +299528,12 @@ NAPALM YANG state T} _ T{ +\fBnfs_export\fP +T} T{ +Management of NFS exports +T} +_ +T{ \fBnftables\fP T} T{ Management of nftables @@ -281190,6 +299576,12 @@ Management of Open vSwitch ports. T} _ T{ +\fBopsgenie\fP +T} T{ +Create/Close an alert in OpsGenie +T} +_ +T{ \fBpagerduty\fP T} T{ Create an Event in PagerDuty @@ -281264,7 +299656,7 @@ _ T{ \fBpkgrepo\fP T} T{ -Management of APT/YUM package repos +Management of APT/RPM package repos T} _ T{ @@ -281444,6 +299836,7 @@ _ T{ \fBreg\fP T} T{ +Manage the Windows registry T} _ T{ @@ -281573,12 +299966,6 @@ StatusPage T} _ T{ -\fBstormpath_account\fP -T} T{ -Support for Stormpath. -T} -_ -T{ \fBsupervisord\fP T} T{ Interaction with the Supervisor daemon @@ -281605,12 +299992,13 @@ _ T{ \fBsysrc\fP T} T{ +State to work with sysrc T} _ T{ \fBtelemetry_alert\fP T} T{ -New in version 2016.3.0.. +Manage Telemetry alert configurations T} _ T{ @@ -281667,13 +300055,15 @@ Management of user accounts T} _ T{ +\fBvagrant\fP +T} T{ +Manage Vagrant VMs +T} +_ +T{ \fBvault\fP T} T{ -.INDENT 0.0 -.TP -.B maintainer -SaltStack -.UNINDENT +States for managing Hashicorp Vault. T} _ T{ @@ -281775,7 +300165,7 @@ _ T{ \fBwin_servermanager\fP T} T{ -Manage Windows features via the ServerManager powershell module +Manage Windows features via the ServerManager powershell module. T} _ T{ @@ -281922,7 +300312,7 @@ dev.example.com: .UNINDENT .INDENT 0.0 .TP -.B salt.states.acme.cert(name, aliases=None, email=None, webroot=None, test_cert=False, renew=None, keysize=None, server=None, owner=\(aqroot\(aq, group=\(aqroot\(aq, certname=None) +.B salt.states.acme.cert(name, aliases=None, email=None, webroot=None, test_cert=False, renew=None, keysize=None, server=None, owner=u\(aqroot\(aq, group=u\(aqroot\(aq, certname=None) Obtain/renew a certificate from an ACME CA, probably Let\(aqs Encrypt. .INDENT 7.0 .TP @@ -282393,7 +300783,6 @@ extract_myapp: \- source: salt://apps/src/myapp\-16.2.4.tar.gz \- user: www \- group: www - \- tar_options: \-\-strip\-components=1 .ft P .fi .UNINDENT @@ -282696,8 +301085,7 @@ used, which is less platform\-independent, so keep this in mind when using this option; the CLI options must be valid options for the \fBtar\fP/\fBunzip\fP implementation on the minion\(aqs OS. .sp -New in version 2016.11.0: The \fBtar_options\fP and \fBzip_options\fP parameters have been -deprecated in favor of a single argument name. +New in version 2016.11.0. .sp Changed in version 2015.8.11,2016.3.2: XZ\-compressed tar archives no longer require \fBJ\fP to manually be @@ -282714,17 +301102,6 @@ For tar archives, main operators like \fB\-x\fP, \fB\-\-extract\fP, \fB\-\-get\fP, \fB\-c\fP and \fB\-f\fP/\fB\-\-file\fP should \fInot\fP be used here. .UNINDENT .UNINDENT -.TP -.B tar_options -Deprecated since version 2016.11.0: Use \fBoptions\fP instead. - -.TP -.B zip_options -New in version 2016.3.1. - -.sp -Deprecated since version 2016.11.0: Use \fBoptions\fP instead. - .TP .B list_options \fBFor tar archives only.\fP This state uses \fBarchive.list\fP to discover the contents of the source @@ -282967,9 +301344,9 @@ graylog2\-server: This state downloads artifacts from artifactory. .INDENT 0.0 .TP -.B salt.states.artifactory.downloaded(name, artifact, target_dir=\(aq/tmp\(aq, target_file=None) +.B salt.states.artifactory.downloaded(name, artifact, target_dir=u\(aq/tmp\(aq, target_file=None, use_literal_group_id=False) Ensures that the artifact from artifactory exists at given location. If it doesn\(aqt exist, then -it will be downloaded. It it already exists then the checksum of existing file is checked against checksum +it will be downloaded. If it already exists then the checksum of existing file is checked against checksum in artifactory. If it is different then the step will fail. .INDENT 7.0 .TP @@ -283421,7 +301798,7 @@ specify the lens to use like this: .ft C redis\-conf: augeas.change: - \- lens: redis + \- lens: redis.lns \- context: /files/etc/redis/redis.conf \- changes: \- set bind 0.0.0.0 @@ -283452,15 +301829,15 @@ and removes an obsolete service: .ft C zabbix\-service: augeas.change: - \- lens: services + \- lens: services.lns \- context: /files/etc/services \- changes: \- ins service\-name after service\-name[last()] - \- set service\-name[last()] zabbix\-agent - \- set service\-name[. = \(aqzabbix\-agent\(aq]/#comment "Zabbix Agent service" - \- set service\-name[. = \(aqzabbix\-agent\(aq]/port 10050 - \- set service\-name[. = \(aqzabbix\-agent\(aq]/protocol tcp - \- rm service\-name[. = \(aqim\-obsolete\(aq] + \- set service\-name[last()] "zabbix\-agent" + \- set "service\-name[. = \(aqzabbix\-agent\(aq]/port" 10050 + \- set "service\-name[. = \(aqzabbix\-agent\(aq]/protocol" tcp + \- set "service\-name[. = \(aqzabbix\-agent\(aq]/#comment" "Zabbix Agent service" + \- rm "service\-name[. = \(aqim\-obsolete\(aq]" \- unless: grep "zabbix\-agent" /etc/services .ft P .fi @@ -283470,10 +301847,24 @@ zabbix\-service: \fBWARNING:\fP .INDENT 7.0 .INDENT 3.5 -Don\(aqt forget the \fBunless\fP here, otherwise a new entry will be added -every time this state is run. +Don\(aqt forget the \fBunless\fP here, otherwise it will fail on next runs +because the service is already defined. Additionally you have to quote +lines containing \fBservice\-name[. = \(aqzabbix\-agent\(aq]\fP otherwise +\fBaugeas_cfg\fP execute will fail because +it will receive more parameters than expected. .UNINDENT .UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Order is important when defining a service with Augeas, in this case +it\(aqs \fBport\fP, \fBprotocol\fP and \fB#comment\fP\&. For more info about +the lens check \fI\%services lens documentation\fP\&. +.UNINDENT +.UNINDENT +.sp +\fI\%http://augeas.net/docs/references/lenses/files/services\-aug.html#Services.record\fP .UNINDENT .SS salt.states.aws_sqs .sp @@ -283547,36 +301938,42 @@ New in version 2015.8.0. .ft C ps: beacon.present: + \- save: True \- enable: False - \- salt\-master: running - \- apache2: stopped + \- services: + salt\-master: running + apache2: stopped sh: - beacon.present: + beacon.present: [] load: beacon.present: - \- 1m: - \- 0.0 - \- 2.0 - \- 5m: - \- 0.0 - \- 1.5 - \- 15m: - \- 0.1 - \- 1.0 + \- averages: + 1m: + \- 0.0 + \- 2.0 + 5m: + \- 0.0 + \- 1.5 + 15m: + \- 0.1 + \- 1.0 .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.states.beacon.absent(name, **kwargs) +.B salt.states.beacon.absent(name, save=False, **kwargs) Ensure beacon is absent. .INDENT 7.0 .TP .B name The name of the beacon ensured absent. +.TP +.B save +True/False, if True the beacons.conf file be updated too. Default is False. .UNINDENT .UNINDENT .INDENT 0.0 @@ -283601,12 +301998,15 @@ The name of the beacon to enable. .UNINDENT .INDENT 0.0 .TP -.B salt.states.beacon.present(name, **kwargs) +.B salt.states.beacon.present(name, save=False, **kwargs) Ensure beacon is configured with the included beacon data. .INDENT 7.0 .TP .B name The name of the beacon ensure is configured. +.TP +.B save +True/False, if True the beacons.conf file be updated too. Default is False. .UNINDENT .UNINDENT .SS salt.states.bigip @@ -285026,7 +303426,7 @@ New in version 2014.7.0. .INDENT 0.0 .TP -.B salt.states.blockdev.formatted(name, fs_type=\(aqext4\(aq, force=False, **kwargs) +.B salt.states.blockdev.formatted(name, fs_type=u\(aqext4\(aq, force=False, **kwargs) Manage filesystems of partitions. .INDENT 7.0 .TP @@ -285968,13 +304368,12 @@ Set True if deleting a private hosted zone. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto3_route53.hosted_zone_present(name, Name=None, PrivateZone=False, CallerReference=None, Comment=\(aq\(aq, VPCs=None, region=None, key=None, keyid=None, profile=None) +.B salt.states.boto3_route53.hosted_zone_present(name, Name=None, PrivateZone=False, CallerReference=None, Comment=u\(aq\(aq, VPCs=None, region=None, key=None, keyid=None, profile=None) Ensure a hosted zone exists with the given attributes. .INDENT 7.0 .TP .B name -The name of the state definition. This will be used as the \(aqCallerReference\(aq param when -creating the hosted zone to help ensure idempotency. +The name of the state definition. .TP .B Name The name of the domain. This should be a fully\-specified domain, and should terminate with a @@ -286395,7 +304794,7 @@ contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_apigateway.present(name, api_name, swagger_file, stage_name, api_key_required, lambda_integration_role, lambda_region=None, stage_variables=None, region=None, key=None, keyid=None, profile=None, lambda_funcname_format=\(aq{stage}_{api}_{resource}_{method}\(aq, authorization_type=\(aqNONE\(aq, error_response_template=None, response_template=None) +.B salt.states.boto_apigateway.present(name, api_name, swagger_file, stage_name, api_key_required, lambda_integration_role, lambda_region=None, stage_variables=None, region=None, key=None, keyid=None, profile=None, lambda_funcname_format=u\(aq{stage}_{api}_{resource}_{method}\(aq, authorization_type=u\(aqNONE\(aq, error_response_template=None, response_template=None) .INDENT 7.0 .INDENT 3.5 Ensure the spcified api_name with the corresponding swaggerfile is deployed to the @@ -286472,6 +304871,33 @@ An optional pattern field can be specified in errorMessage field to aid the resp to the proper error return status codes. .INDENT 0.0 .INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +Error: + type: object + properties: + stackTrace: + type: array + items: + type: array + items: + type: string + description: call stack + errorType: + type: string + description: error type + errorMessage: + type: string + description: | + Error message, will be matched based on pattern. + If no pattern is specified, the default pattern used for response mapping will be +*. +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 @@ -287095,7 +305521,7 @@ that contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_asg.present(name, launch_config_name, availability_zones, min_size, max_size, launch_config=None, desired_capacity=None, load_balancers=None, default_cooldown=None, health_check_type=None, health_check_period=None, placement_group=None, vpc_zone_identifier=None, subnet_names=None, tags=None, termination_policies=None, termination_policies_from_pillar=\(aqboto_asg_termination_policies\(aq, suspended_processes=None, scaling_policies=None, scaling_policies_from_pillar=\(aqboto_asg_scaling_policies\(aq, scheduled_actions=None, scheduled_actions_from_pillar=\(aqboto_asg_scheduled_actions\(aq, alarms=None, alarms_from_pillar=\(aqboto_asg_alarms\(aq, region=None, key=None, keyid=None, profile=None, notification_arn=None, notification_arn_from_pillar=\(aqboto_asg_notification_arn\(aq, notification_types=None, notification_types_from_pillar=\(aqboto_asg_notification_types\(aq) +.B salt.states.boto_asg.present(name, launch_config_name, availability_zones, min_size, max_size, launch_config=None, desired_capacity=None, load_balancers=None, default_cooldown=None, health_check_type=None, health_check_period=None, placement_group=None, vpc_zone_identifier=None, subnet_names=None, tags=None, termination_policies=None, termination_policies_from_pillar=u\(aqboto_asg_termination_policies\(aq, suspended_processes=None, scaling_policies=None, scaling_policies_from_pillar=u\(aqboto_asg_scaling_policies\(aq, scheduled_actions=None, scheduled_actions_from_pillar=u\(aqboto_asg_scheduled_actions\(aq, alarms=None, alarms_from_pillar=u\(aqboto_asg_alarms\(aq, region=None, key=None, keyid=None, profile=None, notification_arn=None, notification_arn_from_pillar=u\(aqboto_asg_notification_arn\(aq, notification_types=None, notification_types_from_pillar=u\(aqboto_asg_notification_types\(aq) Ensure the autoscale group exists. .INDENT 7.0 .TP @@ -287453,6 +305879,119 @@ keyid (string) \- Access key to be used. profile (dict) \- A dict with region, key and keyid, or a pillar key (string) that contains a dict with region, key and keyid. .UNINDENT +.SS salt.states.boto_cloudfront +.sp +Manage CloudFront distributions +.sp +New in version 2018.3.0. + +.sp +Create, update and destroy CloudFront distributions. +.sp +This module accepts explicit AWS credentials but can also utilize +IAM roles assigned to the instance through Instance Profiles. +Dynamic credentials are then automatically obtained from AWS API +and no further configuration is necessary. +More information available \fI\%here\fP\&. +.sp +If IAM roles are not used you need to specify them, +either in a pillar file or in the minion\(aqs config file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +cloudfront.keyid: GKTADJGHEIQSXMKKRBJ08H +cloudfront.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +It\(aqs also possible to specify \fBkey\fP, \fBkeyid\fP, and \fBregion\fP via a profile, +either passed in as a dict, or a string to pull from pillars or minion config: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +myprofile: + keyid: GKTADJGHEIQSXMKKRBJ08H + key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs + region: us\-east\-1 +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +aws: + region: + us\-east\-1: + profile: + keyid: GKTADJGHEIQSXMKKRBJ08H + key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs + region: us\-east\-1 +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B depends +boto3 +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.boto_cloudfront.present(name, config, tags, region=None, key=None, keyid=None, profile=None) +Ensure the CloudFront distribution is present. +.INDENT 7.0 +.TP +.B name (string) +Name of the CloudFront distribution +.TP +.B config (dict) +Configuration for the distribution +.TP +.B tags (dict) +Tags to associate with the distribution +.TP +.B region (string) +Region to connect to +.TP +.B key (string) +Secret key to use +.TP +.B keyid (string) +Access key to use +.TP +.B profile (dict or string) +A dict with region, key, and keyid, +or a pillar key (string) that contains such a dict. +.UNINDENT +.sp +Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +Manage my_distribution CloudFront distribution: + boto_cloudfront.present: + \- name: my_distribution + \- config: + Comment: \(aqpartial config shown, most parameters elided\(aq + Enabled: True + \- tags: + testing_key: testing_value +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.states.boto_cloudtrail module .SS Manage CloudTrail Objects .sp @@ -288126,7 +306665,7 @@ that contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_datapipeline.present(name, pipeline_objects=None, pipeline_objects_from_pillars=\(aqboto_datapipeline_pipeline_objects\(aq, parameter_objects=None, parameter_objects_from_pillars=\(aqboto_datapipeline_parameter_objects\(aq, parameter_values=None, parameter_values_from_pillars=\(aqboto_datapipeline_parameter_values\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.states.boto_datapipeline.present(name, pipeline_objects=None, pipeline_objects_from_pillars=u\(aqboto_datapipeline_pipeline_objects\(aq, parameter_objects=None, parameter_objects_from_pillars=u\(aqboto_datapipeline_parameter_objects\(aq, parameter_values=None, parameter_values_from_pillars=u\(aqboto_datapipeline_parameter_values\(aq, region=None, key=None, keyid=None, profile=None) Ensure the data pipeline exists with matching definition. .INDENT 7.0 .TP @@ -288378,7 +306917,7 @@ that contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_dynamodb.present(name=None, table_name=None, region=None, key=None, keyid=None, profile=None, read_capacity_units=None, write_capacity_units=None, alarms=None, alarms_from_pillar=\(aqboto_dynamodb_alarms\(aq, hash_key=None, hash_key_data_type=None, range_key=None, range_key_data_type=None, local_indexes=None, global_indexes=None, backup_configs_from_pillars=\(aqboto_dynamodb_backup_configs\(aq) +.B salt.states.boto_dynamodb.present(name=None, table_name=None, region=None, key=None, keyid=None, profile=None, read_capacity_units=None, write_capacity_units=None, alarms=None, alarms_from_pillar=u\(aqboto_dynamodb_alarms\(aq, hash_key=None, hash_key_data_type=None, range_key=None, range_key_data_type=None, local_indexes=None, global_indexes=None, backup_configs_from_pillars=u\(aqboto_dynamodb_backup_configs\(aq) Ensure the DynamoDB table exists. Table throughput can be updated after table creation. .sp @@ -288623,6 +307162,9 @@ that contains a dict with region, key and keyid. .TP .B salt.states.boto_ec2.instance_absent(name, instance_name=None, instance_id=None, release_eip=False, region=None, key=None, keyid=None, profile=None, filters=None) Ensure an EC2 instance does not exist (is stopped and removed). +.sp +Changed in version 2016.11.0. + .INDENT 7.0 .TP .B name @@ -288656,6 +307198,17 @@ delete. .UNINDENT .sp YAML example fragment: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +\- filters: + vpc\-id: vpc\-abcdef12 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -288909,6 +307462,69 @@ Ensure key pair is present. .UNINDENT .INDENT 0.0 .TP +.B salt.states.boto_ec2.private_ips_absent(name, network_interface_name=None, network_interface_id=None, private_ip_addresses=None, region=None, key=None, keyid=None, profile=None) +Ensure an ENI does not have secondary private ip addresses associated with it +.INDENT 7.0 +.TP +.B name +(String) \- State definition name +.TP +.B network_interface_id +(String) \- The EC2 network interface id, example eni\-123456789 +.TP +.B private_ip_addresses +(List or String) \- The secondary private ip address(es) that should be absent on the ENI. +.TP +.B region +(string) \- Region to connect to. +.TP +.B key +(string) \- Secret key to be used. +.TP +.B keyid +(string) \- Access key to be used. +.TP +.B profile +(variable) \- A dict with region, key and keyid, or a pillar key (string) that contains a +dict with region, key and keyid. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.boto_ec2.private_ips_present(name, network_interface_name=None, network_interface_id=None, private_ip_addresses=None, allow_reassignment=False, region=None, key=None, keyid=None, profile=None) +Ensure an ENI has secondary private ip addresses associated with it +.INDENT 7.0 +.TP +.B name +(String) \- State definition name +.TP +.B network_interface_id +(String) \- The EC2 network interface id, example eni\-123456789 +.TP +.B private_ip_addresses +(List or String) \- The secondary private ip address(es) that should be present on the ENI. +.TP +.B allow_reassignment +(Boolean) \- If true, will reassign a secondary private ip address associated with another +ENI. If false, state will fail if the secondary private ip address is associated with +another ENI. +.TP +.B region +(string) \- Region to connect to. +.TP +.B key +(string) \- Secret key to be used. +.TP +.B keyid +(string) \- Access key to be used. +.TP +.B profile +(variable) \- A dict with region, key and keyid, or a pillar key (string) that contains a +dict with region, key and keyid. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.states.boto_ec2.snapshot_created(name, ami_name, instance_name, wait_until_available=True, wait_timeout_seconds=300, **kwargs) Create a snapshot from the given instance .sp @@ -288962,6 +307578,76 @@ that contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP +.B salt.states.boto_ec2.volume_present(name, volume_name=None, volume_id=None, instance_name=None, instance_id=None, device=None, size=None, snapshot_id=None, volume_type=None, iops=None, encrypted=False, kms_key_id=None, region=None, key=None, keyid=None, profile=None) +Ensure the EC2 volume is present and attached. +.INDENT 7.0 +.TP +.B name +State definition name. +.TP +.B volume_name +The Name tag value for the volume. If no volume with that matching name tag is found, +a new volume will be created. If multiple volumes are matched, the state will fail. +.TP +.B volume_id +Resource ID of the volume. Exclusive with \(aqvolume_name\(aq. +.TP +.B instance_name +Attach volume to instance with this Name tag. +Exclusive with \(aqinstance_id\(aq. +.TP +.B instance_id +Attach volume to instance with this ID. +Exclusive with \(aqinstance_name\(aq. +.TP +.B device +The device on the instance through which the volume is exposed (e.g. /dev/sdh) +.TP +.B size +The size of the new volume, in GiB. If you\(aqre creating the volume from a snapshot +and don\(aqt specify a volume size, the default is the snapshot size. Optionally specified +at volume creation time; will be ignored afterward. Requires \(aqvolume_name\(aq. +.TP +.B snapshot_id +The snapshot ID from which the new Volume will be created. Optionally specified +at volume creation time; will be ignored afterward. Requires \(aqvolume_name\(aq. +.TP +.B volume_type +The type of the volume. Optionally specified at volume creation time; will be ignored afterward. +Requires \(aqvolume_name\(aq. +Valid volume types for AWS can be found here: +\fI\%http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html\fP +.TP +.B iops +The provisioned IOPS you want to associate with this volume. Optionally specified +at volume creation time; will be ignored afterward. Requires \(aqvolume_name\(aq. +.TP +.B encrypted +Specifies whether the volume should be encrypted. Optionally specified +at volume creation time; will be ignored afterward. Requires \(aqvolume_name\(aq. +.TP +.B kms_key_id +If encrypted is True, this KMS Key ID may be specified to encrypt volume with this key. +Optionally specified at volume creation time; will be ignored afterward. +Requires \(aqvolume_name\(aq. +e.g.: arn:aws:kms:us\-east\-1:012345678910:key/abcd1234\-a123\-456a\-a12b\-a123b4cd56ef +.TP +.B region +Region to connect to. +.TP +.B key +Secret key to be used. +.TP +.B keyid +Access key to be used. +.TP +.B profile +A dict with region, key and keyid, or a pillar key (string) +that contains a dict with region, key and keyid. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.states.boto_ec2.volumes_tagged(name, tag_maps, authoritative=False, region=None, key=None, keyid=None, profile=None) Ensure EC2 volume(s) matching the given filters have the defined tags. .sp @@ -288984,6 +307670,33 @@ volumes can be all tagged differently with one call to this function. .sp YAML example fragment: .INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +\- filters: + attachment.instance_id: i\-abcdef12 + tags: + Name: dev\-int\-abcdef12.aws\-foo.com +\- filters: + attachment.device: /dev/sdf + tags: + ManagedSnapshots: true + BillingGroup: bubba.hotep@aws\-foo.com +\- filters: + instance_name: prd\-foo\-01.aws\-foo.com + tags: + Name: prd\-foo\-01.aws\-foo.com + BillingGroup: infra\-team@aws\-foo.com +\- filters: + volume_ids: [ vol\-12345689, vol\-abcdef12 ] + tags: + BillingGroup: infra\-team@aws\-foo.com +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 .TP .B authoritative Should un\-declared tags currently set on matched volumes be deleted? Boolean. @@ -289401,7 +308114,7 @@ contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_elasticsearch_domain.present(name, DomainName, ElasticsearchClusterConfig=None, EBSOptions=None, AccessPolicies=None, SnapshotOptions=None, AdvancedOptions=None, Tags=None, region=None, key=None, keyid=None, profile=None, ElasticsearchVersion=\(aq1.5\(aq) +.B salt.states.boto_elasticsearch_domain.present(name, DomainName, ElasticsearchClusterConfig=None, EBSOptions=None, AccessPolicies=None, SnapshotOptions=None, AdvancedOptions=None, Tags=None, region=None, key=None, keyid=None, profile=None, ElasticsearchVersion=u\(aq1.5\(aq) Ensure domain exists. .INDENT 7.0 .TP @@ -289789,7 +308502,7 @@ name of the ELB .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_elb.present(name, listeners, availability_zones=None, subnets=None, subnet_names=None, security_groups=None, scheme=\(aqinternet\-facing\(aq, health_check=None, attributes=None, attributes_from_pillar=\(aqboto_elb_attributes\(aq, cnames=None, alarms=None, alarms_from_pillar=\(aqboto_elb_alarms\(aq, policies=None, policies_from_pillar=\(aqboto_elb_policies\(aq, backends=None, region=None, key=None, keyid=None, profile=None, wait_for_sync=True, tags=None, instance_ids=None, instance_names=None) +.B salt.states.boto_elb.present(name, listeners, availability_zones=None, subnets=None, subnet_names=None, security_groups=None, scheme=u\(aqinternet\-facing\(aq, health_check=None, attributes=None, attributes_from_pillar=u\(aqboto_elb_attributes\(aq, cnames=None, alarms=None, alarms_from_pillar=u\(aqboto_elb_alarms\(aq, policies=None, policies_from_pillar=u\(aqboto_elb_policies\(aq, backends=None, region=None, key=None, keyid=None, profile=None, wait_for_sync=True, tags=None, instance_ids=None, instance_names=None) Ensure the ELB exists. .INDENT 7.0 .TP @@ -290002,7 +308715,117 @@ myprofile: .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_elbv2.targets_deregistered(name, targets, region=None, key=None, keyid=None, profile=None) +.B salt.states.boto_elbv2.create_target_group(name, protocol, port, vpc_id, region=None, key=None, keyid=None, profile=None, health_check_protocol=u\(aqHTTP\(aq, health_check_port=u\(aqtraffic\-port\(aq, health_check_path=u\(aq/\(aq, health_check_interval_seconds=30, health_check_timeout_seconds=5, healthy_threshold_count=5, unhealthy_threshold_count=2, **kwargs) +New in version 2017.11.0. + +.sp +Create target group if not present. +.INDENT 7.0 +.TP +.B name +(string) \- The name of the target group. +.TP +.B protocol +(string) \- The protocol to use for routing traffic to the targets +.TP +.B port +(int) \- The port on which the targets receive traffic. This port is used unless +you specify a port override when registering the traffic. +.TP +.B vpc_id +(string) \- The identifier of the virtual private cloud (VPC). +.TP +.B health_check_protocol +(string) \- The protocol the load balancer uses when performing health check on +targets. The default is the HTTP protocol. +.TP +.B health_check_port +(string) \- The port the load balancer uses when performing health checks on +targets. The default is \(aqtraffic\-port\(aq, which indicates the port on which each +target receives traffic from the load balancer. +.TP +.B health_check_path +(string) \- The ping path that is the destination on the targets for health +checks. The default is /. +.TP +.B health_check_interval_seconds +(integer) \- The approximate amount of time, in seconds, between health checks +of an individual target. The default is 30 seconds. +.TP +.B health_check_timeout_seconds +(integer) \- The amount of time, in seconds, during which no response from a +target means a failed health check. The default is 5 seconds. +.TP +.B healthy_threshold_count +(integer) \- The number of consecutive health checks successes required before +considering an unhealthy target healthy. The default is 5. +.TP +.B unhealthy_threshold_count +(integer) \- The number of consecutive health check failures required before +considering a target unhealthy. The default is 2. +.TP +.B returns +(bool) \- True on success, False on failure. +.UNINDENT +.sp +CLI example: +.. code\-block:: yaml +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B create\-target: +.INDENT 7.0 +.TP +.B boto_elb2.create_targets_group: +.INDENT 7.0 +.IP \(bu 2 +name: myALB +.IP \(bu 2 +protocol: https +.IP \(bu 2 +port: 443 +.IP \(bu 2 +vpc_id: myVPC +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.boto_elbv2.delete_target_group(name, region=None, key=None, keyid=None, profile=None) +Delete target group. +.INDENT 7.0 +.TP +.B name +(string) \- The Amazon Resource Name (ARN) of the resource. +.TP +.B returns +(bool) \- True on success, False on failure. +.UNINDENT +.sp +CLI example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +check\-target: + boto_elb2.delete_targets_group: + \- name: myALB + \- protocol: https + \- port: 443 + \- vpc_id: myVPC +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.boto_elbv2.targets_deregistered(name, targets, region=None, key=None, keyid=None, profile=None, **kwargs) Remove targets to an Application Load Balancer target group. .INDENT 7.0 .TP @@ -290033,7 +308856,7 @@ remove\-targets: .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_elbv2.targets_registered(name, targets, region=None, key=None, keyid=None, profile=None) +.B salt.states.boto_elbv2.targets_registered(name, targets, region=None, key=None, keyid=None, profile=None, **kwargs) New in version 2017.7.0. .sp @@ -290338,7 +309161,7 @@ that contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_iam.group_present(name, policies=None, policies_from_pillars=None, managed_policies=None, users=None, path=\(aq/\(aq, region=None, key=None, keyid=None, profile=None, delete_policies=True) +.B salt.states.boto_iam.group_present(name, policies=None, policies_from_pillars=None, managed_policies=None, users=None, path=u\(aq/\(aq, region=None, key=None, keyid=None, profile=None, delete_policies=True) New in version 2015.8.0. .sp @@ -290363,7 +309186,7 @@ policies defined in the policies argument. If keys conflict, the keys in the policies argument will override the keys defined in policies_from_pillars. .TP -.B manaaged_policies (list) +.B managed_policies (list) A list of policy names or ARNs that should be attached to this group. .TP .B users (list) @@ -290420,7 +309243,7 @@ that contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_iam.keys_present(name, number, save_dir, region=None, key=None, keyid=None, profile=None, save_format=\(aq{2}\en{0}\en{3}\en{1}\en\(aq) +.B salt.states.boto_iam.keys_present(name, number, save_dir, region=None, key=None, keyid=None, profile=None, save_format=u\(aq{2}\en{0}\en{3}\en{1}\en\(aq) .INDENT 7.0 .INDENT 3.5 New in version 2015.8.0. @@ -290533,6 +309356,9 @@ that contains a dict with region, key and keyid. .INDENT 0.0 .TP .B salt.states.boto_iam.saml_provider_absent(name, region=None, key=None, keyid=None, profile=None) +New in version 2016.11.0. + +.sp Ensure the SAML provider with the specified name is absent. .INDENT 7.0 .TP @@ -290559,6 +309385,9 @@ that contains a dict with region, key and keyid. .INDENT 0.0 .TP .B salt.states.boto_iam.saml_provider_present(name, saml_metadata_document, region=None, key=None, keyid=None, profile=None) +New in version 2016.11.0. + +.sp Ensure the SAML provider with the specified name is present. .INDENT 7.0 .TP @@ -291229,7 +310058,7 @@ contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_iot.topic_rule_present(name, ruleName, sql, actions, description=\(aq\(aq, ruleDisabled=False, region=None, key=None, keyid=None, profile=None) +.B salt.states.boto_iot.topic_rule_present(name, ruleName, sql, actions, description=u\(aq\(aq, ruleDisabled=False, region=None, key=None, keyid=None, profile=None) Ensure topic rule exists. .INDENT 7.0 .TP @@ -291638,7 +310467,7 @@ contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_lambda.alias_present(name, FunctionName, Name, FunctionVersion, Description=\(aq\(aq, region=None, key=None, keyid=None, profile=None) +.B salt.states.boto_lambda.alias_present(name, FunctionName, Name, FunctionVersion, Description=u\(aq\(aq, region=None, key=None, keyid=None, profile=None) Ensure alias exists. .INDENT 7.0 .TP @@ -291782,7 +310611,7 @@ contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_lambda.function_present(name, FunctionName, Runtime, Role, Handler, ZipFile=None, S3Bucket=None, S3Key=None, S3ObjectVersion=None, Description=\(aq\(aq, Timeout=3, MemorySize=128, Permissions=None, RoleRetries=5, region=None, key=None, keyid=None, profile=None, VpcConfig=None, Environment=None) +.B salt.states.boto_lambda.function_present(name, FunctionName, Runtime, Role, Handler, ZipFile=None, S3Bucket=None, S3Key=None, S3ObjectVersion=None, Description=u\(aq\(aq, Timeout=3, MemorySize=128, Permissions=None, RoleRetries=5, region=None, key=None, keyid=None, profile=None, VpcConfig=None, Environment=None) Ensure function exists. .INDENT 7.0 .TP @@ -291843,6 +310672,26 @@ to an image processing function. The default value is 128 MB. The value must be If your Lambda function accesses resources in a VPC, you must provide this parameter identifying the list of security group IDs/Names and subnet IDs/Name. These must all belong to the same VPC. This is a dict of the form: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +VpcConfig: + SecurityGroupNames: + \- mysecgroup1 + \- mysecgroup2 + SecurityGroupIds: + \- sg\-abcdef1234 + SubnetNames: + \- mysubnet1 + SubnetIds: + \- subnet\-1234abcd + \- subnet\-abcd1234 +.ft P +.fi +.UNINDENT +.UNINDENT .sp If VpcConfig is provided at all, you MUST pass at least one security group and one subnet. .TP @@ -292031,7 +310880,7 @@ that contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_lc.present(name, image_id, key_name=None, vpc_id=None, vpc_name=None, security_groups=None, user_data=None, cloud_init=None, instance_type=\(aqm1.small\(aq, kernel_id=None, ramdisk_id=None, block_device_mappings=None, delete_on_termination=None, instance_monitoring=False, spot_price=None, instance_profile_name=None, ebs_optimized=False, associate_public_ip_address=None, region=None, key=None, keyid=None, profile=None) +.B salt.states.boto_lc.present(name, image_id, key_name=None, vpc_id=None, vpc_name=None, security_groups=None, user_data=None, cloud_init=None, instance_type=u\(aqm1.small\(aq, kernel_id=None, ramdisk_id=None, block_device_mappings=None, delete_on_termination=None, instance_monitoring=False, spot_price=None, instance_profile_name=None, ebs_optimized=False, associate_public_ip_address=None, region=None, key=None, keyid=None, profile=None) Ensure the launch configuration exists. .INDENT 7.0 .TP @@ -292238,7 +311087,7 @@ boto3 .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_rds.absent(name, skip_final_snapshot=None, final_db_snapshot_identifier=None, tags=None, region=None, key=None, keyid=None, profile=None, wait_for_deletion=True, timeout=180) +.B salt.states.boto_rds.absent(name, skip_final_snapshot=None, final_db_snapshot_identifier=None, tags=None, wait_for_deletion=True, timeout=180, region=None, key=None, keyid=None, profile=None) Ensure RDS instance is absent. .INDENT 7.0 .TP @@ -292257,6 +311106,13 @@ snapshot. .B tags A dict of tags. .TP +.B wait_for_deletion (bool) +Wait for the RDS instance to be deleted completely before finishing +the state. +.TP +.B timeout (in seconds) +The amount of time that can pass before raising an Exception. +.TP .B region Region to connect to. .TP @@ -292270,19 +311126,10 @@ Access key to be used. A dict with region, key and keyid, or a pillar key (string) that contains a dict with region, key and keyid. .UNINDENT -.INDENT 7.0 -.TP -.B wait_for_deletion (bool) -Wait for the RDS instance to be deleted completely before finishing -the state. -.TP -.B timeout (in seconds) -The amount of time that can pass before raising an Exception. -.UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_rds.parameter_present(name, db_parameter_group_family, description, parameters=None, apply_method=\(aqpending\-reboot\(aq, tags=None, region=None, key=None, keyid=None, profile=None) +.B salt.states.boto_rds.parameter_present(name, db_parameter_group_family, description, parameters=None, apply_method=u\(aqpending\-reboot\(aq, tags=None, region=None, key=None, keyid=None, profile=None) Ensure DB parameter group exists and update parameters. .INDENT 7.0 .TP @@ -292329,7 +311176,7 @@ contains a dict with region, key and keyid. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_rds.present(name, allocated_storage, db_instance_class, engine, master_username, master_user_password, db_name=None, storage_type=None, db_security_groups=None, vpc_security_group_ids=None, availability_zone=None, db_subnet_group_name=None, preferred_maintenance_window=None, db_parameter_group_name=None, db_cluster_identifier=None, tde_credential_arn=None, tde_credential_password=None, storage_encrypted=None, kms_keyid=None, backup_retention_period=None, preferred_backup_window=None, port=None, multi_az=None, engine_version=None, auto_minor_version_upgrade=None, license_model=None, iops=None, option_group_name=None, character_set_name=None, publicly_accessible=None, wait_status=None, tags=None, copy_tags_to_snapshot=None, region=None, domain=None, key=None, keyid=None, monitoring_interval=None, monitoring_role_arn=None, domain_iam_role_name=None, promotion_tier=None, profile=None) +.B salt.states.boto_rds.present(name, allocated_storage, db_instance_class, engine, master_username, master_user_password, db_name=None, storage_type=None, db_security_groups=None, vpc_security_group_ids=None, vpc_security_groups=None, availability_zone=None, db_subnet_group_name=None, preferred_maintenance_window=None, db_parameter_group_name=None, db_cluster_identifier=None, tde_credential_arn=None, tde_credential_password=None, storage_encrypted=None, kms_keyid=None, backup_retention_period=None, preferred_backup_window=None, port=None, multi_az=None, engine_version=None, auto_minor_version_upgrade=None, license_model=None, iops=None, option_group_name=None, character_set_name=None, publicly_accessible=None, wait_status=None, tags=None, copy_tags_to_snapshot=None, region=None, domain=None, key=None, keyid=None, monitoring_interval=None, monitoring_role_arn=None, domain_iam_role_name=None, promotion_tier=None, profile=None) Ensure RDS instance exists. .INDENT 7.0 .TP @@ -292371,7 +311218,10 @@ a value for the Iops parameter. A list of DB security groups to associate with this DB instance. .TP .B vpc_security_group_ids -A list of EC2 VPC security groups to associate with this DB instance. +A list of EC2 VPC security group IDs to associate with this DB instance. +.TP +.B vpc_security_groups +A list of EC2 VPC security groups (IDs or Name tags) to associate with this DB instance. .TP .B availability_zone The EC2 Availability Zone that the database instance will be created @@ -292696,23 +311546,21 @@ provided, the value of name will be used. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_route53.hosted_zone_present(name, domain_name=None, private_zone=False, comment=\(aq\(aq, vpc_id=None, vpc_name=None, vpc_region=None, region=None, key=None, keyid=None, profile=None) -Ensure a hosted zone exists with the given attributes. Note that most -things cannot be modified once a zone is created \- it must be deleted and -re\-spun to update these attributes: +.B salt.states.boto_route53.hosted_zone_present(name, domain_name=None, private_zone=False, caller_ref=None, comment=u\(aq\(aq, vpc_id=None, vpc_name=None, vpc_region=None, region=None, key=None, keyid=None, profile=None) +Ensure a hosted zone exists with the given attributes. Note that most things cannot be +modified once a zone is created \- it must be deleted and re\-spun to update these attributes. +If you need the ability to update these attributes, please use the newer boto3_route53 +module instead: .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 private_zone (AWS API limitation). .IP \(bu 2 -.INDENT 2.0 -.TP -.B comment (the appropriate call exists in the AWS API and in boto3, but -has not, as of this writing, been added to boto2). -.UNINDENT +comment (the appropriate call exists in the AWS API and in boto3, but has not, as of +this writing, been added to boto2). .IP \(bu 2 -vpc_id (same story \- we really need to rewrite this module with boto3) +vpc_id (boto3 only) .IP \(bu 2 vpc_name (really just a pointer to vpc_id anyway). .IP \(bu 2 @@ -292723,38 +311571,41 @@ vpc_region (again, supported in boto3 but not boto2). .INDENT 7.0 .TP .B name -The name of the state definition. This will be used as the \(aqcaller_ref\(aq -param if/when creating the hosted zone. +The name of the state definition. .TP .B domain_name -The name of the domain. This should be a fully\-specified domain, and -should terminate with a period. This is the name you have registered -with your DNS registrar. It is also the name you will delegate from your -registrar to the Amazon Route 53 delegation servers returned in response +The name of the domain. This must be fully\-qualified, terminating with a period. This is +the name you have registered with your domain registrar. It is also the name you will +delegate from your registrar to the Amazon Route 53 delegation servers returned in response to this request. Defaults to the value of name if not provided. .TP -.B comment -Any comments you want to include about the hosted zone. -.TP .B private_zone Set True if creating a private hosted zone. .TP +.B caller_ref +A unique string that identifies the request and that allows create_hosted_zone() calls to be +retried without the risk of executing the operation twice. This helps ensure idempotency +across state calls, but can cause issues if a zone is deleted and then an attempt is made +to recreate it with the same caller_ref. If not provided, a unique UUID will be generated +at each state run, which avoids the risk of the above (transient) error. This option is +generally not needed. Maximum length of 128. +.TP +.B comment +Any comments you want to include about the hosted zone. +.TP .B vpc_id -When creating a private hosted zone, either the VPC ID or VPC Name to -associate with is required. Exclusive with vpe_name. Ignored if passed -for a non\-private zone. +When creating a private hosted zone, either the VPC ID or VPC Name to associate with is +required. Exclusive with vpe_name. Ignored when creating a non\-private zone. .TP .B vpc_name -When creating a private hosted zone, either the VPC ID or VPC Name to -associate with is required. Exclusive with vpe_id. Ignored if passed -for a non\-private zone. +When creating a private hosted zone, either the VPC ID or VPC Name to associate with is +required. Exclusive with vpe_id. Ignored when creating a non\-private zone. .TP .B vpc_region -When creating a private hosted zone, the region of the associated VPC is -required. If not provided, an effort will be made to determine it from -vpc_id or vpc_name, if possible. If this fails, you\(aqll need to provide -an explicit value for this option. Ignored if passed for a non\-private -zone. +When creating a private hosted zone, the region of the associated VPC is required. If not +provided, an effort will be made to determine it from vpc_id or vpc_name, where possible. +If this fails, you\(aqll need to provide an explicit value for this option. Ignored when +creating a non\-private zone. .UNINDENT .UNINDENT .INDENT 0.0 @@ -292770,8 +311621,8 @@ Name of the record. .INDENT 7.0 .TP .B Value of the record. As a special case, you can pass in: -private: to have the function autodetermine the private IP -public: to have the function autodetermine the public IP +\fIprivate:\fP to have the function autodetermine the private IP +\fIpublic:\fP to have the function autodetermine the public IP .UNINDENT .TP .B zone @@ -292796,15 +311647,14 @@ Secret key to be used. Access key to be used. .TP .B profile -A dict with region, key and keyid, or a pillar key (string) -that contains a dict with region, key and keyid. +A dict with region, key and keyid, or a pillar key (string) that contains a dict +with region, key and keyid. .TP .B wait_for_sync -Wait for an INSYNC change status from Route53. +Wait for an INSYNC change status from Route53 before returning success. .TP .B split_dns -Route53 supports a public and private DNS zone with the same -names. +Route53 supports parallel public and private DNS zones with the same name. .TP .B private_zone If using split_dns, specify if this is the private zone. @@ -293219,7 +312069,7 @@ New in version 2016.3.0. .UNINDENT .INDENT 0.0 .TP -.B salt.states.boto_secgroup.present(name, description, vpc_id=None, vpc_name=None, rules=None, rules_egress=None, region=None, key=None, keyid=None, profile=None, tags=None) +.B salt.states.boto_secgroup.present(name, description, vpc_id=None, vpc_name=None, rules=None, rules_egress=None, delete_ingress_rules=True, delete_egress_rules=True, region=None, key=None, keyid=None, profile=None, tags=None) Ensure the security group exists with the specified rules. .INDENT 7.0 .TP @@ -293251,6 +312101,16 @@ A list of egress rule dicts. If not specified, \fBrules_egress=None\fP, the egress rules will be unmanaged. If set to an empty list, \fB[]\fP, then all egress rules will be removed. .TP +.B delete_ingress_rules +Some tools (EMR comes to mind) insist on adding rules on\-the\-fly, which +salt will happily remove on the next run. Set this param to False to +avoid deleting rules which were added outside of salt. +.TP +.B delete_egress_rules +Some tools (EMR comes to mind) insist on adding rules on\-the\-fly, which +salt will happily remove on the next run. Set this param to False to +avoid deleting rules which were added outside of salt. +.TP .B region Region to connect to. .TP @@ -294822,6 +313682,16 @@ User to set privilege to .sp Manage Chocolatey package installs .. versionadded:: 2016.3.0 +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Chocolatey pulls data from the Chocolatey internet database to determine +current versions, find available versions, etc. This is normally a slow +operation and may be optimized by specifying a local, smaller chocolatey +repo. +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.states.chocolatey.installed(name, version=None, source=None, force=False, pre_versions=False, install_args=None, override_args=False, force_x86=False, package_args=None, allow_multiple=False) @@ -294907,6 +313777,61 @@ When this is set to False uninstall_args will be appended to the end of the default arguments .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.states.chocolatey.upgraded(name, version=None, source=None, force=False, pre_versions=False, install_args=None, override_args=False, force_x86=False, package_args=None) +Upgrades a package. Will install the package if not installed. +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name of the package to be installed. Required. +.IP \(bu 2 +\fBversion\fP (\fI\%str\fP) \-\- Install a specific version of the package. Defaults to latest +version. If the version is greater than the one installed then the +specified version will be installed. Default is \fBNone\fP\&. +.IP \(bu 2 +\fBsource\fP (\fI\%str\fP) \-\- Chocolatey repository (directory, share or remote URL, feed). +Defaults to the official Chocolatey feed. Default is \fBNone\fP\&. +.IP \(bu 2 +\fBforce\fP (\fI\%bool\fP) \-\- \fBTrue\fP will reinstall an existing package with the same version. +Default is \fBFalse\fP\&. +.IP \(bu 2 +\fBpre_versions\fP (\fI\%bool\fP) \-\- \fBTrue\fP will nclude pre\-release packages. Default is \fBFalse\fP\&. +.IP \(bu 2 +\fBinstall_args\fP (\fI\%str\fP) \-\- Install arguments you want to pass to the installation process, i.e +product key or feature list. Default is \fBNone\fP\&. +.IP \(bu 2 +\fBoverride_args\fP (\fI\%bool\fP) \-\- \fBTrue\fP will override the original install arguments (for the +native installer) in the package and use those specified in +\fBinstall_args\fP\&. \fBFalse\fP will append install_args to the end of +the default arguments. Default is \fBFalse\fP\&. +.IP \(bu 2 +\fBforce_x86\fP (\fI\%bool\fP) \-\- \fBTrue\fP forces 32bit installation on 64 bit systems. Default is +\fBFalse\fP\&. +.IP \(bu 2 +\fBpackage_args\fP (\fI\%str\fP) \-\- Arguments you want to pass to the package. Default is \fBNone\fP\&. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +upgrade_some_package: + chocolatey.upgraded: + \- name: packagename + \- version: \(aq12.04\(aq + \- source: \(aqmychocolatey/source\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.states.chronos_job module .sp Configure Chronos jobs via a salt proxy. @@ -295355,8 +314280,8 @@ Run masterscript: \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -Use \fBcmd.run\fP together with \fBonchanges\fP -instead of \fBcmd.wait\fP\&. +Use \fI\%cmd.run\fP together with onchanges +instead of \fI\%cmd.wait\fP\&. .UNINDENT .UNINDENT .sp @@ -295431,7 +314356,7 @@ printenv: .UNINDENT .INDENT 0.0 .TP -.B salt.states.cmd.call(name, func, args=(), kws=None, onlyif=None, unless=None, creates=None, output_loglevel=\(aqdebug\(aq, use_vt=False, **kwargs) +.B salt.states.cmd.call(name, func, args=(), kws=None, onlyif=None, unless=None, creates=None, output_loglevel=u\(aqdebug\(aq, hide_output=False, use_vt=False, **kwargs) Invoke a pre\-defined Python function with arguments specified in the state declaration. This function is mainly used by the \fBsalt.renderers.pydsl\fP renderer. @@ -295461,7 +314386,7 @@ expected to be a JSON serializable object, and this dictionary is returned: \(aqname\(aq: name \(aqchanges\(aq: {\(aqretval\(aq: result}, \(aqresult\(aq: True if result is None else bool(result), - \(aqcomment\(aq: result if isinstance(result, string_types) else \(aq\(aq + \(aqcomment\(aq: result if isinstance(result, six.string_types) else \(aq\(aq } .ft P .fi @@ -295484,7 +314409,7 @@ Execute a cmd function based on a watch call .UNINDENT .INDENT 0.0 .TP -.B salt.states.cmd.run(name, onlyif=None, unless=None, creates=None, cwd=None, runas=None, shell=None, env=None, stateful=False, umask=None, output_loglevel=\(aqdebug\(aq, quiet=False, timeout=None, ignore_timeout=False, use_vt=False, **kwargs) +.B salt.states.cmd.run(name, onlyif=None, unless=None, creates=None, cwd=None, runas=None, shell=None, env=None, prepend_path=None, stateful=False, umask=None, output_loglevel=u\(aqdebug\(aq, hide_output=False, timeout=None, ignore_timeout=False, use_vt=False, **kwargs) Run a command if certain circumstances are met. Use \fBcmd.wait\fP if you want to use the \fBwatch\fP requisite. .INDENT 7.0 @@ -295495,11 +314420,11 @@ path and permissions of the salt\-minion. .TP .B onlyif A command to run as a check, run the named command only if the command -passed to the \fBonlyif\fP option returns true +passed to the \fBonlyif\fP option returns a zero exit status .TP .B unless A command to run as a check, only run the named command if the command -passed to the \fBunless\fP option returns false +passed to the \fBunless\fP option returns a non\-zero exit status .TP .B cwd The current working directory to execute the command in, defaults to @@ -295571,6 +314496,13 @@ mycommand: .fi .UNINDENT .UNINDENT +.TP +.B prepend_path +$PATH segment to prepend (trailing \(aq:\(aq not necessary) to $PATH. This is +an easier alternative to the Jinja workaround. +.sp +New in version 2018.3.0. + .TP .B stateful The command being executed is expected to return data about executing @@ -295580,15 +314512,40 @@ a state. For more information, see the \fI\%Using the "Stateful" Argument\fP sec The umask (in octal) to use when running the command. .TP .B output_loglevel -Control the loglevel at which the output from the command is logged. -Note that the command being run will still be logged (loglevel: DEBUG) -regardless, unless \fBquiet\fP is used for this value. +debug +Control the loglevel at which the output from the command is logged to +the minion log. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT +.TP +.B hide_output +False +Suppress stdout and stderr in the state\(aqs results. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + .TP .B quiet -The command will be executed quietly, meaning no log entries of the -actual command or its return data. This is deprecated as of the -\fB2014.1.0\fP release, and is being replaced with -\fBoutput_loglevel: quiet\fP\&. +This option no longer has any functionality and will be removed, please +set \fBoutput_loglevel\fP to \fBquiet\fP to suppress logging of the +command. +.sp +Deprecated since version 2014.1.0. + .TP .B timeout If the command has not terminated after timeout seconds, send the @@ -295608,12 +314565,14 @@ New in version 2014.7.0. .TP .B use_vt +False Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. .TP .B bg -If \fBTrue\fP, run command in background and do not await or deliver it\(aqs +False +If \fBTrue\fP, run command in background and do not await or deliver its results. .sp New in version 2016.3.6. @@ -295650,7 +314609,7 @@ getpip: .UNINDENT .INDENT 0.0 .TP -.B salt.states.cmd.script(name, source=None, template=None, onlyif=None, unless=None, creates=None, cwd=None, runas=None, shell=None, env=None, stateful=False, umask=None, timeout=None, use_vt=False, output_loglevel=\(aqdebug\(aq, defaults=None, context=None, **kwargs) +.B salt.states.cmd.script(name, source=None, template=None, onlyif=None, unless=None, creates=None, cwd=None, runas=None, shell=None, env=None, stateful=False, umask=None, timeout=None, use_vt=False, output_loglevel=u\(aqdebug\(aq, hide_output=False, defaults=None, context=None, **kwargs) Download a script and execute it with specified arguments. .INDENT 7.0 .TP @@ -295792,20 +314751,44 @@ New in version 2016.3.0. Default context passed to the template. .TP .B output_loglevel -Control the loglevel at which the output from the command is logged. -Note that the command being run will still be logged (loglevel: DEBUG) -regardless, unless \fBquiet\fP is used for this value. +debug +Control the loglevel at which the output from the command is logged to +the minion log. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT +.TP +.B hide_output +False +Suppress stdout and stderr in the state\(aqs results. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.states.cmd.wait(name, onlyif=None, unless=None, creates=None, cwd=None, runas=None, shell=None, env=(), stateful=False, umask=None, output_loglevel=\(aqdebug\(aq, use_vt=False, **kwargs) +.B salt.states.cmd.wait(name, onlyif=None, unless=None, creates=None, cwd=None, runas=None, shell=None, env=(), stateful=False, umask=None, output_loglevel=u\(aqdebug\(aq, hide_output=False, use_vt=False, **kwargs) Run the given command only if the watch statement calls it. .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -Use \fI\%cmd.run\fP with \fBonchange\fP instead. +Use \fI\%cmd.run\fP together with \fBonchanges\fP +instead of \fI\%cmd.wait\fP\&. .UNINDENT .UNINDENT .INDENT 7.0 @@ -295907,9 +314890,32 @@ New in version 2014.7.0. .TP .B output_loglevel -Control the loglevel at which the output from the command is logged. -Note that the command being run will still be logged (loglevel: DEBUG) -regardless, unless \fBquiet\fP is used for this value. +debug +Control the loglevel at which the output from the command is logged to +the minion log. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. +.UNINDENT +.UNINDENT +.TP +.B hide_output +False +Suppress stdout and stderr in the state\(aqs results. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + .TP .B use_vt Use VT utils (saltstack) to stream the command output more @@ -295919,7 +314925,7 @@ This is experimental. .UNINDENT .INDENT 0.0 .TP -.B salt.states.cmd.wait_script(name, source=None, template=None, onlyif=None, unless=None, cwd=None, runas=None, shell=None, env=None, stateful=False, umask=None, use_vt=False, output_loglevel=\(aqdebug\(aq, **kwargs) +.B salt.states.cmd.wait_script(name, source=None, template=None, onlyif=None, unless=None, cwd=None, runas=None, shell=None, env=None, stateful=False, umask=None, use_vt=False, output_loglevel=u\(aqdebug\(aq, hide_output=False, **kwargs) Download a script from a remote source and execute it only if a watch statement calls it. .INDENT 7.0 @@ -296026,20 +315032,37 @@ The command being executed is expected to return data about executing a state. For more information, see the \fI\%Using the "Stateful" Argument\fP section. .TP .B use_vt -.INDENT 7.0 -.INDENT 3.5 Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. -.UNINDENT -.UNINDENT -.INDENT 7.0 .TP .B output_loglevel -Control the loglevel at which the output from the command is logged. -Note that the command being run will still be logged (loglevel: DEBUG) -regardless, unless \fBquiet\fP is used for this value. +debug +Control the loglevel at which the output from the command is logged to +the minion log. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +The command being run will still be logged at the \fBdebug\fP +loglevel regardless, unless \fBquiet\fP is used for this value. .UNINDENT +.UNINDENT +.TP +.B hide_output +False +Suppress stdout and stderr in the state\(aqs results. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This is separate from \fBoutput_loglevel\fP, which only handles how +Salt logs to the minion log. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + .UNINDENT .UNINDENT .SS salt.states.composer @@ -296086,7 +315109,7 @@ install\-composer: .UNINDENT .INDENT 0.0 .TP -.B salt.states.composer.installed(name, composer=None, php=None, user=None, prefer_source=None, prefer_dist=None, no_scripts=None, no_plugins=None, optimize=None, no_dev=None, quiet=False, composer_home=\(aq/root\(aq, always_check=True) +.B salt.states.composer.installed(name, composer=None, php=None, user=None, prefer_source=None, prefer_dist=None, no_scripts=None, no_plugins=None, optimize=None, no_dev=None, quiet=False, composer_home=u\(aq/root\(aq, always_check=True) Verify that the correct versions of composer dependencies are present. .INDENT 7.0 .TP @@ -296140,7 +315163,7 @@ vendor directory present. .UNINDENT .INDENT 0.0 .TP -.B salt.states.composer.update(name, composer=None, php=None, user=None, prefer_source=None, prefer_dist=None, no_scripts=None, no_plugins=None, optimize=None, no_dev=None, quiet=False, composer_home=\(aq/root\(aq) +.B salt.states.composer.update(name, composer=None, php=None, user=None, prefer_source=None, prefer_dist=None, no_scripts=None, no_plugins=None, optimize=None, no_dev=None, quiet=False, composer_home=u\(aq/root\(aq) Composer update the directory to ensure we have the latest versions of all project dependencies. .INDENT 7.0 @@ -296386,7 +315409,7 @@ This counter part definition will ensure than a job with a special keyword is not set. .INDENT 0.0 .TP -.B salt.states.cron.absent(name, user=\(aqroot\(aq, identifier=False, special=None, **kwargs) +.B salt.states.cron.absent(name, user=u\(aqroot\(aq, identifier=False, special=None, **kwargs) Verifies that the specified cron job is absent for the specified user; only the name is matched when removing a cron job. .INDENT 7.0 @@ -296409,7 +315432,7 @@ Quotes must be used, otherwise PyYAML will strip the \(aq@\(aq sign. .UNINDENT .INDENT 0.0 .TP -.B salt.states.cron.env_absent(name, user=\(aqroot\(aq) +.B salt.states.cron.env_absent(name, user=u\(aqroot\(aq) Verifies that the specified environment variable is absent from the crontab for the specified user .INDENT 7.0 @@ -296424,7 +315447,7 @@ the root user .UNINDENT .INDENT 0.0 .TP -.B salt.states.cron.env_present(name, value=None, user=\(aqroot\(aq) +.B salt.states.cron.env_present(name, value=None, user=u\(aqroot\(aq) Verifies that the specified environment variable is present in the crontab for the specified user. .INDENT 7.0 @@ -296442,7 +315465,7 @@ The value to set for the given environment variable .UNINDENT .INDENT 0.0 .TP -.B salt.states.cron.file(name, source_hash=\(aq\(aq, source_hash_name=None, user=\(aqroot\(aq, template=None, context=None, replace=True, defaults=None, backup=\(aq\(aq, **kwargs) +.B salt.states.cron.file(name, source_hash=u\(aq\(aq, source_hash_name=None, user=u\(aqroot\(aq, template=None, context=None, replace=True, defaults=None, backup=u\(aq\(aq, **kwargs) Provides file.managed\-like functionality (templating, etc.) for a pre\-made crontab file, to be assigned to a given user. .INDENT 7.0 @@ -296550,7 +315573,7 @@ Overrides the default backup mode for the user\(aqs crontab. .UNINDENT .INDENT 0.0 .TP -.B salt.states.cron.present(name, user=\(aqroot\(aq, minute=\(aq*\(aq, hour=\(aq*\(aq, daymonth=\(aq*\(aq, month=\(aq*\(aq, dayweek=\(aq*\(aq, comment=None, commented=False, identifier=False, special=None) +.B salt.states.cron.present(name, user=u\(aqroot\(aq, minute=u\(aq*\(aq, hour=u\(aq*\(aq, daymonth=u\(aq*\(aq, month=u\(aq*\(aq, dayweek=u\(aq*\(aq, comment=None, commented=False, identifier=False, special=None) Verifies that the specified cron job is present for the specified user. For more advanced information about what exactly can be set in the cron timing parameters, check your cron system\(aqs documentation. Most Unix\-like @@ -296605,6 +315628,32 @@ New in version 2016.3.0. .UNINDENT .UNINDENT .SS salt.states.csf module +.SS CSF Ip tables management +.INDENT 0.0 +.TP +.B depends +.INDENT 7.0 +.IP \(bu 2 +csf utility +.UNINDENT +.TP +.B configuration +See \fI\%http://download.configserver.com/csf/install.txt\fP +for setup instructions. +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +Simply allow/deny rules: + csf.rule_present: + ip: 1.2.3.4 + method: allow +.ft P +.fi +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.states.csf.nics_skip(name, nics, ipv6) @@ -296644,7 +315693,7 @@ Boolean. If set to true, csf will be reloaded after. .UNINDENT .INDENT 0.0 .TP -.B salt.states.csf.ports_open(name, ports, proto=\(aqtcp\(aq, direction=\(aqin\(aq) +.B salt.states.csf.ports_open(name, ports, proto=u\(aqtcp\(aq, direction=u\(aqin\(aq) Ensure ports are open for a protocol, in a direction. e.g. \- proto=\(aqtcp\(aq, direction=\(aqin\(aq would set the values for TCP_IN in the csf.conf file. @@ -296665,7 +315714,7 @@ traffic, or both. .UNINDENT .INDENT 0.0 .TP -.B salt.states.csf.rule_absent(name, method, port=None, proto=\(aqtcp\(aq, direction=\(aqin\(aq, port_origin=\(aqd\(aq, ip_origin=\(aqs\(aq, ttl=None, reload=False) +.B salt.states.csf.rule_absent(name, method, port=None, proto=u\(aqtcp\(aq, direction=u\(aqin\(aq, port_origin=u\(aqd\(aq, ip_origin=u\(aqs\(aq, ttl=None, reload=False) Ensure iptable is not present. .INDENT 7.0 .TP @@ -296709,7 +315758,7 @@ Default false. .UNINDENT .INDENT 0.0 .TP -.B salt.states.csf.rule_present(name, method, port=None, proto=\(aqtcp\(aq, direction=\(aqin\(aq, port_origin=\(aqd\(aq, ip_origin=\(aqs\(aq, ttl=None, comment=\(aq\(aq, reload=False) +.B salt.states.csf.rule_present(name, method, port=None, proto=u\(aqtcp\(aq, direction=u\(aqin\(aq, port_origin=u\(aqd\(aq, ip_origin=u\(aqs\(aq, ttl=None, comment=u\(aq\(aq, reload=False) Ensure iptable rule exists. .INDENT 7.0 .TP @@ -296836,7 +315885,7 @@ Return a set of the keys with unchanged values. .UNINDENT .INDENT 0.0 .TP -.B salt.states.cyg.installed(name, cyg_arch=\(aqx86_64\(aq, mirrors=None) +.B salt.states.cyg.installed(name, cyg_arch=u\(aqx86_64\(aq, mirrors=None) Make sure that a package is installed. .INDENT 7.0 .TP @@ -296872,7 +315921,7 @@ rsync: .UNINDENT .INDENT 0.0 .TP -.B salt.states.cyg.removed(name, cyg_arch=\(aqx86_64\(aq, mirrors=None) +.B salt.states.cyg.removed(name, cyg_arch=u\(aqx86_64\(aq, mirrors=None) Make sure that a package is not installed. .INDENT 7.0 .TP @@ -296908,7 +315957,7 @@ rsync: .UNINDENT .INDENT 0.0 .TP -.B salt.states.cyg.updated(name=None, cyg_arch=\(aqx86_64\(aq, mirrors=None) +.B salt.states.cyg.updated(name=None, cyg_arch=u\(aqx86_64\(aq, mirrors=None) Make sure all packages are up to date. .INDENT 7.0 .TP @@ -297014,7 +316063,7 @@ follow the \fI\%dnspython\fP spec. .UNINDENT .INDENT 0.0 .TP -.B salt.states.ddns.present(name, zone, ttl, data, rdtype=\(aqA\(aq, **kwargs) +.B salt.states.ddns.present(name, zone, ttl, data, rdtype=u\(aqA\(aq, **kwargs) Ensures that the named DNS record is present with the given ttl. .INDENT 7.0 .TP @@ -297490,7 +316539,7 @@ my\-dell\-chassis: .UNINDENT .INDENT 0.0 .TP -.B salt.states.dellchassis.firmware_update(hosts=None, directory=\(aq\(aq) +.B salt.states.dellchassis.firmware_update(hosts=None, directory=u\(aq\(aq) .INDENT 7.0 .INDENT 3.5 State to update the firmware on host @@ -297896,7 +316945,125 @@ multiple_containers: .UNINDENT .INDENT 0.0 .TP -.B salt.states.docker_container.running(name, image=None, skip_translate=None, ignore_collisions=False, validate_ip_addrs=True, force=False, watch_action=\(aqforce\(aq, start=True, shutdown_timeout=10, client_timeout=60, **kwargs) +.B salt.states.docker_container.mod_run_check(onlyif, unless, creates) +Execute the onlyif/unless/creates logic. Returns a result dict if any of +the checks fail, otherwise returns True +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.docker_container.run(name, image=None, onlyif=None, unless=None, creates=None, bg=False, failhard=True, replace=False, force=False, skip_translate=None, ignore_collisions=False, validate_ip_addrs=True, client_timeout=60, **kwargs) +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +If no tag is specified in the image name, and nothing matching the +specified image is pulled on the minion, the \fBdocker pull\fP that +retrieves the image will pull \fIall tags\fP for the image. A tag of +\fBlatest\fP is not implicit for the pull. For this reason, it is +recommended to specify the image in \fBrepo:tag\fP notation. +.UNINDENT +.UNINDENT +.sp +Like the \fBcmd.run\fP state, only for Docker. +Does the equivalent of a \fBdocker run\fP and returns information about the +container that was created, as well as its output. +.sp +This state accepts the same arguments as \fI\%docker_container.running\fP, with the exception of +\fBwatch_action\fP, \fBstart\fP, and \fBshutdown_timeout\fP (though the \fBforce\fP +argument has a different meaning in this state). +.sp +In addition, this state accepts the arguments from \fBdocker.logs\fP, with the exception of \fBfollow\fP, to +control how logs are returned. +.sp +Additionally, the following arguments are supported: +.INDENT 7.0 +.TP +.B onlyif +A command or list of commands to run as a check. The container will +only run if any of the specified commands returns a zero exit status. +.TP +.B unless +A command or list of commands to run as a check. The container will +only run if any of the specified commands returns a non\-zero exit +status. +.TP +.B creates +A path or list of paths. Only run if one or more of the specified paths +do not exist on the minion. +.TP +.B bg +False +If \fBTrue\fP, run container in background and do not await or deliver +its results. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This may not be useful in cases where other states depend on the +results of this state. Also, the logs will be inaccessible once the +container exits if \fBauto_remove\fP is set to \fBTrue\fP, so keep this +in mind. +.UNINDENT +.UNINDENT +.TP +.B failhard +True +If \fBTrue\fP, the state will return a \fBFalse\fP result if the exit code +of the container is non\-zero. When this argument is set to \fBFalse\fP, +the state will return a \fBTrue\fP result regardless of the container\(aqs +exit code. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This has no effect if \fBbg\fP is set to \fBTrue\fP\&. +.UNINDENT +.UNINDENT +.TP +.B replace +False +If \fBTrue\fP, and if the named container already exists, this will +remove the existing container. The default behavior is to return a +\fBFalse\fP result when the container already exists. +.TP +.B force +False +If \fBTrue\fP, and the named container already exists, \fIand\fP \fBreplace\fP +is also set to \fBTrue\fP, then the container will be forcibly removed. +Otherwise, the state will not proceed and will return a \fBFalse\fP +result. +.UNINDENT +.sp +CLI Examples: +.sp +\fBUSAGE EXAMPLE\fP +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{% set pkg_version = salt.pillar.get(\(aqpkg_version\(aq, \(aq1.0\-1\(aq) %} +build_package: + docker_container.run: + \- image: myuser/builder:latest + \- binds: /home/myuser/builds:/build_dir + \- command: /scripts/build.sh {{ pkg_version }} + \- creates: /home/myuser/builds/myapp\-{{ pkg_version }}.noarch.rpm + \- replace: True + \- networks: + \- mynet + \- require: + \- docker_network: mynet +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.docker_container.running(name, image=None, skip_translate=None, ignore_collisions=False, validate_ip_addrs=True, force=False, watch_action=u\(aqforce\(aq, start=True, shutdown_timeout=None, client_timeout=60, networks=None, **kwargs) Ensure that a container with a specific configuration is present and running .INDENT 7.0 @@ -297905,9 +317072,7 @@ running Name of the container .TP .B image -Image to use for the container. Image names can be specified either -using \fBrepo:tag\fP notation, or just the repo name (in which case a tag -of \fBlatest\fP is assumed). +Image to use for the container .sp \fBNOTE:\fP .INDENT 7.0 @@ -297920,6 +317085,13 @@ replacement of the container when the image is updated, then the manage the image. .UNINDENT .UNINDENT +.sp +Changed in version 2018.3.0: If no tag is specified in the image name, and nothing matching the +specified image is pulled on the minion, the \fBdocker pull\fP that +retrieves the image will pull \fIall tags\fP for the image. A tag of +\fBlatest\fP is no longer implicit for the pull. For this reason, it +is recommended to specify the image in \fBrepo:tag\fP notation. + .UNINDENT .INDENT 7.0 .TP @@ -297969,7 +317141,7 @@ mycontainer: docker_container.running: \- image: 7.3.1611 \- skip_translate: port_bindings - \- port_bindings: {8080: [(\(aq10.2.9.10\(aq, 80)], \(aq4193/udp\(aq, 9314} + \- port_bindings: {8080: [(\(aq10.2.9.10\(aq, 80)], \(aq4193/udp\(aq: 9314} .ft P .fi .UNINDENT @@ -298053,11 +317225,11 @@ instances such as this, the container only needs to be started the first time. .TP .B shutdown_timeout -10 If the container needs to be replaced, the container will be stopped -using \fBdocker.stop\fP\&. The value -of this parameter will be passed to \fBdocker.stop\fP as the \fBtimeout\fP value, telling Docker -how long to wait for a graceful shutdown before killing the container. +using \fBdocker.stop\fP\&. If a +\fBshutdown_timout\fP is not set, and the container was created using +\fBstop_timeout\fP, that timeout will be used. If neither of these values +were set, then a timeout of 10 seconds will be used. .sp Changed in version 2017.7.0: This option was renamed from \fBstop_timeout\fP to \fBshutdown_timeout\fP to acommodate the \fBstop_timeout\fP container @@ -298077,6 +317249,52 @@ This is only used if Salt needs to pull the requested image. .UNINDENT .UNINDENT .sp +\fBNETWORK MANAGEMENT\fP +.sp +New in version 2018.3.0. + +.sp +The \fBnetworks\fP argument can be used to ensure that a container is +attached to one or more networks. Optionally, arguments can be passed to +the networks. In the example below, \fBnet1\fP is being configured with +arguments, while \fBnet2\fP is being configured \fIwithout\fP arguments: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +foo: + docker_container.running: + \- image: myuser/myimage:foo + \- networks: + \- net1: + \- aliases: + \- bar + \- baz + \- ipv4_address: 10.0.20.50 + \- net2 + \- require: + \- docker_network: net1 + \- docker_network: net2 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The supported arguments are the ones from the docker\-py\(aqs +\fI\%connect_container_to_network\fP function (other than \fBcontainer\fP and +\fBnet_id\fP). +.sp +\fBIMPORTANT:\fP +.INDENT 7.0 +.INDENT 3.5 +Unlike with the arguments described in the \fBCONTAINER CONFIGURATION +PARAMETERS\fP section below, these network configuration parameters are +not translated at all. Consult the \fI\%connect_container_to_network\fP +documentation for the correct type/format of data to pass. +.UNINDENT +.UNINDENT +.sp \fBCONTAINER CONFIGURATION PARAMETERS\fP .INDENT 7.0 .TP @@ -298123,7 +317341,7 @@ Additionally, the specified selinux context will be set within the container. .UNINDENT .sp -\fB\fP can be either \fBro\fP for read\-write access, or \fBro\fP +\fB\fP can be either \fBrw\fP for read\-write access, or \fBro\fP for read\-only access. When omitted, it is assumed to be read\-write. .sp \fB\fP can be \fBz\fP if the volume is shared between @@ -299017,105 +318235,51 @@ default value on Windows client is \fBhyperv\fP\&. On Linux, only .TP .B labels Add metadata to the container. Labels can be set both with and without -values: -.sp -\fBWITH VALUES\fP -.sp -The below three examples are equivalent: -.INDENT 7.0 -.INDENT 3.5 -.sp +values, and labels with values can be passed either as \fBkey=value\fP or + .nf -.ft C -foo: - docker_container.running: - \- image: bar/baz:latest - \- labels: label1=value1,label2=value2 -.ft P +\(ga\(ga .fi -.UNINDENT -.UNINDENT +key: value \(ga\(ga pairs. For example, while the below would be very +confusing to read, it is technically valid, and demonstrates the +different ways in which labels can be passed: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C -foo: - docker_container.running: - \- image: bar/baz:latest +mynet: + docker_network.present: \- labels: - \- label1=value1 - \- label2=value2 + \- foo + \- bar=baz + \- hello: world .ft P .fi .UNINDENT .UNINDENT +.sp +The labels can also simply be passed as a YAML dictionary, though this +can be error\-prone due to some idiosyncrasies with how PyYAML loads nested data structures: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C foo: - docker_container.running: - \- image: bar/baz:latest + docker_network.present: \- labels: - \- label1: value1 - \- label2: value2 + foo: \(aq\(aq + bar: baz + hello: world .ft P .fi .UNINDENT .UNINDENT .sp -The labels can also simply be passed as a dictionary, though this can -be error\-prone due to some idiosyncrasies -with how PyYAML loads nested data structures: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -foo: - docker_container.running: - \- image: bar/baz:latest - \- labels: - label1: value1 - label2: value2 -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -\fBWITHOUT VALUES\fP -.sp -The below two examples are equivalent: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -foo: - docker_container.running: - \- image: bar/baz:latest - \- labels: label1,label2 -.ft P -.fi -.UNINDENT -.UNINDENT -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -foo: - docker_container.running: - \- image: bar/baz:latest - \- labels: - \- label1 - \- label2 -.ft P -.fi -.UNINDENT -.UNINDENT +Changed in version 2018.3.0: Methods for specifying labels can now be mixed. Earlier releases +required either labels with or without values. + .TP .B links Link this container to another. Links can be specified as a list of @@ -299598,6 +318762,19 @@ foo: .B privileged False If \fBTrue\fP, runs the exec process with extended privileges +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +foo: + docker_container.running: + \- image: bar/baz:lates + \- privileged: True +.ft P +.fi +.UNINDENT +.UNINDENT .TP .B publish_all_ports (or \fIpublish_all\fP) False @@ -300081,7 +319258,7 @@ foo: .UNINDENT .INDENT 0.0 .TP -.B salt.states.docker_container.stopped(name=None, containers=None, shutdown_timeout=10, unpause=False, error_on_absent=True) +.B salt.states.docker_container.stopped(name=None, containers=None, shutdown_timeout=None, unpause=False, error_on_absent=True, **kwargs) Ensure that a container (or containers) is stopped .INDENT 7.0 .TP @@ -300127,9 +319304,11 @@ all specified containers in a single run, rather than executing the state separately on each image (as it would in the first example). .TP .B shutdown_timeout -10 Timeout for graceful shutdown of the container. If this timeout is -exceeded, the container will be killed. +exceeded, the container will be killed. If this value is not passed, +then the container\(aqs configured \fBstop_timeout\fP will be observed. If +\fBstop_timeout\fP was also unset on the container, then a timeout of 10 +seconds will be used. .TP .B unpause False @@ -300280,31 +319459,40 @@ For more granular control, setting a pillar variable named .UNINDENT .INDENT 0.0 .TP -.B salt.states.docker_image.present(name, build=None, load=None, force=False, insecure_registry=False, client_timeout=60, dockerfile=None, sls=None, base=\(aqopensuse/python\(aq, saltenv=\(aqbase\(aq, **kwargs) -Ensure that an image is present. The image can either be pulled from a -Docker registry, built from a Dockerfile, or loaded from a saved image. -Image names can be specified either using \fBrepo:tag\fP notation, or just -the repo name (in which case a tag of \fBlatest\fP is assumed). -Repo identifier is mandatory, we don\(aqt assume the default repository -is docker hub. +.B salt.states.docker_image.present(name, tag=None, build=None, load=None, force=False, insecure_registry=False, client_timeout=60, dockerfile=None, sls=None, base=u\(aqopensuse/python\(aq, saltenv=u\(aqbase\(aq, pillarenv=None, pillar=None, **kwargs) +Changed in version 2018.3.0: The \fBtag\fP argument has been added. It is now required unless pulling +from a registry. + .sp -If neither of the \fBbuild\fP or \fBload\fP arguments are used, then Salt will -pull from the configured registries\&. If the -specified image already exists, it will not be pulled unless \fBforce\fP is -set to \fBTrue\fP\&. Here is an example of a state that will pull an image from -the Docker Hub: +Ensure that an image is present. The image can either be pulled from a +Docker registry, built from a Dockerfile, loaded from a saved image, or +built by running SLS files against a base image. +.sp +If none of the \fBbuild\fP, \fBload\fP, or \fBsls\fP arguments are used, then Salt +will pull from the configured registries\&. If +the specified image already exists, it will not be pulled unless \fBforce\fP +is set to \fBTrue\fP\&. Here is an example of a state that will pull an image +from the Docker Hub: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C -myuser/myimage:mytag: - docker_image.present +myuser/myimage: + docker_image.present: + \- tag: mytag .ft P .fi .UNINDENT .UNINDENT .INDENT 7.0 +.TP +.B tag +Tag name for the image. Required when using \fBbuild\fP, \fBload\fP, or +\fBsls\fP to create the image, but optional if pulling from a repository. +.sp +New in version 2018.3.0. + .TP .B build Path to directory on the Minion containing a Dockerfile @@ -300313,25 +319501,29 @@ Path to directory on the Minion containing a Dockerfile .sp .nf .ft C -myuser/myimage:mytag: +myuser/myimage: docker_image.present: \- build: /home/myuser/docker/myimage + \- tag: mytag - -myuser/myimage:mytag: +myuser/myimage: docker_image.present: \- build: /home/myuser/docker/myimage + \- tag: mytag \- dockerfile: Dockerfile.alternative .ft P .fi .UNINDENT .UNINDENT .sp +The image will be built using \fBdocker.build\fP and the specified image name and tag +will be applied to it. +.sp New in version 2016.11.0. .sp -The image will be built using \fBdocker.build\fP and the specified image name and tag -will be applied to it. +Changed in version 2018.3.0: The \fBtag\fP must be manually specified using the \fBtag\fP argument. + .TP .B load Loads a tar archive created with \fBdocker.load\fP (or the \fBdocker load\fP Docker CLI @@ -300341,13 +319533,17 @@ command), and assigns it the specified repo and tag. .sp .nf .ft C -myuser/myimage:mytag: +myuser/myimage: docker_image.present: \- load: salt://path/to/image.tar + \- tag: mytag .ft P .fi .UNINDENT .UNINDENT +.sp +Changed in version 2018.3.0: The \fBtag\fP must be manually specified using the \fBtag\fP argument. + .TP .B force False @@ -300373,8 +319569,9 @@ which to build. This can be a list or comma\-seperated string. .sp .nf .ft C -myuser/myimage:mytag: +myuser/myimage: docker_image.present: + \- tag: latest \- sls: \- webapp1 \- webapp2 @@ -300384,12 +319581,50 @@ myuser/myimage:mytag: .fi .UNINDENT .UNINDENT +.sp +Changed in version 2018.3.0: The \fBtag\fP must be manually specified using the \fBtag\fP argument. + .TP .B base Base image with which to start \fBdocker.sls_build\fP +.sp +New in version 2017.7.0. + .TP .B saltenv -Environment from which to pull SLS files for \fBdocker.sls_build\fP +Specify the environment from which to retrieve the SLS indicated by the +\fImods\fP parameter. +.sp +New in version 2017.7.0. + +.sp +Changed in version 2018.3.0: Now uses the effective saltenv if not explicitly passed. In earlier +versions, \fBbase\fP was assumed as a default. + +.TP +.B pillarenv +Specify a Pillar environment to be used when applying states. This +can also be set in the minion config file using the +\fBpillarenv\fP option. When neither the +\fBpillarenv\fP minion config option nor this CLI argument is +used, all Pillar environments will be merged together. +.sp +New in version 2018.3.0. + +.TP +.B pillar +Custom Pillar values, passed as a dictionary of key\-value pairs +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Values passed this way will override Pillar values set via +\fBpillar_roots\fP or an external Pillar source. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + .UNINDENT .UNINDENT .SS salt.states.docker_network @@ -300450,7 +319685,7 @@ Ensure that a network is absent. Name of the network .UNINDENT .sp -Usage Examples: +Usage Example: .INDENT 7.0 .INDENT 3.5 .sp @@ -300465,28 +319700,170 @@ network_foo: .UNINDENT .INDENT 0.0 .TP -.B salt.states.docker_network.present(name, driver=None, containers=None) -Ensure that a network is present. +.B salt.states.docker_network.present(name, skip_translate=None, ignore_collisions=False, validate_ip_addrs=True, containers=None, reconnect=True, **kwargs) +Changed in version 2018.3.0: Support added for network configuration options other than \fBdriver\fP +and \fBdriver_opts\fP, as well as IPAM configuration. + +.sp +Ensure that a network is present +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This state supports all arguments for network and IPAM pool +configuration which are available for the release of docker\-py +installed on the minion. For that reason, the arguments described below +in the \fI\%NETWORK CONFIGURATION\fP and \fI\%IP ADDRESS +MANAGEMENT (IPAM)\fP sections +may not accurately reflect what is available on the minion. The +\fBdocker.get_client_args\fP function can be used to check +the available arguments for the installed version of docker\-py (they +are found in the \fBnetwork_config\fP and \fBipam_config\fP sections of the +return data), but Salt will not prevent a user from attempting to use +an argument which is unsupported in the release of Docker which is +installed. In those cases, network creation be attempted but will fail. +.UNINDENT +.UNINDENT .INDENT 7.0 .TP .B name -Name of the network +Network name .TP -.B driver -Type of driver for that network. -.TP -.B containers: -List of container names that should be part of this network +.B skip_translate +This function translates Salt SLS input into the format which +docker\-py expects. However, in the event that Salt\(aqs translation logic +fails (due to potential changes in the Docker Remote API, or to bugs in +the translation code), this argument can be used to exert granular +control over which arguments are translated and which are not. +.sp +Pass this argument as a comma\-separated list (or Python list) of +arguments, and translation for each passed argument name will be +skipped. Alternatively, pass \fBTrue\fP and \fIall\fP translation will be +skipped. +.sp +Skipping tranlsation allows for arguments to be formatted directly in +the format which docker\-py expects. This allows for API changes and +other issues to be more easily worked around. See the following links +for more information: +.INDENT 7.0 +.IP \(bu 2 +\fI\%docker\-py Low\-level API\fP +.IP \(bu 2 +\fI\%Docker Engine API\fP .UNINDENT .sp -Usage Examples: +New in version 2018.3.0. + +.UNINDENT +.INDENT 7.0 +.TP +.B ignore_collisions +False +Since many of docker\-py\(aqs arguments differ in name from their CLI +counterparts (with which most Docker users are more familiar), Salt +detects usage of these and aliases them to the docker\-py version of +that argument. However, if both the alias and the docker\-py version of +the same argument (e.g. \fBoptions\fP and \fBdriver_opts\fP) are used, an error +will be raised. Set this argument to \fBTrue\fP to suppress these errors +and keep the docker\-py version of the argument. +.sp +New in version 2018.3.0. + +.TP +.B validate_ip_addrs +True +For parameters which accept IP addresses/subnets as input, validation +will be performed. To disable, set this to \fBFalse\fP\&. +.sp +New in version 2018.3.0. + +.TP +.B containers +A list of containers which should be connected to this network. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +As of the 2018.3.0 release, this is not the recommended way of +managing a container\(aqs membership in a network, for a couple +reasons: +.INDENT 0.0 +.IP 1. 3 +It does not support setting static IPs, aliases, or links in the +container\(aqs IP configuration. +.IP 2. 3 +If a \fBdocker_container.running\fP state replaces a +container, it will not be reconnected to the network until the +\fBdocker_network.present\fP state is run again. Since containers +often have \fBrequire\fP requisites to ensure that the network +is present, this means that the \fBdocker_network.present\fP state +ends up being run \fIbefore\fP the \fBdocker_container.running\fP, leaving the container +unattached at the end of the Salt run. +.UNINDENT +.sp +For these reasons, it is recommended to use +docker_container.running\(aqs network management support\&. +.UNINDENT +.UNINDENT +.TP +.B reconnect +True +If \fBcontainers\fP is not used, and the network is replaced, then Salt +will keep track of the containers which were connected to the network +and reconnect them to the network after it is replaced. Salt will first +attempt to reconnect using the same IP the container had before the +network was replaced. If that fails (for instance, if the network was +replaced because the subnet was modified), then the container will be +reconnected without an explicit IP address, and its IP will be assigned +by Docker. +.sp +Set this option to \fBFalse\fP to keep Salt from trying to reconnect +containers. This can be useful in some cases when managing static +IPs in docker_container.running\&. For instance, if a +network\(aqs subnet is modified, it is likely that the static IP will need +to be updated in the \fBdocker_container.running\fP state as well. When +the network is replaced, the initial reconnect attempt would fail, and +the container would be reconnected with an automatically\-assigned IP +address. Then, when the \fBdocker_container.running\fP state executes, it +would disconnect the network \fIagain\fP and reconnect using the new static +IP. Disabling the reconnect behavior in these cases would prevent the +unnecessary extra reconnection. +.sp +New in version 2018.3.0. + +.UNINDENT +.sp +\fBNETWORK CONFIGURATION ARGUMENTS\fP +.INDENT 7.0 +.TP +.B driver +Network driver .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C -network_foo: - docker_network.present +mynet: + docker_network.present: + \- driver: macvlan +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B driver_opts (or \fIdriver_opt\fP, or \fIoptions\fP) +Options for the network driver. Either a dictionary of option names and +values or a Python list of strings in the format \fBvarname=value\fP\&. The +below three examples are equivalent: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- driver: macvlan + \- driver_opts: macvlan_mode=bridge,parent=eth0 .ft P .fi .UNINDENT @@ -300496,12 +319873,412 @@ network_foo: .sp .nf .ft C -network_bar: - docker_network.present - \- name: bar - \- containers: - \- cont1 - \- cont2 +mynet: + docker_network.present: + \- driver: macvlan + \- driver_opts: + \- macvlan_mode=bridge + \- parent=eth0 +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- driver: macvlan + \- driver_opts: + \- macvlan_mode: bridge + \- parent: eth0 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The options can also simply be passed as a dictionary, though this can +be error\-prone due to some idiosyncrasies +with how PyYAML loads nested data structures: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- driver: macvlan + \- driver_opts: + macvlan_mode: bridge + parent: eth0 +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B check_duplicate +True +If \fBTrue\fP, checks for networks with duplicate names. Since networks +are primarily keyed based on a random ID and not on the name, and +network name is strictly a user\-friendly alias to the network which is +uniquely identified using ID, there is no guaranteed way to check for +duplicates. This option providess a best effort, checking for any +networks which have the same name, but it is not guaranteed to catch +all name collisions. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- check_duplicate: False +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B internal +False +If \fBTrue\fP, restricts external access to the network +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- internal: True +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B labels +Add metadata to the network. Labels can be set both with and without +values, and labels with values can be passed either as \fBkey=value\fP or + +.nf +\(ga\(ga +.fi +key: value \(ga\(ga pairs. For example, while the below would be very +confusing to read, it is technically valid, and demonstrates the +different ways in which labels can be passed: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- labels: + \- foo + \- bar=baz + \- hello: world +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The labels can also simply be passed as a YAML dictionary, though this +can be error\-prone due to some idiosyncrasies with how PyYAML loads nested data structures: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +foo: + docker_network.present: + \- labels: + foo: \(aq\(aq + bar: baz + hello: world +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Changed in version 2018.3.0: Methods for specifying labels can now be mixed. Earlier releases +required either labels with or without values. + +.TP +.B enable_ipv6 (or \fIipv6\fP) +False +Enable IPv6 on the network +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- enable_ipv6: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +While it should go without saying, this argument must be set to +\fBTrue\fP to \fI\%configure an IPv6 subnet\fP\&. Also, if this option is +turned on without an IPv6 subnet explicitly configured, you will +get an error unless you have set up a fixed IPv6 subnet. Consult +the +.nf +\(gaDocker IPv6 docs\(ga_ +.fi + for information on how to do this. +.UNINDENT +.UNINDENT +.TP +.B attachable +False +If \fBTrue\fP, and the network is in the global scope, non\-service +containers on worker nodes will be able to connect to the network. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- attachable: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option cannot be reliably managed on CentOS 7. This is because +while support for this option was added in API version 1.24, its +value was not added to the inpsect results until API version 1.26. +The version of Docker which is available for CentOS 7 runs API +version 1.24, meaning that while Salt can pass this argument to the +API, it has no way of knowing the value of this config option in an +existing Docker network. +.UNINDENT +.UNINDENT +.TP +.B scope +Specify the network\(aqs scope (\fBlocal\fP, \fBglobal\fP or \fBswarm\fP) +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- scope: local +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B ingress +False +If \fBTrue\fP, create an ingress network which provides the routing\-mesh in +swarm mode +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- ingress: True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.sp +\fBIP ADDRESS MANAGEMENT (IPAM)\fP +.sp +This state supports networks with either IPv4, or both IPv4 and IPv6. If +configuring IPv4, then you can pass the \fI\%IPAM pool arguments +\(ga\fP below as +individual arguments. However, if configuring IPv4 and IPv6, the arguments +must be passed as a list of dictionaries, in the \fBipam_pools\fP argument +(click \fI\%here\fP for +some examples). \fI\%These docs\fP also have more information on these +arguments. +.sp +\fIIPAM ARGUMENTS\fP +.INDENT 7.0 +.TP +.B ipam_driver +IPAM driver to use, if different from the default one +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- ipam_driver: foo +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B ipam_opts +Options for the IPAM driver. Either a dictionary of option names and +values or a Python list of strings in the format \fBvarname=value\fP\&. The +below three examples are equivalent: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- ipam_driver: foo + \- ipam_opts: foo=bar,baz=qux +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- ipam_driver: foo + \- ipam_opts: + \- foo=bar + \- baz=qux +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- ipam_driver: foo + \- ipam_opts: + \- foo: bar + \- baz: qux +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The options can also simply be passed as a dictionary, though this can +be error\-prone due to some idiosyncrasies +with how PyYAML loads nested data structures: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- ipam_driver: macvlan + \- ipam_opts: + foo: bar + baz: qux +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.sp +\fIIPAM POOL ARGUMENTS\fP +.INDENT 7.0 +.TP +.B subnet +Subnet in CIDR format that represents a network segment +.TP +.B iprange (or \fIip_range\fP) +Allocate container IP from a sub\-range within the subnet +.sp +Subnet in CIDR format that represents a network segment +.TP +.B gateway +IPv4 or IPv6 gateway for the master subnet +.TP +.B aux_addresses (or \fIaux_address\fP) +A dictionary of mapping container names to IP addresses which should be +allocated for them should they connect to the network. Either a +dictionary of option names and values or a Python list of strings in +the format \fBhost=ipaddr\fP\&. +.UNINDENT +.sp +\fIIPAM CONFIGURATION EXAMPLES\fP +.sp +Below is an example of an IPv4\-only network (keep in mind that \fBsubnet\fP +is the only required argument). +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- subnet: 10.0.20.0/24 + \- iprange: 10.0.20.128/25 + \- gateway: 10.0.20.254 + \- aux_addresses: + \- foo.bar.tld: 10.0.20.50 + \- hello.world.tld: 10.0.20.51 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +The \fBaux_addresses\fP can be passed differently, in the same way that +\fBdriver_opts\fP and \fBipam_opts\fP can. +.UNINDENT +.UNINDENT +.sp +This same network could also be configured this way: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- ipam_pools: + \- subnet: 10.0.20.0/24 + iprange: 10.0.20.128/25 + gateway: 10.0.20.254 + aux_addresses: + foo.bar.tld: 10.0.20.50 + hello.world.tld: 10.0.20.51 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Here is an example of a mixed IPv4/IPv6 subnet. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mynet: + docker_network.present: + \- ipam_pools: + \- subnet: 10.0.20.0/24 + gateway: 10.0.20.1 + \- subnet: fe3f:2180:26:1::/123 + gateway: fe3f:2180:26:1::1 .ft P .fi .UNINDENT @@ -300876,7 +320653,7 @@ Name of the index to remove .UNINDENT .INDENT 0.0 .TP -.B salt.states.elasticsearch.index_template_present(name, definition) +.B salt.states.elasticsearch.index_template_present(name, definition, check_definition=False) Ensure that the named index templat eis present. .INDENT 7.0 .TP @@ -300885,6 +320662,9 @@ Name of the index to add .TP .B definition Required dict for creation parameters as per \fI\%https://www.elastic.co/guide/en/elasticsearch/reference/current/indices\-templates.html\fP +.TP +.B check_definition +If the template already exists and the definition is up to date .UNINDENT .sp \fBExample:\fP @@ -301025,6 +320805,26 @@ Optional dict for creation parameters as per \fI\%https://www.elastic.co/guide/e .UNINDENT .sp \fBExample:\fP +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Default settings +mytestindex: + elasticsearch_index.present + +# Extra settings +mytestindex2: + elasticsearch_index.present: + \- definition: + settings: + index: + number_of_shards: 10 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .SS salt.states.elasticsearch_index_template .sp @@ -301065,6 +320865,22 @@ Required dict for creation parameters as per \fI\%https://www.elastic.co/guide/e .UNINDENT .sp \fBExample:\fP +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +mytestindex2_template: + elasticsearch_index_template.present: + \- definition: + template: logstash\-* + order: 1 + settings: + number_of_shards: 1 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .SS salt.states.environ .sp @@ -301231,6 +321047,26 @@ as this makes all master configuration settings available in all minion\(aqs pillars. .UNINDENT .UNINDENT +.sp +Etcd profile configuration can be overriden using following arguments: \fBhost\fP, +\fBport\fP, \fBusername\fP, \fBpassword\fP, \fBca\fP, \fBclient_key\fP and \fBclient_cert\fP\&. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my\-value: + etcd.set: + \- name: /path/to/key + \- value: value + \- host: 127.0.0.1 + \- port: 2379 + \- username: user + \- password: pass +.ft P +.fi +.UNINDENT +.UNINDENT .SS Available Functions .INDENT 0.0 .IP \(bu 2 @@ -301318,12 +321154,38 @@ Performs the same functionality as \fBrm\fP but only if a watch requisite is \fB .UNINDENT .INDENT 0.0 .TP +.B salt.states.etcd_mod.directory(name, profile=None, **kwargs) +Create a directory in etcd. +.INDENT 7.0 +.TP +.B name +The etcd directory name, for example: \fB/foo/bar/baz\fP\&. +.TP +.B profile +Optional, defaults to \fBNone\fP\&. Sets the etcd profile to use which has +been defined in the Salt Master config. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +my_etd_config: + etcd.host: 127.0.0.1 + etcd.port: 4001 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.states.etcd_mod.mod_watch(name, **kwargs) Execute a etcd function based on a watch call requisite. .UNINDENT .INDENT 0.0 .TP -.B salt.states.etcd_mod.rm(name, recurse=False, profile=None) +.B salt.states.etcd_mod.rm(name, recurse=False, profile=None, **kwargs) Deletes a key from etcd. This function is also aliased as \fBrm\fP\&. .INDENT 7.0 .TP @@ -301336,11 +321198,23 @@ Optional, defaults to \fBFalse\fP\&. If \fBTrue\fP performs a recursive delete. .B profile Optional, defaults to \fBNone\fP\&. Sets the etcd profile to use which has been defined in the Salt Master config. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +my_etd_config: + etcd.host: 127.0.0.1 + etcd.port: 4001 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.states.etcd_mod.set(name, value, profile=None) +.B salt.states.etcd_mod.set(name, value, profile=None, **kwargs) Set a key in etcd and can be called as \fBset\fP\&. .INDENT 7.0 .TP @@ -301353,11 +321227,23 @@ The value the key should contain. .B profile Optional, defaults to \fBNone\fP\&. Sets the etcd profile to use which has been defined in the Salt Master config. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +my_etd_config: + etcd.host: 127.0.0.1 + etcd.port: 4001 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.states.etcd_mod.wait_rm(name, recurse=False, profile=None) +.B salt.states.etcd_mod.wait_rm(name, recurse=False, profile=None, **kwargs) Deletes a key from etcd only if the watch statement calls it. This function is also aliased as \fBwait_rm\fP\&. .INDENT 7.0 @@ -301372,11 +321258,23 @@ delete, see: \fI\%https://python\-etcd.readthedocs.io/en/latest/#delete\-a\-key\ .B profile Optional, defaults to \fBNone\fP\&. Sets the etcd profile to use which has been defined in the Salt Master config. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +my_etd_config: + etcd.host: 127.0.0.1 + etcd.port: 4001 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.states.etcd_mod.wait_set(name, value, profile=None) +.B salt.states.etcd_mod.wait_set(name, value, profile=None, **kwargs) Set a key in etcd only if the watch statement calls it. This function is also aliased as \fBwait_set\fP\&. .INDENT 7.0 @@ -301390,6 +321288,18 @@ The value the key should contain. .B profile The etcd profile to use that has been configured on the Salt Master, this is optional and defaults to \fBNone\fP\&. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +my_etd_config: + etcd.host: 127.0.0.1 + etcd.port: 4001 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .UNINDENT .SS salt.states.ethtool module @@ -301638,7 +321548,7 @@ execution functions against ESXi hosts via a Salt Proxy Minion, and a larger sta example. .INDENT 0.0 .TP -.B salt.states.esxi.coredump_configured(name, enabled, dump_ip, host_vnic=\(aqvmk0\(aq, dump_port=6500) +.B salt.states.esxi.coredump_configured(name, enabled, dump_ip, host_vnic=u\(aqvmk0\(aq, dump_port=6500) Ensures a host\(aqs core dump configuration. .INDENT 7.0 .TP @@ -301687,6 +321597,135 @@ configure\-host\-coredump: .UNINDENT .INDENT 0.0 .TP +.B salt.states.esxi.diskgroups_configured(name, diskgroups, erase_disks=False) +Configures the disk groups to use for vsan. +.sp +It will do the following: +(1) checks for if all disks in the diskgroup spec exist and errors if they +don\(aqt +(2) creates diskgroups with the correct disk configurations if diskgroup +(identified by the cache disk canonical name) doesn\(aqt exist +(3) adds extra capacity disks to the existing diskgroup +.INDENT 7.0 +.TP +.B { +\(aqcache_scsi_addr\(aq: \(aqvmhba1:C0:T0:L0\(aq, +\(aqcapacity_scsi_addrs\(aq: [ +.INDENT 7.0 +.INDENT 3.5 +\(aqvmhba2:C0:T0:L0\(aq, +\(aqvmhba3:C0:T0:L0\(aq, +\(aqvmhba4:C0:T0:L0\(aq, +.UNINDENT +.UNINDENT +.sp +] +.UNINDENT +.sp +} +.INDENT 7.0 +.TP +.B name +Mandatory state name. +.TP +.B diskgroups +Disk group representation containing scsi disk addresses. +Scsi addresses are expected for disks in the diskgroup: +.TP +.B erase_disks +Specifies whether to erase all partitions on all disks member of the +disk group before the disk group is created. Default vaule is False. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.esxi.host_cache_configured(name, enabled, datastore, swap_size=u\(aq100%\(aq, dedicated_backing_disk=False, erase_backing_disk=False) +Configures the host cache used for swapping. +.sp +It will do the following: +(1) checks if backing disk exists +(2) creates the VMFS datastore if doesn\(aqt exist (datastore partition will +.INDENT 7.0 +.INDENT 3.5 +be created and use the entire disk +.UNINDENT +.UNINDENT +.INDENT 7.0 +.IP 3. 3 +raises an error if dedicated_backing_disk is True and partitions +already exist on the backing disk +.IP 4. 3 +configures host_cache to use a portion of the datastore for caching +(either a specific size or a percentage of the datastore) +.UNINDENT +.sp +Percentage swap size (can\(aqt be 100%) +.INDENT 7.0 +.TP +.B { +\(aqenabled\(aq: true, +\(aqdatastore\(aq: { +.INDENT 7.0 +.INDENT 3.5 +\(aqbacking_disk_scsi_addr\(aq: \(aqvmhba0:C0:T0:L0\(aq, +\(aqvmfs_version\(aq: 5, +\(aqname\(aq: \(aqhostcache\(aq +} +.UNINDENT +.UNINDENT +.sp +\(aqdedicated_backing_disk\(aq: false +\(aqswap_size\(aq: \(aq98%\(aq, +.UNINDENT +.sp +} +.sp +Fixed sized swap size +.INDENT 7.0 +.TP +.B { +\(aqenabled\(aq: true, +\(aqdatastore\(aq: { +.INDENT 7.0 +.INDENT 3.5 +\(aqbacking_disk_scsi_addr\(aq: \(aqvmhba0:C0:T0:L0\(aq, +\(aqvmfs_version\(aq: 5, +\(aqname\(aq: \(aqhostcache\(aq +} +.UNINDENT +.UNINDENT +.sp +\(aqdedicated_backing_disk\(aq: true +\(aqswap_size\(aq: \(aq10GiB\(aq, +.UNINDENT +.sp +} +.INDENT 7.0 +.TP +.B name +Mandatory state name. +.TP +.B enabled +Specifies whether the host cache is enabled. +.TP +.B datastore +Specifies the host cache datastore. +.TP +.B swap_size +Specifies the size of the host cache swap. Can be a percentage or a +value in GiB. Default value is \fB100%\fP\&. +.TP +.B dedicated_backing_disk +Specifies whether the backing disk is dedicated to the host cache which +means it must have no other partitions. Default is False +.TP +.B erase_backing_disk +Specifies whether to erase all partitions on the backing disk before +the datastore is created. Default vaule is False. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.states.esxi.ntp_configured(name, service_running, ntp_servers=None, service_policy=None, service_restart=False, update_datetime=False) Ensures a host\(aqs NTP server configuration such as setting NTP servers, ensuring the NTP daemon is running or stopped, or restarting the NTP daemon for the ESXi host. @@ -301913,7 +321952,7 @@ configure\-host\-syslog: .UNINDENT .INDENT 0.0 .TP -.B salt.states.esxi.vmotion_configured(name, enabled, device=\(aqvmk0\(aq) +.B salt.states.esxi.vmotion_configured(name, enabled, device=u\(aqvmk0\(aq) Configures a host\(aqs VMotion properties such as enabling VMotion and setting the device VirtualNic that VMotion will use. .INDENT 7.0 @@ -302073,6 +322112,7 @@ the jinja templating system would look like this: \- user: root \- group: root \- mode: 644 + \- attrs: ai \- template: jinja \- defaults: custom_var: "default value" @@ -302141,6 +322181,7 @@ salt fileserver. Here\(aqs an example: \- user: foo \- group: users \- mode: 644 + \- attrs: i \- backup: minion .ft P .fi @@ -302170,6 +322211,7 @@ In this example \fBfoo.conf\fP in the \fBdev\fP environment will be used instead \- user: foo \- group: users \- mode: \(aq0644\(aq + \- attrs: i .ft P .fi .UNINDENT @@ -302407,7 +322449,7 @@ For example: .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.absent(name) +.B salt.states.file.absent(name, **kwargs) Make sure that the named file or directory is absent. If it exists, it will be deleted. This will work to reverse any of the functions in the file state module. If a directory is supplied, it will be recursively deleted. @@ -302501,7 +322543,7 @@ Do not expect any loop over the keys in a deterministic order! .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.append(name, text=None, makedirs=False, source=None, source_hash=None, template=\(aqjinja\(aq, sources=None, source_hashes=None, defaults=None, context=None, ignore_whitespace=True) +.B salt.states.file.append(name, text=None, makedirs=False, source=None, source_hash=None, template=u\(aqjinja\(aq, sources=None, source_hashes=None, defaults=None, context=None, ignore_whitespace=True) Ensure that some text appears at the end of a file. .sp The text will not be appended if it already exists in the file. @@ -302670,7 +322712,7 @@ New in version 0.9.5. .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.blockreplace(name, marker_start=\(aq#\-\- start managed zone \-\-\(aq, marker_end=\(aq#\-\- end managed zone \-\-\(aq, source=None, source_hash=None, template=\(aqjinja\(aq, sources=None, source_hashes=None, defaults=None, context=None, content=\(aq\(aq, append_if_not_found=False, prepend_if_not_found=False, backup=\(aq.bak\(aq, show_changes=True) +.B salt.states.file.blockreplace(name, marker_start=u\(aq#\-\- start managed zone \-\-\(aq, marker_end=u\(aq#\-\- end managed zone \-\-\(aq, source=None, source_hash=None, template=u\(aqjinja\(aq, sources=None, source_hashes=None, defaults=None, context=None, content=u\(aq\(aq, append_if_not_found=False, prepend_if_not_found=False, backup=u\(aq.bak\(aq, show_changes=True) Maintain an edit in a file in a zone delimited by two line markers .sp New in version 2014.1.0. @@ -302880,7 +322922,7 @@ text 4 .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.cached(name, source_hash=\(aq\(aq, source_hash_name=None, skip_verify=False, saltenv=\(aqbase\(aq) +.B salt.states.file.cached(name, source_hash=u\(aq\(aq, source_hash_name=None, skip_verify=False, saltenv=u\(aqbase\(aq) New in version 2017.7.3. .sp @@ -302974,49 +323016,7 @@ module, the actual location of the cached file can be obtained using .sp .nf .ft C -cached = __salt__[\(aqcp.is_cached\(aq](source_match) -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -This function will return the cached path of the file, or an empty string -if the file is not present in the minion cache. -.sp -This state will in most cases not be useful in SLS files, but it is useful -when writing a state or remote\-execution module that needs to make sure -that a file at a given URL has been downloaded to the cachedir. One example -of this is in the \fBarchive.extracted\fP -state: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -result = __states__[\(aqfile.cached\(aq](source_match, - source_hash=source_hash, - source_hash_name=source_hash_name, - skip_verify=skip_verify, - saltenv=__env__) -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -This will return a dictionary containing the state\(aqs return data, including -a \fBresult\fP key which will state whether or not the state was successful. -Note that this will not catch exceptions, so it is best used within a -try/except. -.sp -Once this state has been run from within another state or remote\-execution -module, the actual location of the cached file can be obtained using -\fBcp.is_cached\fP: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -cached = __salt__[\(aqcp.is_cached\(aq](source_match) +cached = __salt__[\(aqcp.is_cached\(aq](source_match, saltenv=__env__) .ft P .fi .UNINDENT @@ -303027,7 +323027,7 @@ if the file is not present in the minion cache. .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.comment(name, regex, char=\(aq#\(aq, backup=\(aq.bak\(aq) +.B salt.states.file.comment(name, regex, char=u\(aq#\(aq, backup=u\(aq.bak\(aq) Comment out specified lines in a file. .INDENT 7.0 .TP @@ -303155,7 +323155,7 @@ additional file paths that are supported by \fI\%states.file.managed\fP and \fI\ .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.decode(name, encoded_data=None, contents_pillar=None, encoding_type=\(aqbase64\(aq, checksum=\(aqmd5\(aq) +.B salt.states.file.decode(name, encoded_data=None, contents_pillar=None, encoding_type=u\(aqbase64\(aq, checksum=u\(aqmd5\(aq) Decode an encoded file and write it to disk .sp New in version 2016.3.0. @@ -303232,7 +323232,7 @@ write_base64_encoded_string_to_a_file: .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.directory(name, user=None, group=None, recurse=None, max_depth=None, dir_mode=None, file_mode=None, makedirs=False, clean=False, require=None, exclude_pat=None, follow_symlinks=False, force=False, backupname=None, allow_symlink=True, children_only=False, win_owner=None, win_perms=None, win_deny_perms=None, win_inheritance=True, **kwargs) +.B salt.states.file.directory(name, user=None, group=None, recurse=None, max_depth=None, dir_mode=None, file_mode=None, makedirs=False, clean=False, require=None, exclude_pat=None, follow_symlinks=False, force=False, backupname=None, allow_symlink=True, children_only=False, win_owner=None, win_perms=None, win_deny_perms=None, win_inheritance=True, win_perms_reset=False, **kwargs) Ensure that a named directory is present and has the right perms .INDENT 7.0 .TP @@ -303421,6 +323421,15 @@ inherit permission. .sp New in version 2017.7.0. +.TP +.B win_perms_reset +False +If \fBTrue\fP the existing DACL will be cleared and replaced with the +settings defined in this function. If \fBFalse\fP, new entries will be +appended to the existing DACL. Default is \fBFalse\fP\&. +.sp +New in version 2018.3.0. + .UNINDENT .sp Here\(aqs an example using the above \fBwin_*\fP parameters: @@ -303459,11 +323468,14 @@ create_config_dir: .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.exists(name) +.B salt.states.file.exists(name, **kwargs) Verify that the named file or directory is present or exists. Ensures pre\-requisites outside of Salt\(aqs purview (e.g., keytabs, private keys, etc.) have been previously satisfied before deployment. +.sp +This function does not create the file if it doesn\(aqt exist, it will return +an error. .INDENT 7.0 .TP .B name @@ -303479,23 +323491,27 @@ New in version 2015.8.0. .INDENT 7.0 .TP -.B name -Filesystem path to the file to be edited. -.TP -.B content -Content of the line. Allowed to be empty if mode=delete. -.TP -.B match +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP \-\- Filesystem path to the file to be edited. +.IP \(bu 2 +\fBcontent\fP \-\- Content of the line. Allowed to be empty if mode=delete. +.IP \(bu 2 +\fBmatch\fP \-\- +.sp Match the target line for an action by a fragment of a string or regular expression. .sp If neither \fBbefore\fP nor \fBafter\fP are provided, and \fBmatch\fP is also \fBNone\fP, match becomes the \fBcontent\fP value. -.TP -.B mode + +.IP \(bu 2 +\fBmode\fP \-\- +.sp Defines how to edit a line. One of the following options is required: -.INDENT 7.0 +.INDENT 2.0 .IP \(bu 2 .INDENT 2.0 .TP @@ -303523,7 +323539,7 @@ Insert a line. .UNINDENT .sp \fBNOTE:\fP -.INDENT 7.0 +.INDENT 2.0 .INDENT 3.5 If \fBmode=insert\fP is used, at least one of the following options must also be defined: \fBlocation\fP, \fBbefore\fP, or @@ -303531,13 +323547,15 @@ options must also be defined: \fBlocation\fP, \fBbefore\fP, or over the other two options. .UNINDENT .UNINDENT -.TP -.B location + +.IP \(bu 2 +\fBlocation\fP \-\- +.sp Defines where to place content in the line. Note this option is only used when \fBmode=insert\fP is specified. If a location is passed in, it takes precedence over both the \fBbefore\fP and \fBafter\fP kwargs. Valid locations are: -.INDENT 7.0 +.INDENT 2.0 .IP \(bu 2 .INDENT 2.0 .TP @@ -303551,46 +323569,39 @@ Place the content at the beginning of the file. Place the content at the end of the file. .UNINDENT .UNINDENT -.TP -.B before -Regular expression or an exact case\-sensitive fragment of the string. + +.IP \(bu 2 +\fBbefore\fP \-\- Regular expression or an exact case\-sensitive fragment of the string. This option is only used when either the \fBensure\fP or \fBinsert\fP mode is defined. -.TP -.B after -Regular expression or an exact case\-sensitive fragment of the string. +.IP \(bu 2 +\fBafter\fP \-\- Regular expression or an exact case\-sensitive fragment of the string. This option is only used when either the \fBensure\fP or \fBinsert\fP mode is defined. -.TP -.B show_changes +.IP \(bu 2 +\fBshow_changes\fP \-\- +.sp Output a unified diff of the old file and the new file. If \fBFalse\fP return a boolean if any changes were made. Default is \fBTrue\fP .sp \fBNOTE:\fP -.INDENT 7.0 +.INDENT 2.0 .INDENT 3.5 Using this option will store two copies of the file in\-memory (the original version and the edited version) in order to generate the diff. .UNINDENT .UNINDENT -.TP -.B backup -Create a backup of the original file with the extension: + +.IP \(bu 2 +\fBbackup\fP \-\- Create a backup of the original file with the extension: "Year\-Month\-Day\-Hour\-Minutes\-Seconds". -.TP -.B quiet -Do not raise any exceptions. E.g. ignore the fact that the file that is +.IP \(bu 2 +\fBquiet\fP \-\- Do not raise any exceptions. E.g. ignore the fact that the file that is tried to be edited does not exist and nothing really happened. -.TP -.B indent -Keep indentation with the previous line. This option is not considered when +.IP \(bu 2 +\fBindent\fP \-\- Keep indentation with the previous line. This option is not considered when the \fBdelete\fP mode is specified. -.UNINDENT -.INDENT 7.0 -.TP -.B Parameters -.INDENT 7.0 .IP \(bu 2 \fBcreate\fP \-\- .sp @@ -303636,7 +323647,7 @@ remote shell command by manually specifying the kwarg: .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.managed(name, source=None, source_hash=\(aq\(aq, source_hash_name=None, keep_source=True, user=None, group=None, mode=None, template=None, makedirs=False, dir_mode=None, context=None, replace=True, defaults=None, backup=\(aq\(aq, show_changes=True, create=True, contents=None, tmp_ext=\(aq\(aq, contents_pillar=None, contents_grains=None, contents_newline=True, contents_delimiter=\(aq:\(aq, encoding=None, encoding_errors=\(aqstrict\(aq, allow_empty=True, follow_symlinks=True, check_cmd=None, skip_verify=False, win_owner=None, win_perms=None, win_deny_perms=None, win_inheritance=True, **kwargs) +.B salt.states.file.managed(name, source=None, source_hash=u\(aq\(aq, source_hash_name=None, keep_source=True, user=None, group=None, mode=None, attrs=None, template=None, makedirs=False, dir_mode=None, context=None, replace=True, defaults=None, backup=u\(aq\(aq, show_changes=True, create=True, contents=None, tmp_ext=u\(aq\(aq, contents_pillar=None, contents_grains=None, contents_newline=True, contents_delimiter=u\(aq:\(aq, encoding=None, encoding_errors=u\(aqstrict\(aq, allow_empty=True, follow_symlinks=True, check_cmd=None, skip_verify=False, win_owner=None, win_perms=None, win_deny_perms=None, win_inheritance=True, win_perms_reset=False, **kwargs) Manage a given file, this function allows for a file to be downloaded from the salt master and potentially run through a templating system. .INDENT 7.0 @@ -303939,6 +323950,21 @@ unable to stat the file as it exists on the fileserver and thus cannot mirror the mode on the salt\-ssh minion .UNINDENT .UNINDENT +.TP +.B attrs +The attributes to have on this file, e.g. \fBa\fP, \fBi\fP\&. The attributes +can be any or a combination of the following characters: +\fBacdijstuADST\fP\&. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This option is \fBnot\fP supported on Windows. +.UNINDENT +.UNINDENT +.sp +New in version 2018.3.0. + .TP .B template If this setting is applied, the named templating engine will be used to @@ -304048,6 +324074,7 @@ For example, the following could be used to deploy an SSH private key: \- user: deployer \- group: deployer \- mode: 600 + \- attrs: a \- contents_pillar: userdata:deployer:id_rsa .ft P .fi @@ -304152,11 +324179,10 @@ or \fBcontents_grains\fP\&. This delimiter will be passed through to \fBpillar.get\fP or \fBgrains.get\fP when retrieving the contents. .TP .B encoding -Encoding used for the file, e.g. \fB\(gaUTF\-8\(ga\fP, \fB\(gabase64\(ga\fP\&. -Default is None, which means str() will be applied to contents to -ensure an ascii encoded file and backwards compatibility. -See \fI\%https://docs.python.org/3/library/codecs.html#standard\-encodings\fP -for available encodings. +If specified, then the specified encoding will be used. Otherwise, the +file will be encoded using the system locale (usually UTF\-8). See +\fI\%https://docs.python.org/3/library/codecs.html#standard\-encodings\fP for +the list of available encodings. .sp New in version 2017.7.0. @@ -304208,6 +324234,7 @@ changes: \- user: root \- group: root \- mode: 0440 + \- attrs: i \- source: salt://sudoers/files/sudoers.jinja \- template: jinja \- check_cmd: /usr/sbin/visudo \-c \-f @@ -304291,6 +324318,15 @@ inherit permission. .sp New in version 2017.7.0. +.TP +.B win_perms_reset +False +If \fBTrue\fP the existing DACL will be cleared and replaced with the +settings defined in this function. If \fBFalse\fP, new entries will be +appended to the existing DACL. Default is \fBFalse\fP\&. +.sp +New in version 2018.3.0. + .UNINDENT .sp Here\(aqs an example using the above \fBwin_*\fP parameters: @@ -304328,7 +324364,7 @@ create_config_file: .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.missing(name) +.B salt.states.file.missing(name, **kwargs) Verify that the named file or directory is missing, this returns True only if the named file is missing but does not remove the file if it is present. .INDENT 7.0 @@ -304339,7 +324375,7 @@ Absolute path which must NOT exist .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.mknod(name, ntype, major=0, minor=0, user=None, group=None, mode=\(aq0600\(aq) +.B salt.states.file.mknod(name, ntype, major=0, minor=0, user=None, group=None, mode=u\(aq0600\(aq) Create a special file similar to the \(aqnix mknod command. The supported device types are \fBp\fP (fifo pipe), \fBc\fP (character device), and \fBb\fP (block device). Provide the major and minor numbers when specifying a @@ -304427,7 +324463,10 @@ otherwise return True .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.not_cached(name, saltenv=\(aqbase\(aq) +.B salt.states.file.not_cached(name, saltenv=u\(aqbase\(aq) +New in version 2017.7.3. + +.sp Ensures that a file is saved to the minion\(aqs cache. This state is primarily invoked by other states to ensure that we do not re\-download a source file if we do not need to. @@ -304453,7 +324492,7 @@ Salt fileserver (i.e. those with \fBsalt://\fP URL). .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.patch(name, source=None, options=\(aq\(aq, dry_run_first=True, **kwargs) +.B salt.states.file.patch(name, source=None, options=u\(aq\(aq, dry_run_first=True, **kwargs) Apply a patch to a file or directory. .sp \fBNOTE:\fP @@ -304523,7 +324562,7 @@ above would need to be specified with the hash type (i.e. .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.prepend(name, text=None, makedirs=False, source=None, source_hash=None, template=\(aqjinja\(aq, sources=None, source_hashes=None, defaults=None, context=None, header=None) +.B salt.states.file.prepend(name, text=None, makedirs=False, source=None, source_hash=None, template=u\(aqjinja\(aq, sources=None, source_hashes=None, defaults=None, context=None, header=None) Ensure that some text appears at the beginning of a file .sp The text will not be prepended again if it already exists in the file. You @@ -304605,7 +324644,7 @@ New in version 2014.7.0. .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.recurse(name, source, keep_source=True, clean=False, require=None, user=None, group=None, dir_mode=None, file_mode=None, sym_mode=None, template=None, context=None, defaults=None, include_empty=False, backup=\(aq\(aq, include_pat=None, exclude_pat=None, maxdepth=None, keep_symlinks=False, force_symlinks=False, **kwargs) +.B salt.states.file.recurse(name, source, keep_source=True, clean=False, require=None, user=None, group=None, dir_mode=None, file_mode=None, sym_mode=None, template=None, context=None, replace=True, defaults=None, include_empty=False, backup=u\(aq\(aq, include_pat=None, exclude_pat=None, maxdepth=None, keep_symlinks=False, force_symlinks=False, **kwargs) Recurse through a subdirectory on the master and copy said subdirectory over to the specified path. .INDENT 7.0 @@ -304718,6 +324757,12 @@ The template option is required when recursively applying templates. .UNINDENT .UNINDENT .TP +.B replace +True +If set to \fBFalse\fP and the file already exists, the file will not be +modified even if changes would otherwise be made. Permissions and +ownership will still be enforced, however. +.TP .B context Overrides default context variables passed to the template. .TP @@ -304827,7 +324872,7 @@ If the target subdirectories don\(aqt exist create them .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.replace(name, pattern, repl, count=0, flags=8, bufsize=1, append_if_not_found=False, prepend_if_not_found=False, not_found_content=None, backup=\(aq.bak\(aq, show_changes=True, ignore_if_missing=False, backslash_literal=False) +.B salt.states.file.replace(name, pattern, repl, count=0, flags=8, bufsize=1, append_if_not_found=False, prepend_if_not_found=False, not_found_content=None, backup=u\(aq.bak\(aq, show_changes=True, ignore_if_missing=False, backslash_literal=False) Maintain an edit in a file. .sp New in version 0.17.0. @@ -305037,7 +325082,7 @@ Defaults to \fBNone\fP which uses the timezone from the locale. .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.serialize(name, dataset=None, dataset_pillar=None, user=None, group=None, mode=None, backup=\(aq\(aq, makedirs=False, show_diff=None, show_changes=True, create=True, merge_if_exists=False, encoding=None, encoding_errors=\(aqstrict\(aq, **kwargs) +.B salt.states.file.serialize(name, dataset=None, dataset_pillar=None, user=None, group=None, mode=None, backup=u\(aq\(aq, makedirs=False, show_changes=True, create=True, merge_if_exists=False, encoding=None, encoding_errors=u\(aqstrict\(aq, **kwargs) Serializes dataset and store it into managed file. Useful for sharing simple configuration files. .INDENT 7.0 @@ -305063,11 +325108,10 @@ Write the data as this format. See the list of \fBserializer modules\fP for supported output formats. .TP .B encoding -Encoding used for the file, e.g. \fB\(gaUTF\-8\(ga\fP, \fB\(gabase64\(ga\fP\&. -Default is None, which means str() will be applied to contents to -ensure an ascii encoded file. -See \fI\%https://docs.python.org/3/library/codecs.html#standard\-encodings\fP -for available encodings. +If specified, then the specified encoding will be used. Otherwise, the +file will be encoded using the system locale (usually UTF\-8). See +\fI\%https://docs.python.org/3/library/codecs.html#standard\-encodings\fP for +the list of available encodings. .sp New in version 2017.7.0. @@ -305111,12 +325155,6 @@ Create parent directories for destination file. .sp New in version 2014.1.3. -.TP -.B show_diff -DEPRECATED: Please use show_changes. -.sp -If set to \fBFalse\fP, the diff will not be shown in the return data if -changes are made. .TP .B show_changes Output a unified diff of the old file and the new file. If \fBFalse\fP @@ -305333,7 +325371,7 @@ New in version 0.9.5. .UNINDENT .INDENT 0.0 .TP -.B salt.states.file.uncomment(name, regex, char=\(aq#\(aq, backup=\(aq.bak\(aq) +.B salt.states.file.uncomment(name, regex, char=u\(aq#\(aq, backup=u\(aq.bak\(aq) Uncomment specified commented lines in a file .INDENT 7.0 .TP @@ -305388,7 +325426,9 @@ New in version 0.9.5. .SS salt.states.firewall module .sp State to check firewall configurations -.. versionadded:: 2016.3.0 +.sp +New in version 2016.3.0. + .INDENT 0.0 .TP .B salt.states.firewall.check(name, port=None, **kwargs) @@ -305550,8 +325590,78 @@ Returns a pretty dictionary meant for command line output. .UNINDENT .INDENT 0.0 .TP -.B salt.states.firewalld.present(name, block_icmp=None, default=None, masquerade=False, ports=None, port_fwd=None, services=None, prune_services=True, interfaces=None, sources=None, rich_rules=None) +.B salt.states.firewalld.present(name, block_icmp=None, prune_block_icmp=False, default=None, masquerade=False, ports=None, prune_ports=False, port_fwd=None, prune_port_fwd=False, services=None, prune_services=None, interfaces=None, prune_interfaces=False, sources=None, prune_sources=False, rich_rules=None, prune_rich_rules=False) Ensure a zone has specific attributes. +.INDENT 7.0 +.TP +.B name +The zone to modify. +.TP +.B default +None +Set this zone as the default zone if \fBTrue\fP\&. +.TP +.B masquerade +False +Enable or disable masquerade for a zone. +.TP +.B block_icmp +None +List of ICMP types to block in the zone. +.TP +.B prune_block_icmp +False +If \fBTrue\fP, remove all but the specified block_icmp from the zone. +.TP +.B ports +None +List of ports to add to the zone. +.TP +.B prune_ports +False +If \fBTrue\fP, remove all but the specified ports from the zone. +.TP +.B port_fwd +None +List of port forwards to add to the zone. +.TP +.B prune_port_fwd +False +If \fBTrue\fP, remove all but the specified port_fwd from the zone. +.TP +.B services +None +List of services to add to the zone. +.TP +.B prune_services +True +If \fBTrue\fP, remove all but the specified services from the zone. +.. note:: Currently defaults to True for compatibility, but will be changed to False in a future release. +.TP +.B interfaces +None +List of interfaces to add to the zone. +.TP +.B prune_interfaces +False +If \fBTrue\fP, remove all but the specified interfaces from the zone. +.TP +.B sources +None +List of sources to add to the zone. +.TP +.B prune_sources +False +If \fBTrue\fP, remove all but the specified sources from the zone. +.TP +.B rich_rules +None +List of rich rules to add to the zone. +.TP +.B prune_rich_rules +False +If \fBTrue\fP, remove all but the specified rich rules from the zone. +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -305907,7 +326017,7 @@ mylocalrepo: .UNINDENT .INDENT 0.0 .TP -.B salt.states.git.detached(name, rev, target=None, remote=\(aqorigin\(aq, user=None, password=None, force_clone=False, force_checkout=False, fetch_remote=True, hard_reset=False, submodules=False, identity=None, https_user=None, https_pass=None, onlyif=False, unless=False, **kwargs) +.B salt.states.git.detached(name, rev, target=None, remote=u\(aqorigin\(aq, user=None, password=None, force_clone=False, force_checkout=False, fetch_remote=True, hard_reset=False, submodules=False, identity=None, https_user=None, https_pass=None, onlyif=False, unless=False, **kwargs) New in version 2016.3.0. .sp @@ -306008,7 +326118,7 @@ passed to the \fBunless\fP option returns false .UNINDENT .INDENT 0.0 .TP -.B salt.states.git.latest(name, rev=\(aqHEAD\(aq, target=None, branch=None, user=None, password=None, update_head=True, force_checkout=False, force_clone=False, force_fetch=False, force_reset=False, submodules=False, bare=False, mirror=False, remote=\(aqorigin\(aq, fetch_tags=True, depth=None, identity=None, https_user=None, https_pass=None, onlyif=False, unless=False, refspec_branch=\(aq*\(aq, refspec_tag=\(aq*\(aq, **kwargs) +.B salt.states.git.latest(name, rev=u\(aqHEAD\(aq, target=None, branch=None, user=None, password=None, update_head=True, force_checkout=False, force_clone=False, force_fetch=False, force_reset=False, submodules=False, bare=False, mirror=False, remote=u\(aqorigin\(aq, fetch_tags=True, depth=None, identity=None, https_user=None, https_pass=None, onlyif=False, unless=False, refspec_branch=u\(aq*\(aq, refspec_tag=u\(aq*\(aq, **kwargs) Make sure the repository is cloned to the given directory and is up\-to\-date. .INDENT 7.0 @@ -306507,7 +326617,7 @@ ensure user test is present in github: .UNINDENT .INDENT 0.0 .TP -.B salt.states.github.absent(name, profile=\(aqgithub\(aq, **kwargs) +.B salt.states.github.absent(name, profile=u\(aqgithub\(aq, **kwargs) Ensure a github user is absent .INDENT 7.0 .INDENT 3.5 @@ -306533,7 +326643,7 @@ Github handle of the user in organization .UNINDENT .INDENT 0.0 .TP -.B salt.states.github.present(name, profile=\(aqgithub\(aq, **kwargs) +.B salt.states.github.present(name, profile=u\(aqgithub\(aq, **kwargs) Ensure a user is present .INDENT 7.0 .INDENT 3.5 @@ -306557,7 +326667,7 @@ This is the github handle of the user in the organization .UNINDENT .INDENT 0.0 .TP -.B salt.states.github.repo_absent(name, profile=\(aqgithub\(aq, **kwargs) +.B salt.states.github.repo_absent(name, profile=u\(aqgithub\(aq, **kwargs) Ensure a repo is absent. .sp Example: @@ -306586,7 +326696,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.states.github.repo_present(name, description=None, homepage=None, private=None, has_issues=None, has_wiki=None, has_downloads=None, auto_init=False, gitignore_template=None, license_template=None, teams=None, profile=\(aqgithub\(aq, **kwargs) +.B salt.states.github.repo_present(name, description=None, homepage=None, private=None, has_issues=None, has_wiki=None, has_downloads=None, auto_init=False, gitignore_template=None, license_template=None, teams=None, profile=u\(aqgithub\(aq, **kwargs) Ensure a repository is present .INDENT 7.0 .TP @@ -306649,7 +326759,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.states.github.team_absent(name, profile=\(aqgithub\(aq, **kwargs) +.B salt.states.github.team_absent(name, profile=u\(aqgithub\(aq, **kwargs) Ensure a team is absent. .sp Example: @@ -306678,7 +326788,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.states.github.team_present(name, description=None, repo_names=None, privacy=\(aqsecret\(aq, permission=\(aqpull\(aq, members=None, enforce_mfa=False, no_mfa_grace_seconds=0, profile=\(aqgithub\(aq, **kwargs) +.B salt.states.github.team_present(name, description=None, repo_names=None, privacy=u\(aqsecret\(aq, permission=u\(aqpull\(aq, members=None, enforce_mfa=False, no_mfa_grace_seconds=0, profile=u\(aqgithub\(aq, **kwargs) Ensure a team is present .INDENT 7.0 .TP @@ -306748,7 +326858,7 @@ New in version 2016.11.0. .SS Managing Images in OpenStack Glance .INDENT 0.0 .TP -.B salt.states.glance.image_present(name, visibility=\(aqpublic\(aq, protected=None, checksum=None, location=None, disk_format=\(aqraw\(aq, wait_for=None, timeout=30) +.B salt.states.glance.image_present(name, visibility=u\(aqpublic\(aq, protected=None, checksum=None, location=None, disk_format=u\(aqraw\(aq, wait_for=None, timeout=30) Checks if given image is present with properties set as specified. .sp @@ -306868,7 +326978,7 @@ mycluster: .UNINDENT .INDENT 0.0 .TP -.B salt.states.glusterfs.volume_present(name, bricks, stripe=False, replica=False, device_vg=False, transport=\(aqtcp\(aq, start=False, force=False) +.B salt.states.glusterfs.volume_present(name, bricks, stripe=False, replica=False, device_vg=False, transport=u\(aqtcp\(aq, start=False, force=False) Ensure that the volume exists .INDENT 7.0 .TP @@ -307182,7 +327292,7 @@ they exist in dashboards. The module will not manage rows that are not defined, allowing users to manage their own custom rows. .INDENT 0.0 .TP -.B salt.states.grafana.dashboard_absent(name, hosts=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana.dashboard_absent(name, hosts=None, profile=u\(aqgrafana\(aq) Ensure the named grafana dashboard is deleted. .INDENT 7.0 .TP @@ -307196,7 +327306,7 @@ elasticsearch index to use. .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana.dashboard_present(name, dashboard=None, dashboard_from_pillar=None, rows=None, rows_from_pillar=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana.dashboard_present(name, dashboard=None, dashboard_from_pillar=None, rows=None, rows_from_pillar=None, profile=u\(aqgrafana\(aq) Ensure the grafana dashboard exists and is managed. .INDENT 7.0 .TP @@ -307275,7 +327385,7 @@ they exist in dashboards. The module will not manage rows that are not defined, allowing users to manage their own custom rows. .INDENT 0.0 .TP -.B salt.states.grafana4_dashboard.absent(name, orgname=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana4_dashboard.absent(name, orgname=None, profile=u\(aqgrafana\(aq) Ensure the named grafana dashboard is absent. .INDENT 7.0 .TP @@ -307292,7 +327402,7 @@ Default is \(aqgrafana\(aq. .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana4_dashboard.present(name, base_dashboards_from_pillar=None, base_panels_from_pillar=None, base_rows_from_pillar=None, dashboard=None, orgname=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana4_dashboard.present(name, base_dashboards_from_pillar=None, base_panels_from_pillar=None, base_rows_from_pillar=None, dashboard=None, orgname=None, profile=u\(aqgrafana\(aq) Ensure the grafana dashboard exists and is managed. .INDENT 7.0 .TP @@ -307379,7 +327489,7 @@ Ensure influxdb data source is present: .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana4_datasource.absent(name, orgname=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana4_datasource.absent(name, orgname=None, profile=u\(aqgrafana\(aq) Ensure that a data source is present. .INDENT 7.0 .TP @@ -307396,7 +327506,7 @@ Default is \(aqgrafana\(aq. .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana4_datasource.present(name, type, url, access=None, user=None, password=None, database=None, basic_auth=None, basic_auth_user=None, basic_auth_password=None, tls_auth=None, json_data=None, is_default=None, with_credentials=None, type_logo_url=None, orgname=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana4_datasource.present(name, type, url, access=None, user=None, password=None, database=None, basic_auth=None, basic_auth_user=None, basic_auth_password=None, tls_auth=None, json_data=None, is_default=None, with_credentials=None, type_logo_url=None, orgname=None, profile=u\(aqgrafana\(aq) Ensure that a data source is present. .INDENT 7.0 .TP @@ -307514,7 +327624,7 @@ Ensure foobar org is present: .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana4_org.absent(name, profile=\(aqgrafana\(aq) +.B salt.states.grafana4_org.absent(name, profile=u\(aqgrafana\(aq) Ensure that a org is present. .INDENT 7.0 .TP @@ -307528,7 +327638,7 @@ Default is \(aqgrafana\(aq. .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana4_org.present(name, users=None, theme=None, home_dashboard_id=None, timezone=None, address1=None, address2=None, city=None, zip_code=None, address_state=None, country=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana4_org.present(name, users=None, theme=None, home_dashboard_id=None, timezone=None, address1=None, address2=None, city=None, zip_code=None, address_state=None, country=None, profile=u\(aqgrafana\(aq) Ensure that an organization is present. .INDENT 7.0 .TP @@ -307634,7 +327744,7 @@ Ensure foobar user is present: .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana4_user.absent(name, profile=\(aqgrafana\(aq) +.B salt.states.grafana4_user.absent(name, profile=u\(aqgrafana\(aq) Ensure that a user is present. .INDENT 7.0 .TP @@ -307648,7 +327758,7 @@ Default is \(aqgrafana\(aq. .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana4_user.present(name, password, email, is_admin=False, fullname=None, theme=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana4_user.present(name, password, email, is_admin=False, fullname=None, theme=None, profile=u\(aqgrafana\(aq) Ensure that a user is present. .INDENT 7.0 .TP @@ -307727,7 +327837,7 @@ they exist in dashboards. The module will not manage rows that are not defined, allowing users to manage their own custom rows. .INDENT 0.0 .TP -.B salt.states.grafana_dashboard.absent(name, profile=\(aqgrafana\(aq) +.B salt.states.grafana_dashboard.absent(name, profile=u\(aqgrafana\(aq) Ensure the named grafana dashboard is absent. .INDENT 7.0 .TP @@ -307740,7 +327850,7 @@ A pillar key or dict that contains grafana information .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana_dashboard.present(name, base_dashboards_from_pillar=None, base_panels_from_pillar=None, base_rows_from_pillar=None, dashboard=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana_dashboard.present(name, base_dashboards_from_pillar=None, base_panels_from_pillar=None, base_rows_from_pillar=None, dashboard=None, profile=u\(aqgrafana\(aq) Ensure the grafana dashboard exists and is managed. .INDENT 7.0 .TP @@ -307803,7 +327913,7 @@ Ensure influxdb data source is present: .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana_datasource.absent(name, profile=\(aqgrafana\(aq) +.B salt.states.grafana_datasource.absent(name, profile=u\(aqgrafana\(aq) Ensure that a data source is present. .INDENT 7.0 .TP @@ -307813,7 +327923,7 @@ Name of the data source to remove. .UNINDENT .INDENT 0.0 .TP -.B salt.states.grafana_datasource.present(name, type, url, access=\(aqproxy\(aq, user=\(aq\(aq, password=\(aq\(aq, database=\(aq\(aq, basic_auth=False, basic_auth_user=\(aq\(aq, basic_auth_password=\(aq\(aq, is_default=False, json_data=None, profile=\(aqgrafana\(aq) +.B salt.states.grafana_datasource.present(name, type, url, access=u\(aqproxy\(aq, user=u\(aq\(aq, password=u\(aq\(aq, database=u\(aq\(aq, basic_auth=False, basic_auth_user=u\(aq\(aq, basic_auth_password=u\(aq\(aq, is_default=False, json_data=None, profile=u\(aqgrafana\(aq) Ensure that a data source is present. .INDENT 7.0 .TP @@ -308142,8 +328252,8 @@ either present or absent. User/Group names can be passed to the \fBadduser\fP, \fBdeluser\fP, and \fBmembers\fP parameters. \fBadduser\fP and \fBdeluser\fP can be used together but not with \fBmembers\fP\&. .sp -In Windows, if no domain is specified in the user or group name (ie: -\fIDOMAINusername\(ga\fP) the module will assume a local user or group. +In Windows, if no domain is specified in the user or group name (i.e. +\fBDOMAIN\eusername\fP) the module will assume a local user or group. .INDENT 0.0 .INDENT 3.5 .sp @@ -308465,7 +328575,7 @@ hipchat: .UNINDENT .INDENT 0.0 .TP -.B salt.states.hipchat.send_message(name, room_id, from_name, message, api_url=None, api_key=None, api_version=None, message_color=\(aqyellow\(aq, notify=False) +.B salt.states.hipchat.send_message(name, room_id, from_name, message, api_url=None, api_key=None, api_version=None, message_color=u\(aqyellow\(aq, notify=False) Send a message to a Hipchat room. .INDENT 7.0 .INDENT 3.5 @@ -308703,7 +328813,7 @@ The system user to run htpasswd command with .UNINDENT .INDENT 0.0 .TP -.B salt.states.htpasswd.user_exists(name, password=None, htpasswd_file=None, options=\(aq\(aq, force=False, runas=None, update=False) +.B salt.states.htpasswd.user_exists(name, password=None, htpasswd_file=None, options=u\(aq\(aq, force=False, runas=None, update=False) Make sure the user is inside the specified htpasswd file .INDENT 7.0 .TP @@ -308740,7 +328850,7 @@ New in version 2015.5.0. .INDENT 0.0 .TP -.B salt.states.http.query(name, match=None, match_type=\(aqstring\(aq, status=None, wait_for=None, **kwargs) +.B salt.states.http.query(name, match=None, match_type=u\(aqstring\(aq, status=None, wait_for=None, **kwargs) Perform an HTTP query and statefully return the result .sp New in version 2015.5.0. @@ -308904,7 +329014,7 @@ Authentication ticket generated on icinga2 master .UNINDENT .INDENT 0.0 .TP -.B salt.states.icinga2.request_cert(name, master, ticket, port=\(aq5665\(aq) +.B salt.states.icinga2.request_cert(name, master, ticket, port=u\(aq5665\(aq) Request CA certificate from master icinga2 node. .INDENT 7.0 .TP @@ -309065,7 +329175,7 @@ New in version 0.17.0. .INDENT 0.0 .TP -.B salt.states.incron.absent(name, path, mask, cmd, user=\(aqroot\(aq) +.B salt.states.incron.absent(name, path, mask, cmd, user=u\(aqroot\(aq) Verifies that the specified incron job is absent for the specified user; only the name is matched when removing a incron job. .INDENT 7.0 @@ -309089,7 +329199,7 @@ The cmd that should be executed .UNINDENT .INDENT 0.0 .TP -.B salt.states.incron.present(name, path, mask, cmd, user=\(aqroot\(aq) +.B salt.states.incron.present(name, path, mask, cmd, user=u\(aqroot\(aq) Verifies that the specified incron job is present for the specified user. For more advanced information about what exactly can be set in the cron timing parameters, check your incron system\(aqs documentation. Most Unix\-like @@ -309315,7 +329425,7 @@ Name of the database that the retention policy was defined on. .UNINDENT .INDENT 0.0 .TP -.B salt.states.influxdb_retention_policy.present(name, database, duration=\(aq7d\(aq, replication=1, default=False, **client_args) +.B salt.states.influxdb_retention_policy.present(name, database, duration=u\(aq7d\(aq, replication=1, default=False, **client_args) Ensure that given retention policy is present. .INDENT 7.0 .TP @@ -309370,107 +329480,6 @@ bar_db: all .sp \fBExample:\fP .UNINDENT -.SS salt.states.infoblox module -.sp -states for infoblox stuff -.sp -ensures a record is either present or absent in an Infoblox DNS system -.sp -New in version 2016.3.0. - -.INDENT 0.0 -.TP -.B salt.states.infoblox.absent(name, record_type, dns_view, infoblox_server=None, infoblox_user=None, infoblox_password=None, infoblox_api_version=\(aqv1.4.2\(aq, sslVerify=True) -Ensure a record does not exists -.INDENT 7.0 -.TP -.B name -Name of the record -.TP -.B record_type -record type (host, a, cname, etc) -.TP -.B dns_view -DNS View -.TP -.B infoblox_server -infoblox server to connect to (will try pillar if not specified) -.TP -.B infoblox_user -username to use to connect to infoblox (will try pillar if not specified) -.TP -.B infoblox_password -password to use to connect to infoblox (will try pillar if not specified) -.TP -.B verify_ssl -verify SSL certificates -.UNINDENT -.sp -Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -some\-state: - infoblox.absent: - \- name: some.dns.record - \- record_type: host - \- dns_view: MyView - \- sslVerify: False -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.states.infoblox.present(name, value, record_type, dns_view, infoblox_server=None, infoblox_user=None, infoblox_password=None, infoblox_api_version=\(aqv1.4.2\(aq, sslVerify=True) -Ensure a record exists -.INDENT 7.0 -.TP -.B name -Name of the record -.TP -.B value -Value of the record -.TP -.B record_type -record type (host, a, cname, etc) -.TP -.B dns_view -DNS View -.TP -.B infoblox_server -infoblox server to connect to (will try pillar if not specified) -.TP -.B infoblox_user -username to use to connect to infoblox (will try pillar if not specified) -.TP -.B infoblox_password -password to use to connect to infoblox (will try pillar if not specified) -.TP -.B verify_ssl -verify SSL certificates -.UNINDENT -.sp -Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -some\-state: - infoblox.present: - \- name: some.dns.record - \- value: 10.1.1.3 - \- record_type: host - \- sslVerify: False -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT .SS salt.states.ini_manage .SS Manage ini files .INDENT 0.0 @@ -309489,7 +329498,7 @@ all .UNINDENT .INDENT 0.0 .TP -.B salt.states.ini_manage.options_absent(name, sections=None, separator=\(aq=\(aq) +.B salt.states.ini_manage.options_absent(name, sections=None, separator=u\(aq=\(aq) .INDENT 7.0 .INDENT 3.5 .sp @@ -309516,7 +329525,7 @@ changes dict will contain the list of changes made .UNINDENT .INDENT 0.0 .TP -.B salt.states.ini_manage.options_present(name, sections=None, separator=\(aq=\(aq, strict=False) +.B salt.states.ini_manage.options_present(name, sections=None, separator=u\(aq=\(aq, strict=False) .INDENT 7.0 .INDENT 3.5 .sp @@ -309545,7 +329554,7 @@ changes dict will contain the list of changes made .UNINDENT .INDENT 0.0 .TP -.B salt.states.ini_manage.sections_absent(name, sections=None, separator=\(aq=\(aq) +.B salt.states.ini_manage.sections_absent(name, sections=None, separator=u\(aq=\(aq) .INDENT 7.0 .INDENT 3.5 .sp @@ -309567,7 +329576,7 @@ changes dict will contain the sections that changed .UNINDENT .INDENT 0.0 .TP -.B salt.states.ini_manage.sections_present(name, sections=None, separator=\(aq=\(aq) +.B salt.states.ini_manage.sections_present(name, sections=None, separator=u\(aq=\(aq) .INDENT 7.0 .INDENT 3.5 .sp @@ -309637,7 +329646,7 @@ ensure myipmi system is powered on: .UNINDENT .INDENT 0.0 .TP -.B salt.states.ipmi.boot_device(name=\(aqdefault\(aq, **kwargs) +.B salt.states.ipmi.boot_device(name=u\(aqdefault\(aq, **kwargs) Request power state change .INDENT 7.0 .TP @@ -309674,7 +329683,7 @@ api_kg=None .UNINDENT .INDENT 0.0 .TP -.B salt.states.ipmi.power(name=\(aqpower_on\(aq, wait=300, **kwargs) +.B salt.states.ipmi.power(name=u\(aqpower_on\(aq, wait=300, **kwargs) Request power state change .INDENT 7.0 .TP @@ -309745,7 +329754,7 @@ api_kg=None .UNINDENT .INDENT 0.0 .TP -.B salt.states.ipmi.user_present(name, uid, password, channel=14, callback=False, link_auth=True, ipmi_msg=True, privilege_level=\(aqadministrator\(aq, **kwargs) +.B salt.states.ipmi.user_present(name, uid, password, channel=14, callback=False, link_auth=True, ipmi_msg=True, privilege_level=u\(aqadministrator\(aq, **kwargs) Ensure IPMI user and user privileges. .INDENT 7.0 .TP @@ -309887,7 +329896,7 @@ setname: .UNINDENT .INDENT 0.0 .TP -.B salt.states.ipset.absent(name, entry=None, entries=None, family=\(aqipv4\(aq, **kwargs) +.B salt.states.ipset.absent(name, entry=None, entries=None, family=u\(aqipv4\(aq, **kwargs) New in version 2014.7.0. .sp @@ -309904,7 +329913,7 @@ Network family, ipv4 or ipv6. .UNINDENT .INDENT 0.0 .TP -.B salt.states.ipset.flush(name, family=\(aqipv4\(aq, **kwargs) +.B salt.states.ipset.flush(name, family=u\(aqipv4\(aq, **kwargs) New in version 2014.7.0. .sp @@ -309917,7 +329926,7 @@ Networking family, either ipv4 or ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.states.ipset.present(name, entry=None, family=\(aqipv4\(aq, **kwargs) +.B salt.states.ipset.present(name, entry=None, family=u\(aqipv4\(aq, **kwargs) New in version 2014.7.0. .sp @@ -309937,7 +329946,7 @@ Network family, ipv4 or ipv6. .UNINDENT .INDENT 0.0 .TP -.B salt.states.ipset.set_absent(name, family=\(aqipv4\(aq, **kwargs) +.B salt.states.ipset.set_absent(name, family=u\(aqipv4\(aq, **kwargs) New in version 2014.7.0. .sp @@ -309950,7 +329959,7 @@ Networking family, either ipv4 or ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.states.ipset.set_present(name, set_type, family=\(aqipv4\(aq, **kwargs) +.B salt.states.ipset.set_present(name, set_type, family=u\(aqipv4\(aq, **kwargs) New in version 2014.7.0. .sp @@ -310168,7 +330177,7 @@ releases of \fBiptables\fP\&. .UNINDENT .INDENT 0.0 .TP -.B salt.states.iptables.append(name, table=\(aqfilter\(aq, family=\(aqipv4\(aq, **kwargs) +.B salt.states.iptables.append(name, table=u\(aqfilter\(aq, family=u\(aqipv4\(aq, **kwargs) New in version 0.17.0. .sp @@ -310196,7 +330205,7 @@ string. .UNINDENT .INDENT 0.0 .TP -.B salt.states.iptables.chain_absent(name, table=\(aqfilter\(aq, family=\(aqipv4\(aq) +.B salt.states.iptables.chain_absent(name, table=u\(aqfilter\(aq, family=u\(aqipv4\(aq) New in version 2014.1.0. .sp @@ -310212,7 +330221,7 @@ Networking family, either ipv4 or ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.states.iptables.chain_present(name, table=\(aqfilter\(aq, family=\(aqipv4\(aq) +.B salt.states.iptables.chain_present(name, table=u\(aqfilter\(aq, family=u\(aqipv4\(aq) New in version 2014.1.0. .sp @@ -310231,7 +330240,7 @@ Networking family, either ipv4 or ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.states.iptables.delete(name, table=\(aqfilter\(aq, family=\(aqipv4\(aq, **kwargs) +.B salt.states.iptables.delete(name, table=u\(aqfilter\(aq, family=u\(aqipv4\(aq, **kwargs) New in version 2014.1.0. .sp @@ -310259,7 +330268,7 @@ string. .UNINDENT .INDENT 0.0 .TP -.B salt.states.iptables.flush(name, table=\(aqfilter\(aq, family=\(aqipv4\(aq, **kwargs) +.B salt.states.iptables.flush(name, table=u\(aqfilter\(aq, family=u\(aqipv4\(aq, **kwargs) New in version 2014.1.0. .sp @@ -310275,7 +330284,7 @@ Networking family, either ipv4 or ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.states.iptables.insert(name, table=\(aqfilter\(aq, family=\(aqipv4\(aq, **kwargs) +.B salt.states.iptables.insert(name, table=u\(aqfilter\(aq, family=u\(aqipv4\(aq, **kwargs) New in version 2014.1.0. .sp @@ -310313,7 +330322,7 @@ low chunks and merges them into a single rules ref in the present low data .UNINDENT .INDENT 0.0 .TP -.B salt.states.iptables.set_policy(name, table=\(aqfilter\(aq, family=\(aqipv4\(aq, **kwargs) +.B salt.states.iptables.set_policy(name, table=u\(aqfilter\(aq, family=u\(aqipv4\(aq, **kwargs) New in version 2014.1.0. .sp @@ -310630,7 +330639,7 @@ use the latest salt code from github until the next release. Refer to \fBjunos\fP for information on connecting to junos proxy. .INDENT 0.0 .TP -.B salt.states.junos.cli(name, format=\(aqtext\(aq, **kwargs) +.B salt.states.junos.cli(name, format=u\(aqtext\(aq, **kwargs) Executes the CLI commands and reuturns the text output. .INDENT 7.0 .INDENT 3.5 @@ -311125,7 +331134,7 @@ Path to the file where any diffs will be written. (default = None) .UNINDENT .INDENT 0.0 .TP -.B salt.states.junos.rpc(name, dest=None, format=\(aqxml\(aq, args=None, **kwargs) +.B salt.states.junos.rpc(name, dest=None, format=u\(aqxml\(aq, args=None, **kwargs) Executes the given rpc. The returned data can be stored in a file by specifying the destination path with dest as an argument .INDENT 7.0 @@ -311450,7 +331459,7 @@ Name of the task. .UNINDENT .INDENT 0.0 .TP -.B salt.states.kapacitor.task_present(name, tick_script, task_type=\(aqstream\(aq, database=None, retention_policy=\(aqdefault\(aq, enable=True) +.B salt.states.kapacitor.task_present(name, tick_script, task_type=u\(aqstream\(aq, database=None, retention_policy=u\(aqdefault\(aq, enable=True) Ensure that a task is present and up\-to\-date in Kapacitor. .INDENT 7.0 .TP @@ -311474,6 +331483,178 @@ Which retention policy to fetch data from. Defaults to \(aqdefault\(aq. Whether to enable the task or not. Defaults to True. .UNINDENT .UNINDENT +.SS salt.states.kernelpkg +.SS Manage kernel packages and active kernel version +.sp +Example state to install the latest kernel from package repositories: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +install\-latest\-kernel: + kernel.latest_installed: [] +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Example state to boot the system if a new kernel has been installed: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +boot\-latest\-kernel: + kernel.latest_active: + \- at_time: 1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Example state chaining the install and reboot operations: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +install\-latest\-kernel: + kernel.latest_installed: [] + +boot\-latest\-kernel: + kernel.latest_active: + \- at_time: 1 + \- onchanges: + \- kernel: install\-latest\-kernel +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Chaining can also be acheived using wait/listen requisites: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +install\-latest\-kernel: + kernel.latest_installed: [] + +boot\-latest\-kernel: + kernel.latest_wait: + \- at_time: 1 + \- listen: + \- kernel: install\-latest\-kernel +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.kernelpkg.latest_active(name, at_time=None, **kwargs) +Initiate a reboot if the running kernel is not the latest one installed. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This state does not install any patches. It only compares the running +kernel version number to other kernel versions also installed in the +system. If the running version is not the latest one installed, this +state will reboot the system. +.sp +See \fBkernelpkg.upgrade\fP and +\fI\%latest_installed()\fP +for ways to install new kernel packages. +.sp +This module does not attempt to understand or manage boot loader configurations +it is possible to have a new kernel installed, but a boot loader configuration +that will never activate it. For this reason, it would not be advisable to +schedule this state to run automatically. +.sp +Because this state function may cause the system to reboot, it may be preferable +to move it to the very end of the state run. +See \fI\%latest_wait()\fP +for a waitable state that can be called with the \fIlisten\fP requesite. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B name +Arbitrary name for the state. Does not affect behavior. +.TP +.B at_time +The wait time in minutes before the system will be rebooted. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.kernelpkg.latest_installed(name, **kwargs) +Ensure that the latest version of the kernel available in the +repositories is installed. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +This state only installs the kernel, but does not activate it. +The new kernel should become active at the next reboot. +See \fBkernelpkg.needs_reboot\fP for details on +how to detect this condition, and \fI\%latest_active()\fP +to initiale a reboot when needed. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B name +Arbitrary name for the state. Does not affect behavior. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.kernelpkg.latest_wait(name, at_time=None, **kwargs) +Initiate a reboot if the running kernel is not the latest one installed. This is the +waitable version of \fI\%latest_active()\fP and +will not take any action unless triggered by a watch or listen requesite. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Because this state function may cause the system to reboot, it may be preferable +to move it to the very end of the state run using \fIlisten\fP or \fIlisten_in\fP requisites. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +system\-up\-to\-date: + pkg.uptodate: + \- refresh: true + +boot\-latest\-kernel: + kernelpkg.latest_wait: + \- at_time: 1 + \- listen: + \- pkg: system\-up\-to\-date +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B name +Arbitrary name for the state. Does not affect behavior. +.TP +.B at_time +The wait time in minutes before the system will be rebooted. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.kernelpkg.mod_watch(name, sfun, **kwargs) +Execute a kernelpkg state based on a watch or listen call +.UNINDENT .SS salt.states.keyboard .SS Management of keyboard layouts .sp @@ -312023,12 +332204,13 @@ Ensures that the named configmap is absent from the given namespace. The name of the configmap .TP .B namespace -The name of the namespace +The namespace holding the configmap. The \(aqdefault\(aq one is going to be +used unless a different one is specified. .UNINDENT .UNINDENT .INDENT 0.0 .TP -.B salt.states.kubernetes.configmap_present(name, namespace=\(aqdefault\(aq, data=None, source=\(aq\(aq, template=\(aq\(aq, **kwargs) +.B salt.states.kubernetes.configmap_present(name, namespace=\(aqdefault\(aq, data=None, source=None, template=None, **kwargs) Ensures that the named configmap is present inside of the specified namespace with the given data. If the configmap exists it will be replaced. @@ -312110,7 +332292,7 @@ Ensures that the named namespace is present. .INDENT 7.0 .TP .B name -The name of the deployment. +The name of the namespace. .UNINDENT .UNINDENT .INDENT 0.0 @@ -312214,7 +332396,7 @@ The name of the namespace .UNINDENT .INDENT 0.0 .TP -.B salt.states.kubernetes.secret_present(name, namespace=\(aqdefault\(aq, data=None, source=\(aq\(aq, template=\(aq\(aq, **kwargs) +.B salt.states.kubernetes.secret_present(name, namespace=\(aqdefault\(aq, data=None, source=None, template=None, **kwargs) Ensures that the named secret is present inside of the specified namespace with the given data. If the secret exists it will be replaced. @@ -312673,16 +332855,19 @@ Example: .sp .nf .ft C -webserver: +my\-zone: libcloud_dns.zone_present: - name: mywebsite.com - profile: profile1 + \- name: mywebsite.com + \- profile: profile1 +my\-website: libcloud_dns.record_present: - name: www - zone: mywebsite.com - type: A - data: 12.34.32.3 - profile: profile1 + \- name: www + \- zone: mywebsite.com + \- type: A + \- data: 12.34.32.3 + \- profile: profile1 + \- require: + \- libcloud_dns: my\-zone .ft P .fi .UNINDENT @@ -312742,7 +332927,7 @@ argument. .UNINDENT .INDENT 0.0 .TP -.B salt.states.libcloud_dns.state_result(name, result, message) +.B salt.states.libcloud_dns.state_result(result, message, name, changes=None) .UNINDENT .INDENT 0.0 .TP @@ -312776,6 +332961,341 @@ Ensures a record is present. .UNINDENT .UNINDENT .UNINDENT +.SS salt.states.libcloud_loadbalancer module +.SS Apache Libcloud Load Balancer State +.sp +Manage load balancers using libcloud +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B codeauthor + +.nf +:email:\(gaAnthony Shaw \(ga +.fi + +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Apache Libcloud load balancer management for a full list +of supported clouds, see \fI\%http://libcloud.readthedocs.io/en/latest/loadbalancer/supported_providers.html\fP +.sp +Clouds include Amazon ELB, ALB, Google, Aliyun, CloudStack, Softlayer +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B configuration +This module uses a configuration profile for one or multiple Cloud providers +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +libcloud_loadbalancer: + profile_test1: + driver: gce + key: GOOG0123456789ABCXYZ + secret: mysecret + profile_test2: + driver: alb + key: 12345 + secret: mysecret +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Example: +.sp +Using States to deploy a load balancer with extended arguments to specify region +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lb_test: + libcloud_loadbalancer.balancer_present: + \- name: example + \- port: 80 + \- protocol: http + \- profile: google + \- ex_region: us\-east1 +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B depends +apache\-libcloud +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_loadbalancer.balancer_absent(name, profile, **libcloud_kwargs) +Ensures a load balancer is absent. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Load Balancer name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_loadbalancer.balancer_present(name, port, protocol, profile, algorithm=None, members=None, **libcloud_kwargs) +Ensures a load balancer is present. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Load Balancer name +.IP \(bu 2 +\fBport\fP (\fBstr\fP) \-\- Port the load balancer should listen on, defaults to 80 +.IP \(bu 2 +\fBprotocol\fP (\fBstr\fP) \-\- Loadbalancer protocol, defaults to http. +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBalgorithm\fP (\fBstr\fP) \-\- Load balancing algorithm, defaults to ROUND_ROBIN. See Algorithm type +in Libcloud documentation for a full listing. +.IP \(bu 2 +\fBmembers\fP (\fBlist\fP of \fBdict\fP (ip, port)) \-\- An optional list of members to create on deployment +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_loadbalancer.member_absent(ip, port, balancer_id, profile, **libcloud_kwargs) +Ensure a load balancer member is absent, based on IP and Port +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBip\fP (\fBstr\fP) \-\- IP address for the member +.IP \(bu 2 +\fBport\fP (\fBint\fP) \-\- Port for the member +.IP \(bu 2 +\fBbalancer_id\fP (\fBstr\fP) \-\- id of a load balancer you want to detach the member from +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_loadbalancer.member_present(ip, port, balancer_id, profile, **libcloud_kwargs) +Ensure a load balancer member is present +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBip\fP (\fBstr\fP) \-\- IP address for the new member +.IP \(bu 2 +\fBport\fP (\fBint\fP) \-\- Port for the new member +.IP \(bu 2 +\fBbalancer_id\fP (\fBstr\fP) \-\- id of a load balancer you want to attach the member to +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_loadbalancer.state_result(result, message, name, changes=None) +.UNINDENT +.SS salt.states.libcloud_storage module +.SS Apache Libcloud Storage State +.sp +Manage cloud storage using libcloud +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B codeauthor + +.nf +:email:\(gaAnthony Shaw \(ga +.fi + +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Apache Libcloud Storage (object/blob) management for a full list +of supported clouds, see \fI\%http://libcloud.readthedocs.io/en/latest/storage/supported_providers.html\fP +.sp +Clouds include Amazon S3, Google Storage, Aliyun, Azure Blobs, Ceph, OpenStack swift +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B configuration +This module uses a configuration profile for one or multiple Storage providers +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +libcloud_storage: + profile_test1: + driver: google_storage + key: GOOG0123456789ABCXYZ + secret: mysecret + profile_test2: + driver: s3 + key: 12345 + secret: mysecret +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +Examples.SS Creating a container and uploading a file +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +web_things: + libcloud_storage.container_present: + name: my_container_name + profile: profile1 + libcloud_storage.object_present: + name: my_file.jpg + container: my_container_name + path: /path/to/local/file.jpg + profile: profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Downloading a file +.sp +This example will download the file from the remote cloud and keep it locally +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +web_things: + libcloud_storage.file_present: + name: my_file.jpg + container: my_container_name + path: /path/to/local/file.jpg + profile: profile1 +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B depends +apache\-libcloud +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_storage.container_absent(name, profile) +Ensures a container is absent. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_storage.container_present(name, profile) +Ensures a container is present. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_storage.file_present(container, name, path, profile, overwrite_existing=False) +Ensures a object is downloaded locally. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Object name in cloud +.IP \(bu 2 +\fBpath\fP (\fBstr\fP) \-\- Local path to file +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.IP \(bu 2 +\fBoverwrite_existing\fP (\fBbool\fP) \-\- Replace if already exists +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_storage.object_absent(container, name, profile) +Ensures a object is absent. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Object name in cloud +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_storage.object_present(container, name, path, profile) +Ensures a object is presnt. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontainer\fP (\fBstr\fP) \-\- Container name +.IP \(bu 2 +\fBname\fP (\fBstr\fP) \-\- Object name in cloud +.IP \(bu 2 +\fBpath\fP (\fBstr\fP) \-\- Local path to file +.IP \(bu 2 +\fBprofile\fP (\fBstr\fP) \-\- The profile key +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.libcloud_storage.state_result(result, message, name, changes) +.UNINDENT .SS salt.states.linux_acl .sp Linux File Access Control Lists @@ -312817,12 +333337,12 @@ root: .UNINDENT .INDENT 0.0 .TP -.B salt.states.linux_acl.absent(name, acl_type, acl_name=\(aq\(aq, perms=\(aq\(aq, recurse=False) +.B salt.states.linux_acl.absent(name, acl_type, acl_name=u\(aq\(aq, perms=u\(aq\(aq, recurse=False) Ensure a Linux ACL does not exist .UNINDENT .INDENT 0.0 .TP -.B salt.states.linux_acl.present(name, acl_type, acl_name=\(aq\(aq, perms=\(aq\(aq, recurse=False) +.B salt.states.linux_acl.present(name, acl_type, acl_name=u\(aq\(aq, perms=u\(aq\(aq, recurse=False) Ensure a Linux ACL is present .UNINDENT .SS salt.states.locale @@ -312871,6 +333391,78 @@ Set the locale for the system The name of the locale to use .UNINDENT .UNINDENT +.SS salt.states.logadm module +.sp +Management of logs using Solaris logadm. +.INDENT 0.0 +.TP +.B maintainer +Jorge Schrauwen <\fI\%sjorge@blackdot.be\fP> +.TP +.B maturity +new +.TP +.B depends +salt.modulus.logadm +.TP +.B platform +Oracle Solaris, Sun Solaris, illumos +.UNINDENT +.sp +New in version nitrogen. + +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +\&.. note:: + TODO +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.logadm.remove(name, log_file=None) +Remove a log from the logadm configuration +.INDENT 7.0 +.TP +.B name +string +entryname +.TP +.B log_file +string +(optional) log file path +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +If log_file is specified it will be used instead of the entry name. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.logadm.rotate(name, **kwargs) +Add a log to the logadm configuration +.INDENT 7.0 +.TP +.B name +string +alias for entryname +.TP +.B +.nf +** +.fi +kwargs +boolean|string|int +optional additional flags and parameters +.UNINDENT +.UNINDENT .SS salt.states.logrotate module .sp Module for managing logrotate. @@ -312879,7 +333471,7 @@ New in version 2017.7.0. .INDENT 0.0 .TP -.B salt.states.logrotate.set(name, key, value, setting=None, conf_file=\(aq/etc/logrotate.conf\(aq) +.B salt.states.logrotate.set(name, key, value, setting=None, conf_file=u\(aq/etc/logrotate.conf\(aq) Set a new value for a specific configuration line. .INDENT 7.0 .TP @@ -313033,7 +333625,7 @@ The volume group name .UNINDENT .INDENT 0.0 .TP -.B salt.states.lvm.lv_present(name, vgname=None, size=None, extents=None, snapshot=None, pv=\(aq\(aq, thinvolume=False, thinpool=False, **kwargs) +.B salt.states.lvm.lv_present(name, vgname=None, size=None, extents=None, snapshot=None, pv=u\(aq\(aq, thinvolume=False, thinpool=False, force=False, **kwargs) Create a new logical volume .INDENT 7.0 .TP @@ -313070,6 +333662,14 @@ Logical volume is thinly provisioned .B thinpool Logical volume is a thin pool .UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 7.0 +.TP +.B force +Assume yes to all prompts +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -313145,7 +333745,7 @@ The LVS real server address. .UNINDENT .INDENT 0.0 .TP -.B salt.states.lvs_server.present(name, protocol=None, service_address=None, server_address=None, packet_forward_method=\(aqdr\(aq, weight=1) +.B salt.states.lvs_server.present(name, protocol=None, service_address=None, server_address=None, packet_forward_method=u\(aqdr\(aq, weight=1) Ensure that the named service is present. .INDENT 7.0 .TP @@ -313204,7 +333804,7 @@ The LVS service address .UNINDENT .INDENT 0.0 .TP -.B salt.states.lvs_service.present(name, protocol=None, service_address=None, scheduler=\(aqwlc\(aq) +.B salt.states.lvs_service.present(name, protocol=None, service_address=None, scheduler=u\(aqwlc\(aq) Ensure that the named service is present. .INDENT 7.0 .TP @@ -313687,7 +334287,7 @@ The user to write the defaults to .UNINDENT .INDENT 0.0 .TP -.B salt.states.mac_defaults.write(name, domain, value, vtype=\(aqstring\(aq, user=None) +.B salt.states.mac_defaults.write(name, domain, value, vtype=u\(aqstring\(aq, user=None) Write a default to the system .INDENT 7.0 .TP @@ -313726,7 +334326,7 @@ Install certificats to the macOS keychain .UNINDENT .INDENT 0.0 .TP -.B salt.states.mac_keychain.default_keychain(name, domain=\(aquser\(aq, user=None) +.B salt.states.mac_keychain.default_keychain(name, domain=u\(aquser\(aq, user=None) Set the default keychain to use .INDENT 7.0 .TP @@ -313742,7 +334342,7 @@ The user to run as .UNINDENT .INDENT 0.0 .TP -.B salt.states.mac_keychain.installed(name, password, keychain=\(aq/Library/Keychains/System.keychain\(aq, **kwargs) +.B salt.states.mac_keychain.installed(name, password, keychain=u\(aq/Library/Keychains/System.keychain\(aq, **kwargs) Install a p12 certificate file into the macOS keychain .INDENT 7.0 .TP @@ -313767,7 +334367,7 @@ before running the import .UNINDENT .INDENT 0.0 .TP -.B salt.states.mac_keychain.uninstalled(name, password, keychain=\(aq/Library/Keychains/System.keychain\(aq, keychain_password=None) +.B salt.states.mac_keychain.uninstalled(name, password, keychain=u\(aq/Library/Keychains/System.keychain\(aq, keychain_password=None) Uninstall a p12 certificate file from the macOS keychain .INDENT 7.0 .TP @@ -313823,7 +334423,7 @@ Install any kind of pkg, dmg or app file on macOS: \&.*7B91b .INDENT 0.0 .TP -.B salt.states.mac_package.installed(name, target=\(aqLocalSystem\(aq, dmg=False, store=False, app=False, mpkg=False, user=None, onlyif=None, unless=None, force=False, allow_untrusted=False, version_check=None) +.B salt.states.mac_package.installed(name, target=u\(aqLocalSystem\(aq, dmg=False, store=False, app=False, mpkg=False, user=None, onlyif=None, unless=None, force=False, allow_untrusted=False, version_check=None) Install a Mac OS Package from a pkg or dmg file, if given a dmg file it will first be mounted in a temporary location .INDENT 7.0 @@ -313866,6 +334466,16 @@ Allow the installation of untrusted packages .TP .B version_check The command and version that we want to check against, the version number can use regex. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +version_check: python \-\-version_check=2.7.[0\-9] +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .UNINDENT .SS salt.states.mac_xattr module @@ -314131,7 +334741,7 @@ New in version 2014.1.0. .INDENT 0.0 .TP -.B salt.states.memcached.absent(name, value=None, host=\(aq127.0.0.1\(aq, port=11211, time=0) +.B salt.states.memcached.absent(name, value=None, host=u\(aq127.0.0.1\(aq, port=11211, time=0) Ensure that a memcached key is not present. .INDENT 7.0 .TP @@ -314167,7 +334777,7 @@ bar: .UNINDENT .INDENT 0.0 .TP -.B salt.states.memcached.managed(name, value=None, host=\(aq127.0.0.1\(aq, port=11211, time=0, min_compress_len=0) +.B salt.states.memcached.managed(name, value=None, host=u\(aq127.0.0.1\(aq, port=11211, time=0, min_compress_len=0) Manage a memcached key. .INDENT 7.0 .TP @@ -314201,7 +334811,7 @@ foo: State to control Apache modjk .INDENT 0.0 .TP -.B salt.states.modjk.worker_activated(name, workers=None, profile=\(aqdefault\(aq) +.B salt.states.modjk.worker_activated(name, workers=None, profile=u\(aqdefault\(aq) Activate all the workers in the modjk load balancer .sp Example: @@ -314222,7 +334832,7 @@ loadbalancer: .UNINDENT .INDENT 0.0 .TP -.B salt.states.modjk.worker_disabled(name, workers=None, profile=\(aqdefault\(aq) +.B salt.states.modjk.worker_disabled(name, workers=None, profile=u\(aqdefault\(aq) Disable all the workers in the modjk load balancer .sp Example: @@ -314243,7 +334853,7 @@ loadbalancer: .UNINDENT .INDENT 0.0 .TP -.B salt.states.modjk.worker_recover(name, workers=None, profile=\(aqdefault\(aq) +.B salt.states.modjk.worker_recover(name, workers=None, profile=u\(aqdefault\(aq) Recover all the workers in the modjk load balancer .sp Example: @@ -314264,7 +334874,7 @@ loadbalancer: .UNINDENT .INDENT 0.0 .TP -.B salt.states.modjk.worker_stopped(name, workers=None, profile=\(aqdefault\(aq) +.B salt.states.modjk.worker_stopped(name, workers=None, profile=u\(aqdefault\(aq) Stop all the workers in the modjk load balancer .sp Example: @@ -314304,7 +334914,7 @@ execution module \fBdocumentation\fP .UNINDENT .INDENT 0.0 .TP -.B salt.states.modjk_worker.activate(name, lbn, target, profile=\(aqdefault\(aq, tgt_type=\(aqglob\(aq, expr_form=None) +.B salt.states.modjk_worker.activate(name, lbn, target, profile=u\(aqdefault\(aq, tgt_type=u\(aqglob\(aq, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -314331,7 +334941,7 @@ disable\-before\-deploy: .UNINDENT .INDENT 0.0 .TP -.B salt.states.modjk_worker.disable(name, lbn, target, profile=\(aqdefault\(aq, tgt_type=\(aqglob\(aq, expr_form=None) +.B salt.states.modjk_worker.disable(name, lbn, target, profile=u\(aqdefault\(aq, tgt_type=u\(aqglob\(aq, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -314359,7 +334969,7 @@ disable\-before\-deploy: .UNINDENT .INDENT 0.0 .TP -.B salt.states.modjk_worker.stop(name, lbn, target, profile=\(aqdefault\(aq, tgt_type=\(aqglob\(aq, expr_form=None) +.B salt.states.modjk_worker.stop(name, lbn, target, profile=u\(aqdefault\(aq, tgt_type=u\(aqglob\(aq, expr_form=None) Changed in version 2017.7.0: The \fBexpr_form\fP argument has been renamed to \fBtgt_type\fP, earlier releases must use \fBexpr_form\fP\&. @@ -314675,6 +335285,9 @@ and can be done using mongodb_user.present .INDENT 0.0 .TP .B salt.states.mongodb_database.absent(name, user=None, password=None, host=None, port=None, authdb=None) +Deprecated since version Fluorine: Use \fBmongodb.database_absent\fP instead + +.sp Ensure that the named database is absent .INDENT 7.0 .TP @@ -314708,7 +335321,10 @@ This module requires PyMongo to be installed. .UNINDENT .INDENT 0.0 .TP -.B salt.states.mongodb_user.absent(name, user=None, password=None, host=None, port=None, database=\(aqadmin\(aq, authdb=None) +.B salt.states.mongodb_user.absent(name, user=None, password=None, host=None, port=None, database=u\(aqadmin\(aq, authdb=None) +Deprecated since version Fluorine: Use \fBmongodb.user_absent\fP instead + +.sp Ensure that the named user is absent .INDENT 7.0 .TP @@ -314737,7 +335353,10 @@ The database in which to authenticate .UNINDENT .INDENT 0.0 .TP -.B salt.states.mongodb_user.present(name, passwd, database=\(aqadmin\(aq, user=None, password=None, host=\(aqlocalhost\(aq, port=27017, authdb=None, roles=None) +.B salt.states.mongodb_user.present(name, passwd, database=u\(aqadmin\(aq, user=None, password=None, host=u\(aqlocalhost\(aq, port=27017, authdb=None, roles=None) +Deprecated since version Fluorine: Use \fBmongodb.user_present\fP instead + +.sp Ensure that the user is present with the specified properties .INDENT 7.0 .TP @@ -314881,6 +335500,16 @@ Mount any type of mountable filesystem with the mounted function: \- pass_num: 2 \- persist: True \- mkmnt: True + +/var/lib/bigdata: + mount.mounted: + \- device: /srv/bigdata + \- fstype: none + \- opts: bind + \- dump: 0 + \- pass_num: 0 + \- persist: True + \- mkmnt: True .ft P .fi .UNINDENT @@ -314897,7 +335526,7 @@ The name of the mount point .UNINDENT .INDENT 0.0 .TP -.B salt.states.mount.mounted(name, device, fstype, mkmnt=False, opts=\(aqdefaults\(aq, dump=0, pass_num=0, config=\(aq/etc/fstab\(aq, persist=True, mount=True, user=None, match_on=\(aqauto\(aq, device_name_regex=None, extra_mount_invisible_options=None, extra_mount_invisible_keys=None, extra_mount_ignore_fs_keys=None, extra_mount_translate_options=None, hidden_opts=None) +.B salt.states.mount.mounted(name, device, fstype, mkmnt=False, opts=u\(aqdefaults\(aq, dump=0, pass_num=0, config=u\(aq/etc/fstab\(aq, persist=True, mount=True, user=None, match_on=u\(aqauto\(aq, device_name_regex=None, extra_mount_invisible_options=None, extra_mount_invisible_keys=None, extra_mount_ignore_fs_keys=None, extra_mount_translate_options=None, hidden_opts=None, **kwargs) Verify that a device is mounted .INDENT 7.0 .TP @@ -315048,7 +335677,7 @@ New in version 2015.8.2. .UNINDENT .INDENT 0.0 .TP -.B salt.states.mount.swap(name, persist=True, config=\(aq/etc/fstab\(aq) +.B salt.states.mount.swap(name, persist=True, config=u\(aq/etc/fstab\(aq) Activates a swap device .INDENT 7.0 .INDENT 3.5 @@ -315071,7 +335700,7 @@ Activates a swap device .UNINDENT .INDENT 0.0 .TP -.B salt.states.mount.unmounted(name, device=None, config=\(aq/etc/fstab\(aq, persist=False, user=None) +.B salt.states.mount.unmounted(name, device=None, config=u\(aq/etc/fstab\(aq, persist=False, user=None, **kwargs) New in version 0.17.0. .sp @@ -315297,7 +335926,7 @@ restricted_singletable: .UNINDENT .INDENT 0.0 .TP -.B salt.states.mysql_grants.absent(name, grant=None, database=None, user=None, host=\(aqlocalhost\(aq, grant_option=False, escape=True, **connection_args) +.B salt.states.mysql_grants.absent(name, grant=None, database=None, user=None, host=u\(aqlocalhost\(aq, grant_option=False, escape=True, **connection_args) Ensure that the grant is absent .INDENT 7.0 .TP @@ -315319,7 +335948,7 @@ The network/host that the grant should apply to .UNINDENT .INDENT 0.0 .TP -.B salt.states.mysql_grants.present(name, grant=None, database=None, user=None, host=\(aqlocalhost\(aq, grant_option=False, escape=True, revoke_first=False, ssl_option=False, **connection_args) +.B salt.states.mysql_grants.present(name, grant=None, database=None, user=None, host=u\(aqlocalhost\(aq, grant_option=False, escape=True, revoke_first=False, ssl_option=False, **connection_args) Ensure that the grant is present with the specified properties .INDENT 7.0 .TP @@ -315545,7 +336174,7 @@ This state is not able to grant permissions for the user. See \fBsalt.states.mysql_grants\fP for further instructions. .INDENT 0.0 .TP -.B salt.states.mysql_user.absent(name, host=\(aqlocalhost\(aq, **connection_args) +.B salt.states.mysql_user.absent(name, host=u\(aqlocalhost\(aq, **connection_args) Ensure that the named user is absent .INDENT 7.0 .TP @@ -315555,7 +336184,7 @@ The name of the user to remove .UNINDENT .INDENT 0.0 .TP -.B salt.states.mysql_user.present(name, host=\(aqlocalhost\(aq, password=None, password_hash=None, allow_passwordless=False, unix_socket=False, password_column=None, **connection_args) +.B salt.states.mysql_user.present(name, host=u\(aqlocalhost\(aq, password=None, password_hash=None, allow_passwordless=False, unix_socket=False, password_column=None, **connection_args) Ensure that the named user is present with the specified properties. A passwordless user can be configured by omitting \fBpassword\fP and \fBpassword_hash\fP, and setting \fBallow_passwordless\fP to \fBTrue\fP\&. @@ -315635,7 +336264,7 @@ it requires \fI\%NAPALM\fP library to be installed: \fBpip install napalm\fP\&. Please check \fI\%Installation\fP for complete details. .INDENT 0.0 .TP -.B salt.states.netacl.filter(name, filter_name, filter_options=None, terms=None, prepend=True, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=False, only_lower_merge=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=\(aq%Y/%m/%d\(aq, test=False, commit=True, debug=False) +.B salt.states.netacl.filter(name, filter_name, filter_options=None, terms=None, prepend=True, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=False, only_lower_merge=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=u\(aq%Y/%m/%d\(aq, test=False, commit=True, debug=False) Generate and load the configuration of a policy filter. .INDENT 7.0 .TP @@ -315868,7 +336497,7 @@ instead of relying on the default Python serializer. .UNINDENT .INDENT 0.0 .TP -.B salt.states.netacl.managed(name, filters=None, prepend=True, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=False, only_lower_merge=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=\(aq%Y/%m/%d\(aq, test=False, commit=True, debug=False) +.B salt.states.netacl.managed(name, filters=None, prepend=True, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=False, only_lower_merge=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=u\(aq%Y/%m/%d\(aq, test=False, commit=True, debug=False) Manage the whole firewall configuration. .INDENT 7.0 .TP @@ -316171,7 +336800,7 @@ instead of relying on the default Python serializer. .UNINDENT .INDENT 0.0 .TP -.B salt.states.netacl.term(name, filter_name, term_name, filter_options=None, pillar_key=\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=\(aq%Y/%m/%d\(aq, test=False, commit=True, debug=False, source_service=None, destination_service=None, **term_fields) +.B salt.states.netacl.term(name, filter_name, term_name, filter_options=None, pillar_key=u\(aqacl\(aq, pillarenv=None, saltenv=None, merge_pillar=False, revision_id=None, revision_no=None, revision_date=True, revision_date_format=u\(aq%Y/%m/%d\(aq, test=False, commit=True, debug=False, source_service=None, destination_service=None, **term_fields) Manage the configuration of a specific policy term. .INDENT 7.0 .TP @@ -316366,6 +336995,8 @@ flattened_addr flattened_saddr .IP \(bu 2 flattened_daddr +.IP \(bu 2 +priority .UNINDENT .UNINDENT .UNINDENT @@ -316680,7 +337311,7 @@ New in version 2017.7.0. .INDENT 0.0 .TP -.B salt.states.netconfig.managed(name, template_name, template_source=None, template_path=None, template_hash=None, template_hash_name=None, template_user=\(aqroot\(aq, template_group=\(aqroot\(aq, template_mode=\(aq755\(aq, saltenv=None, template_engine=\(aqjinja\(aq, skip_verify=False, defaults=None, test=False, commit=True, debug=False, replace=False, **template_vars) +.B salt.states.netconfig.managed(name, template_name, template_source=None, template_path=None, template_hash=None, template_hash_name=None, template_user=u\(aqroot\(aq, template_group=u\(aqroot\(aq, template_mode=u\(aq755\(aq, template_attrs=u\(aq\-\-\-\-\-\-\-\-\-\-\-\-\-\-e\-\-\-\-\(aq, saltenv=None, template_engine=u\(aqjinja\(aq, skip_verify=False, defaults=None, test=False, commit=True, debug=False, replace=False, **template_vars) Manages the configuration on network devices. .sp By default this state will commit the changes on the device. If there are no changes required, it does not commit @@ -316762,8 +337393,14 @@ Owner of file. .B template_user: root Group owner of file. .TP -.B template_user: 755 +.B template_mode: 755 Permissions of file +.TP +.B template_attrs: "\-\-\-\-\-\-\-\-\-\-\-\-\-\-e\-\-\-\-" +Attributes of file (see \fIman lsattr\fP) +.sp +New in version 2018.3.0. + .TP .B saltenv: base Specifies the template environment. This will influence the relative imports inside the templates. @@ -317646,7 +338283,7 @@ it requires \fI\%NAPALM\fP library to be installed: \fBpip install napalm\fP\&. Please check \fI\%Installation\fP for complete details. .INDENT 0.0 .TP -.B salt.states.netyang.configured(name, data, models, **kwargs) +.B salt.states.netyang.configured(name, data, *models, **kwargs) Configure the network device, given the input data strucuted according to the YANG models. .sp @@ -317734,7 +338371,7 @@ openconfig_interfaces_cfg: .UNINDENT .INDENT 0.0 .TP -.B salt.states.netyang.managed(name, data, models, **kwargs) +.B salt.states.netyang.managed(name, data, *models, **kwargs) Manage the device configuration given the input data strucuted according to the YANG models. .INDENT 7.0 @@ -317813,6 +338450,176 @@ openconfig_interfaces_cfg: .UNINDENT .UNINDENT .UNINDENT +.SS salt.states.nfs_export +.SS Management of NFS exports +.sp +New in version 2018.3.0. + +.sp +To ensure an NFS export exists: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +add_simple_export: + nfs_export.present: + \- name: \(aq/srv/nfs\(aq + \- hosts: \(aq10.0.2.0/24\(aq + \- options: + \- \(aqrw\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This creates the following in /etc/exports: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +/srv/nfs 10.0.2.0/24(rw) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +For more complex exports with multiple groups of hosts, use \(aqclients\(aq: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +add_complex_export: + nfs_export.present: + \- name: \(aq/srv/nfs\(aq + \- clients: + # First export, same as simple one above + \- hosts: \(aq10.0.2.0/24\(aq + options: + \- \(aqrw\(aq + # Second export + \- hosts: \(aq*.example.com\(aq + options: + \- \(aqro\(aq + \- \(aqsubtree_check\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This creates the following in /etc/exports: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +/srv/nfs 10.0.2.0/24(rw) 192.168.0.0/24,172.19.0.0/16(ro,subtree_check) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Any export of the given path will be modified to match the one specified. +.sp +To ensure an NFS export is absent: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +delete_export: + nfs_export.absent: + \- name: \(aq/srv/nfs\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.nfs_export.absent(name, exports=u\(aq/etc/exports\(aq) +Ensure that the named path is not exported +.INDENT 7.0 +.TP +.B name +The export path to remove +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.nfs_export.present(name, clients=None, hosts=None, options=None, exports=u\(aq/etc/exports\(aq) +Ensure that the named export is present with the given options +.INDENT 7.0 +.TP +.B name +The export path to configure +.TP +.B clients +A list of hosts and the options applied to them. +This option may not be used in combination with +the \(aqhosts\(aq or \(aqoptions\(aq shortcuts. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +\- clients: + # First export + \- hosts: \(aq10.0.2.0/24\(aq + options: + \- \(aqrw\(aq + # Second export + \- hosts: \(aq*.example.com\(aq + options: + \- \(aqro\(aq + \- \(aqsubtree_check\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B hosts +A string matching a number of hosts, for example: +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +hosts: \(aq10.0.2.123\(aq + +hosts: \(aq10.0.2.0/24\(aq + +hosts: \(aqminion1.example.com\(aq + +hosts: \(aq*.example.com\(aq + +hosts: \(aq*\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B options +A list of NFS options, for example: +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +options: + \- \(aqrw\(aq + \- \(aqsubtree_check\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.states.nftables .SS Management of nftables .sp @@ -317919,7 +338726,7 @@ httpd: .UNINDENT .INDENT 0.0 .TP -.B salt.states.nftables.append(name, family=\(aqipv4\(aq, **kwargs) +.B salt.states.nftables.append(name, family=u\(aqipv4\(aq, **kwargs) New in version 0.17.0. .sp @@ -317941,7 +338748,7 @@ specified as \fIconnstate\fP instead of \fIstate\fP (not to be confused with .UNINDENT .INDENT 0.0 .TP -.B salt.states.nftables.chain_absent(name, table=\(aqfilter\(aq, family=\(aqipv4\(aq) +.B salt.states.nftables.chain_absent(name, table=u\(aqfilter\(aq, family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -317954,7 +338761,7 @@ Networking family, either ipv4 or ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.states.nftables.chain_present(name, table=\(aqfilter\(aq, table_type=None, hook=None, priority=None, family=\(aqipv4\(aq) +.B salt.states.nftables.chain_present(name, table=u\(aqfilter\(aq, table_type=None, hook=None, priority=None, family=u\(aqipv4\(aq) New in version 2014.7.0. .sp @@ -317973,7 +338780,7 @@ Networking family, either ipv4 or ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.states.nftables.delete(name, family=\(aqipv4\(aq, **kwargs) +.B salt.states.nftables.delete(name, family=u\(aqipv4\(aq, **kwargs) New in version 2014.7.0. .sp @@ -317995,7 +338802,7 @@ specified as \fIconnstate\fP instead of \fIstate\fP (not to be confused with .UNINDENT .INDENT 0.0 .TP -.B salt.states.nftables.flush(name, family=\(aqipv4\(aq, **kwargs) +.B salt.states.nftables.flush(name, family=u\(aqipv4\(aq, **kwargs) New in version 2014.7.0. .sp @@ -318008,7 +338815,7 @@ Networking family, either ipv4 or ipv6 .UNINDENT .INDENT 0.0 .TP -.B salt.states.nftables.insert(name, family=\(aqipv4\(aq, **kwargs) +.B salt.states.nftables.insert(name, family=u\(aqipv4\(aq, **kwargs) New in version 2014.7.0. .sp @@ -318348,7 +339155,7 @@ delete: .UNINDENT .INDENT 0.0 .TP -.B salt.states.nxos.user_present(name, password=None, roles=None, encrypted=False, crypt_salt=None, algorithm=\(aqsha256\(aq) +.B salt.states.nxos.user_present(name, password=None, roles=None, encrypted=False, crypt_salt=None, algorithm=u\(aqsha256\(aq) Ensure a user is present with the specified groups .INDENT 7.0 .TP @@ -318522,6 +339329,104 @@ Ensures that the named port exists on bridge, eventually creates it. .UNINDENT .UNINDENT .UNINDENT +.SS salt.states.opsgenie +.SS Create/Close an alert in OpsGenie +.sp +New in version 2018.3.0. + +.sp +This state is useful for creating or closing alerts in OpsGenie +during state runs. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +used_space: + disk.status: + \- name: / + \- maximum: 79% + \- minimum: 20% + +opsgenie_create_action_sender: + opsgenie.create_alert: + \- api_key: XXXXXXXX\-XXXX\-XXXX\-XXXX\-XXXXXXXXXXXX + \- reason: \(aqDisk capacity is out of designated range.\(aq + \- name: disk.status + \- onfail: + \- disk: used_space + +opsgenie_close_action_sender: + opsgenie.close_alert: + \- api_key: XXXXXXXX\-XXXX\-XXXX\-XXXX\-XXXXXXXXXXXX + \- name: disk.status + \- require: + \- disk: used_space +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.opsgenie.close_alert(name=None, api_key=None, reason=u\(aqConditions are met.\(aq, action_type=u\(aqClose\(aq) +Close an alert in OpsGenie. It\(aqs a wrapper function for create_alert. +Example usage with Salt\(aqs requisites and other global state arguments +could be found above. +.sp +Required Parameters: +.INDENT 7.0 +.TP +.B name +It will be used as alert\(aqs alias. If you want to use the close +functionality you must provide name field for both states like +in above case. +.UNINDENT +.sp +Optional Parameters: +.INDENT 7.0 +.TP +.B api_key +It\(aqs the API Key you\(aqve copied while adding integration in OpsGenie. +.TP +.B reason +It will be used as alert\(aqs default message in OpsGenie. +.TP +.B action_type +OpsGenie supports the default values Create/Close for action_type. +You can customize this field with OpsGenie\(aqs custom actions for +other purposes like adding notes or acknowledging alerts. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.opsgenie.create_alert(name=None, api_key=None, reason=None, action_type=u\(aqCreate\(aq) +Create an alert in OpsGenie. Example usage with Salt\(aqs requisites and other +global state arguments could be found above. +.sp +Required Parameters: +.INDENT 7.0 +.TP +.B api_key +It\(aqs the API Key you\(aqve copied while adding integration in OpsGenie. +.TP +.B reason +It will be used as alert\(aqs default message in OpsGenie. +.UNINDENT +.sp +Optional Parameters: +.INDENT 7.0 +.TP +.B name +It will be used as alert\(aqs alias. If you want to use the close +functionality you must provide name field for both states like +in above case. +.TP +.B action_type +OpsGenie supports the default values Create/Close for action_type. +You can customize this field with OpsGenie\(aqs custom actions for +other purposes like adding notes or acknowledging alerts. +.UNINDENT +.UNINDENT .SS salt.states.pagerduty .SS Create an Event in PagerDuty .sp @@ -318624,7 +339529,7 @@ ensure test escalation policy: .UNINDENT .INDENT 0.0 .TP -.B salt.states.pagerduty_escalation_policy.absent(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.states.pagerduty_escalation_policy.absent(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Ensure that a PagerDuty escalation policy does not exist. Accepts all the arguments that pagerduty_escalation_policy.present accepts; but ignores all arguments except the name. @@ -318633,7 +339538,7 @@ Name can be the escalation policy id or the escalation policy name. .UNINDENT .INDENT 0.0 .TP -.B salt.states.pagerduty_escalation_policy.present(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.states.pagerduty_escalation_policy.present(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Ensure that a pagerduty escalation policy exists. Will create or update as needed. .sp This method accepts as args everything defined in @@ -318769,13 +339674,13 @@ rotation_turn_length_seconds: 604800 .UNINDENT .INDENT 0.0 .TP -.B salt.states.pagerduty_schedule.absent(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.states.pagerduty_schedule.absent(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Ensure that a pagerduty schedule does not exist. Name can be pagerduty schedule id or pagerduty schedule name. .UNINDENT .INDENT 0.0 .TP -.B salt.states.pagerduty_schedule.present(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.states.pagerduty_schedule.present(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Ensure that a pagerduty schedule exists. This method accepts as args everything defined in \fI\%https://developer.pagerduty.com/documentation/rest/schedules/create\fP\&. @@ -318824,13 +339729,13 @@ type: nagios .UNINDENT .INDENT 0.0 .TP -.B salt.states.pagerduty_service.absent(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.states.pagerduty_service.absent(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Ensure a pagerduty service does not exist. Name can be the service name or pagerduty service id. .UNINDENT .INDENT 0.0 .TP -.B salt.states.pagerduty_service.present(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.states.pagerduty_service.present(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Ensure pagerduty service exists. This method accepts as arguments everything defined in \fI\%https://developer.pagerduty.com/documentation/rest/services/create\fP @@ -318929,13 +339834,13 @@ requester_id: P1GV5NT .UNINDENT .INDENT 0.0 .TP -.B salt.states.pagerduty_user.absent(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.states.pagerduty_user.absent(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Ensure pagerduty user does not exist. Name can be pagerduty id, email address, or user name. .UNINDENT .INDENT 0.0 .TP -.B salt.states.pagerduty_user.present(profile=\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) +.B salt.states.pagerduty_user.present(profile=u\(aqpagerduty\(aq, subdomain=None, api_key=None, **kwargs) Ensure pagerduty user exists. Arguments match those supported by \fI\%https://developer.pagerduty.com/documentation/rest/users/create\fP\&. @@ -319178,7 +340083,7 @@ New in version 2016.3.0. .INDENT 0.0 .TP -.B salt.states.pcs.auth(name, nodes, pcsuser=\(aqhacluster\(aq, pcspasswd=\(aqhacluster\(aq, extra_args=None) +.B salt.states.pcs.auth(name, nodes, pcsuser=u\(aqhacluster\(aq, pcspasswd=u\(aqhacluster\(aq, extra_args=None) Ensure all nodes are authorized to the cluster .INDENT 7.0 .TP @@ -319331,7 +340236,7 @@ pcs_setup__node_add_node1.example.com: .UNINDENT .INDENT 0.0 .TP -.B salt.states.pcs.cluster_setup(name, nodes, pcsclustername=\(aqpcscluster\(aq, extra_args=None) +.B salt.states.pcs.cluster_setup(name, nodes, pcsclustername=u\(aqpcscluster\(aq, extra_args=None) Setup Pacemaker cluster on nodes. Should be run on one cluster node only (there may be races) @@ -319662,7 +340567,7 @@ mongo: .UNINDENT .INDENT 0.0 .TP -.B salt.states.pecl.installed(name, version=None, defaults=False, force=False, preferred_state=\(aqstable\(aq) +.B salt.states.pecl.installed(name, version=None, defaults=False, force=False, preferred_state=u\(aqstable\(aq) New in version 0.17.0. .sp @@ -320251,7 +341156,7 @@ base: \- keyserver: keyserver.ubuntu.com logstash: - pkg.installed + pkg.installed: \- fromrepo: ppa:wolfnet/logstash .ft P .fi @@ -320363,6 +341268,14 @@ common_packages: .UNINDENT .UNINDENT +.IP \(bu 2 +\fBresolve_capabilities\fP (\fI\%bool\fP) \-\- +.sp +Turn on resolving capabilities. This allow to name "provides" or alias names for packages. +.sp +New in version 2018.3.0. + + .UNINDENT .UNINDENT .sp @@ -320467,6 +341380,7 @@ Install a specific version of a package. This option is ignored if for the following pkg providers: \fBapt\fP, \fBebuild\fP, \fBpacman\fP, +\fBpkgin\fP, \fBwin_pkg\fP, \fByumpkg\fP, and \fBzypper\fP\&. The version number includes the @@ -320722,6 +341636,12 @@ Force strict package naming. Disables lookup of package alternatives. .sp New in version 2014.1.1. +.TP +.B param bool resolve_capabilities +Turn on resolving capabilities. This allow to name "provides" or alias names for packages. +.sp +New in version 2018.3.0. + .TP .B param bool allow_updates Allow the package to be updated outside Salt\(aqs control (e.g. auto @@ -320954,9 +341874,10 @@ mypkgs: .UNINDENT .UNINDENT .sp -Additionally, \fBebuild\fP, \fBpacman\fP and \fBzypper\fP support -the \fB<\fP, \fB<=\fP, \fB>=\fP, and \fB>\fP operators for more control over -what versions will be installed. For example: +Additionally, \fBebuild\fP, \fBpacman\fP, \fBzypper\fP, +\fByum/dnf\fP, and \fBapt\fP support the \fB<\fP, \fB<=\fP, \fB>=\fP, and \fB>\fP +operators for more control over what versions will be installed. For +example: .INDENT 7.0 .INDENT 3.5 .sp @@ -321255,6 +342176,12 @@ This parameter is available only on Debian based distributions and has no effect on the rest. .UNINDENT .UNINDENT +.TP +.B param bool resolve_capabilities +Turn on resolving capabilities. This allow to name "provides" or alias names for packages. +.sp +New in version 2018.3.0. + .UNINDENT .sp Multiple Package Installation Options: @@ -321692,6 +342619,9 @@ New in version 0.16.0. .B salt.states.pkg.uptodate(name, refresh=False, pkgs=None, **kwargs) New in version 2014.7.0. +.sp +Changed in version 2018.3.0: Added support for the \fBpkgin\fP provider. + .sp Verify that the system is completely up to date. .INDENT 7.0 @@ -321709,6 +342639,8 @@ list of packages to upgrade .INDENT 7.0 .TP .B Parameters +.INDENT 7.0 +.IP \(bu 2 \fBcache_valid_time\fP (\fI\%str\fP) \-\- .sp This parameter sets the value in seconds after which cache marked as invalid, @@ -321719,13 +342651,22 @@ In this case cache_valid_time is set, refresh will not take place for amount in seconds since last \fBapt\-get update\fP executed on the system. .sp \fBNOTE:\fP -.INDENT 7.0 +.INDENT 2.0 .INDENT 3.5 This parameter available only on Debian based distributions, and have no effect on the rest. .UNINDENT .UNINDENT +.IP \(bu 2 +\fBresolve_capabilities\fP (\fI\%bool\fP) \-\- +.sp +Turn on resolving capabilities. This allow to name "provides" or alias names for packages. +.sp +New in version 2018.3.0. + + +.UNINDENT .UNINDENT .INDENT 7.0 .TP @@ -322045,9 +342986,9 @@ pkgng_clients: .UNINDENT .UNINDENT .SS salt.states.pkgrepo -.SS Management of APT/YUM package repos +.SS Management of APT/RPM package repos .sp -Package repositories for APT\-based and YUM\-based distros can be managed with +Package repositories for APT\-based and RPM\-based distros(openSUSE/SUSE, CentOS/Fedora/Redhat) can be managed with these states. Here is some example SLS: .INDENT 0.0 .INDENT 3.5 @@ -322151,10 +343092,9 @@ Also, some Ubuntu releases have a \fI\%bug\fP in their \fBpython\-pycurl\fP will need to be manually installed if it is not present once \fBpython\-software\-properties\fP is installed. .sp -On Ubuntu & Debian systems, the \fB\(gapython\-apt\fP package is required to be -installed. To check if this package is installed, run \fBdpkg \-l -python\-software\-properties\fP\&. \fBpython\-apt\fP will need to be manually -installed if it is not present. +On Ubuntu & Debian systems, the \fBpython\-apt\fP package is required to be +installed. To check if this package is installed, run \fBdpkg \-l python\-apt\fP\&. +\fBpython\-apt\fP will need to be manually installed if it is not present. .UNINDENT .UNINDENT .INDENT 0.0 @@ -322259,7 +343199,7 @@ Whether or not the repo is enabled. Can be specified as True/False or .B disabled False Included to reduce confusion due to APT\(aqs use of the \fBdisabled\fP -argument. If this is passed for a yum/dnf/zypper\-based distro, then the +argument. If this is passed for a YUM/DNF/Zypper\-based distro, then the reverse will be passed as \fBenabled\fP\&. For example passing \fBdisabled=True\fP will assume \fBenabled=False\fP\&. .TP @@ -322279,7 +343219,7 @@ enabled configuration. Anything supplied for this list will be saved in the repo configuration with a comment marker (#) in front. .UNINDENT .sp -Additional configuration values seen in yum repo files, such as \fBgpgkey\fP or +Additional configuration values seen in repo files, such as \fBgpgkey\fP or \fBgpgcheck\fP, will be used directly as key\-value pairs. For example: .INDENT 7.0 .INDENT 3.5 @@ -322424,29 +343364,62 @@ Use either \fBkeyid\fP/\fBkeyserver\fP or \fBkey_url\fP, but not both. .UNINDENT .UNINDENT .TP +.B key_text +.INDENT 7.0 +.INDENT 3.5 +The string representation of the GPG key to install. +.sp +New in version 2018.3.0. + +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Use either \fBkeyid\fP/\fBkeyserver\fP, \fBkey_url\fP, or \fBkey_text\fP but +not more than one method. +.UNINDENT +.UNINDENT +.TP .B consolidate -If set to true, this will consolidate all sources definitions to -the sources.list file, cleanup the now unused files, consolidate -components (e.g. main) for the same URI, type, and architecture -to a single line, and finally remove comments from the sources.list -file. The consolidate will run every time the state is processed. The -option only needs to be set on one repo managed by salt to take effect. +False +If set to \fBTrue\fP, this will consolidate all sources definitions to the +sources.list file, cleanup the now unused files, consolidate components +(e.g. main) for the same URI, type, and architecture to a single line, +and finally remove comments from the sources.list file. The consolidate +will run every time the state is processed. The option only needs to be +set on one repo managed by salt to take effect. .TP .B clean_file -If set to true, empty file before config repo, dangerous if use -multiple sources in one file. +False +If set to \fBTrue\fP, empty the file before config repo +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +Use with care. This can be dangerous if multiple sources are +configured in the same file. +.UNINDENT +.UNINDENT .sp New in version 2015.8.0. +.TP +.B refresh +True +If set to \fBFalse\fP this will skip refreshing the apt package database +on debian based systems. .TP .B refresh_db -If set to false this will skip refreshing the apt package database on -debian based systems. +True +Deprecated since version 2018.3.0: Use \fBrefresh\fP instead. + .TP .B require_in Set this to a list of pkg.installed or pkg.latest to trigger the running of apt\-get update prior to attempting to install these -packages. Setting a require in the pkg will not work for this. +packages. Setting a require in the pkg state will not work for this. .UNINDENT .UNINDENT .SS salt.states.portage_config @@ -322993,7 +343966,7 @@ pgsql\-data\-dir: .UNINDENT .INDENT 0.0 .TP -.B salt.states.postgres_initdb.present(name, user=None, password=None, auth=\(aqpassword\(aq, encoding=\(aqUTF8\(aq, locale=None, runas=None) +.B salt.states.postgres_initdb.present(name, user=None, password=None, auth=u\(aqpassword\(aq, encoding=u\(aqUTF8\(aq, locale=None, runas=None) Initialize the PostgreSQL data directory .INDENT 7.0 .TP @@ -323207,7 +344180,7 @@ andrew: .UNINDENT .INDENT 0.0 .TP -.B salt.states.postgres_privileges.absent(name, object_name, object_type, privileges=None, prepend=\(aqpublic\(aq, maintenance_db=None, user=None, db_password=None, db_host=None, db_port=None, db_user=None) +.B salt.states.postgres_privileges.absent(name, object_name, object_type, privileges=None, prepend=u\(aqpublic\(aq, maintenance_db=None, user=None, db_password=None, db_host=None, db_port=None, db_user=None) Revoke the requested privilege(s) on the specificed object(s) .INDENT 7.0 .TP @@ -323237,6 +344210,8 @@ group .IP \(bu 2 function .UNINDENT +.sp +View permissions should specify \fIobject_type: table\fP\&. .TP .B privileges Comma separated list of privileges to revoke, from the list below: @@ -323299,7 +344274,7 @@ Database port if different from config or default .UNINDENT .INDENT 0.0 .TP -.B salt.states.postgres_privileges.present(name, object_name, object_type, privileges=None, grant_option=None, prepend=\(aqpublic\(aq, maintenance_db=None, user=None, db_password=None, db_host=None, db_port=None, db_user=None) +.B salt.states.postgres_privileges.present(name, object_name, object_type, privileges=None, grant_option=None, prepend=u\(aqpublic\(aq, maintenance_db=None, user=None, db_password=None, db_host=None, db_port=None, db_user=None) Grant the requested privilege(s) on the specified object to a role .INDENT 7.0 .TP @@ -323330,6 +344305,8 @@ group .IP \(bu 2 function .UNINDENT +.sp +View permissions should specify \fIobject_type: table\fP\&. .TP .B privileges List of privileges to grant, from the list below: @@ -323411,7 +344388,7 @@ public: .UNINDENT .INDENT 0.0 .TP -.B salt.states.postgres_schema.absent(dbname, name, db_user=None, db_password=None, db_host=None, db_port=None) +.B salt.states.postgres_schema.absent(dbname, name, user=None, db_user=None, db_password=None, db_host=None, db_port=None) Ensure that the named schema is absent. .INDENT 7.0 .TP @@ -323421,6 +344398,9 @@ The database\(aqs name will work on .B name The name of the schema to remove .TP +.B user +system user all operations should be performed on behalf of +.TP .B db_user database username if different from config or default .TP @@ -323436,7 +344416,7 @@ Database port if different from config or default .UNINDENT .INDENT 0.0 .TP -.B salt.states.postgres_schema.present(dbname, name, owner=None, db_user=None, db_password=None, db_host=None, db_port=None) +.B salt.states.postgres_schema.present(dbname, name, owner=None, user=None, db_user=None, db_password=None, db_host=None, db_port=None) Ensure that the named schema is present in the database. .INDENT 7.0 .TP @@ -323446,8 +344426,8 @@ The database\(aqs name will work on .B name The name of the schema to manage .TP -.B owner -The database user that will be the owner of the schema +.B user +system user all operations should be performed on behalf of .TP .B db_user database username if different from config or default @@ -323616,7 +344596,7 @@ Database port if different from config or default .UNINDENT .INDENT 0.0 .TP -.B salt.states.postgres_user.present(name, createdb=None, createroles=None, createuser=None, encrypted=None, superuser=None, replication=None, inherit=None, login=None, password=None, default_password=None, refresh_password=None, groups=None, user=None, maintenance_db=None, db_password=None, db_host=None, db_port=None, db_user=None) +.B salt.states.postgres_user.present(name, createdb=None, createroles=None, createuser=None, encrypted=None, superuser=None, replication=None, inherit=None, login=None, password=None, default_password=None, refresh_password=None, valid_until=None, groups=None, user=None, maintenance_db=None, db_password=None, db_host=None, db_port=None, db_user=None) Ensure that the named user is present with the specified privileges Please note that the user/group notion in postgresql is just abstract, we have roles, where users can be seens as roles with the LOGIN privilege @@ -323668,7 +344648,7 @@ If encrypted is None or True, the password will be automatically encrypted to the previous format if it is not already done. .TP -.B default_passwoord +.B default_password The password used only when creating the user, unless password is set. .sp New in version 2016.3.0. @@ -323686,6 +344666,9 @@ updated without extra password change check. This behaviour makes it possible to execute in environments without superuser access available, e.g. Amazon RDS for PostgreSQL .TP +.B valid_until +A date and time after which the role\(aqs password is no longer valid. +.TP .B groups A string of comma separated groups the user should be in .TP @@ -323936,7 +344919,7 @@ Setup proxy settings on minions .UNINDENT .INDENT 0.0 .TP -.B salt.states.proxy.managed(name, port, services=None, user=None, password=None, bypass_domains=None, network_service=\(aqEthernet\(aq) +.B salt.states.proxy.managed(name, port, services=None, user=None, password=None, bypass_domains=None, network_service=u\(aqEthernet\(aq) Manages proxy settings for this mininon .INDENT 7.0 .TP @@ -324284,7 +345267,7 @@ rabbit@rabbit.example.com: .UNINDENT .INDENT 0.0 .TP -.B salt.states.rabbitmq_cluster.join(name, host, user=\(aqrabbit\(aq, ram_node=None, runas=\(aqroot\(aq) +.B salt.states.rabbitmq_cluster.join(name, host, user=u\(aqrabbit\(aq, ram_node=None, runas=u\(aqroot\(aq) This function is an alias of \fBjoined\fP\&. .INDENT 7.0 .INDENT 3.5 @@ -324311,7 +345294,7 @@ The user to run the rabbitmq command as .UNINDENT .INDENT 0.0 .TP -.B salt.states.rabbitmq_cluster.joined(name, host, user=\(aqrabbit\(aq, ram_node=None, runas=\(aqroot\(aq) +.B salt.states.rabbitmq_cluster.joined(name, host, user=u\(aqrabbit\(aq, ram_node=None, runas=u\(aqroot\(aq) Ensure the current node joined to a cluster with node \fI\%user@host\fP .INDENT 7.0 .TP @@ -324406,7 +345389,7 @@ rabbit_policy: .UNINDENT .INDENT 0.0 .TP -.B salt.states.rabbitmq_policy.absent(name, vhost=\(aq/\(aq, runas=None) +.B salt.states.rabbitmq_policy.absent(name, vhost=u\(aq/\(aq, runas=None) Ensure the named policy is absent .sp Reference: \fI\%http://www.rabbitmq.com/ha.html\fP @@ -324421,7 +345404,7 @@ Name of the user to run the command as .UNINDENT .INDENT 0.0 .TP -.B salt.states.rabbitmq_policy.present(name, pattern, definition, priority=0, vhost=\(aq/\(aq, runas=None) +.B salt.states.rabbitmq_policy.present(name, pattern, definition, apply_to=None, priority=0, vhost=u\(aq/\(aq, runas=None) Ensure the RabbitMQ policy exists. .sp Reference: \fI\%http://www.rabbitmq.com/ha.html\fP @@ -324439,6 +345422,9 @@ A json dict describing the policy .B priority Priority (defaults to 0) .TP +.B apply_to +Apply policy to \(aqqueues\(aq, \(aqexchanges\(aq or \(aqall\(aq (defailt to \(aqall\(aq) +.TP .B vhost Virtual host to apply to (defaults to \(aq/\(aq) .TP @@ -325073,7 +346059,7 @@ In the above example the path is interpreted as follows: .UNINDENT .INDENT 0.0 .TP -.B salt.states.reg.present(name, vname=None, vdata=None, vtype=\(aqREG_SZ\(aq, use_32bit_registry=False) +.B salt.states.reg.present(name, vname=None, vdata=None, vtype=u\(aqREG_SZ\(aq, use_32bit_registry=False) Ensure a registry key or value is present. .INDENT 7.0 .TP @@ -325208,7 +346194,7 @@ New in version 2016.3.0. .UNINDENT .INDENT 0.0 .TP -.B salt.states.rsync.synchronized(name, source, delete=False, force=False, update=False, passwordfile=None, exclude=None, excludefrom=None, prepare=False, dryrun=False) +.B salt.states.rsync.synchronized(name, source, delete=False, force=False, update=False, passwordfile=None, exclude=None, excludefrom=None, prepare=False, dryrun=False, additional_opts=None) Guarantees that the source directory is always copied to the target. .INDENT 7.0 .TP @@ -325245,6 +346231,12 @@ doing test=True .sp New in version 2016.3.1. +.TP +.B additional_opts +Pass additional options to rsync, should be included as a list. +.sp +New in version 2018.3.0. + .UNINDENT .UNINDENT .SS salt.states.rvm @@ -325354,7 +346346,7 @@ mygemset: .UNINDENT .INDENT 0.0 .TP -.B salt.states.rvm.gemset_present(name, ruby=\(aqdefault\(aq, user=None) +.B salt.states.rvm.gemset_present(name, ruby=u\(aqdefault\(aq, user=None) Verify that the gemset is present. .INDENT 7.0 .TP @@ -325373,7 +346365,7 @@ New in version 0.17.0. .UNINDENT .INDENT 0.0 .TP -.B salt.states.rvm.installed(name, default=False, user=None) +.B salt.states.rvm.installed(name, default=False, user=None, opts=None, env=None) Verify that the specified ruby is installed with RVM. RVM is installed when necessary. .INDENT 7.0 @@ -325387,6 +346379,12 @@ Whether to make this ruby the default. .TP .B user: None The user to run rvm as. +.TP +.B env: None +A list of environment variables to set (ie, RUBY_CONFIGURE_OPTS) +.TP +.B opts: None +A list of option flags to pass to RVM (ie \-C, \-\-patch) .sp New in version 0.17.0. @@ -325432,7 +346430,7 @@ and start the salt\-proxy process (default true), if it isn\(aqt already running. .INDENT 0.0 .TP -.B salt.states.salt_proxy.configure_proxy(name, proxyname=\(aqp8000\(aq, start=True) +.B salt.states.salt_proxy.configure_proxy(name, proxyname=u\(aqp8000\(aq, start=True) Create the salt proxy file and start the proxy process if required .INDENT 7.0 @@ -325501,7 +346499,7 @@ Full Orchestrate Tutorial .UNINDENT .INDENT 0.0 .TP -.B salt.states.saltmod.function(name, tgt, ssh=False, tgt_type=\(aqglob\(aq, expr_form=None, ret=\(aq\(aq, expect_minions=False, fail_minions=None, fail_function=None, arg=None, kwarg=None, timeout=None, batch=None, subset=None) +.B salt.states.saltmod.function(name, tgt, ssh=False, tgt_type=u\(aqglob\(aq, expr_form=None, ret=u\(aq\(aq, ret_config=None, ret_kwargs=None, expect_minions=False, fail_minions=None, fail_function=None, arg=None, kwarg=None, timeout=None, batch=None, subset=None) Execute a single module function on a remote minion via salt or salt\-ssh .INDENT 7.0 .TP @@ -325527,6 +346525,12 @@ The dict (not a list) of keyword arguments to pass into the function .B ret Optionally set a single or a list of returners to use .TP +.B ret_config +Use an alternative returner configuration +.TP +.B ret_kwargs +Override individual returner configuration items +.TP .B expect_minions An optional boolean for failing if some minions do not respond .TP @@ -325548,6 +346552,53 @@ Number of minions from the targeted set to randomly use .sp New in version 2017.7.0. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.saltmod.parallel_runners(name, runners) +Executes multiple runner modules on the master in parallel. +.sp +New in version 2017.x.0: (Nitrogen) + +.sp +A separate thread is spawned for each runner. This state is intended to be +used with the orchestrate runner in place of the \fBsaltmod.runner\fP state +when different tasks should be run in parallel. In general, Salt states are +not safe when used concurrently, so ensure that they are used in a safe way +(e.g. by only targeting separate minions in parallel tasks). +.INDENT 7.0 +.TP +.B name: +name identifying this state. The name is provided as part of the +output, but not used for anything else. +.TP +.B runners: +list of runners that should be run in parallel. Each element of the +list has to be a dictionary. This dictionary\(aqs name entry stores the +name of the runner function that shall be invoked. The optional kwarg +entry stores a dictionary of named arguments that are passed to the +runner function. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +parallel\-state: + salt.parallel_runners: + \- runners: + my_runner_1: + \- name: state.orchestrate + \- kwarg: + mods: orchestrate_state_1 + my_runner_2: + \- name: state.orchestrate + \- kwarg: + mods: orchestrate_state_2 +.ft P +.fi +.UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 @@ -325580,7 +346631,7 @@ run\-manage\-up: .UNINDENT .INDENT 0.0 .TP -.B salt.states.saltmod.state(name, tgt, ssh=False, tgt_type=\(aqglob\(aq, expr_form=None, ret=\(aq\(aq, highstate=None, sls=None, top=None, saltenv=None, test=False, pillar=None, pillarenv=None, expect_minions=True, fail_minions=None, allow_fail=0, concurrent=False, timeout=None, batch=None, queue=False, subset=None, orchestration_jid=None) +.B salt.states.saltmod.state(name, tgt, ssh=False, tgt_type=u\(aqglob\(aq, expr_form=None, ret=u\(aq\(aq, ret_config=None, ret_kwargs=None, highstate=None, sls=None, top=None, saltenv=None, test=False, pillar=None, pillarenv=None, expect_minions=True, fail_minions=None, allow_fail=0, concurrent=False, timeout=None, batch=None, queue=False, subset=None, orchestration_jid=None, **kwargs) Invoke a state run on a given target .INDENT 7.0 .TP @@ -325603,6 +346654,12 @@ Deprecated since version 2017.7.0: Use tgt_type instead .B ret Optionally set a single or a list of returners to use .TP +.B ret_config +Use an alternative returner configuration +.TP +.B ret_kwargs +Override individual returner configuration items +.TP .B highstate Defaults to None, if set to True the target systems will ignore any sls references specified in the sls option and call state.highstate @@ -325711,7 +346768,7 @@ databases: .UNINDENT .INDENT 0.0 .TP -.B salt.states.saltmod.wait_for_event(name, id_list, event_id=\(aqid\(aq, timeout=300, node=\(aqmaster\(aq) +.B salt.states.saltmod.wait_for_event(name, id_list, event_id=u\(aqid\(aq, timeout=300, node=u\(aqmaster\(aq) Watch Salt\(aqs event bus and block until a condition is met .sp New in version 2014.7.0. @@ -325876,6 +346933,23 @@ This will schedule the command: state.sls httpd test=True at 5pm on Monday, Wednesday and Friday, and 3pm on Tuesday and Thursday. Using the xmpp returner to return the results of the scheduled job, with the alternative configuration options found in the xmpp_state_run section. + +job1: + schedule.present: + \- function: state.sls + \- job_args: + \- httpd + \- job_kwargs: + test: True + \- hours: 1 + \- skip_during_range: + \- start: 2pm + \- end: 3pm + \- run_after_skip_range: True + +This will schedule the command: state.sls httpd test=True at 5pm on Monday, +Wednesday and Friday, and 3pm on Tuesday and Thursday. Requires that +python\-dateutil is installed on the minion. .ft P .fi .UNINDENT @@ -326016,6 +347090,15 @@ as a dictionary. .TP .B persist Whether the job should persist between minion restarts, defaults to True. +.TP +.B skip_during_range +This will ensure that the scheduled command does not run within the +range specified. The range parameter must be a dictionary with the +date strings using the dateutil format. Requires python\-dateutil. +.TP +.B run_after_skip_range +Whether the job should run immediately after the skip_during_range time +period ends. .UNINDENT .UNINDENT .SS salt.states.selinux @@ -326070,7 +347153,7 @@ reboot .UNINDENT .INDENT 0.0 .TP -.B salt.states.selinux.fcontext_policy_absent(name, filetype=\(aqa\(aq, sel_type=None, sel_user=None, sel_level=None) +.B salt.states.selinux.fcontext_policy_absent(name, filetype=u\(aqa\(aq, sel_type=None, sel_user=None, sel_level=None) New in version 2017.7.0. .sp @@ -326107,7 +347190,7 @@ applied. .UNINDENT .INDENT 0.0 .TP -.B salt.states.selinux.fcontext_policy_present(name, sel_type, filetype=\(aqa\(aq, sel_user=None, sel_level=None) +.B salt.states.selinux.fcontext_policy_present(name, sel_type, filetype=u\(aqa\(aq, sel_user=None, sel_level=None) New in version 2017.7.0. .sp @@ -326155,7 +347238,7 @@ The mode to run SELinux in, permissive, enforcing, or disabled. .UNINDENT .INDENT 0.0 .TP -.B salt.states.selinux.module(name, module_state=\(aqEnabled\(aq, version=\(aqany\(aq, **opts) +.B salt.states.selinux.module(name, module_state=u\(aqEnabled\(aq, version=u\(aqany\(aq, **opts) Enable/Disable and optionally force a specific version for an SELinux module .INDENT 7.0 .TP @@ -327082,7 +348165,7 @@ server\-warning\-message: .UNINDENT .INDENT 0.0 .TP -.B salt.states.smtp.send_msg(name, recipient, subject, sender=None, profile=None, use_ssl=\(aqTrue\(aq) +.B salt.states.smtp.send_msg(name, recipient, subject, sender=None, profile=None, use_ssl=u\(aqTrue\(aq) Send a message via SMTP .INDENT 7.0 .INDENT 3.5 @@ -327262,7 +348345,7 @@ Linux .UNINDENT .INDENT 0.0 .TP -.B salt.states.snapper.baseline_snapshot(name, number=None, tag=None, include_diff=True, config=\(aqroot\(aq, ignore=None) +.B salt.states.snapper.baseline_snapshot(name, number=None, tag=None, include_diff=True, config=u\(aqroot\(aq, ignore=None) Enforces that no file is modified comparing against a previously defined snapshot identified by number. .INDENT 7.0 @@ -327349,7 +348432,7 @@ ensure example test user 1: .UNINDENT .INDENT 0.0 .TP -.B salt.states.splunk.absent(email, profile=\(aqsplunk\(aq, **kwargs) +.B salt.states.splunk.absent(email, profile=u\(aqsplunk\(aq, **kwargs) Ensure a splunk user is absent .INDENT 7.0 .INDENT 3.5 @@ -327377,7 +348460,7 @@ This is the splunk username used to identify the user. .UNINDENT .INDENT 0.0 .TP -.B salt.states.splunk.present(email, profile=\(aqsplunk\(aq, **kwargs) +.B salt.states.splunk.present(email, profile=u\(aqsplunk\(aq, **kwargs) Ensure a user is present .INDENT 7.0 .INDENT 3.5 @@ -327425,7 +348508,7 @@ server\-warning\-message: .UNINDENT .INDENT 0.0 .TP -.B salt.states.splunk_search.absent(name, profile=\(aqsplunk\(aq) +.B salt.states.splunk_search.absent(name, profile=u\(aqsplunk\(aq) Ensure a search is absent .INDENT 7.0 .INDENT 3.5 @@ -327448,7 +348531,7 @@ This is the name of the search in splunk .UNINDENT .INDENT 0.0 .TP -.B salt.states.splunk_search.present(name, profile=\(aqsplunk\(aq, **kwargs) +.B salt.states.splunk_search.present(name, profile=u\(aqsplunk\(aq, **kwargs) Ensure a search is present .INDENT 7.0 .INDENT 3.5 @@ -327772,7 +348855,7 @@ sshkeys: .UNINDENT .INDENT 0.0 .TP -.B salt.states.ssh_auth.absent(name, user, enc=\(aqssh\-rsa\(aq, comment=\(aq\(aq, source=\(aq\(aq, options=None, config=\(aq.ssh/authorized_keys\(aq, fingerprint_hash_type=None) +.B salt.states.ssh_auth.absent(name, user, enc=u\(aqssh\-rsa\(aq, comment=u\(aq\(aq, source=u\(aq\(aq, options=None, config=u\(aq.ssh/authorized_keys\(aq, fingerprint_hash_type=None) Verifies that the specified SSH key is absent .INDENT 7.0 .TP @@ -327823,7 +348906,7 @@ The default value of the \fBfingerprint_hash_type\fP will change to .UNINDENT .INDENT 0.0 .TP -.B salt.states.ssh_auth.present(name, user, enc=\(aqssh\-rsa\(aq, comment=\(aq\(aq, source=\(aq\(aq, options=None, config=\(aq.ssh/authorized_keys\(aq, fingerprint_hash_type=None, **kwargs) +.B salt.states.ssh_auth.present(name, user, enc=u\(aqssh\-rsa\(aq, comment=u\(aq\(aq, source=u\(aq\(aq, options=None, config=u\(aq.ssh/authorized_keys\(aq, fingerprint_hash_type=None, **kwargs) Verifies that the specified SSH key is present for the specified user .INDENT 7.0 .TP @@ -327905,6 +348988,7 @@ github.com: \- present \- user: root \- fingerprint: 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 + \- fingerprint_hash_type: md5 example.com: ssh_known_hosts: @@ -327922,6 +349006,9 @@ Verifies that the specified host is not known by the given user .TP .B name The host name +Note that only single host names are supported. If foo.example.com +and bar.example.com are the same machine and you need to exclude both, +you will need one Salt state for each. .TP .B user The user who owns the ssh authorized keys file to modify @@ -327945,6 +349032,9 @@ type. .TP .B name The name of the remote host (e.g. "github.com") +Note that only a single hostname is supported, if foo.example.com and +bar.example.com have the same host you will need two separate Salt +States to represent them. .TP .B user The user who owns the ssh authorized keys file to modify @@ -328231,70 +349321,6 @@ update\-my\-incident: .UNINDENT .UNINDENT .UNINDENT -.SS salt.states.stormpath_account -.sp -Support for Stormpath. -.sp -New in version 2015.8.0. - -.INDENT 0.0 -.TP -.B salt.states.stormpath_account.absent(name, directory_id=None) -Ensure that an account associated with the given email address is absent. -Will search all directories for the account, unless a directory_id is -specified. -.INDENT 7.0 -.TP -.B name -The email address of the account to delete. -.TP -.B directory_id -Optional. The ID of the directory that the account is expected to belong -to. If not specified, then a list of directories will be retrieved, and -each will be scanned for the account. Specifying a directory_id will -therefore cut down on the number of requests to Stormpath, and increase -performance of this state. -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.states.stormpath_account.present(name, **kwargs) -Ensure that an account is present and properly configured -.INDENT 7.0 -.TP -.B name -The email address associated with the Stormpath account -.TP -.B directory_id -The ID of a directory which the account belongs to. Required. -.TP -.B password -Required when creating a new account. If specified, it is advisable to -reference the password in another database using an \fBsdb://\fP URL. -Will NOT update the password if an account already exists. -.TP -.B givenName -Required when creating a new account. -.TP -.B surname -Required when creating a new account. -.TP -.B username -Optional. Must be unique across the owning directory. If not specified, -the username will default to the email field. -.TP -.B middleName -Optional. -.TP -.B status -\fBenabled\fP accounts are able to login to their assigned applications, -\fBdisabled\fP accounts may not login to applications, \fBunverified\fP -accounts are disabled and have not verified their email address. -.TP -.B customData. -Optional. Must be specified as a dict. -.UNINDENT -.UNINDENT .SS salt.states.supervisord .SS Interaction with the Supervisor daemon .INDENT 0.0 @@ -328611,6 +349637,8 @@ their system. Kills syslog\-ng. .UNINDENT .SS salt.states.sysrc +.sp +State to work with sysrc .INDENT 0.0 .TP .B salt.states.sysrc.absent(name, **kwargs) @@ -328662,10 +349690,10 @@ syslogd: .UNINDENT .UNINDENT .SS salt.states.telemetry_alert -.sp -New in version 2016.3.0.. - .SS Manage Telemetry alert configurations +.sp +New in version 2016.3.0. + .sp Create, Update and destroy Mongo Telemetry alert configurations. .sp @@ -328694,7 +349722,7 @@ ensure telemetry alert X is defined on deployment Y: .UNINDENT .INDENT 0.0 .TP -.B salt.states.telemetry_alert.absent(name, deployment_id, metric_name, api_key=None, profile=\(aqtelemetry\(aq) +.B salt.states.telemetry_alert.absent(name, deployment_id, metric_name, api_key=None, profile=u\(aqtelemetry\(aq) Ensure the telemetry alert config is deleted .INDENT 7.0 .TP @@ -328718,7 +349746,7 @@ api_key. .UNINDENT .INDENT 0.0 .TP -.B salt.states.telemetry_alert.present(name, deployment_id, metric_name, alert_config, api_key=None, profile=\(aqtelemetry\(aq) +.B salt.states.telemetry_alert.present(name, deployment_id, metric_name, alert_config, api_key=None, profile=u\(aqtelemetry\(aq) Ensure the telemetry alert exists. .INDENT 7.0 .TP @@ -328759,11 +349787,9 @@ api_key. .UNINDENT .SS salt.states.test .SS Test States -.INDENT 0.0 -.TP -.B Provide test case states that enable easy testing of things to do with -state calls, e.g. running, calling, logging, output filtering etc. -.UNINDENT +.sp +Provide test case states that enable easy testing of things to do with state +calls, e.g. running, calling, logging, output filtering etc. .INDENT 0.0 .INDENT 3.5 .sp @@ -328839,7 +349865,7 @@ is\-pillar\-foo\-present\-and\-bar\-is\-int: .UNINDENT .INDENT 0.0 .TP -.B salt.states.test.configurable_test_state(name, changes=True, result=True, comment=\(aq\(aq) +.B salt.states.test.configurable_test_state(name, changes=True, result=True, comment=u\(aq\(aq) A configurable test state which determines its output based on the inputs. .sp New in version 2014.7.0. @@ -329120,13 +350146,13 @@ Linux .UNINDENT .INDENT 0.0 .TP -.B salt.states.tomcat.mod_watch(name, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.states.tomcat.mod_watch(name, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) The tomcat watcher function. When called it will reload the webapp in question .UNINDENT .INDENT 0.0 .TP -.B salt.states.tomcat.undeployed(name, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.states.tomcat.undeployed(name, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) Enforce that the WAR will be undeployed from the server .INDENT 7.0 .TP @@ -329160,7 +350186,7 @@ jenkins: .UNINDENT .INDENT 0.0 .TP -.B salt.states.tomcat.wait(name, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180) +.B salt.states.tomcat.wait(name, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180) Wait for the Tomcat Manager to load. .sp Notice that if tomcat is not running we won\(aqt wait for it start and the @@ -329208,7 +350234,7 @@ jenkins: .UNINDENT .INDENT 0.0 .TP -.B salt.states.tomcat.war_deployed(name, war, force=False, url=\(aqhttp://localhost:8080/manager\(aq, timeout=180, temp_war_location=None, version=True) +.B salt.states.tomcat.war_deployed(name, war, force=False, url=u\(aqhttp://localhost:8080/manager\(aq, timeout=180, temp_war_location=None, version=True) Enforce that the WAR will be deployed and started in the context path, while making use of WAR versions in the filename. .sp @@ -329922,9 +350948,293 @@ A brief description of the purpose of the users account. .sp Changed in version 2015.8.0. +.UNINDENT +.UNINDENT +.SS salt.states.vagrant +.SS Manage Vagrant VMs +.sp +Manange execution of Vagrant virtual machines on Salt minions. +.sp +\fI\%Vagrant\fP is a tool for building and managing virtual machine environments. +It can use various providers, such as \fI\%VirtualBox\fP, \fI\%Docker\fP, or \fI\%VMware\fP, to run its VMs. +Vagrant provides some of the functionality of a light\-weight hypervisor. +The combination of Salt modules, Vagrant running on the host, and a +virtual machine provider, gives hypervisor\-like functionality for +developers who use Vagrant to quickly define their virtual environments. +.INDENT 0.0 +.INDENT 3.5 +New in version 2018.3.0. + +.UNINDENT +.UNINDENT +.sp +The configuration of each virtual machine is defined in a file named +\fBVagrantfile\fP which must exist on the VM host machine. +The essential parameters which must be defined to start a Vagrant VM +are the directory where the \fBVagrantfile\fP is located (argument \fBcwd:\fP), +and the username which will own the \fBVagrant box\fP created for the VM ( +argument \fBvagrant_runas:\fP). +.sp +A single \fBVagrantfile\fP may define one or more virtual machines. +Use the \fBmachine\fP argument to chose among them. The default (blank) +value will select the \fBprimary\fP (or only) machine in the Vagrantfile. +.sp +[NOTE:] Each virtual machine host must have the following: +.INDENT 0.0 +.IP \(bu 2 +a working salt\-minion +.IP \(bu 2 +a Salt sdb database configured for \fBvagrant_sdb_data\fP\&. +.IP \(bu 2 +Vagrant installed and the \fBvagrant\fP command working +.IP \(bu 2 +a suitable VM provider +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# EXAMPLE: +# file /etc/salt/minion.d/vagrant_sdb.conf on the host computer +# \-\- this sdb database is required by the Vagrant module \-\- +vagrant_sdb_data: # The sdb database must have this name. + driver: sqlite3 # Let\(aqs use SQLite to store the data ... + database: /var/cache/salt/vagrant.sqlite # ... in this file ... + table: sdb # ... using this table name. + create_table: True # if not present +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.vagrant.destroyed(name) +Stops a VM (or VMs) and removes all refences to it (them). (Runs \fBvagrant destroy\fP\&.) +.sp +Subsequent re\-use of the same machine will requere another operation of \fBvagrant.running\fP +or a call to the \fBvagrant.init\fP execution module. +.INDENT 7.0 +.TP +.B Parameters +\fBname\fP \-\- May be a Salt_id node or a POSIX\-style wildcard string. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +node_name: + vagrant.destroyed +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.vagrant.initialized(name, **kwargs) +Defines a new VM with specified arguments, but does not start it. +.INDENT 7.0 +.TP +.B Parameters +\fBname\fP \-\- the Salt_id node name you wish your VM to have. +.UNINDENT +.sp +Each machine must be initialized individually using this function +or the "vagrant.running" function, or the vagrant.init execution module call. +.sp +This command will not change the state of a running or paused machine. +.sp +Possible keyword arguments: +.INDENT 7.0 +.IP \(bu 2 +cwd: The directory (path) containing the Vagrantfile +.IP \(bu 2 +machine: (\(aq\(aq) the name of the machine (in the Vagrantfile) if not default +.IP \(bu 2 +vagrant_runas: (\(aqroot\(aq) the username who owns the vagrantbox file +.IP \(bu 2 +vagrant_provider: the provider to run the VM (usually \(aqvirtualbox\(aq) +.IP \(bu 2 +vm: ({}) a dictionary containing these or other keyword arguments +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +node_name1: + vagrant.initialized + \- cwd: /projects/my_project + \- vagrant_runas: my_username + \- machine: machine1 + +node_name2: + vagrant.initialized + \- cwd: /projects/my_project + \- vagrant_runas: my_username + \- machine: machine2 + +start_nodes: + vagrant.start: + \- name: node_name? +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.vagrant.paused(name) +Stores the state of a VM (or VMs) for fast restart. (Runs \fBvagrant suspend\fP\&.) +.INDENT 7.0 +.TP +.B Parameters +\fBname\fP \-\- May be a Salt_id node or a POSIX\-style wildcard string. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +node_name: + vagrant.paused +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.vagrant.powered_off(name) +Stops a VM (or VMs) by power off. (Runs \fBvagrant halt\fP\&.) +.sp +This method is provided for compatibility with other VM\-control +state modules. For Vagrant, the action is identical with \fBstopped\fP\&. +.INDENT 7.0 +.TP +.B Parameters +\fBname\fP \-\- May be a Salt_id node or a POSIX\-style wildcard string. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +node_name: + vagrant.unpowered +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.vagrant.rebooted(name) +Reboots a running, paused, or stopped VM (or VMs). (Runs \fBvagrant reload\fP\&.) +.sp +The will re\-run the provisioning +.INDENT 7.0 +.TP +.B Parameters +\fBname\fP \-\- May be a Salt_id node or a POSIX\-style wildcard string. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +node_name: + vagrant.reloaded +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.vagrant.running(name, **kwargs) +Defines and starts a new VM with specified arguments, or restart a +VM (or group of VMs). (Runs \fBvagrant up\fP\&.) +.INDENT 7.0 +.TP +.B Parameters +\fBname\fP \-\- the Salt_id node name you wish your VM to have. +.UNINDENT +.sp +If \fBname\fP contains a "?" or "*" then it will re\-start a group of VMs +which have been paused or stopped. +.sp +Each machine must be initially started individually using this function +or the vagrant.init execution module call. +.sp +[NOTE:] Keyword arguments are silently ignored when re\-starting an existing VM. +.sp +Possible keyword arguments: +.INDENT 7.0 +.IP \(bu 2 +cwd: The directory (path) containing the Vagrantfile +.IP \(bu 2 +machine: (\(aq\(aq) the name of the machine (in the Vagrantfile) if not default +.IP \(bu 2 +vagrant_runas: (\(aqroot\(aq) the username who owns the vagrantbox file +.IP \(bu 2 +vagrant_provider: the provider to run the VM (usually \(aqvirtualbox\(aq) +.IP \(bu 2 +vm: ({}) a dictionary containing these or other keyword arguments +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +node_name: + vagrant.running +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +node_name: + vagrant.running: + \- cwd: /projects/my_project + \- vagrant_runas: my_username + \- machine: machine1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.vagrant.stopped(name) +Stops a VM (or VMs) by shutting it (them) down nicely. (Runs \fBvagrant halt\fP) +.INDENT 7.0 +.TP +.B Parameters +\fBname\fP \-\- May be a Salt_id node, or a POSIX\-style wildcard string. +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +node_name: + vagrant.stopped +.ft P +.fi +.UNINDENT .UNINDENT .UNINDENT .SS salt.states.vault module +.sp +States for managing Hashicorp Vault. +Currently handles policies. Configuration instructions are documented in the execution module docs. .INDENT 0.0 .TP .B maintainer @@ -329939,9 +351249,6 @@ all .sp New in version 2017.7.0. -.sp -States for managing Hashicorp Vault. Currently handles policies. Configuration -instructions are documented in the execution module docs. .INDENT 0.0 .TP .B salt.states.vault.policy_present(name, rules) @@ -330088,7 +351395,7 @@ webserver\-warning\-message: .UNINDENT .INDENT 0.0 .TP -.B salt.states.victorops.create_event(name, message_type, routing_key=\(aqeveryone\(aq, **kwargs) +.B salt.states.victorops.create_event(name, message_type, routing_key=u\(aqeveryone\(aq, **kwargs) Create an event on the VictorOps service .INDENT 7.0 .INDENT 3.5 @@ -330182,7 +351489,7 @@ libvirt_keys: .UNINDENT .INDENT 0.0 .TP -.B salt.states.virt.keys(name, basepath=\(aq/etc/pki\(aq) +.B salt.states.virt.keys(name, basepath=u\(aq/etc/pki\(aq, **kwargs) Manage libvirt keys. .INDENT 7.0 .TP @@ -330193,6 +351500,55 @@ The name variable used to track the execution Defaults to \fB/etc/pki\fP, this is the root location used for libvirt keys on the hypervisor .UNINDENT +.sp +The following parameters are optional: +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B country +The country that the certificate should use. Defaults to US. +.UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B state +The state that the certificate should use. Defaults to Utah. +.UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B locality +The locality that the certificate should use. +Defaults to Salt Lake City. +.UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B organization +The organization that the certificate should use. +Defaults to Salted. +.UNINDENT +.sp +New in version 2018.3.0. + +.INDENT 0.0 +.TP +.B expiration_days +The number of days that the certificate should be valid for. +Defaults to 365 days (1 year) +.UNINDENT +.sp +New in version 2018.3.0. + +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -330397,6 +351753,10 @@ Create a virtualenv and optionally manage it with pip .B name Path to the virtualenv. .TP +.B venv_bin: virtualenv +The name (and optionally path) of the virtualenv command. This can also +be set globally in the minion config file as \fBvirtualenv.venv_bin\fP\&. +.TP .B requirements: None Path to a pip requirements file. If the path begins with \fBsalt://\fP the file will be transferred from the master file server. @@ -330487,7 +351847,7 @@ salt://certs/cert.cer: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_certutil.add_store(name, store, saltenv=\(aqbase\(aq) +.B salt.states.win_certutil.add_store(name, store, saltenv=u\(aqbase\(aq) Store a certificate to the given store .INDENT 7.0 .TP @@ -330505,7 +351865,7 @@ path is specified .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_certutil.del_store(name, store, saltenv=\(aqbase\(aq) +.B salt.states.win_certutil.del_store(name, store, saltenv=u\(aqbase\(aq) Remove a certificate in the given store .INDENT 7.0 .TP @@ -330912,12 +352272,12 @@ remove_KB1231231: Module for configuring DNS Client on Windows systems .INDENT 0.0 .TP -.B salt.states.win_dns_client.dns_dhcp(name, interface=\(aqLocal Area Connection\(aq) +.B salt.states.win_dns_client.dns_dhcp(name, interface=u\(aqLocal Area Connection\(aq) Configure the DNS server list from DHCP Server .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_dns_client.dns_exists(name, servers=None, interface=\(aqLocal Area Connection\(aq, replace=False) +.B salt.states.win_dns_client.dns_exists(name, servers=None, interface=u\(aqLocal Area Connection\(aq, replace=False) Configure the DNS server list in the specified interface .sp Example: @@ -330974,7 +352334,7 @@ primary_dns_suffix: State for configuring Windows Firewall .INDENT 0.0 .TP -.B salt.states.win_firewall.add_rule(name, localport, protocol=\(aqtcp\(aq, action=\(aqallow\(aq, dir=\(aqin\(aq, remoteip=\(aqany\(aq) +.B salt.states.win_firewall.add_rule(name, localport, protocol=u\(aqtcp\(aq, action=u\(aqallow\(aq, dir=u\(aqin\(aq, remoteip=u\(aqany\(aq) Add a new inbound or outbound rule to the firewall policy .INDENT 7.0 .TP @@ -331078,7 +352438,7 @@ open_smb_port: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_firewall.disabled(name=\(aqallprofiles\(aq) +.B salt.states.win_firewall.disabled(name=u\(aqallprofiles\(aq) Disable all the firewall profiles (Windows only) .INDENT 7.0 .TP @@ -331122,7 +352482,7 @@ disable_all: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_firewall.enabled(name=\(aqallprofiles\(aq) +.B salt.states.win_firewall.enabled(name=u\(aqallprofiles\(aq) Enable all the firewall profiles (Windows only) .INDENT 7.0 .TP @@ -331309,7 +352669,7 @@ site0\-apppool: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_iis.create_binding(name, site, hostheader=\(aq\(aq, ipaddress=\(aq*\(aq, port=80, protocol=\(aqhttp\(aq, sslflags=0) +.B salt.states.win_iis.create_binding(name, site, hostheader=u\(aq\(aq, ipaddress=u\(aq*\(aq, port=80, protocol=u\(aqhttp\(aq, sslflags=0) Create an IIS binding. .INDENT 7.0 .TP @@ -331365,7 +352725,7 @@ site0\-https\-binding: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_iis.create_cert_binding(name, site, hostheader=\(aq\(aq, ipaddress=\(aq*\(aq, port=443, sslflags=0) +.B salt.states.win_iis.create_cert_binding(name, site, hostheader=u\(aq\(aq, ipaddress=u\(aq*\(aq, port=443, sslflags=0) Assign a certificate to an IIS binding. .INDENT 7.0 .TP @@ -331425,7 +352785,7 @@ New in version 2016.11.0. .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_iis.create_vdir(name, site, sourcepath, app=\(aq/\(aq) +.B salt.states.win_iis.create_vdir(name, site, sourcepath, app=u\(aq/\(aq) Create an IIS virtual directory. .INDENT 7.0 .TP @@ -331477,7 +352837,7 @@ site0\-foo\-vdir: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_iis.deployed(name, sourcepath, apppool=\(aq\(aq, hostheader=\(aq\(aq, ipaddress=\(aq*\(aq, port=80, protocol=\(aqhttp\(aq) +.B salt.states.win_iis.deployed(name, sourcepath, apppool=u\(aq\(aq, hostheader=u\(aq\(aq, ipaddress=u\(aq*\(aq, port=80, protocol=u\(aqhttp\(aq) Ensure the website has been deployed. .INDENT 7.0 .TP @@ -331592,7 +352952,7 @@ defaultapppool\-remove: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_iis.remove_binding(name, site, hostheader=\(aq\(aq, ipaddress=\(aq*\(aq, port=80) +.B salt.states.win_iis.remove_binding(name, site, hostheader=u\(aq\(aq, ipaddress=u\(aq*\(aq, port=80) Remove an IIS binding. .INDENT 7.0 .TP @@ -331642,7 +353002,7 @@ site0\-https\-binding\-remove: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_iis.remove_cert_binding(name, site, hostheader=\(aq\(aq, ipaddress=\(aq*\(aq, port=443) +.B salt.states.win_iis.remove_cert_binding(name, site, hostheader=u\(aq\(aq, ipaddress=u\(aq*\(aq, port=443) Remove a certificate from an IIS binding. .INDENT 7.0 .TP @@ -331723,7 +353083,7 @@ defaultwebsite\-remove: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_iis.remove_vdir(name, site, app=\(aq/\(aq) +.B salt.states.win_iis.remove_vdir(name, site, app=u\(aq/\(aq) Remove an IIS virtual directory. .INDENT 7.0 .TP @@ -331953,7 +353313,7 @@ server_policy: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_lgpo.set(name, setting=None, policy_class=None, computer_policy=None, user_policy=None, cumulative_rights_assignments=True, adml_language=\(aqen\-US\(aq) +.B salt.states.win_lgpo.set(name, setting=None, policy_class=None, computer_policy=None, user_policy=None, cumulative_rights_assignments=True, adml_language=u\(aqen\-US\(aq) Ensure the specified policy is set .INDENT 7.0 .TP @@ -332157,13 +353517,23 @@ Example: .TP .B salt.states.win_path.exists(name, index=None) Add the directory to the system PATH at index location +.INDENT 7.0 +.TP +.B index +Position where the directory should be placed in the PATH. This is +0\-indexed, so 0 means to prepend at the very start of the PATH. .sp -index: where the directory should be placed in the PATH (default: None). -This is 0\-indexed, so 0 means to prepend at the very start of the PATH. -[Note: Providing no index will append directory to PATH and -will not enforce its location within the PATH.] +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +If the index is not specified, and the directory needs to be added +to the PATH, then the directory will be appended to the PATH, and +this state will not enforce its location within the PATH. +.UNINDENT +.UNINDENT +.UNINDENT .sp -Example: +Examples: .INDENT 7.0 .INDENT 3.5 .sp @@ -332175,6 +353545,10 @@ Example: \(aqC:\esysinternals\(aq: win_path.exists: \- index: 0 + +\(aqC:\emystuff\(aq: + win_path.exists: + \- index: \-1 .ft P .fi .UNINDENT @@ -332193,7 +353567,7 @@ New in version 2016.11.0. .INDENT 0.0 .TP -.B salt.states.win_pki.import_cert(name, cert_format=\(aqcer\(aq, context=\(aqLocalMachine\(aq, store=\(aqMy\(aq, exportable=True, password=\(aq\(aq, saltenv=\(aqbase\(aq) +.B salt.states.win_pki.import_cert(name, cert_format=u\(aqcer\(aq, context=u\(aqLocalMachine\(aq, store=u\(aqMy\(aq, exportable=True, password=u\(aq\(aq, saltenv=u\(aqbase\(aq) Import the certificate file into the given certificate store. .INDENT 7.0 .TP @@ -332252,7 +353626,7 @@ site0\-cert\-imported: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_pki.remove_cert(name, thumbprint, context=\(aqLocalMachine\(aq, store=\(aqMy\(aq) +.B salt.states.win_pki.remove_cert(name, thumbprint, context=u\(aqLocalMachine\(aq, store=u\(aqMy\(aq) Remove the certificate from the given certificate store. .INDENT 7.0 .TP @@ -332319,7 +353693,7 @@ monitor: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_powercfg.set_timeout(name, value, power=\(aqac\(aq, scheme=None) +.B salt.states.win_powercfg.set_timeout(name, value, power=u\(aqac\(aq, scheme=None) Set the sleep timeouts of specific items such as disk, monitor. .sp CLI Example: @@ -332358,66 +353732,134 @@ The scheme to use, leave as None to use the current. .UNINDENT .SS salt.states.win_servermanager .sp -Manage Windows features via the ServerManager powershell module +Manage Windows features via the ServerManager powershell module. Can install and +remove roles/features. .INDENT 0.0 .TP -.B salt.states.win_servermanager.installed(name, recurse=False, force=False, restart=False, source=None, exclude=None) -Install the windows feature -.INDENT 7.0 +.B maintainer +Shane Lee <\fI\%slee@saltstack.com\fP> .TP -.B Parameters -.INDENT 7.0 -.IP \(bu 2 -\fBname\fP (\fI\%str\fP) \-\- Short name of the feature (the right column in -win_servermanager.list_available) -.IP \(bu 2 -\fBrecurse\fP (\fIOptional[bool]\fP) \-\- install all sub\-features as well -.IP \(bu 2 -\fBforce\fP (\fIOptional[bool]\fP) \-\- if the feature is installed but one of its -sub\-features are not installed set this to True to force the -installation of the sub\-features -.IP \(bu 2 -\fBsource\fP (\fIOptional[str]\fP) \-\- Path to the source files if missing from the -target system. None means that the system will use windows update -services to find the required files. Default is None -.IP \(bu 2 -\fBrestart\fP (\fIOptional[bool]\fP) \-\- Restarts the computer when installation is -complete, if required by the role/feature installed. Default is -False -.IP \(bu 2 -\fBexclude\fP (\fIOptional[str]\fP) \-\- The name of the feature to exclude when -installing the named feature. -.UNINDENT -.UNINDENT -.INDENT 7.0 +.B platform +Windows Server 2008R2 or greater .TP -.B restart: -Restarts the computer when installation is complete, if restarting is required by the role feature installed. +.B depends +win_servermanager.install +.TP +.B depends +win_servermanager.remove .UNINDENT +.INDENT 0.0 +.TP +.B salt.states.win_servermanager.installed(name, features=None, recurse=False, restart=False, source=None, exclude=None, **kwargs) +Install the windows feature. To install a single feature, use the \fBname\fP +parameter. To install multiple features, use the \fBfeatures\fP parameter. .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 Some features require reboot after un/installation. If so, until the server is restarted other features can not be installed! +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- +.sp +Short name of the feature (the right column in +win_servermanager.list_available). This can be a single feature or a +string of features in a comma delimited list (no spaces) +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +A list is not allowed in the name parameter of any state. Use +the \fBfeatures\fP parameter if you want to pass the features as a +list +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBfeatures\fP (\fIOptional[list]\fP) \-\- +.sp +A list of features to install. If this is passed it will be used +instead of the \fBname\fP parameter. +.sp +New in version 2018.3.0. + + +.IP \(bu 2 +\fBrecurse\fP (\fIOptional[bool]\fP) \-\- Install all sub\-features as well. If the feature is installed but +one of its sub\-features are not installed set this will install +additional sub\-features +.IP \(bu 2 +\fBsource\fP (\fIOptional[str]\fP) \-\- Path to the source files if missing from the target system. None +means that the system will use windows update services to find the +required files. Default is None +.IP \(bu 2 +\fBrestart\fP (\fIOptional[bool]\fP) \-\- Restarts the computer when installation is complete, if required by +the role/feature installed. Default is False +.IP \(bu 2 +\fBexclude\fP (\fIOptional[str]\fP) \-\- +.sp +The name of the feature to exclude when installing the named +feature. This can be a single feature, a string of features in a +comma\-delimited list (no spaces), or a list of features. +.sp +\fBWARNING:\fP +.INDENT 2.0 +.INDENT 3.5 +As there is no exclude option for the \fBAdd\-WindowsFeature\fP +or \fBInstall\-WindowsFeature\fP PowerShell commands the features +named in \fBexclude\fP will be installed with other sub\-features +and will then be removed. \fBIf the feature named in \(ga\(gaexclude\(ga\(ga +is not a sub\-feature of one of the installed items it will still +be removed.\fP +.UNINDENT +.UNINDENT + .UNINDENT .UNINDENT Example .sp -Run \fBsalt MinionName win_servermanager.list_available\fP to get a list -of available roles and features. Use the name in the right column. Do -not use the role or feature names mentioned in the PKGMGR documentation. -In this example for IIS\-WebServerRole the name to be used is Web\-Server. +Do not use the role or feature names mentioned in the PKGMGR +documentation. To get a list of available roles and features run the +following command: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C -ISWebserverRole: +salt win_servermanager.list_available +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Use the name in the right column of the results. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Installs the IIS Web Server Role (Web\-Server) +IIS\-WebServerRole: win_servermanager.installed: - \- force: True \- recurse: True \- name: Web\-Server + +# Install multiple features, exclude the Web\-Service +install_multiple_features: + win_servermanager.installed: + \- recurse: True + \- features: + \- RemoteAccess + \- XPS\-Viewer + \- SNMP\-Service + \- exclude: + \- Web\-Service .ft P .fi .UNINDENT @@ -332425,45 +353867,90 @@ ISWebserverRole: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_servermanager.removed(name, remove_payload=False, restart=False) -Remove the windows feature +.B salt.states.win_servermanager.removed(name, features=None, remove_payload=False, restart=False) +Remove the windows feature To remove a single feature, use the \fBname\fP +parameter. To remove multiple features, use the \fBfeatures\fP parameter. .INDENT 7.0 .TP .B Parameters .INDENT 7.0 .IP \(bu 2 -\fBname\fP (\fI\%str\fP) \-\- Short name of the feature (the right column in -win_servermanager.list_available) +\fBname\fP (\fI\%str\fP) \-\- +.sp +Short name of the feature (the right column in +win_servermanager.list_available). This can be a single feature or a +string of features in a comma\-delimited list (no spaces) +.sp +\fBNOTE:\fP +.INDENT 2.0 +.INDENT 3.5 +A list is not allowed in the name parameter of any state. Use +the \fBfeatures\fP parameter if you want to pass the features as a +list +.UNINDENT +.UNINDENT + .IP \(bu 2 -\fBremove_payload\fP (\fIOptional[bool]\fP) \-\- True will case the feature to be -removed from the side\-by\-side store +\fBfeatures\fP (\fIOptional[list]\fP) \-\- +.sp +A list of features to remove. If this is passed it will be used +instead of the \fBname\fP parameter. +.sp +New in version 2018.3.0. + + .IP \(bu 2 -\fBrestart\fP (\fIOptional[bool]\fP) \-\- Restarts the computer when uninstall is -complete, if required by the role/feature removed. Default is False +\fBremove_payload\fP (\fIOptional[bool]\fP) \-\- True will cause the feature to be removed from the side\-by\-side +store. To install the feature in the future you will need to +specify the \fBsource\fP +.IP \(bu 2 +\fBrestart\fP (\fIOptional[bool]\fP) \-\- Restarts the computer when uninstall is complete if required by the +role/feature uninstall. Default is False .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -Some features require a reboot after uninstallation. If so the feature -will not be completely uninstalled until the server is restarted. +Some features require a reboot after uninstall. If so the feature will +not be completely uninstalled until the server is restarted. .UNINDENT .UNINDENT Example .sp -Run \fBsalt MinionName win_servermanager.list_installed\fP to get a list -of all features installed. Use the top name listed for each feature, not -the indented one. Do not use the role or feature names mentioned in the -PKGMGR documentation. +Do not use the role or feature names mentioned in the PKGMGR +documentation. To get a list of available roles and features run the +following command: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C -ISWebserverRole: +salt win_servermanager.list_available +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Use the name in the right column of the results. +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Uninstall the IIS Web Server Rol (Web\-Server) +IIS\-WebserverRole: win_servermanager.removed: \- name: Web\-Server + +# Uninstall multiple features, reboot if required +uninstall_multiple_features: + win_servermanager.removed: + \- features: + \- RemoteAccess + \- XPX\-Viewer + \- SNMP\-Service + \- restart: True .ft P .fi .UNINDENT @@ -332474,7 +353961,7 @@ ISWebserverRole: Module for managing IIS SMTP server configuration on Windows servers. .INDENT 0.0 .TP -.B salt.states.win_smtp_server.active_log_format(name, log_format, server=\(aqSmtpSvc/1\(aq) +.B salt.states.win_smtp_server.active_log_format(name, log_format, server=u\(aqSmtpSvc/1\(aq) Manage the active log format for the SMTP server. .INDENT 7.0 .TP @@ -332503,7 +353990,7 @@ smtp\-log\-format: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_smtp_server.connection_ip_list(name, addresses=None, grant_by_default=False, server=\(aqSmtpSvc/1\(aq) +.B salt.states.win_smtp_server.connection_ip_list(name, addresses=None, grant_by_default=False, server=u\(aqSmtpSvc/1\(aq) Manage IP list for SMTP connections. .INDENT 7.0 .TP @@ -332570,7 +354057,7 @@ smtp\-connection\-blacklist: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_smtp_server.relay_ip_list(name, addresses=None, server=\(aqSmtpSvc/1\(aq) +.B salt.states.win_smtp_server.relay_ip_list(name, addresses=None, server=u\(aqSmtpSvc/1\(aq) Manage IP list for SMTP relay connections. .sp Due to the unusual way that Windows stores the relay IPs, it is advisable to retrieve @@ -332675,7 +354162,7 @@ smtp\-relay\-list: .UNINDENT .INDENT 0.0 .TP -.B salt.states.win_smtp_server.server_setting(name, settings=None, server=\(aqSmtpSvc/1\(aq) +.B salt.states.win_smtp_server.server_setting(name, settings=None, server=u\(aqSmtpSvc/1\(aq) Ensure the value is set for the specified setting. .sp \fBNOTE:\fP @@ -333281,9 +354768,8 @@ needed. .IP \(bu 2 \fBname\fP (\fI\%str\fP) \-\- The identifier of a single update to install. .IP \(bu 2 -\fBupdates\fP (\fIlist\fP) \-\- A list of identifiers for updates to be installed. -.IP \(bu 2 -\fBname. Default is None.\fP (\fIOverrides\fP) \-\- +\fBupdates\fP (\fIlist\fP) \-\- A list of identifiers for updates to be installed. Overrides +\fBname\fP\&. Default is None. .UNINDENT .UNINDENT .sp @@ -333336,7 +354822,7 @@ install_update: # Install multiple updates install_updates: wua.installed: - \- name: + \- updates: \- KB3194343 \- 28cf1b09\-2b1a\-458c\-9bd1\-971d1b26b211 .ft P @@ -333355,9 +354841,8 @@ Ensure Microsoft Updates are uninstalled. .IP \(bu 2 \fBname\fP (\fI\%str\fP) \-\- The identifier of a single update to uninstall. .IP \(bu 2 -\fBupdates\fP (\fIlist\fP) \-\- A list of identifiers for updates to be removed. -.IP \(bu 2 -\fBname. Default is None.\fP (\fIOverrides\fP) \-\- +\fBupdates\fP (\fIlist\fP) \-\- A list of identifiers for updates to be removed. Overrides \fBname\fP\&. +Default is None. .UNINDENT .UNINDENT .sp @@ -333418,6 +354903,117 @@ uninstall_updates: .UNINDENT .UNINDENT .UNINDENT +.INDENT 0.0 +.TP +.B salt.states.win_wua.uptodate(name, software=True, drivers=False, skip_hidden=False, skip_mandatory=False, skip_reboot=True, categories=None, severities=None) +Ensure Microsoft Updates that match the passed criteria are installed. +Updates will be downloaded if needed. +.sp +This state allows you to update a system without specifying a specific +update to apply. All matching updates will be installed. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP (\fI\%str\fP) \-\- The name has no functional value and is only used as a tracking +reference +.IP \(bu 2 +\fBsoftware\fP (\fI\%bool\fP) \-\- Include software updates in the results (default is True) +.IP \(bu 2 +\fBdrivers\fP (\fI\%bool\fP) \-\- Include driver updates in the results (default is False) +.IP \(bu 2 +\fBskip_hidden\fP (\fI\%bool\fP) \-\- Skip updates that have been hidden. Default is False. +.IP \(bu 2 +\fBskip_mandatory\fP (\fI\%bool\fP) \-\- Skip mandatory updates. Default is False. +.IP \(bu 2 +\fBskip_reboot\fP (\fI\%bool\fP) \-\- Skip updates that require a reboot. Default is True. +.IP \(bu 2 +\fBcategories\fP (\fIlist\fP) \-\- +.sp +Specify the categories to list. Must be passed as a list. All +categories returned by default. +.sp +Categories include the following: +.INDENT 2.0 +.IP \(bu 2 +Critical Updates +.IP \(bu 2 +Definition Updates +.IP \(bu 2 +Drivers (make sure you set drivers=True) +.IP \(bu 2 +Feature Packs +.IP \(bu 2 +Security Updates +.IP \(bu 2 +Update Rollups +.IP \(bu 2 +Updates +.IP \(bu 2 +Update Rollups +.IP \(bu 2 +Windows 7 +.IP \(bu 2 +Windows 8.1 +.IP \(bu 2 +Windows 8.1 drivers +.IP \(bu 2 +Windows 8.1 and later drivers +.IP \(bu 2 +Windows Defender +.UNINDENT + +.IP \(bu 2 +\fBseverities\fP (\fIlist\fP) \-\- +.sp +Specify the severities to include. Must be passed as a list. All +severities returned by default. +.sp +Severities include the following: +.INDENT 2.0 +.IP \(bu 2 +Critical +.IP \(bu 2 +Important +.UNINDENT + +.UNINDENT +.TP +.B Returns +A dictionary containing the results of the update +.TP +.B Return type +\fI\%dict\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Update the system using the state defaults +update_system: + wua.up_to_date + +# Update the drivers +update_drivers: + wua.up_to_date: + \- software: False + \- drivers: True + \- skip_reboot: False + +# Apply all critical updates +update_critical: + wua.up_to_date: + \- severities: + \- Critical +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.states.winrepo .sp Manage Windows Package Repository @@ -333714,7 +355310,7 @@ Examples: .UNINDENT .INDENT 0.0 .TP -.B salt.states.x509.crl_managed(name, signing_private_key, signing_private_key_passphrase=None, signing_cert=None, revoked=None, days_valid=100, digest=\(aq\(aq, days_remaining=30, include_expired=False, **kwargs) +.B salt.states.x509.crl_managed(name, signing_private_key, signing_private_key_passphrase=None, signing_cert=None, revoked=None, days_valid=100, digest=u\(aq\(aq, days_remaining=30, include_expired=False, **kwargs) Manage a Certificate Revocation List .INDENT 7.0 .TP @@ -333846,7 +355442,7 @@ Any arguments supported by .UNINDENT .INDENT 0.0 .TP -.B salt.states.x509.private_key_managed(name, bits=2048, passphrase=None, cipher=\(aqaes_128_cbc\(aq, new=False, overwrite=False, verbose=True, **kwargs) +.B salt.states.x509.private_key_managed(name, bits=2048, passphrase=None, cipher=u\(aqaes_128_cbc\(aq, new=False, overwrite=False, verbose=True, **kwargs) Manage a private key\(aqs existence. .INDENT 7.0 .TP @@ -334504,7 +356100,7 @@ installed2 .UNINDENT .INDENT 0.0 .TP -.B salt.states.zcbuildout.installed(name, config=\(aqbuildout.cfg\(aq, quiet=False, parts=None, user=None, env=(), buildout_ver=None, test_release=False, distribute=None, new_st=None, offline=False, newest=False, python=\(aq/usr/bin/python\(aq, debug=False, verbose=False, unless=None, onlyif=None, use_vt=False, loglevel=\(aqdebug\(aq, **kwargs) +.B salt.states.zcbuildout.installed(name, config=u\(aqbuildout.cfg\(aq, quiet=False, parts=None, user=None, env=(), buildout_ver=None, test_release=False, distribute=None, new_st=None, offline=False, newest=False, python=\(aq/usr/bin/python\(aq, debug=False, verbose=False, unless=None, onlyif=None, use_vt=False, loglevel=u\(aqdebug\(aq, **kwargs) Install buildout in a specific directory .sp It is a thin wrapper to modules.buildout.buildout @@ -334604,7 +356200,7 @@ enable_monitoring: .UNINDENT .INDENT 0.0 .TP -.B salt.states.zenoss.monitored(name, device_class=None, collector=\(aqlocalhost\(aq, prod_state=None) +.B salt.states.zenoss.monitored(name, device_class=None, collector=u\(aqlocalhost\(aq, prod_state=None) Ensure a device is monitored. The \(aqname\(aq given will be used for Zenoss device name and should be resolvable. .INDENT 7.0 .INDENT 3.5 @@ -334624,6 +356220,14 @@ enable_monitoring: .UNINDENT .SS salt.states.zk_concurrency .SS Control concurrency of steps within state execution using zookeeper +.INDENT 0.0 +.TP +.B depends +kazoo +.TP +.B configuration +See \fBsalt.modules.zookeeper\fP for setup instructions. +.UNINDENT .sp This module allows you to "wrap" a state\(aqs execution with concurrency control. This is useful to protect against all hosts executing highstate simultaneously @@ -334670,17 +356274,17 @@ This example would allow the file state to change, but would limit the concurrency of the trafficserver service restart to 4. .INDENT 0.0 .TP -.B salt.states.zk_concurrency.lock(name, zk_hosts, identifier=None, max_concurrency=1, timeout=None, ephemeral_lease=False) +.B salt.states.zk_concurrency.lock(name, zk_hosts=None, identifier=None, max_concurrency=1, timeout=None, ephemeral_lease=False, profile=None, scheme=None, username=None, password=None, default_acl=None) Block state execution until you are able to get the lock (or hit the timeout) .UNINDENT .INDENT 0.0 .TP -.B salt.states.zk_concurrency.min_party(name, zk_hosts, min_nodes, blocking=False) +.B salt.states.zk_concurrency.min_party(name, zk_hosts, min_nodes, blocking=False, profile=None, scheme=None, username=None, password=None, default_acl=None) Ensure that there are \fImin_nodes\fP in the party at \fIname\fP, optionally blocking if not available. .UNINDENT .INDENT 0.0 .TP -.B salt.states.zk_concurrency.unlock(name, zk_hosts=None, identifier=None, max_concurrency=1, ephemeral_lease=False) +.B salt.states.zk_concurrency.unlock(name, zk_hosts=None, identifier=None, max_concurrency=1, ephemeral_lease=False, profile=None, scheme=None, username=None, password=None, default_acl=None) Remove lease from semaphore. .UNINDENT .SS salt.states.zfs @@ -334726,7 +356330,7 @@ test/shares/yuki@frozen: zfs.snapshot_present moka_origin: - zfs.hold_present + zfs.hold_present: \- snapshot: test/shares/yuki@frozen test/shares/moka: @@ -334931,6 +356535,9 @@ a schedule must be setup to automatically run the state. this means that if you run the state daily the hourly snapshot will only be made once per day! .UNINDENT .UNINDENT +.sp +Changed in version 2018.3.0: switched to localtime from gmtime so times now take into account timezones. + .UNINDENT .INDENT 0.0 .TP @@ -335304,7 +356911,7 @@ use shutdown instead of halt if true .UNINDENT .INDENT 0.0 .TP -.B salt.states.zone.import(name, path, mode=\(aqimport\(aq, nodataset=False, brand_opts=None) +.B salt.states.zone.import(name, path, mode=u\(aqimport\(aq, nodataset=False, brand_opts=None) Import a zones configuration .INDENT 7.0 .TP @@ -336077,7 +357684,7 @@ succeed or fail based on the state of the register, this creates the pattern of having a command execution get gated by a check state via a requisite. .INDENT 0.0 .TP -.B salt.thorium.check.contains(name, value) +.B salt.thorium.check.contains(name, value, count_lt=None, count_lte=None, count_eq=None, count_gte=None, count_gt=None, count_ne=None) Only succeed if the value in the given register location contains the given value .sp @@ -336198,6 +357805,168 @@ foo: check.gte: \- value: 42 +run_remote_ex: + local.cmd: + \- tgt: \(aq*\(aq + \- func: test.ping + \- require: + \- check: foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.thorium.check.len_eq(name, value) +Only succeed if the length of the given register location is equal to +the given value. +.sp +USAGE: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +foo: + check.len_eq: + \- value: 42 + +run_remote_ex: + local.cmd: + \- tgt: \(aq*\(aq + \- func: test.ping + \- require: + \- check: foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.thorium.check.len_gt(name, value) +Only succeed if length of the given register location is greater than +the given value. +.sp +USAGE: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +foo: + check.len_gt: + \- value: 42 + +run_remote_ex: + local.cmd: + \- tgt: \(aq*\(aq + \- func: test.ping + \- require: + \- check: foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.thorium.check.len_gte(name, value) +Only succeed if the length of the given register location is greater or equal +than the given value +.sp +USAGE: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +foo: + check.len_gte: + \- value: 42 + +run_remote_ex: + local.cmd: + \- tgt: \(aq*\(aq + \- func: test.ping + \- require: + \- check: foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.thorium.check.len_lt(name, value) +Only succeed if the lenght of the given register location is less than +the given value. +.sp +USAGE: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +foo: + check.len_lt: + \- value: 42 + +run_remote_ex: + local.cmd: + \- tgt: \(aq*\(aq + \- func: test.ping + \- require: + \- check: foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.thorium.check.len_lte(name, value) +Only succeed if the length of the given register location is less than +or equal the given value +.sp +USAGE: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +foo: + check.len_lte: + \- value: 42 + +run_remote_ex: + local.cmd: + \- tgt: \(aq*\(aq + \- func: test.ping + \- require: + \- check: foo +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.thorium.check.len_ne(name, value) +Only succeed if the length of the given register location is not equal to +the given value. +.sp +USAGE: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +foo: + check.len_ne: + \- value: 42 + run_remote_ex: local.cmd: \- tgt: \(aq*\(aq @@ -336337,6 +358106,9 @@ that can be re\-imported into Python. Save the register to /thorium/saves/, or to an absolute path. .sp +If an absolute path is specified, then the directory will be created +non\-recursively if it doesn\(aqt exist. +.sp USAGE: .INDENT 7.0 .INDENT 3.5 @@ -336390,7 +358162,7 @@ clean_keys: Run remote execution commands via the local client .INDENT 0.0 .TP -.B salt.thorium.local.cmd(name, tgt, func, arg=(), tgt_type=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, **kwargs) +.B salt.thorium.local.cmd(name, tgt, func, arg=(), tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, kwarg=None, **kwargs) Execute a remote execution command .sp USAGE: @@ -337059,7 +358831,7 @@ Return the raw values of the config file Error generator to enable integration testing of salt wheel error handling .INDENT 0.0 .TP -.B salt.wheel.error.error(name=None, message=\(aq\(aq) +.B salt.wheel.error.error(name=None, message=u\(aq\(aq) If name is None Then return empty dict .sp Otherwise raise an exception with __name__ from name, message from message @@ -337082,12 +358854,12 @@ salt\-wheel error.error name="Exception" message="This is an error." Read in files from the file_root and save files to the file root .INDENT 0.0 .TP -.B salt.wheel.file_roots.find(path, saltenv=\(aqbase\(aq) +.B salt.wheel.file_roots.find(path, saltenv=u\(aqbase\(aq) Return a dict of the files located with the given path and environment .UNINDENT .INDENT 0.0 .TP -.B salt.wheel.file_roots.list_env(saltenv=\(aqbase\(aq) +.B salt.wheel.file_roots.list_env(saltenv=u\(aqbase\(aq) Return all of the file paths found in an environment .UNINDENT .INDENT 0.0 @@ -337097,12 +358869,12 @@ Return all of the files names in all available environments .UNINDENT .INDENT 0.0 .TP -.B salt.wheel.file_roots.read(path, saltenv=\(aqbase\(aq) +.B salt.wheel.file_roots.read(path, saltenv=u\(aqbase\(aq) Read the contents of a text file, if the file is binary then .UNINDENT .INDENT 0.0 .TP -.B salt.wheel.file_roots.write(data, path, saltenv=\(aqbase\(aq, index=0) +.B salt.wheel.file_roots.write(data, path, saltenv=u\(aqbase\(aq, index=0) Write the named file, by default the first file found is written, but the index of the file can be specified to write to a lower priority file root .UNINDENT @@ -337626,12 +359398,12 @@ The \fIpillar_roots\fP wheel module is used to manage files under the pillar roo directories on the master server. .INDENT 0.0 .TP -.B salt.wheel.pillar_roots.find(path, saltenv=\(aqbase\(aq) +.B salt.wheel.pillar_roots.find(path, saltenv=u\(aqbase\(aq) Return a dict of the files located with the given path and environment .UNINDENT .INDENT 0.0 .TP -.B salt.wheel.pillar_roots.list_env(saltenv=\(aqbase\(aq) +.B salt.wheel.pillar_roots.list_env(saltenv=u\(aqbase\(aq) Return all of the file paths found in an environment .UNINDENT .INDENT 0.0 @@ -337641,12 +359413,12 @@ Return all of the files names in all available environments .UNINDENT .INDENT 0.0 .TP -.B salt.wheel.pillar_roots.read(path, saltenv=\(aqbase\(aq) +.B salt.wheel.pillar_roots.read(path, saltenv=u\(aqbase\(aq) Read the contents of a text file, if the file is binary then .UNINDENT .INDENT 0.0 .TP -.B salt.wheel.pillar_roots.write(data, path, saltenv=\(aqbase\(aq, index=0) +.B salt.wheel.pillar_roots.write(data, path, saltenv=u\(aqbase\(aq, index=0) Write the named file, by default the first file found is written, but the index of the file can be specified to write to a lower priority file root .UNINDENT @@ -337686,7 +359458,7 @@ environment variables if they exist or otherwise fetch the config from the default location. .INDENT 0.0 .TP -.B salt.config.client_config(path, env_var=\(aqSALT_CLIENT_CONFIG\(aq, defaults=None) +.B salt.config.client_config(path, env_var=u\(aqSALT_CLIENT_CONFIG\(aq, defaults=None) Load Master configuration data .sp Usage: @@ -337712,7 +359484,7 @@ This is useful for master\-side operations like .UNINDENT .INDENT 0.0 .TP -.B salt.config.minion_config(path, env_var=\(aqSALT_MINION_CONFIG\(aq, defaults=None, cache_minion_id=False, ignore_config_errors=True, minion_id=None, role=\(aqminion\(aq) +.B salt.config.minion_config(path, env_var=u\(aqSALT_MINION_CONFIG\(aq, defaults=None, cache_minion_id=False, ignore_config_errors=True, minion_id=None, role=u\(aqminion\(aq) Reads in the minion configuration file and sets up special options .sp This is useful for Minion\-side operations, such as the @@ -337800,7 +359572,7 @@ __salt__[\(aqtest.ping\(aq]() .UNINDENT .INDENT 0.0 .TP -.B salt.loader.raw_mod(opts, name, functions, mod=\(aqmodules\(aq) +.B salt.loader.raw_mod(opts, name, functions, mod=u\(aqmodules\(aq) Returns a single module loaded raw and bypassing the __virtual__ function .INDENT 7.0 .INDENT 3.5 @@ -337901,7 +359673,7 @@ grainfuncs = salt.loader.grain_funcs(__opts__) .SS LocalClient .INDENT 0.0 .TP -.B class salt.client.LocalClient(c_path=\(aq/etc/salt/master\(aq, mopts=None, skip_perm_errors=False, io_loop=None, keep_loop=False, auto_reconnect=False) +.B class salt.client.LocalClient(c_path=u\(aq/etc/salt/master\(aq, mopts=None, skip_perm_errors=False, io_loop=None, keep_loop=False, auto_reconnect=False) The interface used by the \fBsalt\fP CLI tool on the Salt Master .sp \fBLocalClient\fP is used to send a command to Salt minions to execute @@ -337939,7 +359711,7 @@ local.cmd(\(aq*\(aq, \(aqtest.fib\(aq, [10]) .UNINDENT .INDENT 7.0 .TP -.B cmd(tgt, fun, arg=(), timeout=None, tgt_type=\(aqglob\(aq, ret=\(aq\(aq, jid=\(aq\(aq, full_return=False, kwarg=None, **kwargs) +.B cmd(tgt, fun, arg=(), timeout=None, tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, jid=u\(aq\(aq, full_return=False, kwarg=None, **kwargs) Synchronously execute a command on targeted minions .sp The cmd method will execute and wait for the timeout period for all @@ -338089,7 +359861,7 @@ function name. .UNINDENT .INDENT 7.0 .TP -.B cmd_async(tgt, fun, arg=(), tgt_type=\(aqglob\(aq, ret=\(aq\(aq, jid=\(aq\(aq, kwarg=None, **kwargs) +.B cmd_async(tgt, fun, arg=(), tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, jid=u\(aq\(aq, kwarg=None, **kwargs) Asynchronously send a command to connected minions .sp The function signature is the same as \fBcmd()\fP with the @@ -338113,7 +359885,7 @@ A job ID or 0 on failure. .UNINDENT .INDENT 7.0 .TP -.B cmd_batch(tgt, fun, arg=(), tgt_type=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, batch=\(aq10%\(aq, **kwargs) +.B cmd_batch(tgt, fun, arg=(), tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, kwarg=None, batch=u\(aq10%\(aq, **kwargs) Iteratively execute a command on subsets of minions at a time .sp The function signature is the same as \fBcmd()\fP with the @@ -338144,11 +359916,15 @@ A generator of minion returns .UNINDENT .INDENT 7.0 .TP -.B cmd_iter(tgt, fun, arg=(), timeout=None, tgt_type=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, **kwargs) +.B cmd_iter(tgt, fun, arg=(), timeout=None, tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, kwarg=None, **kwargs) Yields the individual minion returns as they come in .sp The function signature is the same as \fBcmd()\fP with the following exceptions. +.sp +Normally \fBcmd_iter()\fP does not yield results for minions that +are not connected. If you want it to return results for disconnected +minions set \fIexpect_minions=True\fP in \fIkwargs\fP\&. .INDENT 7.0 .TP .B Returns @@ -338172,7 +359948,7 @@ A generator yielding the individual minion returns .UNINDENT .INDENT 7.0 .TP -.B cmd_iter_no_block(tgt, fun, arg=(), timeout=None, tgt_type=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, show_jid=False, verbose=False, **kwargs) +.B cmd_iter_no_block(tgt, fun, arg=(), timeout=None, tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, kwarg=None, show_jid=False, verbose=False, **kwargs) .INDENT 7.0 .TP .B Yields the individual minion returns as they come in, or None @@ -338208,7 +359984,7 @@ None .UNINDENT .INDENT 7.0 .TP -.B cmd_subset(tgt, fun, arg=(), tgt_type=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, sub=3, cli=False, progress=False, **kwargs) +.B cmd_subset(tgt, fun, arg=(), tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, kwarg=None, sub=3, cli=False, progress=False, **kwargs) Execute a command on a random subset of the targeted systems .sp The function signature is the same as \fBcmd()\fP with the @@ -338232,7 +360008,7 @@ following exceptions. .UNINDENT .INDENT 7.0 .TP -.B get_cli_returns(jid, minions, timeout=None, tgt=\(aq*\(aq, tgt_type=\(aqglob\(aq, verbose=False, show_jid=False, **kwargs) +.B get_cli_returns(jid, minions, timeout=None, tgt=u\(aq*\(aq, tgt_type=u\(aqglob\(aq, verbose=False, show_jid=False, **kwargs) Starts a watcher looking at the return data for a specified JID .INDENT 7.0 .TP @@ -338248,7 +360024,7 @@ is reached. .UNINDENT .INDENT 7.0 .TP -.B run_job(tgt, fun, arg=(), tgt_type=\(aqglob\(aq, ret=\(aq\(aq, timeout=None, jid=\(aq\(aq, kwarg=None, listen=False, **kwargs) +.B run_job(tgt, fun, arg=(), tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, timeout=None, jid=u\(aq\(aq, kwarg=None, listen=False, **kwargs) Asynchronously send a command to connected minions .sp Prep the job directory and publish a command to any targeted minions. @@ -338275,7 +360051,7 @@ list of all minions that are expected to return data. .SS Salt Caller .INDENT 0.0 .TP -.B class salt.client.Caller(c_path=\(aq/etc/salt/minion\(aq, mopts=None) +.B class salt.client.Caller(c_path=u\(aq/etc/salt/minion\(aq, mopts=None) \fBCaller\fP is the same interface used by the \fBsalt\-call\fP command\-line tool on the Salt Minion. .sp @@ -338365,7 +360141,7 @@ eauth user must be authorized to execute runner modules: (\fB@runner\fP). Only the \fBmaster_call()\fP below supports eauth. .INDENT 7.0 .TP -.B async(fun, low, user=\(aqUNKNOWN\(aq, pub=None) +.B async(fun, low, user=u\(aqUNKNOWN\(aq, pub=None) Execute the function in a multiprocess and return the event tag to use to watch for the return .UNINDENT @@ -338451,7 +360227,7 @@ wheel = salt.wheel.WheelClient(opts) .UNINDENT .INDENT 7.0 .TP -.B async(fun, low, user=\(aqUNKNOWN\(aq, pub=None) +.B async(fun, low, user=u\(aqUNKNOWN\(aq, pub=None) Execute the function in a multiprocess and return the event tag to use to watch for the return .UNINDENT @@ -338595,7 +360371,7 @@ client.extra_action(names=[\(aqsalt\-net\(aq], action=\(aqnetwork_create\(aq, .UNINDENT .INDENT 7.0 .TP -.B full_query(query_type=\(aqlist_nodes_full\(aq) +.B full_query(query_type=u\(aqlist_nodes_full\(aq) Query all instance information .UNINDENT .INDENT 7.0 @@ -338625,7 +360401,7 @@ Pass in a location for a map to execute .UNINDENT .INDENT 7.0 .TP -.B min_query(query_type=\(aqlist_nodes_min\(aq) +.B min_query(query_type=u\(aqlist_nodes_min\(aq) Query select instance information .UNINDENT .INDENT 7.0 @@ -338647,22 +360423,22 @@ Example: .ft C >>> client= salt.cloud.CloudClient(path=\(aq/etc/salt/cloud\(aq) >>> client.profile(\(aqdo_512_git\(aq, names=[\(aqminion01\(aq,]) -{\(aqminion01\(aq: {u\(aqbackups_active\(aq: \(aqFalse\(aq, - u\(aqcreated_at\(aq: \(aq2014\-09\-04T18:10:15Z\(aq, - u\(aqdroplet\(aq: {u\(aqevent_id\(aq: 31000502, - u\(aqid\(aq: 2530006, - u\(aqimage_id\(aq: 5140006, - u\(aqname\(aq: u\(aqminion01\(aq, - u\(aqsize_id\(aq: 66}, - u\(aqid\(aq: \(aq2530006\(aq, - u\(aqimage_id\(aq: \(aq5140006\(aq, - u\(aqip_address\(aq: \(aq107.XXX.XXX.XXX\(aq, - u\(aqlocked\(aq: \(aqTrue\(aq, - u\(aqname\(aq: \(aqminion01\(aq, - u\(aqprivate_ip_address\(aq: None, - u\(aqregion_id\(aq: \(aq4\(aq, - u\(aqsize_id\(aq: \(aq66\(aq, - u\(aqstatus\(aq: \(aqnew\(aq}} +{\(aqminion01\(aq: {\(aqbackups_active\(aq: \(aqFalse\(aq, + \(aqcreated_at\(aq: \(aq2014\-09\-04T18:10:15Z\(aq, + \(aqdroplet\(aq: {\(aqevent_id\(aq: 31000502, + \(aqid\(aq: 2530006, + \(aqimage_id\(aq: 5140006, + \(aqname\(aq: \(aqminion01\(aq, + \(aqsize_id\(aq: 66}, + \(aqid\(aq: \(aq2530006\(aq, + \(aqimage_id\(aq: \(aq5140006\(aq, + \(aqip_address\(aq: \(aq107.XXX.XXX.XXX\(aq, + \(aqlocked\(aq: \(aqTrue\(aq, + \(aqname\(aq: \(aqminion01\(aq, + \(aqprivate_ip_address\(aq: None, + \(aqregion_id\(aq: \(aq4\(aq, + \(aqsize_id\(aq: \(aq66\(aq, + \(aqstatus\(aq: \(aqnew\(aq}} .ft P .fi .UNINDENT @@ -338670,26 +360446,26 @@ Example: .UNINDENT .INDENT 7.0 .TP -.B query(query_type=\(aqlist_nodes\(aq) +.B query(query_type=u\(aqlist_nodes\(aq) Query basic instance information .UNINDENT .INDENT 7.0 .TP -.B select_query(query_type=\(aqlist_nodes_select\(aq) +.B select_query(query_type=u\(aqlist_nodes_select\(aq) Query select instance information .UNINDENT .UNINDENT .SS SSHClient .INDENT 0.0 .TP -.B class salt.client.ssh.client.SSHClient(c_path=\(aq/etc/salt/master\(aq, mopts=None, disable_custom_roster=False) +.B class salt.client.ssh.client.SSHClient(c_path=u\(aq/etc/salt/master\(aq, mopts=None, disable_custom_roster=False) Create a client object for executing routines via the salt\-ssh backend .sp New in version 2015.5.0. .INDENT 7.0 .TP -.B cmd(tgt, fun, arg=(), timeout=None, tgt_type=\(aqglob\(aq, kwarg=None, **kwargs) +.B cmd(tgt, fun, arg=(), timeout=None, tgt_type=u\(aqglob\(aq, kwarg=None, **kwargs) Execute a single command via the salt\-ssh subsystem and return all routines at once .sp @@ -338698,7 +360474,7 @@ New in version 2015.5.0. .UNINDENT .INDENT 7.0 .TP -.B cmd_iter(tgt, fun, arg=(), timeout=None, tgt_type=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, **kwargs) +.B cmd_iter(tgt, fun, arg=(), timeout=None, tgt_type=u\(aqglob\(aq, ret=u\(aq\(aq, kwarg=None, **kwargs) Execute a single command via the salt\-ssh subsystem and return a generator .sp @@ -340317,20 +362093,10 @@ keep_jobs: 24 .fi .UNINDENT .UNINDENT +.SS Use and External Job Cache .sp -If no job history is needed, the job cache can be disabled: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -job_cache: False -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -If the job cache is necessary there are (currently) 2 options: +An external job cache allows for job storage to be placed on an external +system, such as a database. .INDENT 0.0 .IP \(bu 2 ext_job_cache: this will have the minions store their return data directly @@ -340353,6 +362119,26 @@ for up to sixty seconds by default. .sp To enable the master key cache, set \fIkey_cache: \(aqsched\(aq\fP in the master configuration file. +.SS Disable The Job Cache +.sp +The job cache is a central component of the Salt Master and many aspects of +the Salt Master will not function correctly without a running job cache. +.sp +Disabling the job cache is \fBSTRONGLY DISCOURAGED\fP and should not be done +unless the master is being used to execute routines that require no history +or reliable feedback! +.sp +The job cache can be disabled: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +job_cache: False +.ft P +.fi +.UNINDENT +.UNINDENT .SS Multi Master Tutorial .sp As of Salt 0.16.0, the ability to connect minions to multiple masters has been @@ -341141,6 +362927,66 @@ cache: consul .fi .UNINDENT .UNINDENT +.SH SLOTS +.sp +New in version 2018.3.0. + +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +This functionality is under development and could be changed in the +future releases +.UNINDENT +.UNINDENT +.sp +Many times it is useful to store the results of a command during the course of +an execution. Salt Slots are designed to allow to store this information and +use it later during the highstate or other job +execution. +.sp +Slots extend the state syntax and allows you to do things right before the +state function is executed. So you can make a decision in the last moment right +before a state is executed. +.SS Execution functions +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Using execution modules return data as a state values is a first step +of Slots development. Other functionality is under development. +.UNINDENT +.UNINDENT +.sp +Slots allow you to use the return from a remote\-execution function as an +argument value in states. +.sp +Slot syntax looks close to the simple python function call. +.sp +Also there are some specifics in the syntax coming from the execution functions +nature and a desire to simplify the user experience. First one is that you +don\(aqt need to quote the strings passed to the slots functions. The second one +is that all arguments handled as strings. +.sp +Here is a simple example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +copy\-some\-file: + file.copy: + \- name: __slot__:salt:test.echo(text=/tmp/some_file) + \- source: __slot__:salt:test.echo(/etc/hosts) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This will execute the \fBtest.echo\fP execution +functions right before calling the state. The functions in the example will +return \fI/tmp/some_file\fP and \fI/etc/hosts\fP strings that will be used as a target +and source arguments in the state function \fIfile.copy\fP\&. .SH WINDOWS .sp This section contains details on the Windows Package Manager, and specific information you need @@ -342366,8 +364212,8 @@ IPC: publish_pull.ipc Each salt minion establishes a connection to the master Publisher. .SS EventPublisher .sp -The EventPublisher publishes events onto the event bus. It is bound to the -following: +The EventPublisher publishes master events out to any event listeners. It is +bound to the following: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 @@ -342425,45 +364271,35 @@ A command is issued on the CLI. For example, \(aqsalt my_minion test.ping\(aq. .sp 2) The \(aqsalt\(aq command uses LocalClient to generate a request to the salt master by connecting to the ReqServer on \fI\%TCP:4506\fP and issuing the job. -.sp 3) The salt\-master ReqServer sees the request and passes it to an available MWorker over workers.ipc. -.sp 4) A worker picks up the request and handles it. First, it checks to ensure that the requested user has permissions to issue the command. Then, it sends the publish command to all connected minions. For the curious, this happens in ClearFuncs.publish(). -.sp 5) The worker announces on the master event bus that it is about to publish a job to connected minions. This happens by placing the event on the master event bus (master_event_pull.ipc) where the EventPublisher picks it up and distributes it to all connected event listeners on master_event_pub.ipc. -.sp 6) The message to the minions is encrypted and sent to the Publisher via IPC on publish_pull.ipc. -.sp 7) Connected minions have a TCP session established with the Publisher on TCP port 4505 where they await commands. When the Publisher receives the job over publish_pull, it sends the jobs across the wire to the minions for processing. -.sp 8) After the minions receive the request, they decrypt it and perform any requested work, if they determine that they are targeted to do so. -.sp 9) When the minion is ready to respond, it publishes the result of its job back to the master by sending the encrypted result back to the master on TCP 4506 where it is again picked up by the ReqServer and forwarded to an available MWorker for processing. (Again, this happens by passing this message across workers.ipc to an available worker.) -.sp 10) When the MWorker receives the job it decrypts it and fires an event onto the master event bus (master_event_pull.ipc). (Again for the curious, this happens in AESFuncs._return(). -.sp 11) The EventPublisher sees this event and re\-publishes it on the bus to all connected listeners of the master event bus (on master_event_pub.ipc). This is where the LocalClient has been waiting, listening to the event bus for minion replies. It gathers the job and stores the result. -.sp 12) When all targeted minions have replied or the timeout has been exceeded, the salt client displays the results of the job to the user on the CLI. .SS Salt Minion @@ -342474,8 +364310,8 @@ Salt. It can either operate as a stand\-alone daemon which accepts commands locally via \(aqsalt\-call\(aq or it can connect back to a master and receive commands remotely. .sp -When starting up, salt minions connect _back_ to a master defined in the minion -config file. The connect to two ports on the master: +When starting up, salt minions connect \fIback\fP to a master defined in the minion +config file. They connect to two ports on the master: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 @@ -342510,7 +364346,7 @@ necessitates a mechanism by which those processes can communicate with each other. Secondarily, this provides a bus by which any user with sufficient permissions can read or write to the bus as a common interface with the salt minion. -.SS Job Flow +.SS Minion Job Flow .sp When a salt minion starts up, it attempts to connect to the Publisher and the ReqServer on the salt master. It then attempts to authenticate and once the @@ -342518,29 +364354,23 @@ minion has successfully authenticated, it simply listens for jobs. .sp Jobs normally come either come from the \(aqsalt\-call\(aq script run by a local user on the salt minion or they can come directly from a master. -.SS Master Job Flow +.sp +The job flow on a minion, coming from the master via a \(aqsalt\(aq command is as +follows: .sp 1) A master publishes a job that is received by a minion as outlined by the master\(aqs job flow above. -.sp 2) The minion is polling its receive socket that\(aqs connected to the master Publisher (TCP 4505 on master). When it detects an incoming message, it picks it up from the socket and decrypts it. -.sp 3) A new minion process or thread is created and provided with the contents of the decrypted message. The _thread_return() method is provided with the contents of the received message. -.sp 4) The new minion thread is created. The _thread_return() function starts up and actually calls out to the requested function contained in the job. -.INDENT 0.0 -.IP 5. 3 -The requested function runs and returns a result. [Still in thread.] -.UNINDENT -.sp +5) The requested function runs and returns a result. [Still in thread.] 6) The result of the function that\(aqs run is encrypted and returned to the master\(aqs ReqServer (TCP 4506 on master). [Still in thread.] -.sp 7) Thread exits. Because the main thread was only blocked for the time that it took to initialize the worker thread, many other requests could have been received and processed during this time. @@ -342551,11 +364381,8 @@ clear and when they are passed using encryption. There are two rules governing this behaviour: .sp 1) ClearFuncs is used for intra\-master communication and during the initial -authentication handshake between a minion and master during the key exhange. -.INDENT 0.0 -.IP 2. 3 -AESFuncs is used everywhere else. -.UNINDENT +authentication handshake between a minion and master during the key exchange. +2) AESFuncs is used everywhere else. .SS Contributing .sp There is a great need for contributions to Salt and patches are welcome! The goal @@ -343215,10 +365042,10 @@ on the significance and complexity of the changes required by the user. .sp Salt feature releases are based on the Periodic Table. Any new features going into the develop branch will be named after the next element in the Periodic -Table. For example, Beryllium was the feature release name of the develop branch -before the 2015.8 branch was tagged. At that point in time, any new features going -into the develop branch after 2015.8 was branched were part of the Boron feature -release. +Table. For example, Beryllium was the feature release name of the develop +branch before the 2015.8 branch was tagged. At that point in time, any new +features going into the develop branch after 2015.8 was branched were part of +the Boron feature release. .sp A deprecation warning should be in place for at least two major releases before the deprecated code and its accompanying deprecation warning are removed. More @@ -343226,12 +365053,14 @@ time should be given for more complex changes. For example, if the current release under development is \fBSodium\fP, the deprecated code and associated warnings should remain in place and warn for at least \fBAluminum\fP\&. .sp -To help in this deprecation task, salt provides \fBsalt.utils.warn_until\fP\&. The idea behind this helper function is to show the -deprecation warning to the user until salt reaches the provided version. Once -that provided version is equaled \fBsalt.utils.warn_until\fP will raise a \fI\%RuntimeError\fP making salt stop -its execution. This stoppage is unpleasant and will remind the developer that -the deprecation limit has been reached and that the code can then be safely -removed. +To help in this deprecation task, salt provides +\fBsalt.utils.versions.warn_until\fP\&. The +idea behind this helper function is to show the deprecation warning to the user +until salt reaches the provided version. Once that provided version is equaled +\fBsalt.utils.versions.warn_until\fP will +raise a \fI\%RuntimeError\fP making salt stop its execution. This stoppage is +unpleasant and will remind the developer that the deprecation limit has been +reached and that the code can then be safely removed. .sp Consider the following example: .INDENT 0.0 @@ -343241,7 +365070,7 @@ Consider the following example: .ft C def some_function(bar=False, foo=None): if foo is not None: - salt.utils.warn_until( + salt.utils.versions.warn_until( \(aqAluminum\(aq, \(aqThe \e\(aqfoo\e\(aq argument has been deprecated and its \(aq \(aqfunctionality removed, as such, its usage is no longer \(aq @@ -343301,6 +365130,8 @@ State Modules Returners .IP \(bu 2 Runners +.IP \(bu 2 +SDB Modules .UNINDENT .sp \fB__salt__\fP contains the execution module functions. This allows for all @@ -344798,13 +366629,13 @@ The second return value will be a string with two possible values: .sp Both before and after the installing the target(s), you should run \fBlist_pkgs\fP to obtain a list of the installed packages. You should then -return the output of \fBsalt.utils.compare_dicts()\fP +return the output of \fBsalt.utils.data.compare_dicts()\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -return salt.utils.compare_dicts(old, new) +return salt.utils.data.compare_dicts(old, new) .ft P .fi .UNINDENT @@ -346046,7 +367877,7 @@ the default cloud provider configuration file for DigitalOcean looks like this: .nf .ft C digitalocean\-config: - driver: digital_ocean + driver: digitalocean client_key: \(aq\(aq api_key: \(aq\(aq location: New York 1 @@ -346063,7 +367894,7 @@ must be provided: .nf .ft C digitalocean\-config: - driver: digital_ocean + driver: digitalocean client_key: wFGEwgregeqw3435gDger api_key: GDE43t43REGTrkilg43934t34qT43t4dgegerGEgg location: New York 1 @@ -347106,7 +368937,7 @@ One design goal of Salt\(aqs GitFS fileserver backend was to facilitate reusable States. GitFS is a quick and natural way to use Formulas. .INDENT 0.0 .IP 1. 3 -Install and configure GitFS\&. +Install any necessary dependencies and configure GitFS\&. .IP 2. 3 Add one or more Formula repository URLs as remotes in the \fBgitfs_remotes\fP list in the Salt Master configuration file: @@ -347132,6 +368963,12 @@ upstream with a quick pull request! .IP 3. 3 Restart the Salt master. .UNINDENT +.sp +Beginning with the 2018.3.0 release, using formulas with GitFS is now much more +convenient for deployments which use many different fileserver environments +(i.e. saltenvs). Using the all_saltenvs +parameter, files from a single git branch/tag will appear in all environments. +See here for more information on this feature. .SS Adding a Formula directory manually .sp Formulas are simply directories that can be copied onto the local file system @@ -347300,24 +369137,37 @@ additions as a pull request. Add tips and tricks to the repository wiki. .sp Each Formula is a separate repository in the \fI\%saltstack\-formulas\fP organization on GitHub. -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -Get involved creating new Formulas +.SS Get involved creating new Formulas .sp The best way to create new Formula repositories for now is to create a -repository in your own account on GitHub and notify a SaltStack employee -when it is ready. We will add you to the contributors team on the -\fI\%saltstack\-formulas\fP organization and help you transfer the repository -over. Ping a SaltStack employee on IRC (\fB#salt\fP on Freenode) or send an -email to the \fI\%salt\-users\fP mailing list. +repository in your own account on GitHub and notify a SaltStack employee when +it is ready. We will add you to the Contributors team on the +\fI\%saltstack\-formulas\fP organization and help you transfer the repository over. +Ping a SaltStack employee on IRC (\fB#salt\fP on Freenode) or send an email to +the \fI\%salt\-users\fP mailing list. .sp -There are a lot of repositories in that organization! Team members can -manage which repositories they are subscribed to on GitHub\(aqs watching page: +There are a lot of repositories in that organization! Team members can manage +which repositories they are subscribed to on GitHub\(aqs watching page: \fI\%https://github.com/watching\fP\&. -.UNINDENT -.UNINDENT +.sp +Members of the Contributors team are welcome to participate in reviewing pull +requests across the Organization. Some repositories will have regular +contributors and some repositories will not. As you get involved in a +repository be sure to communicate with any other contributors there on pull +requests that are large or have breaking changes. +.sp +In general it is best to have another Contributor review and merge any pull +requests that you open. Feel free to +.nf +\(gaat\-mention\(ga__ +.fi + other regular contributors +to a repository and request a review. However, there are a lot of formula +repositories so if a repository does not yet have regular contributors or if +your pull request has stayed open for more than a couple days feel free to +"selfie\-merge" your own pull request. +.sp +__: \fI\%https://help.github.com/articles/basic\-writing\-and\-formatting\-syntax/#mentioning\-users\-and\-teams\fP .SS Style .sp Maintainability, readability, and reusability are all marks of a good Salt sls @@ -349575,43 +371425,53 @@ _ This module is a central location for all salt exceptions .INDENT 0.0 .TP -.B exception salt.exceptions.AuthenticationError(message=\(aq\(aq) +.B exception salt.exceptions.ArgumentValueError(message=u\(aq\(aq, info=None) +Used when an invalid argument was passed to a command execution +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.AuthenticationError(message=u\(aq\(aq) If sha256 signature fails during decryption .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.AuthorizationError(message=\(aq\(aq) +.B exception salt.exceptions.AuthorizationError(message=u\(aq\(aq) Thrown when runner or wheel execution fails due to permissions .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.CommandExecutionError(message=\(aq\(aq, info=None) +.B exception salt.exceptions.CheckError(message=u\(aq\(aq, info=None) +Used when a check fails +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.CommandExecutionError(message=u\(aq\(aq, info=None) Used when a module runs a command which returns an error and wants to show the user the output gracefully instead of dying .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.CommandNotFoundError(message=\(aq\(aq) +.B exception salt.exceptions.CommandNotFoundError(message=u\(aq\(aq) Used in modules or grains when a required binary is not available .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.EauthAuthenticationError(message=\(aq\(aq) +.B exception salt.exceptions.EauthAuthenticationError(message=u\(aq\(aq) Thrown when eauth authentication fails .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.FileLockError(msg, time_start=None, *args, **kwargs) +.B exception salt.exceptions.FileLockError(message, time_start=None, *args, **kwargs) Used when an error occurs obtaining a file lock .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.FileserverConfigError(message=\(aq\(aq) +.B exception salt.exceptions.FileserverConfigError(message=u\(aq\(aq) Used when invalid fileserver settings are detected .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.GitLockError(errno, strerror, *args, **kwargs) +.B exception salt.exceptions.GitLockError(errno, message, *args, **kwargs) Raised when an uncaught error occurs in the midst of obtaining an update/checkout lock in salt.utils.gitfs. .sp @@ -349622,13 +371482,23 @@ an OSError. .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.GitRemoteError(message=\(aq\(aq) +.B exception salt.exceptions.GitRemoteError(message=u\(aq\(aq) Used by GitFS to denote a problem with the existence of the "origin" remote or part of its configuration .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.LoaderError(message=\(aq\(aq) +.B exception salt.exceptions.InvalidConfigError(message=u\(aq\(aq, info=None) +Used when the config is invalid +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.InvalidEntityError(message=u\(aq\(aq, info=None) +Used when an entity fails validation +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.LoaderError(message=u\(aq\(aq) Problems loading the right renderer .UNINDENT .INDENT 0.0 @@ -349638,71 +371508,71 @@ Rise when the master exits .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.MinionError(message=\(aq\(aq) +.B exception salt.exceptions.MinionError(message=u\(aq\(aq) Minion problems reading uris such as salt:// or http:// .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.NotImplemented(message=\(aq\(aq) +.B exception salt.exceptions.NotImplemented(message=u\(aq\(aq) Used when a module runs a command which returns an error and wants to show the user the output gracefully instead of dying .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.PkgParseError(message=\(aq\(aq) +.B exception salt.exceptions.PkgParseError(message=u\(aq\(aq) Used when of the pkg modules cannot correctly parse the output from the CLI tool (pacman, yum, apt, aptitude, etc) .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.PublishError(message=\(aq\(aq) +.B exception salt.exceptions.PublishError(message=u\(aq\(aq) Problems encountered when trying to publish a command .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltCacheError(message=\(aq\(aq) +.B exception salt.exceptions.SaltCacheError(message=u\(aq\(aq) Thrown when a problem was encountered trying to read or write from the salt cache .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltClientError(message=\(aq\(aq) +.B exception salt.exceptions.SaltClientError(message=u\(aq\(aq) Problem reading the master root key .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltClientTimeout(msg, jid=None, *args, **kwargs) +.B exception salt.exceptions.SaltClientTimeout(message, jid=None, *args, **kwargs) Thrown when a job sent through one of the Client interfaces times out .sp Takes the \fBjid\fP as a parameter .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltCloudConfigError(message=\(aq\(aq) +.B exception salt.exceptions.SaltCloudConfigError(message=u\(aq\(aq) Raised when a configuration setting is not found and should exist. .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltCloudException(message=\(aq\(aq) +.B exception salt.exceptions.SaltCloudException(message=u\(aq\(aq) Generic Salt Cloud Exception .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltCloudExecutionFailure(message=\(aq\(aq) +.B exception salt.exceptions.SaltCloudExecutionFailure(message=u\(aq\(aq) Raised when too much failures have occurred while querying/waiting for data. .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltCloudExecutionTimeout(message=\(aq\(aq) +.B exception salt.exceptions.SaltCloudExecutionTimeout(message=u\(aq\(aq) Raised when too much time has passed while querying/waiting for data. .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltCloudNotFound(message=\(aq\(aq) +.B exception salt.exceptions.SaltCloudNotFound(message=u\(aq\(aq) Raised when some cloud provider function cannot find what\(aqs being searched. .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltCloudPasswordError(message=\(aq\(aq) +.B exception salt.exceptions.SaltCloudPasswordError(message=u\(aq\(aq) Raise when virtual terminal password input failed .UNINDENT .INDENT 0.0 @@ -349712,18 +371582,18 @@ This exception is raised when the execution should be stopped. .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltConfigurationError(message=\(aq\(aq) +.B exception salt.exceptions.SaltConfigurationError(message=u\(aq\(aq) Configuration error .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltDaemonNotRunning(message=\(aq\(aq) +.B exception salt.exceptions.SaltDaemonNotRunning(message=u\(aq\(aq) Throw when a running master/minion/syndic is not running but is needed to perform the requested operation (e.g., eauth). .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltException(message=\(aq\(aq) +.B exception salt.exceptions.SaltException(message=u\(aq\(aq) Base exception class; all Salt\-specific exceptions should subclass this .INDENT 7.0 .TP @@ -349734,40 +371604,40 @@ transport via msgpack .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltInvocationError(message=\(aq\(aq) +.B exception salt.exceptions.SaltInvocationError(message=u\(aq\(aq) Used when the wrong number of arguments are sent to modules or invalid arguments are specified on the command line .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltMasterError(message=\(aq\(aq) +.B exception salt.exceptions.SaltMasterError(message=u\(aq\(aq) Problem reading the master root key .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltNoMinionsFound(message=\(aq\(aq) +.B exception salt.exceptions.SaltNoMinionsFound(message=u\(aq\(aq) An attempt to retrieve a list of minions failed .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltRenderError(message, line_num=None, buf=\(aq\(aq, marker=\(aq <======================\(aq, trace=None) +.B exception salt.exceptions.SaltRenderError(message, line_num=None, buf=u\(aq\(aq, marker=u\(aq <======================\(aq, trace=None) Used when a renderer needs to raise an explicit error. If a line number and buffer string are passed, get_context will be invoked to get the location of the error. .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltReqTimeoutError(message=\(aq\(aq) +.B exception salt.exceptions.SaltReqTimeoutError(message=u\(aq\(aq) Thrown when a salt master request call fails to return within the timeout .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltRunnerError(message=\(aq\(aq) +.B exception salt.exceptions.SaltRunnerError(message=u\(aq\(aq) Problem in runner .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltSyndicMasterError(message=\(aq\(aq) +.B exception salt.exceptions.SaltSyndicMasterError(message=u\(aq\(aq) Problem while proxying a request in the syndication master .UNINDENT .INDENT 0.0 @@ -349778,59 +371648,104 @@ nothing else to do, salt should just exit. .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.SaltWheelError(message=\(aq\(aq) +.B exception salt.exceptions.SaltWheelError(message=u\(aq\(aq) Problem in wheel .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.TimedProcTimeoutError(message=\(aq\(aq) +.B exception salt.exceptions.TemplateError(message=u\(aq\(aq) +Used when a custom error is triggered in a template +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.TimedProcTimeoutError(message=u\(aq\(aq) Thrown when a timed subprocess does not terminate within the timeout, or if the specified timeout is not an int or a float .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.TimeoutError(message=\(aq\(aq) +.B exception salt.exceptions.TimeoutError(message=u\(aq\(aq) Thrown when an opration cannot be completet within a given time limit. .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.TokenAuthenticationError(message=\(aq\(aq) +.B exception salt.exceptions.TokenAuthenticationError(message=u\(aq\(aq) Thrown when token authentication fails .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.VMwareApiError(message=\(aq\(aq, info=None) +.B exception salt.exceptions.VMwareApiError(message=u\(aq\(aq, info=None) Used when representing a generic VMware API error .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.VMwareConnectionError(message=\(aq\(aq, info=None) +.B exception salt.exceptions.VMwareConnectionError(message=u\(aq\(aq, info=None) Used when the client fails to connect to a either a VMware vCenter server or to a ESXi host .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.VMwareObjectRetrievalError(message=\(aq\(aq, info=None) +.B exception salt.exceptions.VMwareFileNotFoundError(message=u\(aq\(aq, info=None) +Used when representing a generic VMware error if a file not found +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.VMwareMultipleObjectsError(message=u\(aq\(aq, info=None) +Used when multiple objects were retrieved (and one was expected) +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.VMwareNotFoundError(message=u\(aq\(aq, info=None) +Used when a VMware object was not found +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.VMwareObjectExistsError(message=u\(aq\(aq, info=None) +Used when a VMware object already exists +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.VMwareObjectNotFoundError(message=u\(aq\(aq, info=None) +Used when a VMware object was not found +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.VMwareObjectRetrievalError(message=u\(aq\(aq, info=None) Used when a VMware object cannot be retrieved .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.VMwareRuntimeError(message=\(aq\(aq, info=None) +.B exception salt.exceptions.VMwarePowerOnError(message=u\(aq\(aq, info=None) +Used when error occurred during power on +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.VMwareRuntimeError(message=u\(aq\(aq, info=None) Used when a runtime error is encountered when communicating with the vCenter .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.VMwareSaltError(message=\(aq\(aq, info=None) +.B exception salt.exceptions.VMwareSaltError(message=u\(aq\(aq, info=None) Used when a VMware object cannot be retrieved .UNINDENT .INDENT 0.0 .TP -.B exception salt.exceptions.VMwareSystemError(message=\(aq\(aq, info=None) +.B exception salt.exceptions.VMwareSystemError(message=u\(aq\(aq, info=None) Used when representing a generic VMware system error .UNINDENT .INDENT 0.0 .TP +.B exception salt.exceptions.VMwareVmCreationError(message=u\(aq\(aq, info=None) +Used when a configuration parameter is incorrect +.UNINDENT +.INDENT 0.0 +.TP +.B exception salt.exceptions.VMwareVmRegisterError(message=u\(aq\(aq, info=None) +Used when a configuration parameter is incorrect +.UNINDENT +.INDENT 0.0 +.TP .B salt.exceptions.get_error_message(error) Get human readable message from Python Exception .UNINDENT @@ -350661,6 +372576,2292 @@ information about the version numbering scheme. .sp Release Candidate .SS Previous Releases +.SS Salt 2018.3.0 Release Notes \- Codename Oxygen +.SS Lots of Docker Improvements +.SS Much Improved Support for Docker Networking +.sp +The \fBdocker_network.present\fP +state has undergone a full rewrite, which includes the following improvements: +.SS Full API Support for Network Management +.sp +The improvements made to input handling in the +\fBdocker_container.running\fP +state for 2017.7.0 have now been expanded to \fBdocker_network.present\fP\&. This brings with it full support for all +tunable configuration arguments. +.SS Custom Subnets +.sp +Custom subnets can now be configured. Both IPv4 and mixed IPv4/IPv6 networks +are supported. See here for +more information. +.SS Network Configuration in \fBdocker_container.running()\fP States +.sp +A long\-requested feature has finally been added! It is now possible to +configure static IPv4/IPv6 addresses, as well as links and labels. See +here for more +information. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +While the \fBcontainers\fP argument to \fBdocker_network.present()\fP +will continue to be supported, it will no longer be the recommended way of +ensuring that a container is attached to a network. +.UNINDENT +.UNINDENT +.SS Improved Handling of Images from Custom Registries +.sp +Rather than attempting to parse the tag from the passed image name, Salt will +now resolve that tag down to an image ID and use that ID instead. +.sp +\fBIMPORTANT:\fP +.INDENT 0.0 +.INDENT 3.5 +Due to this change, there are some backward\-incompatible changes to image +management. See below for a full list of these changes. +.UNINDENT +.UNINDENT +.SS Backward\-incompatible Changes to Docker Image Management +.sp +Passing image names to the following functions must now be done using separate +\fBrepository\fP and \fBtag\fP arguments: +.INDENT 0.0 +.IP \(bu 2 +\fBdocker.build\fP +.IP \(bu 2 +\fBdocker.commit\fP +.IP \(bu 2 +\fBdocker.import\fP +.IP \(bu 2 +\fBdocker.load\fP +.IP \(bu 2 +\fBdocker.tag\fP +.IP \(bu 2 +\fBdocker.sls_build\fP +.UNINDENT +.sp +Additionally, the \fBtag\fP argument must now be explicitly passed to the +\fBdocker_image.present\fP state, +unless the image is being pulled from a docker registry. +.SS \fButils\fP functions moved into separate modules +.sp +The Salt utility functions from \fBsalt.utils\fP have been moved into different +modules, grouped logically based on their functionality. This change is +backwards compatible, but the old imports will no longer be supported starting +with release Neon. +.sp +The functions have been moved as follows: +.INDENT 0.0 +.IP \(bu 2 +\fBsalt.utils.appendproctitle\fP: use \fBsalt.utils.process.appendproctitle\fP +instead. +.IP \(bu 2 +\fBsalt.utils.daemonize\fP: use \fBsalt.utils.process.daemonize\fP instead. +.IP \(bu 2 +\fBsalt.utils.daemonize_if\fP: use \fBsalt.utils.process.daemonize_if\fP instead. +.IP \(bu 2 +\fBsalt.utils.reinit_crypto\fP: use \fBsalt.utils.crypt.reinit_crypto\fP instead. +.IP \(bu 2 +\fBsalt.utils.pem_finger\fP: use \fBsalt.utils.crypt.pem_finger\fP instead. +.IP \(bu 2 +\fBsalt.utils.to_bytes\fP: use \fBsalt.utils.stringutils.to_bytes\fP instead. +.IP \(bu 2 +\fBsalt.utils.to_str\fP: use \fBsalt.utils.stringutils.to_str\fP instead. +.IP \(bu 2 +\fBsalt.utils.to_unicode\fP: use \fBsalt.utils.stringutils.to_unicode\fP instead. +.IP \(bu 2 +\fBsalt.utils.str_to_num\fP: use \fBsalt.utils.stringutils.to_num\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_quoted\fP: use \fBsalt.utils.stringutils.is_quoted\fP instead. +.IP \(bu 2 +\fBsalt.utils.dequote\fP: use \fBsalt.utils.stringutils.dequote\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_hex\fP: use \fBsalt.utils.stringutils.is_hex\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_bin_str\fP: use \fBsalt.utils.stringutils.is_bin_str\fP instead. +.IP \(bu 2 +\fBsalt.utils.rand_string\fP: use \fBsalt.utils.stringutils.random\fP instead. +.IP \(bu 2 +\fBsalt.utils.contains_whitespace\fP: use +\fBsalt.utils.stringutils.contains_whitespace\fP instead. +.IP \(bu 2 +\fBsalt.utils.build_whitespace_split_regex\fP: use +\fBsalt.utils.stringutils.build_whitespace_split_regex\fP instead. +.IP \(bu 2 +\fBsalt.utils.expr_match\fP: use \fBsalt.utils.stringutils.expr_match\fP instead. +.IP \(bu 2 +\fBsalt.utils.check_whitelist_blacklist\fP: use +\fBsalt.utils.stringutils.check_whitelist_blacklist\fP instead. +.IP \(bu 2 +\fBsalt.utils.check_include_exclude\fP: use +\fBsalt.utils.stringutils.check_include_exclude\fP instead. +.IP \(bu 2 +\fBsalt.utils.print_cli\fP: use \fBsalt.utils.stringutils.print_cli\fP instead. +.IP \(bu 2 +\fBsalt.utils.clean_kwargs\fP: use \fBsalt.utils.args.clean_kwargs\fP instead. +.IP \(bu 2 +\fBsalt.utils.invalid_kwargs\fP: use \fBsalt.utils.args.invalid_kwargs\fP +instead. +.IP \(bu 2 +\fBsalt.utils.shlex_split\fP: use \fBsalt.utils.args.shlex_split\fP instead. +.IP \(bu 2 +\fBsalt.utils.arg_lookup\fP: use \fBsalt.utils.args.arg_lookup\fP instead. +.IP \(bu 2 +\fBsalt.utils.argspec_report\fP: use \fBsalt.utils.args.argspec_report\fP +instead. +.IP \(bu 2 +\fBsalt.utils.split_input\fP: use \fBsalt.utils.args.split_input\fP instead. +.IP \(bu 2 +\fBsalt.utils.test_mode\fP: use \fBsalt.utils.args.test_mode\fP instead. +.IP \(bu 2 +\fBsalt.utils.format_call\fP: use \fBsalt.utils.args.format_call\fP instead. +.IP \(bu 2 +\fBsalt.utils.which\fP: use \fBsalt.utils.path.which\fP instead. +.IP \(bu 2 +\fBsalt.utils.which_bin\fP: use \fBsalt.utils.path.which_bin\fP instead. +.IP \(bu 2 +\fBsalt.utils.path_join\fP: use \fBsalt.utils.path.join\fP instead. +.IP \(bu 2 +\fBsalt.utils.check_or_die\fP: use \fBsalt.utils.path.check_or_die\fP instead. +.IP \(bu 2 +\fBsalt.utils.sanitize_win_path_string\fP: use +\fBsalt.utils.path.sanitize_win_path\fP instead. +.IP \(bu 2 +\fBsalt.utils.rand_str\fP: use \fBsalt.utils.hashutils.random_hash\fP instead. +.IP \(bu 2 +\fBsalt.utils.get_hash\fP: use \fBsalt.utils.hashutils.get_hash\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_windows\fP: use \fBsalt.utils.platform.is_windows\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_proxy\fP: use \fBsalt.utils.platform.is_proxy\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_linux\fP: use \fBsalt.utils.platform.is_linux\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_darwin\fP: use \fBsalt.utils.platform.is_darwin\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_sunos\fP: use \fBsalt.utils.platform.is_sunos\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_smartos\fP: use \fBsalt.utils.platform.is_smartos\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_smartos_globalzone\fP: use +\fBsalt.utils.platform.is_smartos_globalzone\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_smartos_zone\fP: use \fBsalt.utils.platform.is_smartos_zone\fP +instead. +.IP \(bu 2 +\fBsalt.utils.is_freebsd\fP: use \fBsalt.utils.platform.is_freebsd\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_netbsd\fP: use \fBsalt.utils.platform.is_netbsd\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_openbsd\fP: use \fBsalt.utils.platform.is_openbsd\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_aix\fP: use \fBsalt.utils.platform.is_aix\fP instead. +.IP \(bu 2 +\fBsalt.utils.safe_rm\fP: use \fBsalt.utils.files.safe_rm\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_empty\fP: use \fBsalt.utils.files.is_empty\fP instead. +.IP \(bu 2 +\fBsalt.utils.fopen\fP: use \fBsalt.utils.files.fopen\fP instead. +.IP \(bu 2 +\fBsalt.utils.flopen\fP: use \fBsalt.utils.files.flopen\fP instead. +.IP \(bu 2 +\fBsalt.utils.fpopen\fP: use \fBsalt.utils.files.fpopen\fP instead. +.IP \(bu 2 +\fBsalt.utils.rm_rf\fP: use \fBsalt.utils.files.rm_rf\fP instead. +.IP \(bu 2 +\fBsalt.utils.mkstemp\fP: use \fBsalt.utils.files.mkstemp\fP instead. +.IP \(bu 2 +\fBsalt.utils.istextfile\fP: use \fBsalt.utils.files.is_text_file\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_bin_file\fP: use \fBsalt.utils.files.is_binary\fP instead. +.IP \(bu 2 +\fBsalt.utils.list_files\fP: use \fBsalt.utils.files.list_files\fP instead. +.IP \(bu 2 +\fBsalt.utils.safe_walk\fP: use \fBsalt.utils.files.safe_walk\fP instead. +.IP \(bu 2 +\fBsalt.utils.st_mode_to_octal\fP: use \fBsalt.utils.files.st_mode_to_octal\fP +instead. +.IP \(bu 2 +\fBsalt.utils.normalize_mode\fP: use \fBsalt.utils.files.normalize_mode\fP +instead. +.IP \(bu 2 +\fBsalt.utils.human_size_to_bytes\fP: use +\fBsalt.utils.files.human_size_to_bytes\fP instead. +.IP \(bu 2 +\fBsalt.utils.backup_minion\fP: use \fBsalt.utils.files.backup_minion\fP instead. +.IP \(bu 2 +\fBsalt.utils.str_version_to_evr\fP: use \fBsalt.utils.pkg.rpm.version_to_evr\fP +instead. +.IP \(bu 2 +\fBsalt.utils.parse_docstring\fP: use \fBsalt.utils.doc.parse_docstring\fP +instead. +.IP \(bu 2 +\fBsalt.utils.compare_versions\fP: use \fBsalt.utils.versions.compare\fP instead. +.IP \(bu 2 +\fBsalt.utils.version_cmp\fP: use \fBsalt.utils.versions.version_cmp\fP instead. +.IP \(bu 2 +\fBsalt.utils.warn_until\fP: use \fBsalt.utils.versions.warn_until\fP instead. +.IP \(bu 2 +\fBsalt.utils.kwargs_warn_until\fP: use +\fBsalt.utils.versions.kwargs_warn_until\fP instead. +.IP \(bu 2 +\fBsalt.utils.get_color_theme\fP: use \fBsalt.utils.color.get_color_theme\fP +instead. +.IP \(bu 2 +\fBsalt.utils.get_colors\fP: use \fBsalt.utils.color.get_colors\fP instead. +.IP \(bu 2 +\fBsalt.utils.gen_state_tag\fP: use \fBsalt.utils.state.gen_tag\fP instead. +.IP \(bu 2 +\fBsalt.utils.search_onfail_requisites\fP: use +\fBsalt.utils.state.search_onfail_requisites\fP instead. +.IP \(bu 2 +\fBsalt.utils.check_state_result\fP: use \fBsalt.utils.state.check_result\fP +instead. +.IP \(bu 2 +\fBsalt.utils.get_user\fP: use \fBsalt.utils.user.get_user\fP instead. +.IP \(bu 2 +\fBsalt.utils.get_uid\fP: use \fBsalt.utils.user.get_uid\fP instead. +.IP \(bu 2 +\fBsalt.utils.get_specific_user\fP: use \fBsalt.utils.user.get_specific_user\fP +instead. +.IP \(bu 2 +\fBsalt.utils.chugid\fP: use \fBsalt.utils.user.chugid\fP instead. +.IP \(bu 2 +\fBsalt.utils.chugid_and_umask\fP: use \fBsalt.utils.user.chugid_and_umask\fP +instead. +.IP \(bu 2 +\fBsalt.utils.get_default_group\fP: use \fBsalt.utils.user.get_default_group\fP +instead. +.IP \(bu 2 +\fBsalt.utils.get_group_list\fP: use \fBsalt.utils.user.get_group_list\fP +instead. +.IP \(bu 2 +\fBsalt.utils.get_group_dict\fP: use \fBsalt.utils.user.get_group_dict\fP +instead. +.IP \(bu 2 +\fBsalt.utils.get_gid_list\fP: use \fBsalt.utils.user.get_gid_list\fP instead. +.IP \(bu 2 +\fBsalt.utils.get_gid\fP: use \fBsalt.utils.user.get_gid\fP instead. +.IP \(bu 2 +\fBsalt.utils.enable_ctrl_logoff_handler\fP: use +\fBsalt.utils.win_functions.enable_ctrl_logoff_handler\fP instead. +.IP \(bu 2 +\fBsalt.utils.traverse_dict\fP: use \fBsalt.utils.data.traverse_dict\fP instead. +.IP \(bu 2 +\fBsalt.utils.traverse_dict_and_list\fP: use +\fBsalt.utils.data.traverse_dict_and_list\fP instead. +.IP \(bu 2 +\fBsalt.utils.filter_by\fP: use \fBsalt.utils.data.filter_by\fP instead. +.IP \(bu 2 +\fBsalt.utils.subdict_match\fP: use \fBsalt.utils.data.subdict_match\fP instead. +.IP \(bu 2 +\fBsalt.utils.substr_in_list\fP: use \fBsalt.utils.data.substr_in_list\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_dictlist\fP: use \fBsalt.utils.data.is_dictlist\fP\&. +.IP \(bu 2 +\fBsalt.utils.repack_dictlist\fP: use \fBsalt.utils.data.repack_dictlist\fP +instead. +.IP \(bu 2 +\fBsalt.utils.compare_dicts\fP: use \fBsalt.utils.data.compare_dicts\fP instead. +.IP \(bu 2 +\fBsalt.utils.compare_lists\fP: use \fBsalt.utils.data.compare_lists\fP instead. +.IP \(bu 2 +\fBsalt.utils.decode_dict\fP: use \fBsalt.utils.data.encode_dict\fP instead. +.IP \(bu 2 +\fBsalt.utils.decode_list\fP: use \fBsalt.utils.data.encode_list\fP instead. +.IP \(bu 2 +\fBsalt.utils.exactly_n\fP: use \fBsalt.utils.data.exactly_n\fP instead. +.IP \(bu 2 +\fBsalt.utils.exactly_one\fP: use \fBsalt.utils.data.exactly_one\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_list\fP: use \fBsalt.utils.data.is_list\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_iter\fP: use \fBsalt.utils.data.is_iter\fP instead. +.IP \(bu 2 +\fBsalt.utils.isorted\fP: use \fBsalt.utils.data.sorted_ignorecase\fP instead. +.IP \(bu 2 +\fBsalt.utils.is_true\fP: use \fBsalt.utils.data.is_true\fP instead. +.IP \(bu 2 +\fBsalt.utils.mysql_to_dict\fP: use \fBsalt.utils.data.mysql_to_dict\fP instead. +.IP \(bu 2 +\fBsalt.utils.simple_types_filter\fP: use +\fBsalt.utils.data.simple_types_filter\fP instead. +.IP \(bu 2 +\fBsalt.utils.ip_bracket\fP: use \fBsalt.utils.zeromq.ip_bracket\fP instead. +.IP \(bu 2 +\fBsalt.utils.gen_mac\fP: use \fBsalt.utils.network.gen_mac\fP instead. +.IP \(bu 2 +\fBsalt.utils.mac_str_to_bytes\fP: use \fBsalt.utils.network.mac_str_to_bytes\fP +instead. +.IP \(bu 2 +\fBsalt.utils.refresh_dns\fP: use \fBsalt.utils.network.refresh_dns\fP instead. +.IP \(bu 2 +\fBsalt.utils.dns_check\fP: use \fBsalt.utils.network.dns_check\fP instead. +.IP \(bu 2 +\fBsalt.utils.get_context\fP: use \fBsalt.utils.stringutils.get_context\fP instead. +.IP \(bu 2 +\fBsalt.utils.get_master_key\fP: use \fBsalt.utils.master.get_master_key\fP +instead. +.IP \(bu 2 +\fBsalt.utils.get_values_of_matching_keys\fP: use +\fBsalt.utils.master.get_values_of_matching_keys\fP instead. +.IP \(bu 2 +\fBsalt.utils.date_cast\fP: use \fBsalt.utils.dateutils.date_cast\fP instead. +.IP \(bu 2 +\fBsalt.utils.date_format\fP: use \fBsalt.utils.dateutils.strftime\fP instead. +.IP \(bu 2 +\fBsalt.utils.total_seconds\fP: use \fBsalt.utils.dateutils.total_seconds\fP +instead. +.IP \(bu 2 +\fBsalt.utils.find_json\fP: use \fBsalt.utils.json.find_json\fP instead. +.IP \(bu 2 +\fBsalt.utils.import_json\fP: use \fBsalt.utils.json.import_json\fP instead. +.IP \(bu 2 +\fBsalt.utils.namespaced_function\fP: use +\fBsalt.utils.functools.namespaced_function\fP instead. +.IP \(bu 2 +\fBsalt.utils.alias_function\fP: use \fBsalt.utils.functools.alias_function\fP +instead. +.IP \(bu 2 +\fBsalt.utils.profile_func\fP: use \fBsalt.utils.profile.profile_func\fP instead. +.IP \(bu 2 +\fBsalt.utils.activate_profile\fP: use \fBsalt.utils.profile.activate_profile\fP +instead. +.IP \(bu 2 +\fBsalt.utils.output_profile\fP: use \fBsalt.utils.profile.output_profile\fP +instead. +.UNINDENT +.SS State and Execution Module Support for \fBdocker run\fP Functionality +.sp +The \fBdocker_container.running\fP +state is good for containers which run services, but it is not as useful for +cases in which the container only needs to run once. The \fBstart\fP argument to +\fBdocker_container.running\fP can +be set to \fBFalse\fP to prevent the container from being started again on a +subsequent run, but for many use cases this is not sufficient. Therefore, the +\fBdocker.run_container\fP +remote\-execution function was added. When used on the Salt CLI, it will return +information about the container, such as its name, ID, exit code, and any +output it produces. +.sp +State support has also been added via the \fBdocker_container.run\fP state. This state is modeled after the +\fBcmd.run\fP state, and includes arguments like +\fBonlyif\fP, \fBunless\fP, and \fBcreates\fP to control whether or not the container +is run. +.SS Full API Support for \fBdocker.logs\fP +.sp +This function now supports all of the functions that its Docker API counterpart +does, allowing you to do things like include timestamps, and also suppress +stdout/stderr, etc. in the return. +.SS \fIstart\fP Argument Added to \fBdocker.create\fP Function +.sp +This removes the need to run \fBdocker.start\fP separately when creating containers on the +Salt CLI. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion docker.create image=foo/bar:baz command=/path/to/command start=True +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Use SaltSSH Minions like regular Master\-Minions +.sp +The Master process can now also call SSH minions as if they were connected to +the master using ZeroMQ. By setting \fIenable_ssh_minions: True\fP in the the +master config file, the master will create a SaltSSH client process which +connects to the minion and returns the output for the \fIsalt\fP commandline to use +like a regular minion. This can be used anywhere the LocalClient is used. +.SS Exceptions Raised for Authentication/Authorization Errors +.sp +When sending \fBpublish\fP commands via \fBmaster.py\fP and \fBmasterapi.py\fP and an +authorization or authentication problem is encountered, Salt will now raise the +appropriate exceptions instead of returning an empty string: \fB\(aq\(aq\fP\&. +.sp +The reasoning behind this change is to make it easier to debug various scenarios +surrounding authentication and authorization issues more effectively. +.SS Comparison Operators in Package Installation +.sp +Salt now supports using comparison operators (e.g. \fB>=1.2.3\fP) when installing +packages on minions which use \fByum/dnf\fP or +\fBapt\fP\&. This is supported both in the +\fBpkg.installed\fP state and in the \fBpkg.install\fP +remote execution function. +.SS Master Tops Changes +.sp +When both Master Tops and a +Top File produce SLS matches for a given minion, the matches +were being merged in an unpredictable manner which did not preserve ordering. This has +been changed. The top file matches now execute in the expected order, followed +by any master tops matches that are not matched via a top file. +.sp +To make master tops matches execute first, followed by top file matches, set +the new \fBmaster_tops_first\fP minion config option to \fBTrue\fP\&. +.SS Several Jinja Filters Renamed +.sp +The following Jinja filters (originally added in 2017.7.0) have been renamed +due to the fact that they were inaccurately named when initially added. The +original names will be supported until the Neon release of Salt. +.INDENT 0.0 +.IP \(bu 2 +\fBrand_str\fP renamed to \fBrandom_hash\fP +.IP \(bu 2 +\fBjinja_decode_dict\fP renamed to \fBjinja_encode_dict\fP +.IP \(bu 2 +\fBjinja_decode_list\fP renamed to \fBjinja_encode_list\fP +.UNINDENT +.SS Return Codes for Runner/Wheel Functions +.sp +When using orchestration, runner and wheel +functions used to report a \fBTrue\fP result if the function ran to completion +without raising an exception. It is now possible to set a return code in the +\fB__context__\fP dictionary, allowing runner and wheel functions to report that +they failed. Here\(aqs some example pseudocode: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +def myrunner(): + ... + do stuff + ... + if some_error_condition: + __context__[\(aqretcode\(aq] = 1 + return result +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Variable Update Intervals for Fileserver Backends +.sp +Prior to this release, fileservers would be updated as part of a dedicated +"maintenance" process, in which various routine maintenance tasks were +performed. This tied the update interval to the \fBloop_interval\fP +config option, and also forced all fileservers to update at the same interval. +.sp +2018.3.0 adds the following configuration options for the various fileserver +backends: +.INDENT 0.0 +.IP \(bu 2 +\fBroots_update_interval\fP +.IP \(bu 2 +\fBazurefs_update_interval\fP +.IP \(bu 2 +\fBgitfs_update_interval\fP +.IP \(bu 2 +\fBhgfs_update_interval\fP +.IP \(bu 2 +\fBminionfs_update_interval\fP +.IP \(bu 2 +\fBs3fs_update_interval\fP +.IP \(bu 2 +\fBsvnfs_update_interval\fP +.UNINDENT +.sp +These allow for update intervals to be set for each individual backend. The +default value for each of these is 60 seconds. +.sp +In addition, for GitFS it is also possible to apply +intervals to individual remotes. See here for +examples. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +git_pillar does not yet support variable update intervals, this is targeted +for the next feature release (Fluorine). +.UNINDENT +.UNINDENT +.SS LDAP via External Authentication Changes +.sp +In this release of Salt, if LDAP Bind Credentials are supplied, then +these credentials will be used for all LDAP access except the first +authentication when a job is submitted. The first authentication will +use the user\(aqs credentials as passed on the CLI. This behavior is to +accommodate certain two\-factor authentication schemes where the authentication +token can only be used once. +.sp +In previous releases the bind credentials would only be used to determine +the LDAP user\(aqs existence and group membership. The user\(aqs LDAP credentials +were used from then on. +.SS Stormpath External Authentication Removed +.sp +Per Stormpath\(aqs announcement, their API will be shutting down on 8/17/2017 at +noon PST so the Stormpath external authentication module has been removed. +.sp +\fI\%https://stormpath.com/oktaplusstormpath\fP +.SS New (Proxy) Minion Configuration Options +.sp +To be able to connect the Minion to the Master using a certain source IP address +or port, the following options have been added: +.INDENT 0.0 +.IP \(bu 2 +\fBsource_interface_name\fP +.IP \(bu 2 +\fBsource_address\fP +.IP \(bu 2 +\fBsource_ret_port\fP +.IP \(bu 2 +\fBsource_publish_port\fP +.UNINDENT +.SS \fBenvironment\fP config option renamed to \fBsaltenv\fP +.sp +The \fBenvironment\fP config option predates referring to a salt +fileserver environment as a \fBsaltenv\fP\&. To pin a minion to a single +environment for running states, one would use \fBenvironment\fP, but +overriding that environment would be done with the \fBsaltenv\fP argument. For +consistency, \fBenvironment\fP is now simply referred to as +\fBsaltenv\fP\&. There are no plans to deprecate or remove +\fBenvironment\fP, if used it will log a warning and its value will be +used as \fBsaltenv\fP\&. +.SS \fBlock_saltenv\fP config option added +.sp +If set to \fBTrue\fP, this option will prevent a minion from allowing the +\fBsaltenv\fP argument to override the value set in \fBsaltenv\fP when +running states. +.SS Failed Minions for State/Function Orchestration Jobs Added to Changes Dictionary +.sp +For orchestration jobs which run states (or run remote execution functions and +also use a fail function to indicate +success or failure), minions which have \fBFalse\fP results were previously +included as a formatted string in the comment field of the return for that +orchestration job. This made the failed returns difficult to parse +programatically\&. The +failed returns in these cases are now included in the changes dictionary, +making for much easier parsing. +.SS New Grains +.sp +New core grains have been added to expose any storage inititator setting. +.sp +The new grains added are: +.INDENT 0.0 +.IP \(bu 2 +\fBfc_wwn\fP: Show all fibre channel world wide port names for a host +.IP \(bu 2 +\fBiscsi_iqn\fP: Show the iSCSI IQN name for a host +.IP \(bu 2 +\fBswap_total\fP: Show the configured swap_total for Linux, *BSD, OS X and Solaris/SunOS +.UNINDENT +.SS Salt Minion Auto\-discovery +.sp +Using auto\-discovery, the Salt Minion now no longer needs to be configured +against a specific DNS name or IP address of a Master. +.sp +For this feature Salt Master now requires port 4520 for UDP broadcast packets to be opened +and the Salt Minion be able to send UDP packets to the same port. +.SS Configuration +.sp +By default, automatic discovery is disabled. +.INDENT 0.0 +.TP +.B \&..warning:: +Due to the current limitations that will be changing in a future, before you turn on auto\-discovery, +make sure your network is secured and trusted. +.UNINDENT +.sp +Auto\-discovery is configured on Master and Minion. Both of them are configured via the \fBdiscovery\fP option +as follows: +.sp +\fBMaster configuration\fP +.sp +To use the default configuration, which accepts any minion, simply set \fBdiscovery\fP to True: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +discovery: true +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +A sub\-option called \fImapping\fP allows auto\-discovery to help find the proper +Master. The mapping contains an arbitrary set of key/value pairs, which the +Minion configuration can target. By default, no mappings are set. +.sp +Example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +discovery: + mapping: + description: SES 5.0 + node: 1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +It is also possible to change the port used from the default of \fB4520\fP, by +setting a \fBport\fP option under the Master\(aqs \fBdiscovery\fP configuration: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +discovery: + port: 4567 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +When using a port number other than the default, the Minion\(aqs \fBdiscovery\fP +configuraton must \fIalso\fP have a port specified, otherwise the Minion will +still attempt to contact the Master on port \fB4520\fP\&. +.UNINDENT +.UNINDENT +.sp +\fBMinion configuration\fP +.sp +In addition to the \fBmapping\fP and \fBport\fP options, the following additional options are available to Minions: +.INDENT 0.0 +.IP \(bu 2 +\fBattempts\fP \- This option specifies how many broadcast requests should be +sent to the network, waiting for any Master response. Each attempt takes a +couple of seconds, so raising this value may result in a slower Minion +startup. Note that, on a properly\-configured network, autodiscovery should +succeed on the first attempt. By default, this value is set to \fB3\fP\&. +.IP \(bu 2 +\fBmatch\fP \- This option can be set to either \fBall\fP or \fBany\fP, and it +determines how the values configured in \fBmapping\fP are matched. If set to +\fBall\fP, then all of the key/value pairs in the Minion\(aqs \fBmapping\fP must +match a given Master. If set to \fBany\fP (the default), then any match to a +key/value mapping will constitute a match. +.IP \(bu 2 +\fBpause\fP \- The interval in seconds between attempts (default: 5). +.UNINDENT +.SS Connection to a type instead of DNS +.sp +By now each Minion was connecting to a Master by DNS or IP address. From now on it is possible +also to connect to a _type_ of a Master. For example, in a network there are three different +Masters, each corresponds for a particular niche or environment or specific role etc. The Minion +is supposed to connect only to one of those Masters that is described approriately. +.sp +To achieve such an effect, each \fI/etc/salt/master\fP configuration should have a \fIdiscovery\fP option, +which should have a \fImapping\fP element with arbitrary key/value pairs. The same configuration should +be on the Minion, so then when mapping matches, Minion recognises Master as its connection target. +.sp +Example for Master configuration (\fI/etc/salt/master\fP): +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +discovery: + mapping: + description: SES 5.0 + node: 1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The example above describes a system that is running a particular product, where \fIdescription\fP is +an arbitrary key and \fISES 5.0\fP is just a string. In order to match exactly this Master, the +following configuration at Minion should be present: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +discovery: + match: all # Can be "all" or "any" + mapping: + description: SES 5.0 + node: 1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Notice \fImatch\fP criteria is set to \fIall\fP\&. This would mean that from all found Masters select only +that, which \fIdescription\fP is set to \fISES 5.0\fP _and_ \fInode\fP is set to \fI1\fP\&. All other Masters will +be ignored. +.SS Limitations +.sp +This feature has a couple of _temporary_ limitations that are subject to change in the future: +.INDENT 0.0 +.IP \(bu 2 +Only one Master on the network is supported. Currently the Minion cannot select which Master +out of few the same to choose. This will change to choosing the Master that is least loaded. +.IP \(bu 2 +Minions will accept _any_ master that matches connection criteria without any particular +security applied (priv/pub key check, signature, fingerprint etc). That implies that administrator +is expected to know his network and make sure it is clean. +.UNINDENT +.SS Grains Changes +.INDENT 0.0 +.IP \(bu 2 +The \fBvirtual\fP grain identifies reports KVM and VMM hypervisors when running +an OpenBSD guest +.UNINDENT +.SS New Modules +.INDENT 0.0 +.IP \(bu 2 +\fBsalt.modules.purefa\fP +.UNINDENT +.SS New NaCl Renderer +.sp +A new renderer has been added for encrypted data. +.SS New support for Cisco UCS Chassis +.sp +The salt proxy minion now allows for control of Cisco USC chassis. See +the \fBcimc\fP modules for details. +.SS New support for Cassandra v3 +.sp +The \fBcassandra_cql\fP module now supports Cassandra v3 which has changed +its internal schema to define keyspaces and columns. +.SS New salt\-ssh roster +.sp +A new roster has been added that allows users to pull in a list of hosts +for salt\-ssh targeting from a \fB~/.ssh\fP configuration. For full details, +please see the \fBsshconfig\fP roster. +.SS New GitFS Features +.sp +Two new features which affect how GitFS maps branches/tags to fileserver +environments (i.e. \fBsaltenvs\fP) have been added: +.INDENT 0.0 +.IP 1. 3 +It is now possible to completely turn off Salt\(aqs default mapping logic +(aside from the mapping of the \fBbase\fP saltenv). This can be triggered +using the new \fBgitfs_disable_saltenv_mapping\fP config option. +.sp +\fBNOTE:\fP +.INDENT 3.0 +.INDENT 3.5 +When this is disabled, only the \fBbase\fP saltenv and any configured +using per\-saltenv configuration parameters will be available. +.UNINDENT +.UNINDENT +.IP 2. 3 +The types of refs which Salt will use as saltenvs can now be controlled. In +previous releases, branches and tags were both mapped as environments, and +individual commit SHAs could be specified as saltenvs in states (and when +caching files using \fBcp.cache_file\fP). +Using the new \fBgitfs_ref_types\fP config option, the types of +refs which are used as saltenvs can be restricted. This makes it possible to +ignore all tags and use branches only, and also to keep SHAs from being made +available as saltenvs. +.UNINDENT +.SS Additional output modes +.sp +The \fBstate_output\fP parameter now supports \fBfull_id\fP, \fBchanges_id\fP and \fBterse_id\fP\&. +Just like \fBmixed_id\fP, these use the state ID as name in the highstate output. +For more information on these output modes, see the docs for the \fBHighstate Outputter\fP\&. +.SS Windows Installer: Changes to existing config handling +.sp +Behavior with existing configuration has changed. With previous installers the +existing config was used and the master and minion id could be modified via the +installer. It was problematic in that it didn\(aqt account for configuration that +may be defined in the \fBminion.d\fP directory. This change gives you the option +via a checkbox to either use the existing config with out changes or the default +config using values you pass to the installer. If you choose to use the existing +config then no changes are made. If not, the existing config is deleted, to +include the \fBminion.d\fP directory, and the default config is used. A +command\-line switch (\fB/use\-existing\-config\fP) has also been added to control +this behavior. +.SS Windows Installer: Multi\-master configuration +.sp +The installer now has the ability to apply a multi\-master configuration either +from the gui or the command line. The \fBmaster\fP field in the gui can accept +either a single master or a comma\-separated list of masters. The command\-line +switch (\fB/master=\fP) can accept the same. +.SS Windows Installer: Command\-line help +.sp +The Windows installer will now display command\-line help when a help switch +(\fB/?\fP) is passed. +.SS Salt Cloud Features +.SS Pre\-Flight Commands +.sp +Support has been added for specified "preflight commands" to run on a VM before +the deploy script is run. These must be defined as a list in a cloud configuration +file. For example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my\-cloud\-profile: + provider: linode\-config + image: Ubuntu 16.04 LTS + size: Linode 2048 + preflight_cmds: + \- whoami + \- echo \(aqhello world!\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +These commands will run in sequence \fBbefore\fP the bootstrap script is executed. +.SS New salt\-cloud Grains +.sp +When salt cloud creates a new minon, it will now add grain information +to the minion configuration file, identifying the resources originally used +to create it. +.sp +The generated grain information will appear similar to: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +grains: + salt\-cloud: + driver: ec2 + provider: my_ec2:ec2 + profile: ec2\-web +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The generation of salt\-cloud grains can be surpressed by the +option \fBenable_cloud_grains: \(aqFalse\(aq\fP in the cloud configuration file. +.SS Upgraded Saltify Driver +.sp +The salt\-cloud Saltify driver is used to provision machines which +are not controlled by a dedicated cloud supervisor (such as typical hardware +machines) by pushing a salt\-bootstrap command to them and accepting them on +the salt master. Creation of a node has been its only function and no other +salt\-cloud commands were implemented. +.sp +With this upgrade, it can use the salt\-api to provide advanced control, +such as rebooting a machine, querying it along with conventional cloud minions, +and, ultimately, disconnecting it from its master. +.sp +After disconnection from ("destroying" on) one master, a machine can be +re\-purposed by connecting to ("creating" on) a subsequent master. +.SS New Vagrant Driver +.sp +The salt\-cloud Vagrant driver brings virtual machines running in a limited +environment, such as a programmer\(aqs workstation, under salt\-cloud control. +This can be useful for experimentation, instruction, or testing salt configurations. +.sp +Using salt\-api on the master, and a salt\-minion running on the host computer, +the Vagrant driver can create (\fBvagrant up\fP), restart (\fBvagrant reload\fP), +and destroy (\fBvagrant destroy\fP) VMs, as controlled by salt\-cloud profiles +which designate a \fBVagrantfile\fP on the host machine. +.sp +The master can be a very limited machine, such as a Raspberry Pi, or a small +VagrantBox VM. +.SS New pillar/master_tops module called saltclass +.sp +This module clones the behaviour of reclass (\fI\%http://reclass.pantsfullofunix.net/\fP), without the need of an external app, and add several features to improve flexibility. +Saltclass lets you define your nodes from simple \fByaml\fP files (\fB\&.yml\fP) through hierarchical class inheritance with the possibility to override pillars down the tree. +.sp +\fBFeatures\fP +.INDENT 0.0 +.IP \(bu 2 +Define your nodes through hierarchical class inheritance +.IP \(bu 2 +.INDENT 2.0 +.TP +.B Reuse your reclass datas with minimal modifications +.INDENT 7.0 +.IP \(bu 2 +applications => states +.IP \(bu 2 +parameters => pillars +.UNINDENT +.UNINDENT +.IP \(bu 2 +Use Jinja templating in your yaml definitions +.IP \(bu 2 +.INDENT 2.0 +.TP +.B Access to the following Salt objects in Jinja +.INDENT 7.0 +.IP \(bu 2 +\fB__opts__\fP +.IP \(bu 2 +\fB__salt__\fP +.IP \(bu 2 +\fB__grains__\fP +.IP \(bu 2 +\fB__pillars__\fP +.IP \(bu 2 +\fBminion_id\fP +.UNINDENT +.UNINDENT +.IP \(bu 2 +Chose how to merge or override your lists using ^ character (see examples) +.IP \(bu 2 +Expand variables ${} with possibility to escape them if needed ${} (see examples) +.IP \(bu 2 +Ignores missing node/class and will simply return empty without breaking the pillar module completely \- will be logged +.UNINDENT +.sp +An example subset of datas is available here: \fI\%http://git.mauras.ch/salt/saltclass/src/master/examples\fP +.TS +center; +|l|l|. +_ +T{ +Terms usable in yaml files +T} T{ +Description +T} +_ +T{ +classes +T} T{ +A list of classes that will be processed in order +T} +_ +T{ +states +T} T{ +A list of states that will be returned by master_tops function +T} +_ +T{ +pillars +T} T{ +A yaml dictionnary that will be returned by the ext_pillar function +T} +_ +T{ +environment +T} T{ +Node saltenv that will be used by master_tops +T} +_ +.TE +.sp +A class consists of: +.INDENT 0.0 +.IP \(bu 2 +zero or more parent classes +.IP \(bu 2 +zero or more states +.IP \(bu 2 +any number of pillars +.UNINDENT +.sp +A child class can override pillars from a parent class. +A node definition is a class in itself with an added \fBenvironment\fP parameter for \fBsaltenv\fP definition. +.sp +\fBclass names\fP +.sp +Class names mimic salt way of defining states and pillar files. +This means that \fBdefault.users\fP class name will correspond to one of these: +.INDENT 0.0 +.IP \(bu 2 +\fB/classes/default/users.yml\fP +.IP \(bu 2 +\fB/classes/default/users/init.yml\fP +.UNINDENT +.sp +\fBSaltclass tree\fP +.sp +A saltclass tree would look like this: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C + +├── classes +│ ├── app +│ │ ├── borgbackup.yml +│ │ └── ssh +│ │ └── server.yml +│ ├── default +│ │ ├── init.yml +│ │ ├── motd.yml +│ │ └── users.yml +│ ├── roles +│ │ ├── app.yml +│ │ └── nginx +│ │ ├── init.yml +│ │ └── server.yml +│ └── subsidiaries +│ ├── gnv.yml +│ ├── qls.yml +│ └── zrh.yml +└── nodes + ├── geneva + │ └── gnv.node1.yml + ├── lausanne + │ ├── qls.node1.yml + │ └── qls.node2.yml + ├── node127.yml + └── zurich + ├── zrh.node1.yml + ├── zrh.node2.yml + └── zrh.node3.yml +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBExamples\fP +.sp +\fB/nodes/lausanne/qls.node1.yml\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +environment: base + +classes: +{% for class in [\(aqdefault\(aq] %} + \- {{ class }} +{% endfor %} + \- subsidiaries.{{ __grains__[\(aqid\(aq].split(\(aq.\(aq)[0] }} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fB/classes/default/init.yml\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +classes: + \- default.users + \- default.motd + +states: + \- openssh + +pillars: + default: + network: + dns: + srv1: 192.168.0.1 + srv2: 192.168.0.2 + domain: example.com + ntp: + srv1: 192.168.10.10 + srv2: 192.168.10.20 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fB/classes/subsidiaries/gnv.yml\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pillars: + default: + network: + sub: Geneva + dns: + srv1: 10.20.0.1 + srv2: 10.20.0.2 + srv3: 192.168.1.1 + domain: gnv.example.com + users: + adm1: + uid: 1210 + gid: 1210 + gecos: \(aqSuper user admin1\(aq + homedir: /srv/app/adm1 + adm3: + uid: 1203 + gid: 1203 + gecos: \(aqSuper user adm +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Variable expansions: +.sp +Escaped variables are rendered as is \- \fB${test}\fP +.sp +Missing variables are rendered as is \- \fB${net:dns:srv2}\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pillars: + app: + config: + dns: + srv1: ${default:network:dns:srv1} + srv2: ${net:dns:srv2} + uri: https://application.domain/call?\e${test} + prod_parameters: + \- p1 + \- p2 + \- p3 + pkg: + \- app\-core + \- app\-backend +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +List override: +.sp +Not using \fB^\fP as the first entry will simply merge the lists +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pillars: + app: + pkg: + \- ^ + \- app\-frontend +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBKnown limitation\fP +.sp +Currently you can\(aqt have both a variable and an escaped variable in the same string as the escaped one will not be correctly rendered \- \(aq${xx}\(aq will stay as is instead of being rendered as \(aq${xx}\(aq +.SS Newer PyWinRM Versions +.sp +Versions of \fBpywinrm>=0.2.1\fP are finally able to disable validation of self +signed certificates. Here for more information. +.SS DigitalOcean +.sp +The DigitalOcean driver has been renamed to conform to the company name. The +new driver name is \fBdigitalocean\fP\&. The old name \fBdigital_ocean\fP and a +short one \fBdo\fP will still be supported through virtual aliases, this is mostly +cosmetic. +.SS Solaris Logical Domains In Virtual Grain +.sp +Support has been added to the \fBvirtual\fP grain for detecting Solaris LDOMs +running on T\-Series SPARC hardware. The \fBvirtual_subtype\fP grain is +populated as a list of domain roles. +.SS Lists of comments in state returns +.sp +State functions can now return a list of strings for the \fBcomment\fP field, +as opposed to only a single string. +This is meant to ease writing states with multiple or multi\-part comments. +.SS Beacon configuration changes +.sp +In order to remain consistent and to align with other Salt components such as states, +support for configuring beacons using dictionary based configuration has been deprecated +in favor of list based configuration. All beacons have a validation function which will +check the configuration for the correct format and only load if the validation passes. +.INDENT 0.0 +.IP \(bu 2 +\fBavahi_announce\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + avahi_announce: + run_once: True + servicetype: _demo._tcp + port: 1234 + txt: + ProdName: grains.productname + SerialNo: grains.serialnumber + Comments: \(aqthis is a test\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + avahi_announce: + \- run_once: True + \- servicetype: _demo._tcp + \- port: 1234 + \- txt: + ProdName: grains.productname + SerialNo: grains.serialnumber + Comments: \(aqthis is a test\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +\fBbonjour_announce\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + bonjour_announce: + run_once: True + servicetype: _demo._tcp + port: 1234 + txt: + ProdName: grains.productname + SerialNo: grains.serialnumber + Comments: \(aqthis is a test\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + bonjour_announce: + \- run_once: True + \- servicetype: _demo._tcp + \- port: 1234 + \- txt: + ProdName: grains.productname + SerialNo: grains.serialnumber + Comments: \(aqthis is a test\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +\fBbtmp\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + btmp: {} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + btmp: [] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBglxinfo\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + glxinfo: + user: frank + screen_event: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + glxinfo: + \- user: frank + \- screen_event: True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBhaproxy\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + haproxy: + \- www\-backend: + threshold: 45 + servers: + \- web1 + \- web2 + \- interval: 120 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + haproxy: + \- backends: + www\-backend: + threshold: 45 + servers: + \- web1 + \- web2 + \- interval: 120 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBinotify\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + inotify: + /path/to/file/or/dir: + mask: + \- open + \- create + \- close_write + recurse: True + auto_add: True + exclude: + \- /path/to/file/or/dir/exclude1 + \- /path/to/file/or/dir/exclude2 + \- /path/to/file/or/dir/regex[a\-m]*$: + regex: True + coalesce: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + inotify: + \- files: + /path/to/file/or/dir: + mask: + \- open + \- create + \- close_write + recurse: True + auto_add: True + exclude: + \- /path/to/file/or/dir/exclude1 + \- /path/to/file/or/dir/exclude2 + \- /path/to/file/or/dir/regex[a\-m]*$: + regex: True + \- coalesce: True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBjournald\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + journald: + sshd: + SYSLOG_IDENTIFIER: sshd + PRIORITY: 6 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + journald: + \- services: + sshd: + SYSLOG_IDENTIFIER: sshd + PRIORITY: 6 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBload\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + load: + 1m: + \- 0.0 + \- 2.0 + 5m: + \- 0.0 + \- 1.5 + 15m: + \- 0.1 + \- 1.0 + emitatstartup: True + onchangeonly: False +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + load: + \- averages: + 1m: + \- 0.0 + \- 2.0 + 5m: + \- 0.0 + \- 1.5 + 15m: + \- 0.1 + \- 1.0 + \- emitatstartup: True + \- onchangeonly: False +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBlog\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + log: + file: + : + regex: +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + log: + \- file: + \- tags: + : + regex: +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBnetwork_info\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + network_info: + \- eth0: + type: equal + bytes_sent: 100000 + bytes_recv: 100000 + packets_sent: 100000 + packets_recv: 100000 + errin: 100 + errout: 100 + dropin: 100 + dropout: 100 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + network_info: + \- interfaces: + eth0: + type: equal + bytes_sent: 100000 + bytes_recv: 100000 + packets_sent: 100000 + packets_recv: 100000 + errin: 100 + errout: 100 + dropin: 100 + dropout: 100 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBnetwork_settings\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + network_settings: + eth0: + ipaddr: + promiscuity: + onvalue: 1 + eth1: + linkmode: +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + network_settings: + \- interfaces: + \- eth0: + ipaddr: + promiscuity: + onvalue: 1 + \- eth1: + linkmode: +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBproxy_example\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + proxy_example: + endpoint: beacon +\(ga\(ga\(ga +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B New behavior: + +.nf +\(ga\(ga +.fi +\(ga +beacons: +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B proxy_example: +.INDENT 7.0 +.IP \(bu 2 +endpoint: beacon +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBps\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + ps: + \- salt\-master: running + \- mysql: stopped +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + ps: + \- processes: + salt\-master: running + mysql: stopped +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBsalt_proxy\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + salt_proxy: + \- p8000: {} + \- p8001: {} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + salt_proxy: + \- proxies: + p8000: {} + p8001: {} +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBsensehat\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + sensehat: + humidity: 70% + temperature: [20, 40] + temperature_from_pressure: 40 + pressure: 1500 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + sensehat: + \- sensors: + humidity: 70% + temperature: [20, 40] + temperature_from_pressure: 40 + pressure: 1500 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBservice\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + service: + salt\-master: + mysql: +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + service: + \- services: + nginx: + onchangeonly: True + delay: 30 + uncleanshutdown: /run/nginx.pid +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBsh\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + sh: {} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + sh: [] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBstatus\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + status: {} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + status: [] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBtelegram_bot_msg\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + telegram_bot_msg: + token: "" + accept_from: + \- "" + interval: 10 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + telegram_bot_msg: + \- token: "" + \- accept_from: + \- "" + \- interval: 10 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBtwilio_txt_msg\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + twilio_txt_msg: + account_sid: "" + auth_token: "" + twilio_number: "+15555555555" + interval: 10 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + twilio_txt_msg: + \- account_sid: "" + \- auth_token: "" + \- twilio_number: "+15555555555" + \- interval: 10 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBwtmp\fP beacon +.INDENT 2.0 +.INDENT 3.5 +Old behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + wtmp: {} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +New behavior: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + wtmp: [] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.SS New requisites available in state compiler +.INDENT 0.0 +.IP \(bu 2 +\fBrequire_any\fP +.UNINDENT +.sp +The use of \fBrequire_any\fP demands that one of the required states executes before the +dependent state. The state containing the \fBrequire_any\fP requisite is defined as the +dependent state. The states specified in the \fBrequire_any\fP statement are defined as the +required states. If at least one of the required state\(aqs execution succeeds, the dependent state +will then execute. If at least one of the required state\(aqs execution fails, the dependent state +will not execute. +.INDENT 0.0 +.IP \(bu 2 +\fBwatch_any\fP +.UNINDENT +.sp +The state containing the \fBwatch_any\fP requisite is defined as the watching +state. The states specified in the \fBwatch_any\fP statement are defined as the watched +states. When the watched states execute, they will return a dictionary containing +a key named "changes". +.sp +If the "result" of any of the watched states is \fBTrue\fP, the watching state \fIwill +execute normally\fP, and if all of them are \fBFalse\fP, the watching state will never run. +This part of \fBwatch\fP mirrors the functionality of the \fBrequire\fP requisite. +.sp +If the "result" of any of the watched states is \fBTrue\fP \fIand\fP the "changes" +key contains a populated dictionary (changes occurred in the watched state), +then the \fBwatch\fP requisite can add additional behavior. This additional +behavior is defined by the \fBmod_watch\fP function within the watching state +module. If the \fBmod_watch\fP function exists in the watching state module, it +will be called \fIin addition to\fP the normal watching state. The return data +from the \fBmod_watch\fP function is what will be returned to the master in this +case; the return data from the main watching function is discarded. +.sp +If the "changes" key contains an empty dictionary, the \fBwatch\fP requisite acts +exactly like the \fBrequire\fP requisite (the watching state will execute if +"result" is \fBTrue\fP, and fail if "result" is \fBFalse\fP in the watched state). +.INDENT 0.0 +.IP \(bu 2 +\fBonchanges_any\fP +.UNINDENT +.sp +The \fBonchanges_any\fP requisite makes a state only apply one of the required states +generates changes, and if one of the watched state\(aqs "result" is \fBTrue\fP\&. This can be +a useful way to execute a post hook after changing aspects of a system. +.INDENT 0.0 +.IP \(bu 2 +\fBonfail_any\fP +.UNINDENT +.sp +The \fBonfail_any\fP requisite allows for reactions to happen strictly as a response +to the failure of at least one other state. This can be used in a number of ways, such as +executing a second attempt to set up a service or begin to execute a separate +thread of states because of a failure. +.sp +The \fBonfail_any\fP requisite is applied in the same way as \fBrequire_any\fP and \fBwatch_any\fP: +.SS Basic Slots support in states compiler +.sp +Slots extend the state syntax and allows you to do things right before the +state function is executed. So you can make a decision in the last moment right +before a state is executed. +.sp +Slot syntax looks close to the simple python function call. Here is a simple example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +copy\-some\-file: + file.copy: + \- name: __slot__:salt:test.echo(text=/tmp/some_file) + \- source: __slot__:salt:test.echo(/etc/hosts) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Read more here\&. +.SS Cryptographic layer changes +.sp +M2Crypto is coming back. We are making the crypto backend modular but in this +release M2Crypto is enabled if it\(aqs importable by Python. If not Cryptodome or +PyCrypto is used as it was in the previous releases. M2Crypto is used in the +same way as PyCrypto so there would be no compatibility issues, different nodes +could use different backends. +.SS Deprecations +.SS Configuration Option Deprecations +.INDENT 0.0 +.IP \(bu 2 +The \fBrequests_lib\fP configuration option has been removed. Please use +\fBbackend\fP instead. +.UNINDENT +.SS Profitbricks Cloud Updated Dependency +.sp +The minimum version of the \fBprofitbrick\fP python package for the \fBprofitbricks\fP +cloud driver has changed from 3.0.0 to 3.1.0. +.SS Azure Cloud Updated Dependency +.sp +The azure sdk used for the \fBazurearm\fP cloud driver now depends on \fBazure\-cli>=2.0.12\fP +.SS Module Deprecations +.sp +The \fBblockdev\fP execution module has been removed. Its functions were merged +with the \fBdisk\fP module. Please use the \fBdisk\fP execution module instead. +.sp +The \fBlxc\fP execution module had the following changes: +.INDENT 0.0 +.IP \(bu 2 +The \fBdnsservers\fP option to the \fBcloud_init_interface\fP function no longer +defaults to \fB4.4.4.4\fP and \fB8.8.8.8\fP\&. +.IP \(bu 2 +The \fBdns_via_dhcp\fP option to the \fBcloud_init_interface\fP function defaults +to \fBTrue\fP now instead of \fBFalse\fP\&. +.UNINDENT +.sp +The \fBwin_psget\fP module had the following changes: +.INDENT 0.0 +.IP \(bu 2 +The \fBpsversion\fP function was removed. Please use \fBcmd.shell_info\fP instead. +.UNINDENT +.sp +The \fBwin_service\fP module had the following changes: +.INDENT 0.0 +.IP \(bu 2 +The \fBconfig\fP function was removed. Please use the \fBmodify\fP function +instead. +.IP \(bu 2 +The \fBbinpath\fP option was removed from the \fBcreate\fP function. Please use +\fBbin_path\fP instead. +.IP \(bu 2 +The \fBdepend\fP option was removed from the \fBcreate\fP function. Please use +\fBdependencies\fP instead. +.IP \(bu 2 +The \fBDisplayName\fP option was removed from the \fBcreate\fP function. Please +use \fBdisplay_name\fP instead. +.IP \(bu 2 +The \fBerror\fP option was removed from the \fBcreate\fP function. Please use +\fBerror_control\fP instead. +.IP \(bu 2 +The \fBgroup\fP option was removed from the \fBcreate\fP function. Please use +\fBload_order_group\fP instead. +.IP \(bu 2 +The \fBobj\fP option was removed from the \fBcreate\fP function. Please use +\fBaccount_name\fP instead. +.IP \(bu 2 +The \fBpassword\fP option was removed from the \fBcreate\fP function. Please use +\fBaccount_password\fP instead. +.IP \(bu 2 +The \fBstart\fP option was removed from the \fBcreate\fP function. Please use +\fBstart_type\fP instead. +.IP \(bu 2 +The \fBtype\fP option was removed from the \fBcreate\fP function. Please use +\fBservice_type\fP instead. +.UNINDENT +.SS Runner Deprecations +.sp +The \fBmanage\fP runner had the following changes: +.INDENT 0.0 +.IP \(bu 2 +The \fBroot_user\fP kwarg was removed from the \fBbootstrap\fP function. Please +use \fBsalt\-ssh\fP roster entries for the host instead. +.UNINDENT +.SS State Deprecations +.sp +The \fBarchive\fP state had the following changes: +.INDENT 0.0 +.IP \(bu 2 +The \fBtar_options\fP and the \fBzip_options\fP options were removed from the +\fBextracted\fP function. Please use \fBoptions\fP instead. +.UNINDENT +.sp +The \fBcmd\fP state had the following changes: +.INDENT 0.0 +.IP \(bu 2 +The \fBuser\fP and \fBgroup\fP options were removed from the \fBrun\fP function. +Please use \fBrunas\fP instead. +.IP \(bu 2 +The \fBuser\fP and \fBgroup\fP options were removed from the \fBscript\fP function. +Please use \fBrunas\fP instead. +.IP \(bu 2 +The \fBuser\fP and \fBgroup\fP options were removed from the \fBwait\fP function. +Please use \fBrunas\fP instead. +.IP \(bu 2 +The \fBuser\fP and \fBgroup\fP options were removed from the \fBwait_script\fP +function. Please use \fBrunas\fP instead. +.UNINDENT +.sp +The \fBfile\fP state had the following changes: +.INDENT 0.0 +.IP \(bu 2 +The \fBshow_diff\fP option was removed. Please use \fBshow_changes\fP instead. +.UNINDENT +.SS Grain Deprecations +.sp +For \fBsmartos\fP some grains have been deprecated. These grains will be removed in Neon. +.INDENT 0.0 +.IP \(bu 2 +The \fBhypervisor_uuid\fP has been replaced with \fBmdata:sdc:server_uuid\fP grain. +.IP \(bu 2 +The \fBdatacenter\fP has been replaced with \fBmdata:sdc:datacenter_name\fP grain. +.UNINDENT +.SS Minion Blackout +.sp +During a blackout, minions will not execute any remote execution commands, +except for \fBsaltutil.refresh_pillar\fP\&. +Previously, support was added so that blackouts are enabled using a special +pillar key, \fBminion_blackout\fP set to \fBTrue\fP and an optional pillar key +\fBminion_blackout_whitelist\fP to specify additional functions that are permitted +during blackout. This release adds support for using this feature in the grains +as well, by using special grains keys \fBminion_blackout\fP and +\fBminion_blackout_whitelist\fP\&. +.SS Pillar Deprecations +.sp +The legacy configuration for \fBgit_pillar\fP has been removed. Please use the new +configuration for \fBgit_pillar\fP, which is documented in the external pillar module +for \fBgit_pillar\fP\&. +.SS Utils Deprecations +.sp +The \fBsalt.utils.cloud.py\fP file had the following change: +.INDENT 0.0 +.IP \(bu 2 +The \fBfire_event\fP function now requires a \fBsock_dir\fP argument. It was +previously optional. +.UNINDENT +.SS Other Miscellaneous Deprecations +.sp +The \fBversion.py\fP file had the following changes: +.INDENT 0.0 +.IP \(bu 2 +The \fBrc_info\fP function was removed. Please use \fBpre_info\fP instead. +.UNINDENT +.sp +Warnings for moving away from the \fBenv\fP option were removed. \fBsaltenv\fP +should be used instead. The removal of these warnings does not have a behavior +change. Only the warning text was removed. +.SS Sentry Log Handler +.sp +Configuring sentry raven python client via \fBproject\fP, \fBservers\fP, \fBpublic_key +and \(ga\(gasecret_key\fP is deprecated and won\(aqt work with sentry clients > 3.0. +Instead, the \fBdsn\fP config param must be used. +.SS RAET transport +.sp +We haven\(aqt been doing development on RAET for quite some time and decided that +2018.3.0 is the time to announce the deprecation. RAET support will be removed +in Neon. Please consider to move to \fBzeromq\fP or \fBtcp\fP transport instead of +\fBraet\fP\&. .SS Salt 2017.7.0 Release Notes \- Codename Nitrogen .SS Python 3 .sp @@ -356138,6 +380339,6689 @@ Mac Installer packages have been patched with the following PR: \fI\%43756\fP .SS Salt 2017.7.3 Release Notes .sp Version 2017.7.3 is a bugfix release for 2017.7.0\&. +.SS Changes for v2017.7.2..v2017.7.3 +.sp +Extended changelog courtesy of Todd Stansell (\fI\%https://github.com/tjstansell/salt\-changelogs\fP): +.sp +\fIGenerated at: 2018\-01\-25T20:45:09Z\fP +.sp +Statistics: +.INDENT 0.0 +.IP \(bu 2 +Total Merges: \fB499\fP +.IP \(bu 2 +Total Issue references: \fB161\fP +.IP \(bu 2 +Total PR references: \fB599\fP +.UNINDENT +.sp +Changes: +.SS Windows +.SS Execution module pkg +.sp +Significate changes (PR #43708 & #45390, damon\-atkins) have been made to the pkg execution module. Users should test this release against their existing package sls definition files. +.INDENT 0.0 +.IP \(bu 2 +\fBpkg.list_available\fP no longer defaults to refreshing the winrepo meta database. +.IP \(bu 2 +\fBpkg.install\fP without a \fBversion\fP parameter no longer upgrades software if the software is already installed. Use \fBpkg.install version=latest\fP or in a state use \fBpkg.latest\fP to get the old behavior. +.IP \(bu 2 +\fBpkg.list_pkgs\fP now returns multiple versions if software installed more than once. +.IP \(bu 2 +\fBpkg.list_pkgs\fP now returns \(aqNot Found\(aq when the version is not found instead of \(aq(value not set)\(aq which matches the contents of the sls definitions. +.IP \(bu 2 +\fBpkg.remove()\fP will wait upto 3 seconds (normally about a second) to detect changes in the registry after removing software, improving reporting of version changes. +.IP \(bu 2 +\fBpkg.remove()\fP can remove \fBlatest\fP software, if \fBlatest\fP is defined in sls definition. +.IP \(bu 2 +Documentation was update for the execution module to match the style in new versions, some corrections as well. +.IP \(bu 2 +All install/remove commands are prefix with cmd.exe shell and cmdmod is called with a command line string instead of a list. Some sls files in saltstack/salt\-winrepo\-ng expected the commands to be prefixed with cmd.exe (i.e. the use of \fB&\fP). +.IP \(bu 2 +Some execution module functions results, now behavour more like their Unix/Linux versions. +.UNINDENT +.SS Execution module cmdmod +.sp +Windows cmdmod forcing cmd to be a list (issue #43522) resolved by "cmdmod: Don\(aqt list\-ify string commands on Windows" PR #43807. Linux/Unix OS command & arguments requires a list. Windows was being treated the same. Windows requires commands & arguments to be a string, which this PR fixes. +.INDENT 0.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45681\fP: (\fIdamon\-atkins\fP) 2017.7.3 Release notes for Windows +@ \fI2018\-01\-25T15:13:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +ce41f6a6ee Merge pull request \fI\%#45681\fP from damon\-atkins/2017.7.3_win_release_notes +.IP \(bu 2 +1d21f86228 Update 2017.7.3.rst +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45672\fP: (\fIrallytime\fP) Back\-port \fI\%#45667\fP to 2017.7.3 +@ \fI2018\-01\-25T14:04:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45667\fP: (\fIgtmanfred\fP) default to upgrading when refreshing on archlinux +| refs: \fI\%#45672\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2f303439b7 Merge pull request \fI\%#45672\fP from rallytime/\fI\%bp\-45667\fP +.IP \(bu 2 +74bbaeb7ce we should default to upgrading when refreshing on archlinux +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45669\fP: (\fIrallytime\fP) Update man pages for 2017.7.3 release +@ \fI2018\-01\-24T21:04:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +23ff1264e0 Merge pull request \fI\%#45669\fP from rallytime/man\-pages\-2017.7.3 +.IP \(bu 2 +d31b41adeb Update man pages for 2017.7.3 release +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45666\fP: (\fIterminalmage\fP) Fix failing pkg integration tests for releases with no \(aq.\(aq +@ \fI2018\-01\-24T17:19:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +9a17405ba6 Merge pull request \fI\%#45666\fP from terminalmage/salt\-jenkins\-793 +.IP \(bu 2 +4a6ab729dd Fix failing pkg integration tests for releases with no \(aq.\(aq +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45664\fP: (\fIrallytime\fP) Back\-port \fI\%#45452\fP to 2017.7.3 +@ \fI2018\-01\-24T15:33:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45452\fP: (\fIadelcast\fP) opkg.py: make owner fuction return value, instead of iterator +| refs: \fI\%#45664\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0717f7a578 Merge pull request \fI\%#45664\fP from rallytime/\fI\%bp\-45452\fP +.IP \(bu 2 +369720677b opkg.py: make owner function return value, instead of iterator +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45649\fP: (\fIrallytime\fP) Back\-port \fI\%#45634\fP to 2017.7.3 +@ \fI2018\-01\-24T14:59:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45634\fP: (\fICh3LL\fP) Add different service name for Mac 10.13 test +| refs: \fI\%#45649\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +7934372b7b Merge pull request \fI\%#45649\fP from rallytime/\fI\%bp\-45634\fP +.IP \(bu 2 +1c78fc23ea Add different service name for Mac 10.13 test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45654\fP: (\fItwangboy\fP) Merge forward \fI\%#45638\fP +@ \fI2018\-01\-24T14:59:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45638\fP: (\fItwangboy\fP) Win fix shell info +| refs: \fI\%#45654\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +770f0c4664 Merge pull request \fI\%#45654\fP from twangboy/win_fix_shell_info_2017.7.3 +.IP \(bu 2 +5bb01aeb8c Merge forward \fI\%#45638\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45653\fP: (\fIrallytime\fP) Back\-port \fI\%#45611\fP to 2017.7.3 +@ \fI2018\-01\-24T05:20:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45611\fP: (\fIterminalmage\fP) Fix unnecessary/incorrect usage of six.binary_type +| refs: \fI\%#45653\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6fc293da46 Merge pull request \fI\%#45653\fP from rallytime/\fI\%bp\-45611\fP +.IP \(bu 2 +0a6b06d8ea Fix unnecessary/incorrect usage of six.binary_type +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45642\fP: (\fIrallytime\fP) Back\-port \fI\%#45636\fP to 2017.7.3 +@ \fI2018\-01\-23T22:00:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45636\fP: (\fICh3LL\fP) Fix mac service and pkg tests for 10.13 +| refs: \fI\%#45642\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0a07e0d259 Merge pull request \fI\%#45642\fP from rallytime/\fI\%bp\-45636\fP +.IP \(bu 2 +df0ad54c9a remove unnecessary variable for test +.IP \(bu 2 +acb14fd43d fix pylint +.IP \(bu 2 +a9b12cd1ea Fix mac service and pkg tests for 10.13 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45645\fP: (\fIrallytime\fP) Back\-port \fI\%#45606\fP to 2017.7.3 +@ \fI2018\-01\-23T21:54:45Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45606\fP: (\fIterminalmage\fP) Fix bug affecting salt\-ssh when root_dir differs from the default +| refs: \fI\%#45645\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f37a5b6d8d Merge pull request \fI\%#45645\fP from rallytime/\fI\%bp\-45606\fP +.IP \(bu 2 +d52d96f30a Fix bug affecting salt\-ssh when root_dir differs from the default +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45641\fP: (\fIrallytime\fP) Back\-port \fI\%#45508\fP to 2017.7.3 +@ \fI2018\-01\-23T21:18:39Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45508\fP: (\fIfrogunder\fP) fix test_archive test for mac on 2017.7 branch +| refs: \fI\%#45641\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e659793c09 Merge pull request \fI\%#45641\fP from rallytime/\fI\%bp\-45508\fP +.IP \(bu 2 +e6917a291e fix test_archive test for mac on 2017.7 branch +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45604\fP: (\fIrallytime\fP) Back\-port \fI\%#45582\fP to 2017.7.3 +@ \fI2018\-01\-22T16:54:15Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45582\fP: (\fIterminalmage\fP) Two salt\-ssh fixes +| refs: \fI\%#45604\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ced3269ae8 Merge pull request \fI\%#45604\fP from rallytime/\fI\%bp\-45582\fP +.IP \(bu 2 +bc8a450cc7 Remove state.py utils file from thin list +.IP \(bu 2 +629e6c9674 Further fixes to for salt\-ssh test under heavy load +.IP \(bu 2 +0dff596b59 Add salt/utils/state.py to thin tarball +.IP \(bu 2 +a61afda100 Pass on OSError if thin tarball already removed +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45591\fP: (\fIgtmanfred\fP) mark minion_blackout tests as flaky +@ \fI2018\-01\-22T00:14:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +4672baa6c8 Merge pull request \fI\%#45591\fP from gtmanfred/2017.7.3 +.IP \(bu 2 +f7fd35fc4a test updating the minion blackout timeout to 10 seconds +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45585\fP: (\fIrallytime\fP) Back\-port \fI\%#45579\fP to 2017.7.3 +@ \fI2018\-01\-22T00:13:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45579\fP: (\fIterminalmage\fP) Test suite stability fixes +| refs: \fI\%#45585\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2a992f9017 Merge pull request \fI\%#45585\fP from rallytime/\fI\%bp\-45579\fP +.IP \(bu 2 +0292c8345b Lint fix: use six\(aqs map +.IP \(bu 2 +108d8cbeef Use correct utils path for 2017.7 +.IP \(bu 2 +a38f4cb6d6 Restrict pyzmq optimizations to pyzmq >= 14.3.0 +.IP \(bu 2 +58ad558346 Fix event unpack +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45573\fP: (\fIgtmanfred\fP) update 2017.7.3 tests +@ \fI2018\-01\-20T20:05:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +19cd97ed3b Merge pull request \fI\%#45573\fP from gtmanfred/2017.7.3 +.IP \(bu 2 +bd3cb47fa7 fix mock for opensuse +.IP \(bu 2 +808e26e69a test simple website +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45570\fP: (\fIgtmanfred\fP) Fix tests for 2017.7.3 +@ \fI2018\-01\-20T15:01:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +e72d81ef22 Merge pull request \fI\%#45570\fP from gtmanfred/2017.7.3 +.IP \(bu 2 +1f71f301ba specify checking man page path +.IP \(bu 2 +2ddbcb45c1 fix pkg_resources for usage with testing pip +.IP \(bu 2 +0ba39a7108 switch systemd\-journald for sshd for arch service test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45538\fP: (\fIgtmanfred\fP) Backport test fixes to 2017.7.3 +@ \fI2018\-01\-19T14:39:44Z\fP +.INDENT 2.0 +.IP \(bu 2 +7bc60c56d4 Merge pull request \fI\%#45538\fP from gtmanfred/2017.7.3 +.IP \(bu 2 +801e0639b6 Merge branch \(aq2017.7.3\(aq into 2017.7.3 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45533\fP: (\fIrallytime\fP) Back\-port \fI\%#45529\fP to 2017.7.3 +@ \fI2018\-01\-18T22:52:29Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45529\fP: (\fICh3LL\fP) Fix UnboundLocalError for pacman pkg installs +| refs: \fI\%#45533\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +8ad65e3359 Merge pull request \fI\%#45533\fP from rallytime/\fI\%bp\-45529\fP +.IP \(bu 2 +6d56c64d88 Fix UnboundLocalError for pacman pkg installs +.INDENT 2.0 +.IP \(bu 2 +8d907ee1a0 fix moto version +.IP \(bu 2 +1241ab5fc6 fix test boto imports +.IP \(bu 2 +f4b6367cf9 fix fedora pkg test +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45442\fP: (\fIrallytime\fP) Back\-port \fI\%#45399\fP to 2017.7.3 +@ \fI2018\-01\-17T17:20:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#45394\fP: (\fIdmurphy18\fP) git.latest fails when "depth" is used with a non\-default branch +| refs: \fI\%#45399\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45399\fP: (\fIterminalmage\fP) Fix git.latest failure when rev is not the default branch +| refs: \fI\%#45442\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +7379f9e3e5 Merge pull request \fI\%#45442\fP from rallytime/\fI\%bp\-45399\fP +.IP \(bu 2 +590a6db626 Lint: use support TMP path instead of integration TMP path +.IP \(bu 2 +c081b2c62c Fix git.latest failure when rev is not the default branch +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45468\fP: (\fItwangboy\fP) Fix some issues with reg.py +@ \fI2018\-01\-16T22:23:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +ee5090f69b Merge pull request \fI\%#45468\fP from twangboy/win_reg +.IP \(bu 2 +a0d21c6354 Fix some issues with reg.py +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45434\fP: (\fIrallytime\fP) Back\-port \fI\%#45174\fP to 2017.7.3 +@ \fI2018\-01\-14T12:43:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44913\fP: (\fIari\fP) FreeBSD packaging install performance regression +| refs: \fI\%#45174\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45174\fP: (\fIeradman\fP) Do not force pkg reinstall on FreeBSD +| refs: \fI\%#45434\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ef7a896eb6 Merge pull request \fI\%#45434\fP from rallytime/\fI\%bp\-45174\fP +.IP \(bu 2 +b310ff7ab8 Do not force pkg reinstall on FreeBSD +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45395\fP: (\fIrallytime\fP) Back\-port \fI\%#45380\fP to 2017.7.3 +@ \fI2018\-01\-12T18:49:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45380\fP: (\fItwangboy\fP) Backport changes from \fI\%#45308\fP +| refs: \fI\%#45395\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45308\fP: (\fItwangboy\fP) Fix \fIintegration.modules.test_state\fP for Windows +| refs: \fI\%#45380\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c3fdd1dcc4 Merge pull request \fI\%#45395\fP from rallytime/\fI\%bp\-45380\fP +.IP \(bu 2 +0356b3d56f Backport changes from \fI\%#45308\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45294\fP: (\fIgtmanfred\fP) include backports_abc +@ \fI2018\-01\-11T18:18:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44107\fP: (\fIanlutro\fP) salt\-ssh 2017.7 doesn\(aqt work with Python 3, missing backports_abc +| refs: \fI\%#45294\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f7da716d32 Merge pull request \fI\%#45294\fP from gtmanfred/2017.7 +.IP \(bu 2 +3633ceeaa7 Merge branch \(aq2017.7\(aq into 2017.7 +.IP \(bu 2 +29806e4496 ignore salt.ext in pylint +.IP \(bu 2 +8b597a4890 include backports_abc +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45381\fP: (\fIgtmanfred\fP) fix module.run docs +@ \fI2018\-01\-11T18:02:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43130\fP: (\fIboltronics\fP) module.run documentation issues +| refs: \fI\%#45381\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f77a3e9cd4 Merge pull request \fI\%#45381\fP from gtmanfred/module.run +.IP \(bu 2 +230e899192 fix module.run docs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45368\fP: (\fIDmitryKuzmenko\fP) Fixes to work with pyzmq with \-\-enable\-drafts +@ \fI2018\-01\-11T17:53:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43995\fP: (\fIdragonpaw\fP) Using zmq built with \-\-enable\-draft breaks Salt +| refs: \fI\%#45368\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +8efd29f4d9 Merge pull request \fI\%#45368\fP from DSRCorporation/bugs/zmq_draft +.IP \(bu 2 +7622e355cf Minor: removed a stale comment. +.IP \(bu 2 +00f31bf9b5 Fixes to work with pyzmq with \-\-enable\-drafts +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45371\fP: (\fIrallytime\fP) Back\-port \fI\%#45158\fP to 2017.7 +@ \fI2018\-01\-11T17:51:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45158\fP: (\fIterminalmage\fP) Fix integration.modules.test_state.StateModuleTest.test_exclude +| refs: \fI\%#45371\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +22c3efda06 Merge pull request \fI\%#45371\fP from rallytime/\fI\%bp\-45158\fP +.IP \(bu 2 +3565bc2bf2 Don\(aqt use include\-test SLS in orch tests +.IP \(bu 2 +8bc17e0d7a Fix integration.modules.test_state.StateModuleTest.test_exclude +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45387\fP: (\fIrenner\fP) Set SHELL environment variable +@ \fI2018\-01\-11T16:23:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#40630\fP: (\fImateiw\fP) develop: SUSE specific changes to salt\-api.service +| refs: \fI\%#45387\fP +.IP \(bu 2 +\fBPR\fP \fI\%#40620\fP: (\fImateiw\fP) SUSE specific changes to salt\-api.service +| refs: \fI\%#45387\fP \fI\%#40630\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3a0e2de995 Merge pull request \fI\%#45387\fP from renner/patch\-2 +.IP \(bu 2 +530ddd2d29 Set SHELL environment variable +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45388\fP: (\fIterminalmage\fP) Fix loader error in 2017.7 tests +@ \fI2018\-01\-11T16:13:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +dcf98a2260 Merge pull request \fI\%#45388\fP from terminalmage/fix\-test\-loader\-error +.IP \(bu 2 +5473c085d9 Fix loader error in 2017.7 tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45382\fP: (\fIterminalmage\fP) Skip flaky test on 2017.7 branch +@ \fI2018\-01\-11T14:23:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +d15f9e1020 Merge pull request \fI\%#45382\fP from terminalmage/salt\-jenkins\-686 +.IP \(bu 2 +ff3039db6c Skip flaky test on 2017.7 branch +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45369\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2018\-01\-10T22:14:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45327\fP: (\fIlomeroe\fP) Backport \fI\%#44861\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#45268\fP: (\fIdamon\-atkins\fP) Fix pkg.install packagename version=latest i.e. if on an old version is installed +.IP \(bu 2 +\fBPR\fP \fI\%#44861\fP: (\fItwangboy\fP) Fix win_lgpo for unknown values +| refs: \fI\%#45327\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +dbe21b2c0d Merge pull request \fI\%#45369\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +f65e091df8 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +0959ae4ea3 Merge pull request \fI\%#45327\fP from lomeroe/ +.nf +\(ga +.fi +bp\-44861\(ga__2016.11 +.INDENT 2.0 +.IP \(bu 2 +784139f734 Check for values other than 0 or 1 +.UNINDENT +.IP \(bu 2 +a6db5f95f0 Merge pull request \fI\%#45268\fP from damon\-atkins/2016.11_win_pkg_pkg_install_latest +.INDENT 2.0 +.IP \(bu 2 +325a9f0f66 Update 2016.11.9.rst +.IP \(bu 2 +4da9200b9c Update 2016.11.9.rst +.IP \(bu 2 +126aee36ac Update 2016.11.9.rst +.IP \(bu 2 +1c01967943 Update 2016.11.9.rst +.IP \(bu 2 +a0d89882b8 Fix pkg.install packagename version=latest i.e. if on an old version upgrade to the latest +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45379\fP: (\fIrhoths\fP) Minor spelling/grammar fixes in the highstate returner documentation +@ \fI2018\-01\-10T20:09:52Z\fP +.INDENT 2.0 +.IP \(bu 2 +55979b3a48 Merge pull request \fI\%#45379\fP from rhoths/rhoths\-doc\-highstate\-1 +.IP \(bu 2 +afbbd492cd Minor spelling/grammar fixes in highstate returner +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45358\fP: (\fIUtahDave\fP) gate the minion data cache refresh events. +@ \fI2018\-01\-10T17:21:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45299\fP: (\fIgarethgreenaway\fP) [2017.7] config gate auth_events +| refs: \fI\%#45358\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +541e59fa75 Merge pull request \fI\%#45358\fP from UtahDave/gate_data_cache_refresh +.IP \(bu 2 +379b6cd23e should be \fIself\fP, not \fIsalt\fP +.IP \(bu 2 +a82e158f2d gate the minion data cache refresh events. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45297\fP: (\fICh3LL\fP) Allow macosx service state tests to check for pid return +@ \fI2018\-01\-09T20:47:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +fb87010461 Merge pull request \fI\%#45297\fP from Ch3LL/mac_service_state +.IP \(bu 2 +4e569b5802 Allow macosx service state tests to check for pid return +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45351\fP: (\fIdmurphy18\fP) Update debbuild to explicitly include source code for Debian, Ubuntu +@ \fI2018\-01\-09T17:21:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +beedf6e815 Merge pull request \fI\%#45351\fP from dmurphy18/upd_debbuild +.IP \(bu 2 +478dc70092 Update debbuild flags +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45299\fP: (\fIgarethgreenaway\fP) [2017.7] config gate auth_events +| refs: \fI\%#45358\fP +@ \fI2018\-01\-09T15:00:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +66da9b47bc Merge pull request \fI\%#45299\fP from garethgreenaway/config_gate_auth_events +.IP \(bu 2 +9a15ec3430 Updating versionadded string. Fixing typo. +.IP \(bu 2 +edfc3dc078 Adding in documention for \fIauth_events\fP configuration option +.IP \(bu 2 +3ee4eabffd Fixing small typo +.IP \(bu 2 +6a28bddcc9 Adding some code to config gate if auth_events are sent +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44856\fP: (\fICh3LL\fP) Add state.running ssh integration test +@ \fI2018\-01\-08T21:40:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +8d04c2b3d4 Merge pull request \fI\%#44856\fP from Ch3LL/running_test +.IP \(bu 2 +9a35a73711 add time limit to while loop +.IP \(bu 2 +aeb5f4e248 Add state.running ssh integration test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45295\fP: (\fIgtmanfred\fP) test directory that doesn\(aqt exist +@ \fI2018\-01\-08T20:59:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#675\fP: (\fIakoumjian\fP) virtualenv fails without specifying no_site_packages +| refs: \fI\%#45295\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +d0e5e70277 Merge pull request \fI\%#45295\fP from gtmanfred/test_directory +.IP \(bu 2 +e6178fe6d4 Merge branch \(aq2017.7\(aq into test_directory +.IP \(bu 2 +24114e91c1 test was different slightly on 2017.7 +.IP \(bu 2 +d20fc93625 test directory that doesn\(aqt exist +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45302\fP: (\fIgtmanfred\fP) fix proxy tests for py3 on 2017.7 +@ \fI2018\-01\-08T17:41:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#678\fP: (\fIpille\fP) add watch support for directories +| refs: \fI\%#45302\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f49b204b75 Merge pull request \fI\%#45302\fP from gtmanfred/proxyp3 +.IP \(bu 2 +b295ec0429 make dummy proxy module py3 compatible +.IP \(bu 2 +8736e21f65 fix starting proxy minion on py3 +.IP \(bu 2 +e2824a7253 fix py3 tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45279\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2018\-01\-08T17:26:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45256\fP: (\fIrallytime\fP) Back\-port \fI\%#45034\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#45034\fP: (\fIbrejoc\fP) Fix for pidfile removal logging +| refs: \fI\%#45256\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +eea7158e82 Merge pull request \fI\%#45279\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +8025b14584 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +1c5e905b61 Merge pull request \fI\%#45256\fP from rallytime/\fI\%bp\-45034\fP +.INDENT 2.0 +.IP \(bu 2 +68f971b38f Apply test fixes from \fI\%#45034\fP to parsers_test.py +.IP \(bu 2 +9454236694 Fix for pidfile removal logging +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44853\fP: (\fIgtmanfred\fP) remove not from vault utils +@ \fI2018\-01\-05T17:43:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +dab4a8cff3 Merge pull request \fI\%#44853\fP from gtmanfred/vault +.IP \(bu 2 +bfee1cead6 set role for loading minion config +.IP \(bu 2 +c5af2e5048 if utils is not loaded, load it +.IP \(bu 2 +6a5e0f9ac1 remove not from vault utils +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45277\fP: (\fIrallytime\fP) Back\-port \fI\%#45025\fP to 2017.7 +@ \fI2018\-01\-05T15:35:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45025\fP: (\fIsteverweber\fP) Fix pillar include merge order +| refs: \fI\%#45277\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f09d0e5fdb Merge pull request \fI\%#45277\fP from rallytime/\fI\%bp\-45025\fP +.IP \(bu 2 +942c14bb29 pillar body overrides includes +.IP \(bu 2 +1152202fdc fix pillar includes from merging over the current sls defines +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45276\fP: (\fIrallytime\fP) Back\-port \fI\%#45260\fP to 2017.7 +@ \fI2018\-01\-05T14:45:40Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45260\fP: (\fIgtmanfred\fP) Make some kitchen\-salt tests blue +| refs: \fI\%#45276\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +fc84f1104f Merge pull request \fI\%#45276\fP from rallytime/\fI\%bp\-45260\fP +.IP \(bu 2 +9ab1af738f switch kitchen\-salt to use rsync transport to preserve symlinks +.IP \(bu 2 +cf98ed472e fix up symlinks +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45255\fP: (\fIrallytime\fP) Back\-port \fI\%#44427\fP to 2017.7 +@ \fI2018\-01\-04T21:46:17Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43340\fP: (\fIsyphernl\fP) Upgrading Salt via Salt results in dying minions and broken dpkg +| refs: \fI\%#45255\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44427\fP: (\fIsamodid\fP) use KillMode=process for salt\-minion.service +| refs: \fI\%#45255\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ff9880c498 Merge pull request \fI\%#45255\fP from rallytime/\fI\%bp\-44427\fP +.IP \(bu 2 +6ceafbbf3a use KillMode=process for salt\-minion.service +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45251\fP: (\fIforksaber\fP) Fix \fI\%#23454\fP : make pydsl work with salt\-ssh +@ \fI2018\-01\-04T21:33:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23454\fP: (\fIHontoNoRoger\fP) SLS rendering error with Salt\-SSH (pydsl) +| refs: \fI\%#45251\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e715eb603f Merge pull request \fI\%#45251\fP from forksaber/salt\-ssh\-pydsl +.IP \(bu 2 +b3660d5190 [\fI\%#23454\fP] make pydsl work with salt\-ssh +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45254\fP: (\fICh3LL\fP) Add darwin value for ssh grain items tests on MacOSX +@ \fI2018\-01\-04T21:31:35Z\fP +.INDENT 2.0 +.IP \(bu 2 +2934b60d53 Merge pull request \fI\%#45254\fP from Ch3LL/fix_mac_grain_ssh +.IP \(bu 2 +b4b59b89cd remove platform from salt.utils call for 2017.7 +.IP \(bu 2 +85e853a63d Add darwin value for ssh grain items tests on MacOSX +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45135\fP: (\fItwangboy\fP) Fix win_dacl problems with SIDs +@ \fI2018\-01\-04T21:01:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +af2d880303 Merge pull request \fI\%#45135\fP from twangboy/win_fix_dacl +.IP \(bu 2 +b31e08946a Merge branch \(aq2017.7\(aq into win_fix_dacl +.IP \(bu 2 +35a417f510 Fix win_dacl problems with SIDs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44930\fP: (\fIfrogunder\fP) man_spm_test +@ \fI2018\-01\-04T20:58:02Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43806\fP: (\fICh3LL\fP) Add spm man Test to Auto Test Suite +| refs: \fI\%#44930\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +d0a3770035 Merge pull request \fI\%#44930\fP from frogunder/man_spm +.IP \(bu 2 +48e6953e1f fix_string_error +.IP \(bu 2 +c9fa4ed2a7 man_spm_test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45259\fP: (\fICh3LL\fP) Fix MacOSX Service Status Check and integration test +@ \fI2018\-01\-04T14:25:01Z\fP +.INDENT 2.0 +.IP \(bu 2 +543eebf411 Merge pull request \fI\%#45259\fP from Ch3LL/fix\-mac\-service\-test +.IP \(bu 2 +74e6ed60ea Fix MacOSX Service Status Check and integration test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45263\fP: (\fIsumeetisp\fP) Updating python version for 2017.7 +@ \fI2018\-01\-04T14:16:26Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#1\fP: (\fIthatch45\fP) Enable regex on the salt cli +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +bbbd1872a7 Merge pull request \fI\%#45263\fP from sumeetisp/2017.7 +.IP \(bu 2 +e3a5ee3a08 Merge branch \(aq2017.7\(aq into 2017.7 +.IP \(bu 2 +71aea9a3bc Merge pull request \fI\%#1\fP from sumeetisp/sumeetisp\-python\-version +.INDENT 2.0 +.IP \(bu 2 +1b4806e2b9 Updating python version +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45244\fP: (\fItwangboy\fP) Fix search/replace in Py3 +@ \fI2018\-01\-04T14:02:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +d46e1197be Merge pull request \fI\%#45244\fP from twangboy/win_fix_portable.py +.IP \(bu 2 +e3a8279c01 Get path to python binary based on executable +.IP \(bu 2 +03aec37040 Fix search/replace in Py3 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45233\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2018\-01\-03T15:34:00Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#27160\fP: (\fImartinadolfi\fP) salt.states.mount persistence error using spaces in route +| refs: \fI\%#45232\fP \fI\%#45232\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#598\fP: (\fIsyphernl\fP) Explanation on how to execute interactive installs +| refs: \fI\%#45209\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45235\fP: (\fIrallytime\fP) Back\-port \fI\%#45209\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#45232\fP: (\fIrasathus\fP) Backport \fI\%#27160\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#45209\fP: (\fIgtmanfred\fP) enable UsePAM for ssh tests +| refs: \fI\%#45235\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44965\fP: (\fIgtmanfred\fP) check if VALUE is a string_type +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +eba360870a Merge pull request \fI\%#45233\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +a3d251b2cd Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +b75f50afe3 Merge pull request \fI\%#45235\fP from rallytime/\fI\%bp\-45209\fP +.INDENT 2.0 +.IP \(bu 2 +2d0a9bbf7e enable UsePAM for ssh tests +.UNINDENT +.UNINDENT +.IP \(bu 2 +5d9a1e91e9 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +3ab962b01a Merge pull request \fI\%#44965\fP from gtmanfred/2016.11 +.INDENT 2.0 +.IP \(bu 2 +a5d8a6340e check if VALUE is a string_type +.UNINDENT +.IP \(bu 2 +40fb30f63f Merge pull request \fI\%#45232\fP from rasathus/2016.11 +.INDENT 2.0 +.IP \(bu 2 +7a2bd8f49b Merge branch \(aq2016.11\(aq into 2016.11 +.IP \(bu 2 +de53c45c29 Backport \fI\%#27160\fP to 2016.11 +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45175\fP: (\fIamendlik\fP) Pkg uptodate +@ \fI2018\-01\-02T17:38:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +693cc807e8 Merge pull request \fI\%#45175\fP from amendlik/pkg\-uptodate +.IP \(bu 2 +4f514a29a7 Merge branch \(aq2017.7\(aq into pkg\-uptodate +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45226\fP: (\fIgtmanfred\fP) Update kitchen to use runtests verifier on 2017.7 +@ \fI2017\-12\-31T18:13:28Z\fP +.INDENT 2.0 +.IP \(bu 2 +1b3f3ba1be Merge pull request \fI\%#45226\fP from gtmanfred/2017.7 +.IP \(bu 2 +4f3b089e0e fix copying back +.IP \(bu 2 +f56f062a6a download xml for junit +.IP \(bu 2 +7cc342a5d6 use new runtests verifier +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45221\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-12\-30T18:08:29Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#45188\fP: (\fIjak3kaj\fP) salt state status.process always returns false +| refs: \fI\%#45199\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44516\fP: (\fIdoesitblend\fP) Windows PY3 Minion Returns UTF16 UnicodeError +| refs: \fI\%#44944\fP \fI\%#45161\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45199\fP: (\fIgtmanfred\fP) status.pid returns pid ids not process names +.IP \(bu 2 +\fBPR\fP \fI\%#45161\fP: (\fIlomeroe\fP) Backport \fI\%#44944\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#44944\fP: (\fIlomeroe\fP) win_lgpo registry.pol encoding updates +| refs: \fI\%#45161\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +7d3a6cbc65 Merge pull request \fI\%#45221\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +508599e159 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.IP \(bu 2 +707ef55175 Merge pull request \fI\%#45161\fP from lomeroe/ +.nf +\(ga +.fi +bp\-44944\(ga__2016.11 +.INDENT 2.0 +.IP \(bu 2 +0a4c6b5a83 remove references to six.unichr +.IP \(bu 2 +f3196d795d lint fixes for static regexes +.IP \(bu 2 +11b637d108 lint fixes +.IP \(bu 2 +c14d6282ad do not decode registry.pol file wholesale, but instead decode individual elements of the file +.UNINDENT +.IP \(bu 2 +6f52034e08 Merge pull request \fI\%#45199\fP from gtmanfred/status +.INDENT 2.0 +.IP \(bu 2 +fb07f9ea7d status.pid returns pid ids not process names +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45204\fP: (\fIgarethgreenaway\fP) [2017.7] Fixes to osquery module & addition of unit tests +@ \fI2017\-12\-30T13:25:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#45176\fP: (\fIthuhak\fP) osquery execution module does\(aqt work with attrs parameter +| refs: \fI\%#45204\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +abed378981 Merge pull request \fI\%#45204\fP from garethgreenaway/45176_fixes_to_osquery_module +.IP \(bu 2 +dc933e9e24 Fixing typo +.IP \(bu 2 +d834bd1b6f Fixing some minor lint issues. +.IP \(bu 2 +4738205154 Fixing a bug when attributes are passed to various osquery module functions. +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +66884334d9 Update states.pkg for Python3 compatibility +.IP \(bu 2 +2a7d76ad6e Fail pkg.uptodate if expected packages are not upgraded +.IP \(bu 2 +29ef67bac2 Test pkg.uptodate with failed upgrades +.IP \(bu 2 +23ab93353b Produce changes dict for pkg.uptodate dry\-run mode +.IP \(bu 2 +7c67ec39d9 Add tests for pkg.uptodate state +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45203\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-12\-29T01:11:03Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44728\fP: (\fIcasselt\fP) Nodegroups can not be defined by glob with ? or seq +| refs: \fI\%#45118\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45137\fP: (\fItwangboy\fP) Catch correct error type in list_keys and list_values +.IP \(bu 2 +\fBPR\fP \fI\%#45130\fP: (\fIrallytime\fP) Resolve groups for salt api +.IP \(bu 2 +\fBPR\fP \fI\%#45127\fP: (\fItwangboy\fP) Fix issue with 1641 return code +.IP \(bu 2 +\fBPR\fP \fI\%#45118\fP: (\fIgarethgreenaway\fP) [2016.11] Fix to allow nodegroups to include sequences +.IP \(bu 2 +\fBPR\fP \fI\%#45114\fP: (\fItwangboy\fP) Move pam library load to try/except block +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +5991d8ca15 Merge pull request \fI\%#45203\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +430c913c8c Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +d3381e27d0 Merge pull request \fI\%#45118\fP from garethgreenaway/44728_nodegroups_seq +.INDENT 2.0 +.IP \(bu 2 +0ff811de70 Swapping import to be the old path for 2016.11 +.IP \(bu 2 +b3e2f388f5 Fix to allow nodegroups to include sequences +.UNINDENT +.IP \(bu 2 +f969aca3a3 Merge pull request \fI\%#45127\fP from twangboy/win_fix_pkg +.INDENT 2.0 +.IP \(bu 2 +14639739f2 Fix issue with 1641 return code +.UNINDENT +.IP \(bu 2 +dc357b39f0 Merge pull request \fI\%#45137\fP from twangboy/win_fix_reg_tests +.INDENT 2.0 +.IP \(bu 2 +b6f4ef8d73 Catch correct error type in list_keys and list_values +.UNINDENT +.IP \(bu 2 +0aa1662731 Merge pull request \fI\%#45130\fP from rallytime/api\-groups +.INDENT 2.0 +.IP \(bu 2 +2dcc8df845 Resolve groups for salt api +.UNINDENT +.IP \(bu 2 +7dc3cc4641 Merge pull request \fI\%#45114\fP from twangboy/win_fix_pam +.INDENT 2.0 +.IP \(bu 2 +cf5eae1f77 Move pam library load to try/except block +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45201\fP: (\fIrallytime\fP) [2017.7] Check for running on python3 before decoding bytes +@ \fI2017\-12\-28T22:59:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#45090\fP: (\fIangeloudy\fP) fix TypeError in python 3 +| refs: \fI\%#45201\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +882267314f Merge pull request \fI\%#45201\fP from rallytime/fix\-jinja\-template\-test\-failure +.IP \(bu 2 +b4af3bdff8 Check for running on python3 before decoding bytes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45200\fP: (\fIrallytime\fP) [2017.7] Fix docstring integration test failure +@ \fI2017\-12\-28T22:58:34Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#44552\fP: (\fIDa\-Juan\fP) pip_state: Check if available upgrades fulfill version requirements. +| refs: \fI\%#45200\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2e18398f12 Merge pull request \fI\%#45200\fP from rallytime/fix\-docstring\-test\-failure +.IP \(bu 2 +a26d4795bd [2017.7] Fix docstring integration test failure +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45186\fP: (\fIrallytime\fP) Back\-port \fI\%#44922\fP to 2017.7 +@ \fI2017\-12\-28T19:02:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#44922\fP: (\fIdincamihai\fP) Fix salt\-master for old psutil +| refs: \fI\%#45186\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +67d97303b5 Merge pull request \fI\%#45186\fP from rallytime/\fI\%bp\-44922\fP +.IP \(bu 2 +6970fe8103 Fix salt\-master for old psutil +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44624\fP: (\fIeliasp\fP) Fix Traceback when using the \fIservice.enabled\fP state on non\-booted systems +@ \fI2017\-12\-28T10:58:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +30d7f7257a Merge pull request \fI\%#44624\fP from eliasp/fix\-upstart\-utmp\-exception +.IP \(bu 2 +43d44e051a Do not blindly assume presence of either \fI/var/run/utmp\fP or \fI/run/utmp\fP, none of both might be available (e.g. on non\-booted systems). +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45183\fP: (\fItwangboy\fP) Add libnacl dependency +@ \fI2017\-12\-27T22:08:32Z\fP +.INDENT 2.0 +.IP \(bu 2 +3832e7b227 Merge pull request \fI\%#45183\fP from twangboy/win_add_libnacl_2017.7 +.IP \(bu 2 +b46845888d Add libnacl dependency +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44966\fP: (\fIrcallphin\fP) Fix bug with vault runner creating token on empty policy +@ \fI2017\-12\-22T20:30:37Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44928\fP: (\fIrcallphin\fP) Duplicating master token when no match for Minion policy (Vault Module) +| refs: \fI\%#44966\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +fbbf33574e Merge pull request \fI\%#44966\fP from rcallphin/fix\-bug\-vault\-empty\-policy +.IP \(bu 2 +7f327ab760 Lint: Remove extra whitespace +.IP \(bu 2 +04ab6a5e9d Merge branch \(aq2017.7\(aq into fix\-bug\-vault\-empty\-policy +.IP \(bu 2 +5be463bb46 Merge branch \(aq2017.7\(aq into fix\-bug\-vault\-empty\-policy +.IP \(bu 2 +48d9cc3674 Fix bug with vault runner creating token on empty policy +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44552\fP: (\fIDa\-Juan\fP) pip_state: Check if available upgrades fulfill version requirements. +| refs: \fI\%#45200\fP +@ \fI2017\-12\-22T19:25:17Z\fP +.INDENT 2.0 +.IP \(bu 2 +487207f61d Merge pull request \fI\%#44552\fP from Da\-Juan/avoid_unneeded_pip_install +.IP \(bu 2 +49a6a8f02e Merge branch \(aq2017.7\(aq into avoid_unneeded_pip_install +.IP \(bu 2 +3a8e62493d pip_state: Check if available upgrades fulfill version requirements +.IP \(bu 2 +62252d74d9 pip_state: Compare versions using pkg_resources.parse_version +.IP \(bu 2 +5219ab974c Add list_all_versions function to pip module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45090\fP: (\fIangeloudy\fP) fix TypeError in python 3 +| refs: \fI\%#45201\fP +@ \fI2017\-12\-22T18:11:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +5ae26f0c09 Merge pull request \fI\%#45090\fP from angeloudy/2017.7 +.IP \(bu 2 +cf411f8984 Merge branch \(aq2017.7\(aq into 2017.7 +.IP \(bu 2 +177fd18671 fix TypeError in python 3 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45134\fP: (\fIgarethgreenaway\fP) [2017.7] fix to cmd.script for cwd with space +@ \fI2017\-12\-22T15:31:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44315\fP: (\fIwhytewolf\fP) cmd.* cwd does not escape spaces. 2017.7.2 +| refs: \fI\%#45134\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a1946730a9 Merge pull request \fI\%#45134\fP from garethgreenaway/44315_cmd_script_cwd_with_space +.IP \(bu 2 +48eafe3206 Adding some tests to tests cmd.script with cwd +.IP \(bu 2 +8dfcf71b08 Adding _cmd_quote to handle cases when the current working directory for cmd.script might have a space in it. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44964\fP: (\fIGiandom\fP) added\-highstate\-output\-to\-slack\-engine +@ \fI2017\-12\-21T21:32:01Z\fP +.INDENT 2.0 +.IP \(bu 2 +f41adfc913 Merge pull request \fI\%#44964\fP from Giandom/2017.7\-added\-highstate\-output\-to\-slack\-engine +.IP \(bu 2 +4526c158f1 added\-highstate\-output\-to\-slack\-engine +.IP \(bu 2 +573a0a4143 added\-highstate\-output\-to\-slack\-engine +.IP \(bu 2 +9a6e03ce6e added\-highstate\-output\-to\-slack\-engine +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45124\fP: (\fIgtmanfred\fP) enable using kitchen\-salt with ec2 on 2017.7 +@ \fI2017\-12\-21T19:11:27Z\fP +.INDENT 2.0 +.IP \(bu 2 +b49ee97938 Merge pull request \fI\%#45124\fP from gtmanfred/2017.7 +.IP \(bu 2 +d0586013eb fix pylint +.IP \(bu 2 +59e2e56d13 chmod the xml files before trying to copy +.IP \(bu 2 +a5c1410e23 catch IOError when copying xml files back +.IP \(bu 2 +23bd38ad66 enable using kitchen\-salt on ec2 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45087\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-12\-20T22:24:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#45049\fP: (\fIvernondcole\fP) salt cloud module documentation is missing from the index. +| refs: \fI\%#45070\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#45036\fP: (\fIdijit\fP) Quiet installation of packaged minions fails due to redistributable not being quietly installed [py3] [Windows] +| refs: \fI\%#45040\fP \fI\%#45040\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44820\fP: (\fImsteed\fP) Custom returner breaks manage runner +| refs: \fI\%#44958\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44378\fP: (\fIllua\fP) minion: infinite loop during start when schedule key is null +| refs: \fI\%#44385\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#41286\fP: (\fIarthtux\fP) boto_vpc.accept_vpc_peering_connection wait a object +| refs: \fI\%#41305\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#41044\fP: (\fIpirxthepilot\fP) user.present \(aqdate\(aq parameter is not applying +| refs: \fI\%#44078\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45100\fP: (\fIrallytime\fP) Back\-port \fI\%#45070\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#45098\fP: (\fIrallytime\fP) Back\-port \fI\%#45092\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#45092\fP: (\fIterminalmage\fP) Fix integration.states.test_pip.PipStateTest.test_pip_installed_weird_install +| refs: \fI\%#45098\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45070\fP: (\fIvernondcole\fP) insert clouds modules in index +| refs: \fI\%#45100\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45069\fP: (\fIrallytime\fP) Back\-port \fI\%#45040\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#45040\fP: (\fIdijit\fP) Installation Fails on headless machines. +| refs: \fI\%#45069\fP +.IP \(bu 2 +\fBPR\fP \fI\%#45031\fP: (\fIterminalmage\fP) Fix invalid exception class in mysql returner +.IP \(bu 2 +\fBPR\fP \fI\%#44972\fP: (\fIterminalmage\fP) Backport \fI\%#44958\fP to 2016.11 branch +.IP \(bu 2 +\fBPR\fP \fI\%#44970\fP: (\fIrallytime\fP) Update bootstrap script to latest release: 2017.12.13 +.IP \(bu 2 +\fBPR\fP \fI\%#44969\fP: (\fIrallytime\fP) Back\-port \fI\%#41305\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#44958\fP: (\fIterminalmage\fP) Fix a race condition in manage runner +| refs: \fI\%#44972\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44385\fP: (\fIgtmanfred\fP) schedule should be a dict in opts +.IP \(bu 2 +\fBPR\fP \fI\%#44078\fP: (\fIrossengeorgiev\fP) user.present: allow date param to be 0 +.IP \(bu 2 +\fBPR\fP \fI\%#41305\fP: (\fIarthtux\fP) correct accept_vpc_peering_connection +| refs: \fI\%#44969\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +42e894570d Merge pull request \fI\%#45087\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +fe81e2d39a Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +7e128e8f15 Merge pull request \fI\%#45100\fP from rallytime/\fI\%bp\-45070\fP +.INDENT 2.0 +.IP \(bu 2 +0bdb46dab9 add clouds modules to index +.UNINDENT +.IP \(bu 2 +bdf93f339d Merge pull request \fI\%#45098\fP from rallytime/\fI\%bp\-45092\fP +.INDENT 2.0 +.IP \(bu 2 +80b6bd6813 Fix integration.states.test_pip.PipStateTest.test_pip_installed_weird_install +.UNINDENT +.UNINDENT +.IP \(bu 2 +4f21a2bbfd Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +324b7d4058 Merge pull request \fI\%#44078\fP from rossengeorgiev/\fI\%fix\-41044\fP +.INDENT 2.0 +.IP \(bu 2 +a81a6fe23c fix \fI\%#41044\fP; allow for date param to be 0 +.UNINDENT +.IP \(bu 2 +48a59761df Merge pull request \fI\%#44970\fP from rallytime/update\-bootstrap\-script +.INDENT 2.0 +.IP \(bu 2 +b2c8057427 Update bootstrap script to latest release: 2017.12.13 +.UNINDENT +.IP \(bu 2 +637fdaed58 Merge pull request \fI\%#45069\fP from rallytime/\fI\%bp\-45040\fP +.INDENT 2.0 +.IP \(bu 2 +aa438e1605 Installation Fails on headless machines. +.UNINDENT +.IP \(bu 2 +4d6d640381 Merge pull request \fI\%#44969\fP from rallytime/\fI\%bp\-41305\fP +.INDENT 2.0 +.IP \(bu 2 +5c4bee43dc correct accept_vpc_peering_connection +.UNINDENT +.IP \(bu 2 +10de468f13 Merge pull request \fI\%#45031\fP from terminalmage/fix\-mysql\-returner +.INDENT 2.0 +.IP \(bu 2 +f3bd12c27c Fix invalid exception class in mysql returner +.UNINDENT +.IP \(bu 2 +9a7406207f Merge pull request \fI\%#44972\fP from terminalmage/\fI\%bp\-44958\fP +.INDENT 2.0 +.IP \(bu 2 +a416bf0112 No need to manually do connect_pub, use listen=True in run_job +.IP \(bu 2 +3ec004bd2e Fix a race condition in manage runner +.UNINDENT +.IP \(bu 2 +1032ca3290 Merge pull request \fI\%#44385\fP from gtmanfred/schedule +.INDENT 2.0 +.IP \(bu 2 +9e15c38da2 add comma +.IP \(bu 2 +855d933cb7 schedule should be a dict +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45112\fP: (\fICh3LL\fP) Fix spm big file build test to check /tmp +@ \fI2017\-12\-20T22:09:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +9550e742ac Merge pull request \fI\%#45112\fP from Ch3LL/fix\-arch +.IP \(bu 2 +1bd7110a14 Fix spm big file build test to check /tmp +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45068\fP: (\fIrallytime\fP) Back\-port \fI\%#44976\fP to 2017.7 +@ \fI2017\-12\-20T16:31:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44303\fP: (\fImwerickso\fP) boto3_route53 module times out on retries +| refs: \fI\%#44976\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44976\fP: (\fItkwilliams\fP) Fix bad variable name in boto3_route53 module \- resolves \fI\%#44303\fP +| refs: \fI\%#45068\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +71f9c7ee49 Merge pull request \fI\%#45068\fP from rallytime/\fI\%bp\-44976\fP +.IP \(bu 2 +0ca0f37805 44303 \- resolves \fI\%#44303\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#45099\fP: (\fIrallytime\fP) Back\-port \fI\%#44983\fP to 2017.7 +@ \fI2017\-12\-20T14:41:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44961\fP: (\fIgolmaal\fP) The archive tar function fails to untar file when dest argument is passed +| refs: \fI\%#44983\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44983\fP: (\fIgolmaal\fP) Ref:44961 \- Modified archive.tar to add dest at the end of the tar cmd +| refs: \fI\%#45099\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +54a33c0e1d Merge pull request \fI\%#45099\fP from rallytime/\fI\%bp\-44983\fP +.IP \(bu 2 +23361de8a2 Ref:44961 \- Modified archive.tar to add dest argument at the end of the tar cmd. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44650\fP: (\fIfrogunder\fP) add status.pid test +@ \fI2017\-12\-19T16:21:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43533\fP: (\fICh3LL\fP) Add status.pid Test to Auto Test Suite +| refs: \fI\%#44650\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e0d7b330fa Merge pull request \fI\%#44650\fP from frogunder/status +.IP \(bu 2 +904c0da893 Merge branch \(aq2017.7\(aq into status +.IP \(bu 2 +619bd2be1e fix lint error +.IP \(bu 2 +d406cb07a3 add status.pid test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44944\fP: (\fIlomeroe\fP) win_lgpo registry.pol encoding updates +| refs: \fI\%#45161\fP +@ \fI2017\-12\-19T14:42:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44516\fP: (\fIdoesitblend\fP) Windows PY3 Minion Returns UTF16 UnicodeError +| refs: \fI\%#44944\fP \fI\%#45161\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +422d8b8f1b Merge pull request \fI\%#44944\fP from lomeroe/update_regpol_encoding +.IP \(bu 2 +07d04c7bc7 lint fixes for static regexes +.IP \(bu 2 +d17c46ce41 lint fixes +.IP \(bu 2 +ab8e431729 do not decode registry.pol file wholesale, but instead decode individual elements of the file +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44938\fP: (\fIThe\-Loeki\fP) Libcloud dns fixes +@ \fI2017\-12\-18T15:47:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +d9a4b9681e Merge pull request \fI\%#44938\fP from The\-Loeki/libcloud_dns_fixes +.IP \(bu 2 +276e8828ae libcloud_dns: pylint fix +.IP \(bu 2 +c994423286 Merge branch \(aq2017.7\(aq into libcloud_dns_fixes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44951\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-12\-16T13:16:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44734\fP: (\fIcruscio\fP) Documentation inconsistency for minion ping_interval timing +| refs: \fI\%#44770\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44292\fP: (\fIandrew\-regan\fP) grains[\(aqvirtual_subtype\(aq] assignment for Docker broken on Mac +| refs: \fI\%#44335\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#4\fP: (\fIthatch45\fP) pacman module +.IP \(bu 2 +\fBPR\fP \fI\%#44770\fP: (\fIcruscio\fP) Fix minion ping_interval documentation +.IP \(bu 2 +\fBPR\fP \fI\%#44335\fP: (\fIgtmanfred\fP) add docker\-ce to docker subtype grains check +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +5137be01ec Merge pull request \fI\%#44951\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +a0d2dd2069 Lint fix +.IP \(bu 2 +9db4179462 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +68d901b12c Merge pull request \fI\%#44770\fP from cruscio/2016.11 +.INDENT 2.0 +.IP \(bu 2 +e2682bf441 Fix minion ping_interval documentation +.UNINDENT +.IP \(bu 2 +d4ab55ec47 Merge pull request \fI\%#44335\fP from gtmanfred/2016.11 +.INDENT 2.0 +.IP \(bu 2 +3f1268d67f fix patching for python 2.6 +.IP \(bu 2 +1d0bd5bb32 Merge branch \(aq2016.11\(aq into 2016.11 +.IP \(bu 2 +f02b02032d Merge pull request \fI\%#4\fP from terminalmage/pr\-44335 +.INDENT 2.0 +.IP \(bu 2 +b4eb1527a6 Add test for PR 44335 +.UNINDENT +.IP \(bu 2 +a30af3252e add docker\-ce to docker subtype grains check +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44995\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_file\fP for Windows +@ \fI2017\-12\-15T17:05:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +698b04779e Merge pull request \fI\%#44995\fP from twangboy/win_fix_atomicfile +.IP \(bu 2 +8316481944 Comment the salt import +.IP \(bu 2 +fe34f0c877 Set owner properly on Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44968\fP: (\fIgtmanfred\fP) fix http wait for state +@ \fI2017\-12\-14T20:06:01Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44934\fP: (\fIvernondcole\fP) http.wait_for_successful_query does not pause for documented intervals +| refs: \fI\%#44968\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2e1a57b9bc Merge pull request \fI\%#44968\fP from gtmanfred/http +.IP \(bu 2 +ca6936f6eb fix http wait for state +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +c72db283d5 libcloud_dns: Further fixes to state output, pylint fixes +.IP \(bu 2 +e9bbc23b11 Merge branch \(aq2017.7\(aq into libcloud_dns_fixes +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44900\fP: (\fIxuhcc\fP) Fix TypeError during rbenv ruby installation when rbenv is not found +@ \fI2017\-12\-14T17:37:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44811\fP: (\fIxuhcc\fP) rbenv.installed fails when rbenv installed globally +| refs: \fI\%#44900\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c4f0894689 Merge pull request \fI\%#44900\fP from xuhcc/rbenv\-ret\-fix +.IP \(bu 2 +fdd8310c31 Merge branch \(aq2017.7\(aq into rbenv\-ret\-fix +.IP \(bu 2 +bfd0972d25 Fix TypeError during rbenv ruby installation when rbenv is not found +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44974\fP: (\fItwangboy\fP) Skip test_log_created on Windows +@ \fI2017\-12\-14T13:59:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +f0c2cf3cec Merge pull request \fI\%#44974\fP from twangboy/win_skip_test_parsers +.IP \(bu 2 +40665d7b08 Skip test_log_created on Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44958\fP: (\fIterminalmage\fP) Fix a race condition in manage runner +| refs: \fI\%#44972\fP +@ \fI2017\-12\-13T15:20:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44820\fP: (\fImsteed\fP) Custom returner breaks manage runner +| refs: \fI\%#44958\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +dad2d723ca Merge pull request \fI\%#44958\fP from terminalmage/issue44820 +.IP \(bu 2 +ef749abfc6 No need to manually do connect_pub, use listen=True in run_job +.IP \(bu 2 +2ac70cfab5 Fix a race condition in manage runner +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44956\fP: (\fIterminalmage\fP) Avoid traceback when bogus value in pidfile +@ \fI2017\-12\-13T14:30:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +db58345abb Merge pull request \fI\%#44956\fP from terminalmage/fix\-get_pidfile +.IP \(bu 2 +d66f3a98d7 Avoid traceback when bogus value in pidfile +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44945\fP: (\fIgtmanfred\fP) Fix handling of effective acls +@ \fI2017\-12\-12T21:49:34Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44932\fP: (\fIknine\fP) ACLs Not Completely Verified +| refs: \fI\%#44945\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e8e3b3c8ff Merge pull request \fI\%#44945\fP from gtmanfred/2017.7 +.IP \(bu 2 +66bb755751 add test for effective acls +.IP \(bu 2 +0ff52a93dd use last entry in acl +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44942\fP: (\fIrallytime\fP) Update README with SaltConf18 info +@ \fI2017\-12\-12T21:47:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +47dc7b7afb Merge pull request \fI\%#44942\fP from rallytime/readme\-saltconf\-update +.IP \(bu 2 +d1317c44e2 Update README with SaltConf18 info +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44943\fP: (\fImvivaldi\fP) Fix for the jinja documentation +@ \fI2017\-12\-12T20:20:41Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44665\fP: (\fImvivaldi\fP) Documentation of salt renders jinja +| refs: \fI\%#44895\fP \fI\%#44943\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +7572982419 Merge pull request \fI\%#44943\fP from mvivaldi/filters\-doc +.IP \(bu 2 +d23ac4eabc Fix for the jinja documentation +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44832\fP: (\fIdamon\-atkins\fP) win_pkg: Merge full copy of 2016.11 with many fixes and improvements to 2017.7 +@ \fI2017\-12\-12T18:30:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43417\fP: (\fIdamon\-atkins\fP) win_pkg: pkg.install and pkg.remove general issues +| refs: \fI\%#43708\fP \fI\%#44832\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +465cacad83 Merge pull request \fI\%#44832\fP from damon\-atkins/2017.7_replace_with_newer_2016.11_win_pkg +.IP \(bu 2 +a4f0b41ba2 Should be a smaller change set since recent update from 2016.11 +.IP \(bu 2 +695334b201 Merge branch \(aq2017.7_replace_with_newer_2016.11_win_pkg\(aq of github.com:damon\-atkins/salt into 2017.7_replace_with_newer_2016.11_win_pkg +.INDENT 2.0 +.IP \(bu 2 +843e204582 Merge branch \(aq2017.7\(aq into 2017.7_replace_with_newer_2016.11_win_pkg +.UNINDENT +.IP \(bu 2 +4b60b1ec84 Merge remote branch \(aqrefs/remotes/upstream/2017.7\(aq into 2017.7_replace_with_newer_2016.11_win_pkg +.IP \(bu 2 +b46f818a57 Raise a PR to fix 2016 issues commited here, fixed issues with merge. +.IP \(bu 2 +32ef1e12ae Merge branch \(aq2017.7\(aq into 2017.7_replace_with_newer_2016.11_win_pkg +.IP \(bu 2 +494835c3f2 I backported develop and applied a long list of fixes to 2016.11 this brings these fixes into 2017.7 \- Software was not always being removed, general if & was in the string or msi was downloaded to uninstall the software \- pkg.list_upgrades failed. Added support for \(aqlatest\(aq and \(aqNot Found\(aq for version_cmp() to fix this. \- output fixes \- pkg.list_available no longer forces a pkg.refresh_db this is no longer required, as by default it will update if older than 6 hours \- cmd /s /c is prefixed for all commands i.e. installs and removes. \- cmd are now strings, instead of a list when using cmd.run. As windows only supports strings. And the " were being broken +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44754\fP: (\fItwangboy\fP) Fix inet_pton for Windows on Py3 +@ \fI2017\-12\-12T14:04:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +a811a92b17 Merge pull request \fI\%#44754\fP from twangboy/win_fix_inet_pton +.IP \(bu 2 +25a20109fe Merge branch \(aq2017.7\(aq into win_fix_inet_pton +.IP \(bu 2 +849b99eb34 Merge branch \(aq2017.7\(aq into win_fix_inet_pton +.IP \(bu 2 +df1e6a202b Use salt.ext.six +.IP \(bu 2 +5ac8112585 Use six to ensure unicode value +.IP \(bu 2 +9b5d8c421b Handle unicode values +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44931\fP: (\fIpkruk\fP) add missing parenthis to keep integration with python3 +@ \fI2017\-12\-12T13:49:39Z\fP +.INDENT 2.0 +.IP \(bu 2 +53b34e24cd Merge pull request \fI\%#44931\fP from pkruk/fix\-missing\-parenthis +.IP \(bu 2 +b1ed739b44 Merge branch \(aq2017.7\(aq into fix\-missing\-parenthis +.IP \(bu 2 +4f1b1f12d2 Merge branch \(aqfix\-missing\-parenthis\(aq of \fI\%https://github.com/pkruk/salt\fP into fix\-missing\-parenthis +.INDENT 2.0 +.IP \(bu 2 +3475d3fa01 add missing parenthis to keep integration with python3 +.UNINDENT +.IP \(bu 2 +adf38cacfb add missing parenthis to keep integration with python3 +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +ad55e33f57 libcloud_dns: fix state output +.IP \(bu 2 +a68d594e3a libcloud_dns: copy args before deleting from them +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44891\fP: (\fItwangboy\fP) Fix issue with unsafe path in Windows jenkins tests +@ \fI2017\-12\-11T21:10:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +ba6146250a Merge pull request \fI\%#44891\fP from twangboy/win_fix_verify +.IP \(bu 2 +7232579167 Allow test suite file_roots as a safe path +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44921\fP: (\fICh3LL\fP) Add test to ensure log files are created +@ \fI2017\-12\-11T18:24:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +85160fd297 Merge pull request \fI\%#44921\fP from Ch3LL/log_test +.IP \(bu 2 +3bb58fb577 skip salt\-key log creation test +.IP \(bu 2 +6a379195bc Add test to ensure log files are created +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44787\fP: (\fIrallytime\fP) GroupAdd test: Add destructive test decorator to entire class +@ \fI2017\-12\-11T18:14:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +54d29a61cb Merge pull request \fI\%#44787\fP from rallytime/groupadd\-destructive\-clean +.IP \(bu 2 +817ac002b0 Add destructive test decorator to test class +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44895\fP: (\fImvivaldi\fP) Jinja Filters doc +@ \fI2017\-12\-11T15:32:07Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44665\fP: (\fImvivaldi\fP) Documentation of salt renders jinja +| refs: \fI\%#44895\fP \fI\%#44943\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0292e3612a Merge pull request \fI\%#44895\fP from mvivaldi/filters\-doc +.IP \(bu 2 +62409d608a Added Escape Filters and Set Theory Filters in jinja documentation +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44879\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-12\-10T16:53:44Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44730\fP: (\fImsciciel\fP) State network.routes could not add route without gateway on centos7 +| refs: \fI\%#44741\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44530\fP: (\fIroaldnefs\fP) Identifier not working in salt.states.cron when special is used +| refs: \fI\%#44579\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44365\fP: (\fIicycle77\fP) file.managed appears to ignore source_hash check +| refs: \fI\%#44794\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#35777\fP: (\fIrallytime\fP) Properly deprecate template context data in Fluorine +| refs: \fI\%#44738\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#35523\fP: (\fIrallytime\fP) Come up with a reasonable alternative for lxc.edited_conf +| refs: \fI\%#44738\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44855\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +| refs: \fI\%#44879\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44852\fP: (\fIdamon\-atkins\fP) win_pkg fix spelling typos and minion option 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#44794\fP: (\fIterminalmage\fP) Fix regression in file.managed when source_hash used with local file +.IP \(bu 2 +\fBPR\fP \fI\%#44741\fP: (\fIgtmanfred\fP) if gateway is not specified use iface +.IP \(bu 2 +\fBPR\fP \fI\%#44738\fP: (\fIrallytime\fP) Bump some deprecation warnings from Oxygen to Fluorine +.IP \(bu 2 +\fBPR\fP \fI\%#44579\fP: (\fIroaldnefs\fP) Fix bug in cron module and state \- Fixes \fI\%#44530\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +df28f312ac Merge pull request \fI\%#44879\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +23c5a4ca3e Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +bb1f8dceaf Merge pull request \fI\%#44579\fP from roaldnefs/fix\-cron\-identifier +.INDENT 2.0 +.IP \(bu 2 +df73a4c051 Merge branch \(aq2016.11\(aq into fix\-cron\-identifier +.UNINDENT +.IP \(bu 2 +af0131fa1f Merge pull request \fI\%#44852\fP from damon\-atkins/2016.11_win_pkg_typo_n_fix +.INDENT 2.0 +.IP \(bu 2 +0e7c19084f Lint: Remove extra whitespace +.IP \(bu 2 +7c7e21f94d Fix spelling typo, and fix backwards campatible minion option for repo location +.UNINDENT +.IP \(bu 2 +88c0d66b4e Merge pull request \fI\%#44794\fP from terminalmage/issue44365 +.INDENT 2.0 +.IP \(bu 2 +3b8b6f25e6 Remove debugging line +.IP \(bu 2 +153bf45b03 Fix regression in file.managed when source_hash used with local file +.UNINDENT +.IP \(bu 2 +c8bb9dfbbb Merge pull request \fI\%#44738\fP from rallytime/bump\-oxygen\-warnings +.INDENT 2.0 +.IP \(bu 2 +ead3c569e1 Bump deprecation warnings from Oxygen to Fluorine +.UNINDENT +.IP \(bu 2 +88e3aab00d Merge pull request \fI\%#44741\fP from gtmanfred/rhip +.INDENT 2.0 +.IP \(bu 2 +439dc8dce6 if gateway is not specified use iface +.INDENT 2.0 +.IP \(bu 2 +3ec4329307 Merge branch \(aq2016.11\(aq into fix\-cron\-identifier +.IP \(bu 2 +99fa05a456 Fix for bug in cron state +.IP \(bu 2 +97328faeac Fix for bug in cron module +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44880\fP: (\fIUtahDave\fP) Determine windows hardware arch correctly +@ \fI2017\-12\-08T22:24:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +8e14bc3941 Merge pull request \fI\%#44880\fP from UtahDave/2017.7local +.IP \(bu 2 +6e3c7ac1ac Merge branch \(aq2017.7\(aq into 2017.7local +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44861\fP: (\fItwangboy\fP) Fix win_lgpo for unknown values +| refs: \fI\%#45327\fP +@ \fI2017\-12\-08T18:52:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +dc51174670 Merge pull request \fI\%#44861\fP from twangboy/win_fix_lgpo_invalid_value +.IP \(bu 2 +89f65e19ff Check for values other than 0 or 1 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44621\fP: (\fIisbm\fP) Bugfix: errors in external pillar causes crash, instead of report of them +@ \fI2017\-12\-08T18:46:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +f5a143f8c5 Merge pull request \fI\%#44621\fP from isbm/isbm\-bsc1068446\-2017.7 +.IP \(bu 2 +0d2675c4fe Use variable, instead of direct value +.IP \(bu 2 +1ddc47da0a Add unit test for _get_pillar_errors when external pillar is clean and internal contains errors +.IP \(bu 2 +68480d5dc9 Add unit test for _get_pillar_errors when both external and internal pillars contains errors +.IP \(bu 2 +218a59e93b Add unit test for _get_pillar_errors when external pillar has errors and internal is clean +.IP \(bu 2 +3ce19356c2 Add unit test for _get_pillar_errors when external and internal pillars are clean +.IP \(bu 2 +67034139d9 Fix unit test: wrong error types in side effect +.IP \(bu 2 +d9359bca13 Bugfix: unit test mistakenly expects pillar errors as a string, while it is a list +.IP \(bu 2 +8c2bdc696b Bugfix: do not pull \(aq_errors\(aq from unchecked objects +.IP \(bu 2 +d5e30999c7 Remove unused variable (no exception, within the try/finally block) +.IP \(bu 2 +aad668d559 Fix and clarify docstring. +.IP \(bu 2 +c2c47e4e71 Rename function from ambiguous name +.IP \(bu 2 +265de8e61c Bugfix the logic according to the exact described purpose of the function. +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +dae9c6aa5c Determine windows hardware arch correctly +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43379\fP: (\fItwangboy\fP) Fix file.managed on Windows with test=True +@ \fI2017\-12\-07T21:10:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +abe089ad54 Merge pull request \fI\%#43379\fP from twangboy/win_fix_file.managed +.IP \(bu 2 +edcd581ca5 Merge branch \(aq2017.7\(aq into win_fix_file.managed +.IP \(bu 2 +a27bb6993a Fix py3 error +.IP \(bu 2 +0ff9fa498a Fix test_directory +.IP \(bu 2 +187bc1e61e Add back the try/finally blocks +.IP \(bu 2 +d7241d004f Fix 2 more tests +.IP \(bu 2 +d5dd42aebe Fix integration tests for Windows +.IP \(bu 2 +d56bc9aae9 Fix typo +.IP \(bu 2 +af5565859e Use file functions for symlink and remove +.IP \(bu 2 +72ac59c991 Fix some more integration tests for Linux +.IP \(bu 2 +3f0499cbc4 Fix some integration tests +.IP \(bu 2 +a24b964ea5 Fix unit test to handle new Exception +.IP \(bu 2 +e3c3845f73 Raise CommandExecutionError when file doesn\(aqt exist +.IP \(bu 2 +4602f499a2 Remove loader module mixin, add linux paths +.IP \(bu 2 +99b27c037f Add tests to avoid future regression +.IP \(bu 2 +5c215ed8c2 Fix documentation formatting +.IP \(bu 2 +6a4e77e4b9 Return empty or unmodified dict on file not found +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44570\fP: (\fIgtmanfred\fP) Include client mixin globals in scheduler for runner modules +@ \fI2017\-12\-07T20:23:33Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44565\fP: (\fIarthurlogilab\fP) NameError: global name \(aq__jid_event__\(aq is not defined when running a runner in the scheduler +| refs: \fI\%#44570\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +cf4cbcd340 Merge pull request \fI\%#44570\fP from gtmanfred/2017.7 +.IP \(bu 2 +7b17f9f63c Merge branch \(aq2017.7\(aq into 2017.7 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44494\fP: (\fIskizunov\fP) Fix broken \fIbeacons_before_connect\fP feature +@ \fI2017\-12\-07T18:24:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#38289\fP: (\fIskizunov\fP) Add config options for running beacons/scheduler before connect +| refs: \fI\%#44494\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +febb913743 Merge pull request \fI\%#44494\fP from skizunov/develop2 +.IP \(bu 2 +7adcfbf8ec Merge branch \(aq2017.7\(aq into develop2 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44512\fP: (\fIrallytime\fP) Back\-port \fI\%#44356\fP to 2017.7 +@ \fI2017\-12\-07T14:44:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44298\fP: (\fIskjaro\fP) ipset state check problem +| refs: \fI\%#44356\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#39552\fP: (\fIXiami2012\fP) ipset.check new implementation by @lingonl has countless critical bugs +| refs: \fI\%#44356\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44356\fP: (\fIskjaro\fP) Fix ipset state with multiple entries and subtypes separated with comma +| refs: \fI\%#44512\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +284a817565 Merge pull request \fI\%#44512\fP from rallytime/\fI\%bp\-44356\fP +.IP \(bu 2 +6f92c71834 Merge branch \(aq2017.7\(aq into \fI\%bp\-44356\fP +.IP \(bu 2 +9a325146df Fix lint violation +.IP \(bu 2 +5aac729855 Fix check multiple entries with subtypes separated with comma +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44748\fP: (\fItwangboy\fP) Fix auto login support for OSX +@ \fI2017\-12\-07T14:22:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +74ee7ce541 Merge pull request \fI\%#44748\fP from twangboy/osx_fix_auto_login +.IP \(bu 2 +068e463870 Fix lint, add integration tests +.IP \(bu 2 +3df886df75 Fix lint, add gtmanfreds change +.IP \(bu 2 +16cb24614f Add kcpassword functionality +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44842\fP: (\fItwangboy\fP) Win fix lgpo unicode on Py3 issue +@ \fI2017\-12\-07T14:21:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +b60cca174c Merge pull request \fI\%#44842\fP from twangboy/win_fix_lgpo +.IP \(bu 2 +efe77999d1 Gate log.debug statement behind successful pop +.IP \(bu 2 +1c0ec79cd1 Fix py3 issue +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44843\fP: (\fItwangboy\fP) Fix 2 typos in lgpo module +@ \fI2017\-12\-06T17:56:44Z\fP +.INDENT 2.0 +.IP \(bu 2 +bb58e2fec0 Merge pull request \fI\%#44843\fP from twangboy/win_fix_lgpo_typo +.IP \(bu 2 +c8f93e6dd7 Fix 2 types, shorten line lengths for spellchecking +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44827\fP: (\fImz\-bmcqueen\fP) add more clone options to virtualbox and add better dhcp handling +@ \fI2017\-12\-06T15:02:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +d6c37ea19c Merge pull request \fI\%#44827\fP from mz\-bmcqueen/2017.7 +.IP \(bu 2 +4ead3014b7 Merge branch \(aq2017.7\(aq into 2017.7 +.IP \(bu 2 +b7ce154014 Merge branch \(aq2017.7\(aq of \fI\%https://github.com/mz\-bmcqueen/salt\fP into 2017.7 +.INDENT 2.0 +.IP \(bu 2 +2f80f431b3 Merge branch \(aq2017.7\(aq into 2017.7 +.UNINDENT +.IP \(bu 2 +c2018c9021 fix pylint complaints +.IP \(bu 2 +c38ff74261 add more clone options to virtualbox and add better dhcp handling +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44824\fP: (\fICh3LL\fP) Add spm \-y and \-f arg integration tests +@ \fI2017\-12\-05T21:49:32Z\fP +.INDENT 2.0 +.IP \(bu 2 +019169ed61 Merge pull request \fI\%#44824\fP from Ch3LL/spm_args +.IP \(bu 2 +d8f81d2e4d fix pylint +.IP \(bu 2 +61ac5cf157 Add spm \-y and \-f arg integration tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44742\fP: (\fICh3LL\fP) Add salt\-cloud action rename integration test +@ \fI2017\-12\-05T17:44:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +59b930668c Merge pull request \fI\%#44742\fP from Ch3LL/cloud_action_test +.IP \(bu 2 +951d09ca2f remove unnecessary try/except block +.IP \(bu 2 +c329ced7ee Add salt\-cloud action rename integration test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44771\fP: (\fIgarethgreenaway\fP) [2017.7] Back porting \fI\%#44071\fP +@ \fI2017\-12\-05T17:16:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42676\fP: (\fImind\-code\fP) Changes in Pillar defined Beacons only apply after Minion restart +| refs: \fI\%#44771\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44071\fP: (\fIgarethgreenaway\fP) [develop] Various fixes to beacons +| refs: \fI\%#44771\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +10442d9211 Merge pull request \fI\%#44771\fP from garethgreenaway/42676_backport_44071 +.IP \(bu 2 +ec2a8b2032 Merge branch \(aq2017.7\(aq into 42676_backport_44071 +.IP \(bu 2 +180971203e Updating minion to respond to list_available events for beacons +.IP \(bu 2 +db6fcefe62 Adding list_available which is used by the add function to verify that a becaon exists. +.IP \(bu 2 +e9e0318bc6 Backporting fixes related to having beacons in pillar from \fI\%#44071\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44784\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-12\-05T17:13:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44601\fP: (\fIrallytime\fP) CherryPy 12.0 removed support for "engine.timeout_monitor.on" config option +| refs: \fI\%#44602\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44556\fP: (\fIdoesitblend\fP) \-\-static option doesn\(aqt return highstate output +| refs: \fI\%#44714\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44544\fP: (\fIcreideiki\fP) pgjsonb returner sets wrong timezone on timestamps in database when using Python 2 +| refs: \fI\%#44563\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44423\fP: (\fImtkennerly\fP) The win_path.exists state cannot prepend to the very start of the PATH +| refs: \fI\%#44424\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44034\fP: (\fIseanjnkns\fP) salt\-call pillar overrides broken in 2016.11.8 and 2017.7.2 +| refs: \fI\%#44483\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43417\fP: (\fIdamon\-atkins\fP) win_pkg: pkg.install and pkg.remove general issues +| refs: \fI\%#43708\fP \fI\%#44832\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#41474\fP: (\fIdmaziuk\fP) state.file.* line endings +| refs: \fI\%#44321\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#38452\fP: (\fIjf\fP) file.line with mode=delete does not preserve ownership of a file +.IP \(bu 2 +\fBISSUE\fP \fI\%#31405\fP: (\fISEJeff\fP) Salt leaves tmp file when file.managed dest file is immutable +| refs: \fI\%#44699\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44732\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +| refs: \fI\%#44784\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44714\fP: (\fIrallytime\fP) Allow \-\-static option to display state runs with highstate output +.IP \(bu 2 +\fBPR\fP \fI\%#44699\fP: (\fIjfindlay\fP) utils/files.py remove temp file upon move failure +.IP \(bu 2 +\fBPR\fP \fI\%#44604\fP: (\fIlorengordon\fP) Documents the exclude argument in state execution module +.IP \(bu 2 +\fBPR\fP \fI\%#44602\fP: (\fIrallytime\fP) Handle timeout_monitor attribute error for new versions of CherryPy +| refs: \fI\%#44614\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44563\fP: (\fIcreideiki\fP) Send Unix timestamps to database in pgjsonb returner +.IP \(bu 2 +\fBPR\fP \fI\%#44517\fP: (\fIwhytewolf\fP) Publish port doc missing +.IP \(bu 2 +\fBPR\fP \fI\%#44489\fP: (\fIwhytewolf\fP) update log\-granular\-levels to describe what they are filtering on +.IP \(bu 2 +\fBPR\fP \fI\%#44483\fP: (\fIterminalmage\fP) salt\-call: account for instances where __pillar__ is empty +.IP \(bu 2 +\fBPR\fP \fI\%#44477\fP: (\fIrallytime\fP) Back\-port \fI\%#44424\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#44434\fP: (\fIwhytewolf\fP) add a note that describes grain rebuilding on restart and refresh +.IP \(bu 2 +\fBPR\fP \fI\%#44424\fP: (\fImtkennerly\fP) Fix \fI\%#44423\fP: Handle index=None and index=0 distinctly in the win_path.exists state +| refs: \fI\%#44477\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44321\fP: (\fIgvengel\fP) Fix file.line diff formatting. +.IP \(bu 2 +\fBPR\fP \fI\%#44193\fP: (\fItwangboy\fP) Fix reg.py for use with LGPO module +.IP \(bu 2 +\fBPR\fP \fI\%#43863\fP: (\fInicholasmhughes\fP) Atomicfile only copies mode and not user/group perms +.IP \(bu 2 +\fBPR\fP \fI\%#43708\fP: (\fIdamon\-atkins\fP) Merge Ready : Backport develop win_pkg to 2016.11 with additional bug fixes +.IP \(bu 2 +\fBPR\fP \fI\%#41279\fP: (\fICh3LL\fP) Add fqdn and dns core grain tests +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +23d151b40a Merge pull request \fI\%#44784\fP from rallytime/merge\-2017.7\-1 +.IP \(bu 2 +3d9eafc4bd Lint: Remove extra empty lines at end of files +.IP \(bu 2 +239f3511bf Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +97e0cf569c Merge pull request \fI\%#44699\fP from jfindlay/attr_file +.INDENT 2.0 +.IP \(bu 2 +9e5a40ea7c Merge branch \(aq2016.11\(aq into attr_file +.IP \(bu 2 +5c34607f6c utils/files remove temp file upon move failure +.UNINDENT +.IP \(bu 2 +7434e0afdf Merge pull request \fI\%#44714\fP from rallytime/\fI\%fix\-44556\fP +.INDENT 2.0 +.IP \(bu 2 +1bbe1abeb2 Allow \-\-static option to display state runs with highstate output +.UNINDENT +.IP \(bu 2 +998d714ee7 Merge pull request \fI\%#44517\fP from whytewolf/publish_port_doc_missing +.INDENT 2.0 +.IP \(bu 2 +4b5855283a missed one place where i didnt chanbge master_port from my copy to publish_port +.IP \(bu 2 +e4610baea5 update doc to have publish port +.UNINDENT +.IP \(bu 2 +6169b52749 Merge pull request \fI\%#41279\fP from Ch3LL/add_grain_tests +.INDENT 2.0 +.IP \(bu 2 +1b64f15692 Merge branch \(aq2016.11\(aq into add_grain_tests +.UNINDENT +.IP \(bu 2 +dc6de050a9 Merge pull request \fI\%#44563\fP from creideiki/pgjsonb\-timestamps\-44544 +.INDENT 2.0 +.IP \(bu 2 +231e412ca4 Merge branch \(aq2016.11\(aq into pgjsonb\-timestamps\-44544 +.UNINDENT +.IP \(bu 2 +4369df020b Merge pull request \fI\%#44602\fP from rallytime/\fI\%fix\-44601\fP +.INDENT 2.0 +.IP \(bu 2 +ff303fd060 Handle timeout_monitor/TimeoutError issues for new versions of CherryPy +.UNINDENT +.IP \(bu 2 +4a4756fc37 Merge pull request \fI\%#44604\fP from lorengordon/doc\-exclude +.INDENT 2.0 +.IP \(bu 2 +c4a6c40eb3 Documents the exclude argument in state execution module +.IP \(bu 2 +15c445e6b9 Send Unix timestamps to database in pgjsonb +.IP \(bu 2 +095f1b7d7a Merge branch \(aq2016.11\(aq into add_grain_tests +.UNINDENT +.IP \(bu 2 +91d46d4cfc Merge pull request \fI\%#44434\fP from whytewolf/1837 +.INDENT 2.0 +.IP \(bu 2 +d148e39dda change from md to rst for code reference +.IP \(bu 2 +955e305bda fix bad english, as requested by cachedout +.IP \(bu 2 +7256fcc1c9 update note to take into account grains_cache +.IP \(bu 2 +7a2981585e Merge branch \(aq2016.11\(aq into 1837 +.IP \(bu 2 +aca0405b26 add a note that describes grain rebuilding on restart and refresh +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +9ea4db4224 mock socket.getaddrinfo +.IP \(bu 2 +78a07e30f4 add more fqdn tests and remove some of the mocking +.IP \(bu 2 +5dbf4144ce add ipv6 in opts +.IP \(bu 2 +eabc1b4f9c Add fqdn and dns core grain tests +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +a3bd99317f Merge pull request \fI\%#44321\fP from gvengel/fix\-file\-line\-diff\-output +.INDENT 2.0 +.IP \(bu 2 +69a50204a6 Add newline for lint. +.IP \(bu 2 +ef7b6bbb81 Fixed issue with file.line on Windows running Python 2. +.IP \(bu 2 +8f89c99fa5 Fix FileModuleTest setUp and tearDown to work on Windows. +.IP \(bu 2 +3ac5391f5f Namespace missing functions for file.line on Windows. +.IP \(bu 2 +b2b8f075b9 Fixed test to work on Windows. +.IP \(bu 2 +5a5a2dd026 Added integration test for issue \fI\%#41474\fP +.IP \(bu 2 +24d7315f1a Fix file.line diff formatting. +.UNINDENT +.IP \(bu 2 +9ca563718d Merge pull request \fI\%#43708\fP from damon\-atkins/2016.11_43417_Backport_and_Fixes +.INDENT 2.0 +.IP \(bu 2 +04d03ea6b8 Updated comment +.IP \(bu 2 +1dd565e585 Merge remote branch \(aqupstream/2016.11\(aq into 2016.11_43417_Backport_and_Fixes +.IP \(bu 2 +dd48ba2616 Merge remote branch \(aqupstream/2016.11\(aq into 2016.11_43417_Backport_and_Fixes +.IP \(bu 2 +a0d08598bf dco fix +.IP \(bu 2 +9467899fc6 Merge remote branch \(aqupstream/2016.11\(aq into 2016.11_43417_Backport_and_Fixes +.IP \(bu 2 +6dc180fd0e doco fixes +.IP \(bu 2 +2496a42ea4 lint fix +.IP \(bu 2 +2c937fbe19 Merge remote branch \(aqupstream/2016.11\(aq into 2016.11_43417_Backport_and_Fixes +.IP \(bu 2 +c9c8c48a4d all remove/install commands are passed to cmd.exe /s /c and commands are passed as strings to cmdmod +.IP \(bu 2 +350244bd93 typo in comments and doc strings. +.IP \(bu 2 +ec31f5a9bd 2017.11/develop version() was ignoring saltenv setting. +.IP \(bu 2 +b314549a32 Backport of devlop to 2016.11 with additional bug fixes +.UNINDENT +.IP \(bu 2 +68ea22188e Merge pull request \fI\%#44477\fP from rallytime/\fI\%bp\-44424\fP +.INDENT 2.0 +.IP \(bu 2 +4a9f8dcc96 Fix \fI\%#44423\fP: Handle index=None and index=0 distinctly +.UNINDENT +.IP \(bu 2 +2c89050a24 Merge pull request \fI\%#44483\fP from terminalmage/issue44034 +.INDENT 2.0 +.IP \(bu 2 +a9db8becea salt\-call: account for instances where __pillar__ is empty +.UNINDENT +.IP \(bu 2 +b5c2028680 Merge pull request \fI\%#44489\fP from whytewolf/1956_log\-granular\-levels +.INDENT 2.0 +.IP \(bu 2 +9cdeb4e903 update log\-granular\-levels to describe what they are filtering on +.UNINDENT +.IP \(bu 2 +ea07f9c54c Merge pull request \fI\%#44193\fP from twangboy/win_fix_reg +.INDENT 2.0 +.IP \(bu 2 +44d6d9f46d Remove unused import (lint) +.IP \(bu 2 +f7502436bd Fix various issues +.IP \(bu 2 +221e6e3b91 make salt.utils.to_unicode return none when passed none +.IP \(bu 2 +ce41acc788 Fix many issues with reg.py +.IP \(bu 2 +4a19df1f7f Use six.text_type instead of str +.IP \(bu 2 +1b12acd303 Check type before casting +.IP \(bu 2 +03fa37b445 Cast vdata to it\(aqs proper type +.UNINDENT +.IP \(bu 2 +ed8da2450b Merge pull request \fI\%#43863\fP from nicholasmhughes/fix\-atomicfile\-permission\-copy +.INDENT 2.0 +.IP \(bu 2 +ea852ec5d3 remove index use with stat module attributes +.IP \(bu 2 +dbeeb0e917 fixes \fI\%#38452\fP atomicfile only copies mode and not user/group perms +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44788\fP: (\fIkris\-anderson\fP) Example yaml of influxdb_user state +@ \fI2017\-12\-04T14:28:45Z\fP +.INDENT 2.0 +.IP \(bu 2 +4643a112e7 Merge pull request \fI\%#44788\fP from kris\-anderson/example\-yaml\-of\-influxdb\-user\-state +.IP \(bu 2 +afd23d058c converted yaml example to use 2 spaces +.IP \(bu 2 +29e410c1ea added a code\-block example of how the yaml should be formatted +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44735\fP: (\fIgracinet\fP) Backported issue \fI\%#42713\fP to 2017.7 +@ \fI2017\-12\-04T01:43:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42713\fP: (\fIboltronics\fP) 2017.7.0 master upgrade breaks mine data on non\-glob matching on minions +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +4ebac09f60 Merge pull request \fI\%#44735\fP from gracinet/42713_backport_2017.7 +.IP \(bu 2 +6806d83314 Merge branch \(aq2017.7\(aq into 42713_backport_2017.7 +.IP \(bu 2 +fb586c6dce Backported issue \fI\%#42713\fP to 2017.7 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44766\fP: (\fItwangboy\fP) Fix \fIunit.utils.test_process\fP for Windows +@ \fI2017\-12\-02T13:15:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +06ce7b7328 Merge pull request \fI\%#44766\fP from twangboy/win_fix_test_process +.IP \(bu 2 +a5737e8fc3 Fix lint errors +.IP \(bu 2 +be96de09cc Fix pickling error by decorating +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44716\fP: (\fIrallytime\fP) Back\-port \fI\%#44605\fP to 2017.7 +@ \fI2017\-12\-01T23:12:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44083\fP: (\fIari\fP) timezone.system fails when /etc/localtime is missing on FreeBSD +| refs: \fI\%#44605\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44605\fP: (\fIcampbellmc\fP) Add handling for FreeBSD in timezone.zone_compare +| refs: \fI\%#44716\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f8b8a8966d Merge pull request \fI\%#44716\fP from rallytime/\fI\%bp\-44605\fP +.IP \(bu 2 +9d43221422 Correct indentation +.IP \(bu 2 +d6e28ebed1 Add handling for FreeBSD in method zone_compare to avoid exception when /etc/localtime file does is absent. This is valid configuration on FreeBSD and represents UTC. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44781\fP: (\fImirceaulinic\fP) Correct the thorium runner +@ \fI2017\-12\-01T22:55:52Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#41869\fP: (\fImirceaulinic\fP) Thorium: unable to execute runners +| refs: \fI\%#44781\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +8ed6287762 Merge pull request \fI\%#44781\fP from cloudflare/thorium\-\fI\%fix\-41869\fP +.IP \(bu 2 +83c73a69cb Instance the Runner class instead of the RunnerClient as we\(aqre running on the Master +.IP \(bu 2 +b72b7c5402 Correct the thorium runner +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44466\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_disk\fP for Windows +@ \fI2017\-12\-01T22:31:42Z\fP +.INDENT 2.0 +.IP \(bu 2 +52596be102 Merge pull request \fI\%#44466\fP from twangboy/win_fix_test_disk +.IP \(bu 2 +5615862f23 Fix some lint +.IP \(bu 2 +627d5ab0c9 Mock \fIsalt.utils.which\fP +.IP \(bu 2 +e5a96fe00f Skip test_fstype on Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44719\fP: (\fIrallytime\fP) Back\-port \fI\%#44667\fP to 2017.7 +@ \fI2017\-12\-01T15:20:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42763\fP: (\fIxuhcc\fP) acme.cert state falsely reports about renewed certificate +| refs: \fI\%#44667\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44667\fP: (\fIoarmstrong\fP) Fix acme.cert to run certbot non\-interactively +| refs: \fI\%#44719\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b9ad4bba2d Merge pull request \fI\%#44719\fP from rallytime/\fI\%bp\-44667\fP +.IP \(bu 2 +3d85a260c4 Fix acme.cert to run certbot non\-interactively +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44747\fP: (\fIgtmanfred\fP) use a copy so roster_defaults doesn\(aqt mangle +@ \fI2017\-12\-01T15:13:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44744\fP: (\fIbrmzkw\fP) roster_defaults breaks salt\-ssh globbing +| refs: \fI\%#44747\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +d23192c492 Merge pull request \fI\%#44747\fP from gtmanfred/roster_defaults +.IP \(bu 2 +911411ed8f add unit test +.IP \(bu 2 +eefcfc719c use a copy so roster_defaults doesn\(aqt mangle +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44717\fP: (\fIgarethgreenaway\fP) [2017.7] Fixes to at module +@ \fI2017\-12\-01T14:37:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44694\fP: (\fIthuhak\fP) state module at.absent does\(aqt work +| refs: \fI\%#44717\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +20f20ad9e1 Merge pull request \fI\%#44717\fP from garethgreenaway/44694_at_absent_failing_to_find_jobs +.IP \(bu 2 +1f2b3c5f46 Merge branch \(aq2017.7\(aq into 44694_at_absent_failing_to_find_jobs +.IP \(bu 2 +3bb385b44e removing debugging logging +.IP \(bu 2 +7f0ff5a8b0 When passing IDs on the command line convert them all the strings for later comparision. +.IP \(bu 2 +99e436add4 When looking for job ids to remove based on the tag_name the comparision was comparing an INT to a STR, so the correct job id was not being returned. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44695\fP: (\fIgtmanfred\fP) pop None for runas and runas_password +@ \fI2017\-12\-01T14:35:01Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44136\fP: (\fIdupsatou\fP) KeyError: \(aqrunas\(aq after updating to latest salt in yum repo. +| refs: \fI\%#44695\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6e61aa787f Merge pull request \fI\%#44695\fP from gtmanfred/pop +.IP \(bu 2 +0efb90b6f7 Merge branch \(aq2017.7\(aq into pop +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44725\fP: (\fIwhytewolf\fP) document note suggesting systemd\-run \-\-scope with cmd.run_bg +@ \fI2017\-11\-30T19:18:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +20391c54c0 Merge pull request \fI\%#44725\fP from whytewolf/1919_cmd.run_no_daemons +.IP \(bu 2 +4b11f8d66d add quick documentation suggesting systemd\-run \-\-scope if using cmd.run_bg with systemd +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44760\fP: (\fImirceaulinic\fP) Fix the grains.setvals execution function when working with proxy minions +@ \fI2017\-11\-30T18:27:02Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42300\fP: (\fImirceaulinic\fP) Grains state doesn\(aqt work (fine) with proxy minions +| refs: \fI\%#44760\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#42074\fP: (\fImirceaulinic\fP) How to configure static grains for proxy minions +| refs: \fI\%#44549\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44549\fP: (\fImirceaulinic\fP) Allow proxy minions to load static grains +| refs: \fI\%#44760\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +85451ae977 Merge pull request \fI\%#44760\fP from cloudflare/px\-grains\-set\-42300 +.IP \(bu 2 +655139d01c Different path to the static grains file when running under a proxy minion +.IP \(bu 2 +3eec8dbc63 Dummy proxy: catch EOFError instead of IOError +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44640\fP: (\fIvutny\fP) Fix \fI\%#44583\fP: splay with cron\-like scheduled jobs +@ \fI2017\-11\-30T15:30:41Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44583\fP: (\fIcreideiki\fP) Using splay in cron schedule throws exception "unsupported operand type(s) for +: \(aqNoneType\(aq and \(aqint\(aq" +| refs: \fI\%#44640\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +06fb80b69c Merge pull request \fI\%#44640\fP from vutny/fix\-cron\-schedule\-splay +.IP \(bu 2 +d1f247e49e Add basic unit tests for schedule util eval func +.IP \(bu 2 +6ff8e75ac6 Fix \fI\%#44583\fP: splay with cron\-like scheduled jobs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44712\fP: (\fICh3LL\fP) Add pillar ssh integration tests +@ \fI2017\-11\-30T15:29:33Z\fP +.INDENT 2.0 +.IP \(bu 2 +e5a1401b82 Merge pull request \fI\%#44712\fP from Ch3LL/ssh_pillar_items +.IP \(bu 2 +97ec0e6ea0 Merge branch \(aq2017.7\(aq into ssh_pillar_items +.IP \(bu 2 +c7f5af1274 Add pillar ssh integration tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44763\fP: (\fImirceaulinic\fP) Just a small improvement to the Thorium documentation +@ \fI2017\-11\-30T14:38:03Z\fP +.INDENT 2.0 +.IP \(bu 2 +2e1c946990 Merge pull request \fI\%#44763\fP from cloudflare/thorium\-doc +.IP \(bu 2 +f8d69dd0ba Add thorium_roots configuration example +.IP \(bu 2 +4610fb4e62 thorium_roots not thorium_roots_dir +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44531\fP: (\fImirceaulinic\fP) Add deprecation notes for the NAPALM native templates +@ \fI2017\-11\-30T14:18:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +8ba2df1ea0 Merge pull request \fI\%#44531\fP from cloudflare/deprecate\-napalm\-tpl +.IP \(bu 2 +b462776d8b Add deprecation notes for the NAPALM native templates +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44737\fP: (\fItwangboy\fP) Skip \fIunit.transport.test_ipc\fP for Windows +@ \fI2017\-11\-29T19:18:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +7bde48282e Merge pull request \fI\%#44737\fP from twangboy/win_skip_test_ipc +.IP \(bu 2 +4e0359b603 Skip IPC transport tests in Windows, not supported +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44629\fP: (\fICh3LL\fP) Add masterless state.highstate integration test +@ \fI2017\-11\-29T19:05:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +c5206113ce Merge pull request \fI\%#44629\fP from Ch3LL/high_masterless +.IP \(bu 2 +9b7421b261 Change check to the state id +.IP \(bu 2 +9cc853e3d5 Add masterless state.highstate integration test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44613\fP: (\fICh3LL\fP) Add pillar.items test for masterless +@ \fI2017\-11\-29T14:43:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +2dc3e5c42a Merge pull request \fI\%#44613\fP from Ch3LL/pillar_masterless +.IP \(bu 2 +2c2e1e2332 Merge branch \(aq2017.7\(aq into pillar_masterless +.IP \(bu 2 +69134e83ca Change order of local kwarg in run_call method +.IP \(bu 2 +b3b5ecc6ff Add pillar.items test for masterless +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44659\fP: (\fICh3LL\fP) Add state.sls_id to ssh wrapper and tests +@ \fI2017\-11\-29T14:41:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +cc05481026 Merge pull request \fI\%#44659\fP from Ch3LL/ssh_sls_id +.IP \(bu 2 +04b5a3dd4e Add state.sls_id to ssh wrapper and tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44698\fP: (\fICh3LL\fP) Add salt\-ssh mine.get integration test +@ \fI2017\-11\-28T22:15:29Z\fP +.INDENT 2.0 +.IP \(bu 2 +642eed11e1 Merge pull request \fI\%#44698\fP from Ch3LL/mine_ssh +.IP \(bu 2 +f6a72acfe3 Merge branch \(aq2017.7\(aq into mine_ssh +.IP \(bu 2 +9e67babf85 Add teardown to remove ssh dir +.IP \(bu 2 +f90b4f7653 Add salt\-ssh mine.get integration test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44697\fP: (\fICh3LL\fP) Sort the show_top results for test_state_show_top test +@ \fI2017\-11\-28T20:35:41Z\fP +.INDENT 2.0 +.IP \(bu 2 +5d82df5667 Merge pull request \fI\%#44697\fP from Ch3LL/show_top_test +.IP \(bu 2 +974db59dc1 convert the assert to a union set instead +.IP \(bu 2 +add43c4cfe Sort the show_top results for test_state_show_top test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44608\fP: (\fICh3LL\fP) Add jinja to ssh sls test file +@ \fI2017\-11\-27T22:00:28Z\fP +.INDENT 2.0 +.IP \(bu 2 +f2f6817e86 Merge pull request \fI\%#44608\fP from Ch3LL/ssh_jinja +.IP \(bu 2 +df669b551d Merge branch \(aq2017.7\(aq into ssh_jinja +.IP \(bu 2 +ca97517795 Add jinja to ssh sls test file +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44663\fP: (\fIwhytewolf\fP) Update notes around grains topic, and salt.modules.grains and salt.state.grains +@ \fI2017\-11\-27T21:33:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#33957\fP: (\fIgrobinson\-blockchain\fP) grains.setval doesn\(aqt setval if set in /etc/salt/minion +| refs: \fI\%#44663\fP \fI\%#44663\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +04b97bcfad Merge pull request \fI\%#44663\fP from whytewolf/ZD1777_ensure_understanding_of_minion_config_over_grains_file +.IP \(bu 2 +c9122e4b85 fixed pylint error, and updated description on at the top the the module and state. +.IP \(bu 2 +7fb208b5ad Update note in topics/grains to reflect that not all grains are ignored. only those set in the minion config +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44332\fP: (\fImirceaulinic\fP) Improve the net.load_config execution function +@ \fI2017\-11\-27T21:22:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#11\fP: (\fIthatch45\fP) Add disable_modules to the config +.IP \(bu 2 +\fBISSUE\fP \fI\%#10\fP: (\fIthatch45\fP) list jobs option +.IP \(bu 2 +\fBISSUE\fP \fI\%#9\fP: (\fIthatch45\fP) Enable authentication modes +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +364deee6ac Merge pull request \fI\%#44332\fP from cloudflare/improve\-net\-load +.IP \(bu 2 +cd0bac87e6 Merge branch \(aq2017.7\(aq into improve\-net\-load +.IP \(bu 2 +6d861f9a74 Disable pylint warning +.IP \(bu 2 +3a0945ce3d Merge pull request \fI\%#11\fP from tonybaloney/gh_44332_clone +.INDENT 2.0 +.IP \(bu 2 +88ef9f18fc ignore lint error on import +.IP \(bu 2 +25427d845e convert key iterator to list as python 3 wont index an iterator +.UNINDENT +.IP \(bu 2 +bce50154e5 Merge branch \(aq2017.7\(aq into improve\-net\-load +.IP \(bu 2 +ba4a62769c Fix trailing spaces +.IP \(bu 2 +0a47a7acbf Merge pull request \fI\%#10\fP from tonybaloney/gh_44332_clone +.INDENT 2.0 +.IP \(bu 2 +ba0280e727 linting updates +.IP \(bu 2 +78b90f3d0c add remaining tests +.IP \(bu 2 +386c4e5791 add tests for all the getters +.UNINDENT +.IP \(bu 2 +f3d2d1aaaa Merge pull request \fI\%#9\fP from tonybaloney/gh_44332_clone +.INDENT 2.0 +.IP \(bu 2 +c63222358b update tests with correct assertions and mock methods on device instance +.IP \(bu 2 +b69c559c52 fix kwargs typo +.UNINDENT +.IP \(bu 2 +edea76d3f3 Improve the net.load_config function +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44664\fP: (\fImvivaldi\fP) Patch 1 +@ \fI2017\-11\-27T21:17:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +b6a1ed06b8 Merge pull request \fI\%#44664\fP from mvivaldi/patch\-1 +.IP \(bu 2 +4551999ec7 Update jinja.py +.IP \(bu 2 +ae13d57307 Update file.py +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44549\fP: (\fImirceaulinic\fP) Allow proxy minions to load static grains +| refs: \fI\%#44760\fP +@ \fI2017\-11\-27T20:57:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42074\fP: (\fImirceaulinic\fP) How to configure static grains for proxy minions +| refs: \fI\%#44549\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +9ea4ee1479 Merge pull request \fI\%#44549\fP from cloudflare/fix\-proxy\-grains +.IP \(bu 2 +7b03574ab6 Merge branch \(aq2017.7\(aq into fix\-proxy\-grains +.IP \(bu 2 +0320174ea4 Add doc note regarding static grains on proxy minions +.IP \(bu 2 +509d1af832 Allow proxy minions to load static grains +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44572\fP: (\fICh3LL\fP) Add watch_in integration test +@ \fI2017\-11\-27T20:52:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +5ec7ea0bb5 Merge pull request \fI\%#44572\fP from Ch3LL/watchin_test +.IP \(bu 2 +0a54584ddb Merge branch \(aq2017.7\(aq into watchin_test +.IP \(bu 2 +898c28e6d9 Merge branch \(aq2017.7\(aq into watchin_test +.IP \(bu 2 +3df70f3fed remove iter for watch_in failure test +.IP \(bu 2 +ac437ddf90 add order check and remove iter +.IP \(bu 2 +5f2b4f434e Add watch_in integration test +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +c6733ac1ee pop None +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44616\fP: (\fICh3LL\fP) Add Non Base Environement salt:// source integration test +@ \fI2017\-11\-22T16:13:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +d6ccf4bb30 Merge pull request \fI\%#44616\fP from Ch3LL/nonbase_test +.IP \(bu 2 +80b71652e3 Merge branch \(aq2017.7\(aq into nonbase_test +.IP \(bu 2 +c9ba33432e Add Non Base Environement salt:// source integration test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44617\fP: (\fICh3LL\fP) Add ssh thin_dir integration test +@ \fI2017\-11\-22T16:12:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +3ace504c8c Merge pull request \fI\%#44617\fP from Ch3LL/thindir_ssh +.IP \(bu 2 +071a1bd65b Merge branch \(aq2017.7\(aq into thindir_ssh +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44625\fP: (\fICh3LL\fP) Add salt\-key \-d integration test +@ \fI2017\-11\-22T03:15:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +2cd618f99b Merge pull request \fI\%#44625\fP from Ch3LL/delete_key_test +.IP \(bu 2 +443dc1e16b Merge branch \(aq2017.7\(aq into delete_key_test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44614\fP: (\fIrallytime\fP) [2017.7] Move PR \fI\%#44602\fP forward to 2017.7 +@ \fI2017\-11\-21T21:21:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44601\fP: (\fIrallytime\fP) CherryPy 12.0 removed support for "engine.timeout_monitor.on" config option +| refs: \fI\%#44602\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44602\fP: (\fIrallytime\fP) Handle timeout_monitor attribute error for new versions of CherryPy +| refs: \fI\%#44614\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +4f30e845ee Merge pull request \fI\%#44614\fP from rallytime/44602\-2017.7 +.IP \(bu 2 +628f015c1b Move TimoutError check lower down in exception list +.IP \(bu 2 +d26d9ff5e4 Handle timeout_monitor/TimeoutError issues for new versions of CherryPy +.IP \(bu 2 +359a59dd64 Add salt\-key \-d integration test +.IP \(bu 2 +74ededafa7 Add ssh thin_dir integration test +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +4d0806e28c Merge branch \(aq2017.7\(aq into develop2 +.IP \(bu 2 +4d0d023115 Fix broken \fIbeacons_before_connect\fP feature +.INDENT 2.0 +.IP \(bu 2 +98536110d9 Merge branch \(aq2017.7\(aq into 2017.7 +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44571\fP: (\fIrallytime\fP) Back\-port \fI\%#43822\fP to 2017.7 +@ \fI2017\-11\-20T19:01:26Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#43822\fP: (\fIchnrxn\fP) check_result: Correctly check the __extend__ state. +| refs: \fI\%#44571\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +136b9e3bc4 Merge pull request \fI\%#44571\fP from rallytime/\fI\%bp\-43822\fP +.IP \(bu 2 +f81bb61f2d check_result: Correctly check the __extend__ state. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44588\fP: (\fIrallytime\fP) Add documentation about logging before modules are loaded +@ \fI2017\-11\-20T18:43:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#44576\fP: (\fIrallytime\fP) Remove logging from top of napalm util file +| refs: \fI\%#44588\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44439\fP: (\fImirceaulinic\fP) Adapt napalm modules to the new library structure +| refs: \fI\%#44576\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +bea7f65291 Merge pull request \fI\%#44588\fP from rallytime/logging\-in\-virtual\-funcs +.IP \(bu 2 +90d1cb221d Add documentation about logging before modules are loaded +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44513\fP: (\fIrallytime\fP) Back\-port \fI\%#44472\fP to 2017.7 +@ \fI2017\-11\-20T16:09:02Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#44472\fP: (\fImephi42\fP) nova: fix endpoint URL determination in _v3_setup() +| refs: \fI\%#44513\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a8044b73c3 Merge pull request \fI\%#44513\fP from rallytime/\fI\%bp\-44472\fP +.IP \(bu 2 +6e00e415d3 nova: fix endpoint URL determination in _v3_setup() +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44596\fP: (\fIroaldnefs\fP) Fixed Mattermost module documentation +@ \fI2017\-11\-19T23:30:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +f55b9daa63 Merge pull request \fI\%#44596\fP from roaldnefs/fix\-mattermost\-doc +.IP \(bu 2 +549f4806ce Fixed documentation in Mattermost module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44528\fP: (\fItkwilliams\fP) INFRA\-5978 \- fix for \fI\%https://github.com/saltstack/salt/issues/44290\fP +@ \fI2017\-11\-17T17:35:44Z\fP +.INDENT 2.0 +.IP \(bu 2 +f84a2b5ab1 Merge pull request \fI\%#44528\fP from bodhi\-space/infra5978 +.IP \(bu 2 +ba1d57f5eb Merge branch \(aq2017.7\(aq into infra5978 +.IP \(bu 2 +021692b6c9 INFRA\-5978 \- pylint / whitespace fix +.IP \(bu 2 +c2210aaf7c INFRA\-5978 \- fix for \fI\%https://github.com/saltstack/salt/issues/44290\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44537\fP: (\fICh3LL\fP) Add multiple salt\-ssh state integration tests +@ \fI2017\-11\-17T17:17:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +7f2dd0382c Merge pull request \fI\%#44537\fP from Ch3LL/ssh_highlow +.IP \(bu 2 +b98df6de24 Add known_hosts_file to salt\-ssh opts_pkg in wfuncs +.IP \(bu 2 +913eedc699 Add multiple salt\-ssh state integration tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44576\fP: (\fIrallytime\fP) Remove logging from top of napalm util file +| refs: \fI\%#44588\fP +@ \fI2017\-11\-17T14:55:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#44439\fP: (\fImirceaulinic\fP) Adapt napalm modules to the new library structure +| refs: \fI\%#44576\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +1975fb41bc Merge pull request \fI\%#44576\fP from rallytime/remove\-napalm\-logging +.IP \(bu 2 +eb91af999e Remove logging from top of napalm util file +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44575\fP: (\fICh3LL\fP) Add service.running integration state test +@ \fI2017\-11\-16T22:27:57Z\fP +.INDENT 2.0 +.IP \(bu 2 +c2c3048f46 Merge pull request \fI\%#44575\fP from Ch3LL/ser_run_test +.IP \(bu 2 +7536150567 Add service.running integration state test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44518\fP: (\fItwangboy\fP) Pass root_dir to the win_verify_env function +@ \fI2017\-11\-16T20:57:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +24b1d7af31 Merge pull request \fI\%#44518\fP from twangboy/win_fix_verify_env +.IP \(bu 2 +47114fdb30 Pass root_dirs to the win_verify_env function +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +3385f7faf3 fix pylint +.IP \(bu 2 +a2af3cb857 Include client mixin globals in scheduler for runner modules +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44551\fP: (\fImirceaulinic\fP) Removes proxy minions false alarms and security risks +@ \fI2017\-11\-16T15:09:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +1643bb7fd4 Merge pull request \fI\%#44551\fP from cloudflare/annoying\-tmpnam +.IP \(bu 2 +ce1882943d Use salt.utils.files.mkstemp() instead +.IP \(bu 2 +6689bd3b2d Dont use dangerous os.tmpnam +.IP \(bu 2 +2d6176b0bc Fx2 proxy minion: clean return, like all the other modules +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44541\fP: (\fIterminalmage\fP) Fix test to reflect changes in YAML dumper +@ \fI2017\-11\-15T13:23:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#30454\fP: (\fIfavoretti\fP) Using yaml serializer inside jinja template results in unicode being prepended by \(aq!!python/unicode\(aq +| refs: \fI\%#42064\fP \fI\%#38554\fP \fI\%#38554\fP \fI\%#30481\fP +.IP \(bu 2 +\fBPR\fP \fI\%#42064\fP: (\fIThe\-Loeki\fP) utils.jinja: use utils.yamldumper for safe yaml dumping +| refs: \fI\%#44541\fP +.IP \(bu 2 +\fBPR\fP \fI\%#38554\fP: (\fImultani\fP) Fix YAML deserialization of unicode +| refs: \fI\%#42064\fP +.IP \(bu 2 +\fBPR\fP \fI\%#30481\fP: (\fIbasepi\fP) Add yaml_safe jinja filter +| refs: \fI\%#38554\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +60083ac27b Merge pull request \fI\%#44541\fP from terminalmage/fix\-yaml\-test +.IP \(bu 2 +5b8f54084b Merge branch \(aq2017.7\(aq into fix\-yaml\-test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44538\fP: (\fIgtmanfred\fP) Fix up some test kitchen stuff +@ \fI2017\-11\-14T20:36:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +5c123eb551 Merge pull request \fI\%#44538\fP from gtmanfred/kitchen +.IP \(bu 2 +3e04d2d44c use kitchen\-sync for copying files +.IP \(bu 2 +9bc70fd31b back up to 2017.7.1 for kitchen tests +.IP \(bu 2 +3b93ea058b ubuntu 14 and centos 6 should not have py3 tests +.IP \(bu 2 +958e1aeb8d Fix test to reflect changes in YAML dumper +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#42064\fP: (\fIThe\-Loeki\fP) utils.jinja: use utils.yamldumper for safe yaml dumping +| refs: \fI\%#44541\fP +@ \fI2017\-11\-13T19:45:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#30454\fP: (\fIfavoretti\fP) Using yaml serializer inside jinja template results in unicode being prepended by \(aq!!python/unicode\(aq +| refs: \fI\%#42064\fP \fI\%#38554\fP \fI\%#38554\fP \fI\%#30481\fP +.IP \(bu 2 +\fBPR\fP \fI\%#38554\fP: (\fImultani\fP) Fix YAML deserialization of unicode +| refs: \fI\%#42064\fP +.IP \(bu 2 +\fBPR\fP \fI\%#30481\fP: (\fIbasepi\fP) Add yaml_safe jinja filter +| refs: \fI\%#38554\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +27a7b607b1 Merge pull request \fI\%#42064\fP from The\-Loeki/jinja_unicode +.IP \(bu 2 +b1cf43c02d Merge branch \(aq2017.7\(aq into jinja_unicode +.IP \(bu 2 +8c2ac58523 Merge branch \(aq2017.7\(aq into jinja_unicode +.IP \(bu 2 +57dc6226a2 Merge branch \(aq2017.7\(aq into jinja_unicode +.IP \(bu 2 +0a8346b585 Merge branch \(aq2017.7\(aq into jinja_unicode +.IP \(bu 2 +393fe061b2 jinja utils: yaml import still necessary +.IP \(bu 2 +3c9130f9f0 utils.jinja: use utils.yamldumper for safe yaml dumping +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43692\fP: (\fImirceaulinic\fP) Addressing a bug in the network find runner +@ \fI2017\-11\-13T19:42:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +b1f14c7518 Merge pull request \fI\%#43692\fP from cloudflare/fix\-net\-runner +.IP \(bu 2 +02ffb4f38e Merge branch \(aq2017.7\(aq into fix\-net\-runner +.IP \(bu 2 +4b2f791bd2 Check if addr is short IPv6 +.IP \(bu 2 +765504c137 Add all the possible keys to the result +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43689\fP: (\fIThe\-Loeki\fP) make cached pillars use pillarenv rather than saltenv +@ \fI2017\-11\-13T19:30:00Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42393\fP: (\fIThe\-Loeki\fP) pillarenv ignored with Salt Master pillar_cache: True +| refs: \fI\%#43689\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#36153\fP: (\fIkrcroft\fP) Pillarenv doesn\(aqt allow using separate pillar environments +| refs: \fI\%#43689\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +1e94a5bd5f Merge pull request \fI\%#43689\fP from The\-Loeki/cached_pilarenv +.IP \(bu 2 +395c0c424d Merge branch \(aq2017.7\(aq into cached_pilarenv +.IP \(bu 2 +60e001733b make cached pillars use pillarenv rather than saltenv +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43837\fP: (\fItwangboy\fP) Fix \fIunit.states.test_archive\fP for Windows +@ \fI2017\-11\-13T19:12:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +f9b273a894 Merge pull request \fI\%#43837\fP from twangboy/win_unit_test_archive +.IP \(bu 2 +5505a8819a Merge branch \(aq2017.7\(aq into win_unit_test_archive +.IP \(bu 2 +b1dfe9c3c8 Format patching with statements for easier reading +.IP \(bu 2 +ba2f2eb788 Add Erik\(aqs changes +.IP \(bu 2 +4ef1e3eb97 Fix \fIunit.states.test_archive\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44507\fP: (\fICh3LL\fP) Increase sleep timeout for pillar refresh test +@ \fI2017\-11\-13T18:29:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +caa81728a0 Merge pull request \fI\%#44507\fP from Ch3LL/pillar_time +.IP \(bu 2 +ffa4bddcad Increase sleep timeout for pillar refresh test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44302\fP: (\fImorganwillcock\fP) Fix traceback and incorrect message when resolving an unresolvable SID +@ \fI2017\-11\-13T18:19:01Z\fP +.INDENT 2.0 +.IP \(bu 2 +cffea5ac71 Merge pull request \fI\%#44302\fP from morganwillcock/badsid +.IP \(bu 2 +f3af106e33 Merge branch \(aqbadsid\(aq of \fI\%https://github.com/morganwillcock/salt\fP into badsid +.INDENT 2.0 +.IP \(bu 2 +95733fbb3b Merge branch \(aq2017.7\(aq into badsid +.IP \(bu 2 +facc2cd16e Merge branch \(aq2017.7\(aq into badsid +.UNINDENT +.IP \(bu 2 +c7cf5f6f70 Format pywintypes.error +.IP \(bu 2 +9572aabb67 Fix traceback and incorrect message when resolving an unresolvable SID +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44439\fP: (\fImirceaulinic\fP) Adapt napalm modules to the new library structure +| refs: \fI\%#44576\fP +@ \fI2017\-11\-13T17:43:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +32fc952000 Merge pull request \fI\%#44439\fP from cloudflare/fix\-napalm +.IP \(bu 2 +f45378af04 Lint: remove extra spaces +.IP \(bu 2 +c6a38258a3 Add napalm>2.0.0 note and update URLs +.IP \(bu 2 +52f73835b8 Adapt napalm modules to the new library structure +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44457\fP: (\fItwangboy\fP) Remove wmi monkeypatching +@ \fI2017\-11\-13T17:38:52Z\fP +.INDENT 2.0 +.IP \(bu 2 +ebbe5949ea Merge pull request \fI\%#44457\fP from twangboy/win_remove_wmi_monkeypatching +.IP \(bu 2 +6c872e95e6 Add back the setup_loader_modules function +.IP \(bu 2 +20273e3697 No need for setup_loader_modules since we\(aqre actually importing wmi +.IP \(bu 2 +8c107873cd Remove wmi monkeypatching +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44490\fP: (\fICh3LL\fP) Enable test_deploy ssh test +@ \fI2017\-11\-13T17:12:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +1da1a97d7d Merge pull request \fI\%#44490\fP from Ch3LL/ssh_ping +.IP \(bu 2 +e952cd6712 Enable test_deploy ssh test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44491\fP: (\fICh3LL\fP) Add salt\-ssh raw integration tests +@ \fI2017\-11\-13T15:47:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +18624d6798 Merge pull request \fI\%#44491\fP from Ch3LL/ssh_raw +.IP \(bu 2 +3dc8673417 change class name to raw +.IP \(bu 2 +308596ac8d Add salt\-ssh raw integration tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44492\fP: (\fItwangboy\fP) Fix \fIunit.utils.test_cloud\fP for Windows +@ \fI2017\-11\-13T15:44:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +aa17bfa8e7 Merge pull request \fI\%#44492\fP from twangboy/win_skip_mode_check +.IP \(bu 2 +2f30ad93b1 Skips mode check in Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44484\fP: (\fICh3LL\fP) Add orchestration tests when target exists or not +@ \fI2017\-11\-10T19:24:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +5b95495e75 Merge pull request \fI\%#44484\fP from Ch3LL/orch_test +.IP \(bu 2 +f3ec6df76e Add orchestration tests when target exists or not +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44480\fP: (\fICh3LL\fP) Add integration pillar command line test +@ \fI2017\-11\-10T19:14:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +62c42ca6fb Merge pull request \fI\%#44480\fP from Ch3LL/override_pillar +.IP \(bu 2 +12fed1b4d8 Add integration pillar command line test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44317\fP: (\fICh3LL\fP) Add state tests and state request system to salt\-ssh +@ \fI2017\-11\-10T18:28:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +cc08ad2edc Merge pull request \fI\%#44317\fP from Ch3LL/ssh_test +.IP \(bu 2 +46bce3bd5e add additional parser argument for ssh integration tests +.IP \(bu 2 +e9231430b5 remove logic similar to cloud/proxy tests +.IP \(bu 2 +c731eb8ea6 add ssh dir to test runner when \-\-ssh\-tests set +.IP \(bu 2 +8089a885c2 add wipe function to other run_ssh method +.IP \(bu 2 +200b12ae6a change versionadded salt version +.IP \(bu 2 +e3ebb5e9b3 fix comment and variables +.IP \(bu 2 +faef0886a7 Add state tests and state request system to salt\-ssh +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44478\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-11\-10T18:00:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#39901\fP: (\fIseanjnkns\fP) network.managed ipaddrs ignored +| refs: \fI\%#44260\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44260\fP: (\fIseanjnkns\fP) Fixes \fI\%#39901\fP for RH/CentOS 7 +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6669035a30 Merge pull request \fI\%#44478\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +9fcc2a70b5 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +a66cd67d15 Merge pull request \fI\%#44260\fP from seanjnkns/issue\-39901 +.INDENT 2.0 +.IP \(bu 2 +ed8cccf457 \fI\%#39901\fP: Fix pylint +.IP \(bu 2 +43c81dfdee \fI\%#39901\fP: Add unit tests +.IP \(bu 2 +613d500876 Merge branch \(aq2016.11\(aq into issue\-39901 +.IP \(bu 2 +b97e8046ca Utilize salt.utils.validate.net.* and _raise_error_iface +.IP \(bu 2 +6818f3631d Fixes \fI\%#39901\fP for RH/CentOS 7 +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44444\fP: (\fItwangboy\fP) LGPO: Issue with Maximum Password Age +@ \fI2017\-11\-10T17:26:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +60719d0683 Merge pull request \fI\%#44444\fP from twangboy/win_lgpo_non_zero +.IP \(bu 2 +de6b394445 Remove unneeded functions +.IP \(bu 2 +ee0914f7e9 Fix some lint, remove unnecessary function +.IP \(bu 2 +d52a7c12db Fix typo in PasswordComplexity policy +.IP \(bu 2 +44f8f43812 Fix problem where 0 isn\(aqt 0 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44467\fP: (\fItwangboy\fP) Fix \fIunit.test_doc\fP for Windows +@ \fI2017\-11\-10T15:21:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +4f3a79df07 Merge pull request \fI\%#44467\fP from twangboy/win_fix_test_doc +.IP \(bu 2 +0a9e862bf4 Use regex to split +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44443\fP: (\fICh3LL\fP) Add salt\-ssh grains.items test +@ \fI2017\-11\-09T00:42:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +ff4f13877f Merge pull request \fI\%#44443\fP from Ch3LL/ssh_grains +.IP \(bu 2 +5d1a9af4b5 Add salt\-ssh grains.items test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44429\fP: (\fICh3LL\fP) Fix orch doc from pillat.get to pillar.get +@ \fI2017\-11\-07T23:06:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +dcdf2d4c90 Merge pull request \fI\%#44429\fP from Ch3LL/orch_doc +.IP \(bu 2 +38ca5520f0 Fix orch doc from pillat.get to pillar.get +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43817\fP: (\fIThe\-Loeki\fP) Orchestrate runner forces pillarenv and saltenv to None +@ \fI2017\-11\-07T06:00:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42568\fP: (\fIclallen\fP) Orchestration runner doesn\(aqt populate __pillar__ based on pillarenv +| refs: \fI\%#43817\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +62c4addef8 Merge pull request \fI\%#43817\fP from The\-Loeki/orch\-pillarenv +.IP \(bu 2 +3fd652623c orchestrate runner: retain default envs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44408\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-11\-06T15:53:00Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44313\fP: (\fIrossengeorgiev\fP) salt\-ssh: \-\-user option missing from the cli documentation +| refs: \fI\%#44322\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44383\fP: (\fIgtmanfred\fP) switch salt\-jenkins over to saltstack for kitchen\-salt tests +.IP \(bu 2 +\fBPR\fP \fI\%#44322\fP: (\fIrossengeorgiev\fP) updated CLI docs for salt\-ssh +.IP \(bu 2 +\fBPR\fP \fI\%#44304\fP: (\fIjfindlay\fP) states.cron identifier defaults to name +.IP \(bu 2 +\fBPR\fP \fI\%#44173\fP: (\fItwangboy\fP) Use google style docstrings in win_system.py +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +9e4708b7b9 Merge pull request \fI\%#44408\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +edbbd5fc2b Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.IP \(bu 2 +5e289f42ba Merge pull request \fI\%#44383\fP from gtmanfred/2016kitchen +.INDENT 2.0 +.IP \(bu 2 +b65f4ea4ea switch salt\-jenkins over to saltstack +.UNINDENT +.IP \(bu 2 +cab54e34b5 Merge pull request \fI\%#44173\fP from twangboy/win_system_docs +.INDENT 2.0 +.IP \(bu 2 +8e111b413d Fix some of the wording and grammer errors +.IP \(bu 2 +a12bc5ae41 Use google style docstrings +.UNINDENT +.IP \(bu 2 +7aaea1d179 Merge pull request \fI\%#44304\fP from jfindlay/cron_id +.INDENT 2.0 +.IP \(bu 2 +cc038c5bec states.cron identifier defaults to name +.UNINDENT +.IP \(bu 2 +e4dbbde734 Merge pull request \fI\%#44322\fP from rossengeorgiev/saltssh\-docs\-update +.INDENT 2.0 +.IP \(bu 2 +b18f2e5a6d fix program name and description for \-\-static +.IP \(bu 2 +5b10918f02 updated CLI docs for salt\-ssh +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44358\fP: (\fIThe\-Loeki\fP) Kubernetes client certificate file usage fix +@ \fI2017\-11\-03T21:51:27Z\fP +.INDENT 2.0 +.IP \(bu 2 +b11da0d2da Merge pull request \fI\%#44358\fP from The\-Loeki/kube\-client\-cert\-file +.IP \(bu 2 +35a8b0bb38 Kubernetes client certificate file usage fix +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44347\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-11\-03T21:48:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44336\fP: (\fIcorywright\fP) Docs for archive.tar should not use leading dash for tar options +| refs: \fI\%#44338\fP \fI\%#44339\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44272\fP: (\fIgurubert\fP) [patch] win_service.stop() fails +| refs: \fI\%#44295\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44345\fP: (\fIgtmanfred\fP) remove binding from erb template rendering +.IP \(bu 2 +\fBPR\fP \fI\%#44342\fP: (\fIgtmanfred\fP) render template files platforms.yml and driver.yml +.IP \(bu 2 +\fBPR\fP \fI\%#44339\fP: (\fIcorywright\fP) Remove leading dash from options in archive.tar docs (2016.11) +.IP \(bu 2 +\fBPR\fP \fI\%#44295\fP: (\fIgurubert\fP) fixes issue \fI\%#44272\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44286\fP: (\fIgtmanfred\fP) use our git repo for kitchen\-salt +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +1974e52c06 Merge pull request \fI\%#44347\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +9bad04b94b Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +4e6f09e3eb Merge pull request \fI\%#44345\fP from gtmanfred/2016kitchen +.INDENT 2.0 +.IP \(bu 2 +79b8b2d0bf remove binding +.UNINDENT +.IP \(bu 2 +209847c8c2 Merge pull request \fI\%#44342\fP from gtmanfred/2016kitchen +.INDENT 2.0 +.IP \(bu 2 +c50508f0b7 render template files platforms.yml and driver.yml +.UNINDENT +.IP \(bu 2 +1be65224cb Merge pull request \fI\%#44339\fP from corywright/issue\-44336\-fix\-archive\-tar\-docs\-2016\-11 +.INDENT 2.0 +.IP \(bu 2 +9c1c35a59f Remove leading dash (\-) from options in archive.tar documentation +.UNINDENT +.IP \(bu 2 +bebc33daf5 Merge pull request \fI\%#44295\fP from HeinleinSupport/issue44272 +.INDENT 2.0 +.IP \(bu 2 +f972715a45 fixes issue \fI\%#44272\fP +.UNINDENT +.IP \(bu 2 +e7ca9f8407 Merge pull request \fI\%#44286\fP from gtmanfred/2016.11 +.INDENT 2.0 +.IP \(bu 2 +193e715e37 use our git repo for kitchen\-salt +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44364\fP: (\fICh3LL\fP) Include disk size check for test_spm_build_big_file test +@ \fI2017\-11\-01T13:57:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +aea9f4a115 Merge pull request \fI\%#44364\fP from Ch3LL/fix_size_test +.IP \(bu 2 +952c6bfea4 Include file size check for test_spm_build_big_file test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44273\fP: (\fIDmitryKuzmenko\fP) Workaround progressbar failure if minion is behind syndic. +@ \fI2017\-10\-31T17:07:17Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44239\fP: (\fIboltronics\fP) \-\-progress fails when hosts routed via syndic +| refs: \fI\%#44273\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +609de9367a Merge pull request \fI\%#44273\fP from DSRCorporation/bugs/44239_syndic_progress +.IP \(bu 2 +e1a7605623 Workaround progressbar failure if minion is behind syndic. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44350\fP: (\fIgtmanfred\fP) update salt\-jenkins repo to 2017.7 +@ \fI2017\-10\-30T21:31:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +eef6dbfa58 Merge pull request \fI\%#44350\fP from gtmanfred/2017.7 +.IP \(bu 2 +cf71e3d9f2 update salt\-jenkins repo to 2017.7 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44346\fP: (\fIgtmanfred\fP) remove binding from erb template rendering (2017.7) +@ \fI2017\-10\-30T20:57:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +d586b3bf97 Merge pull request \fI\%#44346\fP from gtmanfred/2017.7 +.IP \(bu 2 +bf577c3d8b remove binding +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44343\fP: (\fIgtmanfred\fP) render template files platforms.yml and driver.yml (2017.7) +@ \fI2017\-10\-30T20:04:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +547aac6658 Merge pull request \fI\%#44343\fP from gtmanfred/2017.7 +.IP \(bu 2 +ec24fbc0c2 render template files platforms.yml and driver.yml +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44338\fP: (\fIcorywright\fP) Remove leading dash from options in archive.tar docs (2017.7 and develop) +@ \fI2017\-10\-30T18:59:33Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44336\fP: (\fIcorywright\fP) Docs for archive.tar should not use leading dash for tar options +| refs: \fI\%#44338\fP \fI\%#44339\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6e2a74c18b Merge pull request \fI\%#44338\fP from corywright/issue\-44336\-fix\-archive\-tar\-docs\-2017\-7\-and\-newer +.IP \(bu 2 +49b0abc284 Remove leading dash (\-) from options in archive.tar documentation +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44265\fP: (\fICh3LL\fP) Add service.status integration test +@ \fI2017\-10\-30T15:00:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +71923bed97 Merge pull request \fI\%#44265\fP from Ch3LL/service_test +.IP \(bu 2 +716aabc0bf Merge branch \(aq2017.7\(aq into service_test +.IP \(bu 2 +dd5c823210 remove skipIf import +.IP \(bu 2 +ff92f31cbe remove skipif for docker +.IP \(bu 2 +c13f37eee4 change service name depending on os +.IP \(bu 2 +980c43ebc9 change skip message check to docker +.IP \(bu 2 +3955537609 change skip if check to docker +.IP \(bu 2 +aa8875a0e2 change service name to docker +.IP \(bu 2 +654071028b change service to crond +.IP \(bu 2 +7911b4b3eb Add service.status integration test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44294\fP: (\fInasenbaer13\fP) Boto asg fixes, Backport of \fI\%#43858\fP +@ \fI2017\-10\-30T14:48:52Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#43858\fP: (\fInasenbaer13\fP) Boto_ASG fixes for scaling policy rate limiting and tag conversion +| refs: \fI\%#44294\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +8ae9769bfb Merge pull request \fI\%#44294\fP from eyj/boto_asg +.IP \(bu 2 +f5ad6aeb70 Debug log added when throttled by API +.IP \(bu 2 +c05d9aeced Encode tags as utf\-8, retry policy readout +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44312\fP: (\fIrallytime\fP) Back\-port \fI\%#44287\fP to 2017.7 +@ \fI2017\-10\-30T14:25:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#44287\fP: (\fIjf\fP) Fix utils.files.guess_archive_type to recognize the "tbz" extension as well +| refs: \fI\%#44312\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +68a9bebf90 Merge pull request \fI\%#44312\fP from rallytime/\fI\%bp\-44287\fP +.IP \(bu 2 +4d02e61f97 Merge branch \(aq2017.7\(aq into \fI\%bp\-44287\fP +.IP \(bu 2 +ba0eaae95e Fix utils.files.guess_archive_type to recognize the "tbz" extension as well (also tidy up list of extensions) +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44311\fP: (\fIrallytime\fP) Back\-port \fI\%#44262\fP to 2017.7 +@ \fI2017\-10\-30T14:25:35Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44258\fP: (\fIoarmstrong\fP) docker_container.running recreates containers with multiple links +| refs: \fI\%#44262\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44262\fP: (\fIoarmstrong\fP) docker_container.running sort list of links +| refs: \fI\%#44311\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b8854e27c0 Merge pull request \fI\%#44311\fP from rallytime/\fI\%bp\-44262\fP +.IP \(bu 2 +72d617cfbe Merge branch \(aq2017.7\(aq into \fI\%bp\-44262\fP +.IP \(bu 2 +ae34a15503 docker_container.running sort list of links +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44314\fP: (\fIgtmanfred\fP) update .kitchen.yml to run py3 tests too +@ \fI2017\-10\-30T14:23:15Z\fP +.INDENT 2.0 +.IP \(bu 2 +48df79ef77 Merge pull request \fI\%#44314\fP from gtmanfred/2017.7 +.IP \(bu 2 +54265769c4 Merge branch \(aq2017.7\(aq into 2017.7 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44316\fP: (\fIrallytime\fP) Fix lint failure on 2017.7 branch +@ \fI2017\-10\-27T18:36:08Z\fP +.INDENT 2.0 +.IP \(bu 2 +dbc5e224e9 Merge pull request \fI\%#44316\fP from rallytime/fix\-lint +.IP \(bu 2 +6d2490f6a0 Fix lint failure on 2017.7 branch +.IP \(bu 2 +39262b625e update .kitchen.yml to run py3 tests too +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44279\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-10\-27T16:17:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44155\fP: (\fIrhoths\fP) file.directory with clean not triggering listener in test mode +| refs: \fI\%#44160\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44269\fP: (\fIterminalmage\fP) Fix log message in salt.utils.gitfs +.IP \(bu 2 +\fBPR\fP \fI\%#44268\fP: (\fItwangboy\fP) Fix typo +.IP \(bu 2 +\fBPR\fP \fI\%#44259\fP: (\fIgtmanfred\fP) begin switching in kitchen\-salt for running the test suite +.IP \(bu 2 +\fBPR\fP \fI\%#44205\fP: (\fIrallytime\fP) Back\-port \fI\%#44177\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#44177\fP: (\fIsenthilkumar\-e\fP) Fixing default redis.host in documentation +| refs: \fI\%#44205\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44160\fP: (\fIgtmanfred\fP) add changes to test return +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b2b0c770a4 Merge pull request \fI\%#44279\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +8237f45a46 Add print_function to __future__ import list +.IP \(bu 2 +055b0701de Lint fix from sloppy merge conflict resolution +.IP \(bu 2 +1c3cb5c6a4 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +8a1ea165af Merge pull request \fI\%#44259\fP from gtmanfred/2016.11 +.INDENT 2.0 +.IP \(bu 2 +56a3ad8f68 fix pylint comments +.IP \(bu 2 +4add666db1 add comment to Gemfile and move copyartifacts +.IP \(bu 2 +b4c8f7eb57 fix pylint +.IP \(bu 2 +392fd4f837 try newest salttesting +.IP \(bu 2 +79251287d0 add logging +.IP \(bu 2 +38963d5a82 use transport if not set in state_file +.IP \(bu 2 +10e309a64f which vagrant should go to stderr +.IP \(bu 2 +9307564de0 fix output columns +.IP \(bu 2 +2da22f87e1 test opennebula +.IP \(bu 2 +9f38f16905 add opennebula to Gemfile +.IP \(bu 2 +7465f9b27a add script for copying back artifacts +.IP \(bu 2 +255118cfd7 run tests with kitchen +.UNINDENT +.IP \(bu 2 +9d6bc8509b Merge pull request \fI\%#44268\fP from twangboy/win_fix_lgpo_typo +.INDENT 2.0 +.IP \(bu 2 +a6a4c10a77 Fix typo +.UNINDENT +.IP \(bu 2 +0beb65a283 Merge pull request \fI\%#44269\fP from terminalmage/fix\-log\-message +.INDENT 2.0 +.IP \(bu 2 +bc9cd65496 Fix log message in salt.utils.gitfs +.UNINDENT +.IP \(bu 2 +304dd2529d Merge pull request \fI\%#44160\fP from gtmanfred/directory +.INDENT 2.0 +.IP \(bu 2 +a7d3d668f4 missed removing changes in the next test +.IP \(bu 2 +ac0b5ec440 fix test +.IP \(bu 2 +d3d00c3e62 add changes to test return +.UNINDENT +.IP \(bu 2 +e10395483d Merge pull request \fI\%#44205\fP from rallytime/\fI\%bp\-44177\fP +.INDENT 2.0 +.IP \(bu 2 +b9940f8521 Fixing default redis.host in documentation +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44291\fP: (\fICh3LL\fP) add saltutil.refresh_pillar test +@ \fI2017\-10\-27T15:19:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +bd5b9dd0aa Merge pull request \fI\%#44291\fP from Ch3LL/pillar_test +.IP \(bu 2 +34e2955445 add saltutil.refresh_pillar test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44267\fP: (\fItwangboy\fP) Fix type and Py3 issues in LGPO module +@ \fI2017\-10\-27T14:27:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +ba17a1c4d0 Merge pull request \fI\%#44267\fP from twangboy/win_fix_lgpo +.IP \(bu 2 +5d22d34cac Use unicode_literals +.IP \(bu 2 +40636397d8 Fix set for Py3 +.IP \(bu 2 +8f8c706426 Fix typo +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44285\fP: (\fICh3LL\fP) add spm integration tests for remove and build +@ \fI2017\-10\-26T21:20:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +e16707c403 Merge pull request \fI\%#44285\fP from Ch3LL/all_spm +.IP \(bu 2 +1f77f3e6a3 add skipif logic for fallocate cmd +.IP \(bu 2 +03b5c4bc6d add spm integration tests for remove and build +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44301\fP: (\fItwangboy\fP) Fix test_pydsl on Windows +@ \fI2017\-10\-26T21:14:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +6392896a22 Merge pull request \fI\%#44301\fP from twangboy/win_fix_test_pydsl +.IP \(bu 2 +6db23757bc Fix test_pydsl on Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44293\fP: (\fIUtahDave\fP) Fix documentation grammar and spelling errors +@ \fI2017\-10\-26T13:05:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +8787d02688 Merge pull request \fI\%#44293\fP from UtahDave/fix_unittest_docs +.IP \(bu 2 +c919648ab4 Fix documentation grammar and spelling errors +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44248\fP: (\fICh3LL\fP) SPM tests: use _spm_build_files method during test_build setup +@ \fI2017\-10\-25T19:45:03Z\fP +.INDENT 2.0 +.IP \(bu 2 +6e33743c1a Merge pull request \fI\%#44248\fP from Ch3LL/spm_create_repo +.IP \(bu 2 +0a387c2ecd fix pylint +.IP \(bu 2 +f383f05a93 Add SPM create_repo integration test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44253\fP: (\fICh3LL\fP) Add multiple spm integration tests +@ \fI2017\-10\-25T13:36:03Z\fP +.INDENT 2.0 +.IP \(bu 2 +bd75be24ca Merge pull request \fI\%#44253\fP from Ch3LL/spm_install +.IP \(bu 2 +9e2e785034 add spm tests to test runner +.IP \(bu 2 +4729ccd32b Add multiple spm integration tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44254\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_win_groupadd\fP for Windows +@ \fI2017\-10\-25T13:33:40Z\fP +.INDENT 2.0 +.IP \(bu 2 +75ee1ebc50 Merge pull request \fI\%#44254\fP from twangboy/win_fix_test_win_groupadd +.IP \(bu 2 +609361bf48 Fix some lint errors +.IP \(bu 2 +1f44d8d5e6 Document helper functions +.IP \(bu 2 +b0caec320e Move _get_all_groups up to the top +.IP \(bu 2 +7a3ff9387d Mock the rest of the tests +.IP \(bu 2 +5ce14df82c Change how members are retrieved in win_groupadd +.IP \(bu 2 +6ab82394be Set up mocking +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44266\fP: (\fICh3LL\fP) Add state, grains and service proxy tests +@ \fI2017\-10\-25T13:08:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +4c23fa63bb Merge pull request \fI\%#44266\fP from Ch3LL/proxy_tests +.IP \(bu 2 +e5701b472d Add state, grains and service proxy tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44244\fP: (\fImirceaulinic\fP) Add explicit non\-zero retcode to napalm config functions +@ \fI2017\-10\-24T09:23:40Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43187\fP: (\fImirceaulinic\fP) How to point from an execution module that a certain function failed +| refs: \fI\%#44244\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c849f350ba Merge pull request \fI\%#44244\fP from cloudflare/add\-retcode +.IP \(bu 2 +a1f27c9f00 Add explicit non\-zero retcode to napalm config functions +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44228\fP: (\fIrklaren\fP) Fixes \fI\%#44227\fP, make salt\-cloud/libvirt cleanup after errors more robust +@ \fI2017\-10\-23T17:09:35Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44227\fP: (\fIrklaren\fP) salt\-cloud leaves a broken vm around when the salt bootstrap fails +| refs: \fI\%#44228\fP \fI\%#44228\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +195b225540 Merge pull request \fI\%#44228\fP from rklaren/fix\-salt\-cloud\-libvirt\-cleanup\-after\-errors +.IP \(bu 2 +7917d1e61e Incorporate review comments. +.IP \(bu 2 +3a10b6aef1 Fixes \fI\%#44227\fP, make salt\-cloud/libvirt cleanup after errors more robust +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44008\fP: (\fImtorromeo\fP) Backport \fI\%#43769\fP to 2017.7 +@ \fI2017\-10\-23T14:19:57Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#19532\fP: (\fIstolendog\fP) salt\-ssh running git clone with not root user +| refs: \fI\%#43769\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#10582\fP: (\fImtorromeo\fP) Git ssh helper may be unable run +| refs: \fI\%#43769\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43769\fP: (\fImtorromeo\fP) Copy git ssh\-id\-wrapper to /tmp only if necessary (Fixes \fI\%#10582\fP, \fI\%#19532\fP) +| refs: \fI\%#44008\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +01e7bab990 Merge pull request \fI\%#44008\fP from mtorromeo/git\-noexec\-fix +.IP \(bu 2 +a7a841d9d2 Merge branch \(aq2017.7\(aq into git\-noexec\-fix +.IP \(bu 2 +d177240cfc Merge branch \(aq2017.7\(aq into git\-noexec\-fix +.IP \(bu 2 +a63e6ca963 Copy git ssh\-id\-wrapper to /tmp only if necessary (Fixes \fI\%#10582\fP, Fixes \fI\%#19532\fP) +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44202\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-10\-23T14:18:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44150\fP: (\fIrossengeorgiev\fP) version param in pkg.installed broken in 2016.11.8/2017.7.2 in EL6\-7 +| refs: \fI\%#44188\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#44140\fP: (\fIvtolstov\fP) incorrect network interfaces settings with network.managed under debian jessie +| refs: \fI\%#44167\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43936\fP: (\fIoeuftete\fP) manage.present still reports \fIlost\fP minion +| refs: \fI\%#43994\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43427\fP: (\fItylerjones4508\fP) Salt\-Cloud There was a profile error: invalid literal for int() with base 10: +| refs: \fI\%#44089\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#38367\fP: (\fItyeapple\fP) logic error in connected_ids function of salt/utils/minions.py when using include_localhost=True +| refs: \fI\%#43994\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44188\fP: (\fIterminalmage\fP) yumpkg: Check pkgname instead of name to see if it is a kernel pkg +.IP \(bu 2 +\fBPR\fP \fI\%#44167\fP: (\fIgarethgreenaway\fP) Fixes to modules/debian_ip +.IP \(bu 2 +\fBPR\fP \fI\%#44158\fP: (\fIrallytime\fP) Back\-port \fI\%#44089\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#44089\fP: (\fIcetanu\fP) Catch on empty Virtualbox network addr \fI\%#43427\fP +| refs: \fI\%#44158\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43994\fP: (\fIoeuftete\fP) Fix manage.present to show lost minions +.IP \(bu 2 +\fBPR\fP \fI\%#43830\fP: (\fIrallytime\fP) Back\-port \fI\%#43644\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43644\fP: (\fIdefanator\fP) Several fixes for RDS DB parameter group management +| refs: \fI\%#43830\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +85c0ef493f Merge pull request \fI\%#44202\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +99ff7a5c12 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +09ddfd0c08 Merge pull request \fI\%#44167\fP from garethgreenaway/44140_debian_ip_fixes +.INDENT 2.0 +.IP \(bu 2 +5f7555846f When looping through the various pre, post, up and down commands put them into the interface dict using the right internet family variable. +.UNINDENT +.IP \(bu 2 +9f9e936b52 Merge pull request \fI\%#43830\fP from rallytime/\fI\%bp\-43644\fP +.INDENT 2.0 +.IP \(bu 2 +12845ae802 Several fixes for RDS DB parameter group management +.UNINDENT +.IP \(bu 2 +07db6a3d8b Merge pull request \fI\%#43994\fP from oeuftete/fix\-manage\-runner\-presence +.INDENT 2.0 +.IP \(bu 2 +f3980d7d83 Fix manage.present to show lost minions +.UNINDENT +.IP \(bu 2 +a07537e258 Merge pull request \fI\%#44188\fP from terminalmage/issue44150 +.INDENT 2.0 +.IP \(bu 2 +0692f442db yumpkg: Check pkgname instead of name to see if it is a kernel pkg +.UNINDENT +.IP \(bu 2 +715edc0cea Merge pull request \fI\%#44158\fP from rallytime/\fI\%bp\-44089\fP +.INDENT 2.0 +.IP \(bu 2 +534faf0b7a Catch on empty Virtualbox network addr \fI\%#43427\fP +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44208\fP: (\fItwangboy\fP) Fix some lint in PR: 44080 +@ \fI2017\-10\-20T16:42:02Z\fP +.INDENT 2.0 +.IP \(bu 2 +d7dc2bd0e8 Merge pull request \fI\%#44208\fP from twangboy/win_fix_group.present +.IP \(bu 2 +61e2e9ccda Fix some lint +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43843\fP: (\fItwangboy\fP) Fix \fIunit.states.test_mount\fP for Windows +@ \fI2017\-10\-20T14:27:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +c6d27ada51 Merge pull request \fI\%#43843\fP from twangboy/win_unit_test_mount +.IP \(bu 2 +a862e0bf2d Remove unneeded import +.IP \(bu 2 +d78f27466d Fix \fIunit.states.test_mount\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44111\fP: (\fIanlutro\fP) Try to correctly parse debian codename from /etc/os\-release +@ \fI2017\-10\-19T22:23:26Z\fP +.INDENT 2.0 +.IP \(bu 2 +372820ea38 Merge pull request \fI\%#44111\fP from alprs/fix\-deb8\-py3\-oscodename +.IP \(bu 2 +1e1e5a3ff6 try to correctly parse debian codename from /etc/os\-release +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44187\fP: (\fItwangboy\fP) Fix pickling errors on Windows +@ \fI2017\-10\-19T20:36:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +75136152c1 Merge pull request \fI\%#44187\fP from twangboy/win_fix_unit_test_daemons.py +.IP \(bu 2 +64d2e4f732 Fix pickling errors on Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44186\fP: (\fIgarethgreenaway\fP) [2017.7] scheduler fixes +@ \fI2017\-10\-19T20:36:04Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44181\fP: (\fIjonans\fP) Scheduler with multiple when values doesn\(aqt run +| refs: \fI\%#44186\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +7a89cd8697 Merge pull request \fI\%#44186\fP from garethgreenaway/44181_scheduler_multiple_whens +.IP \(bu 2 +7eef3b3571 Adding a copy.deepcopy to the for loop that looks for old jobs to avoid stale jobs ending up in the list. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43896\fP: (\fItwangboy\fP) Fix win_lgpo execution module +@ \fI2017\-10\-19T20:13:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +1d16ae8ba7 Merge pull request \fI\%#43896\fP from twangboy/win_fix_lgpo_scom +.IP \(bu 2 +648d1b8d99 Catch CommandExecutionError +.IP \(bu 2 +0040082d0a Fix pylint error +.IP \(bu 2 +91258cd6a8 Fix typo +.IP \(bu 2 +261dba347d Put the file.remove in a try/except/else block +.IP \(bu 2 +020c2a2b85 Fix syntax error +.IP \(bu 2 +d5bec99126 Fix some lint +.IP \(bu 2 +b96186d60d Fix INSTALL_LANGUAGE +.IP \(bu 2 +5471bd521f Fix problem with file handle +.IP \(bu 2 +5ec58c6200 Use System Install Language as default fallback +.IP \(bu 2 +f9ad446019 Fix win_lgpo execution module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44080\fP: (\fItwangboy\fP) Fix a regression in \fIgroup.present\fP in Windows +@ \fI2017\-10\-19T20:10:44Z\fP +.INDENT 2.0 +.IP \(bu 2 +98356b86af Merge pull request \fI\%#44080\fP from twangboy/win_fix_group.present +.IP \(bu 2 +29bc80ff87 Improve get_sam_name +.IP \(bu 2 +ef759a3875 Fix example in function docs for get_sam_name +.IP \(bu 2 +43740c5fed Document 15 character limit +.IP \(bu 2 +83f36cc2ef Account for 15 character limit in hostname +.IP \(bu 2 +aa278966de Remove +.nf +* +.fi +args, pass gid as a keyword +.IP \(bu 2 +5230ecd7e1 Accept +.nf +* +.fi +args +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44171\fP: (\fICh3LL\fP) Add SPM Build Integration Tests +@ \fI2017\-10\-19T19:49:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +5ef124bf2d Merge pull request \fI\%#44171\fP from Ch3LL/spm_int +.IP \(bu 2 +cd79e9444e remove unneded kwarg +.IP \(bu 2 +1541376c4f Add spm build test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44157\fP: (\fIbenediktwerner\fP) Added \(aqversionadded\(aq tags to sensehat modules +@ \fI2017\-10\-19T14:13:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +34a843252d Merge pull request \fI\%#44157\fP from benediktwerner/2017.7 +.IP \(bu 2 +bd825b51cc Changed sensehat versionadded from 2017.7 to 2017.7.0 +.IP \(bu 2 +f1d3c5bbcf Added \(aqversionadded\(aq tags to sensehat modules +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44164\fP: (\fIterminalmage\fP) Fix examples in docker_container.{stopped,absent} docstrings +@ \fI2017\-10\-19T14:12:37Z\fP +.INDENT 2.0 +.IP \(bu 2 +1427c72e1e Merge pull request \fI\%#44164\fP from terminalmage/fix\-docker\-docstring +.IP \(bu 2 +7b46489e33 Fix examples in docker_container.{stopped,absent} docstrings +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44168\fP: (\fItwangboy\fP) Fix \fIunit.test_auth\fP for Windows +@ \fI2017\-10\-19T14:12:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +77969c4161 Merge pull request \fI\%#44168\fP from twangboy/win_skip_pam_eath +.IP \(bu 2 +bb1d2eb85b Skip tests that are failing on PAM eauth +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44151\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-10\-18T16:52:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44087\fP: (\fImfussenegger\fP) Using state.highstate with \fIterse=true\fP prevents useful error output +| refs: \fI\%#44093\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43307\fP: (\fImarek\-knappe\fP) Filesystem creation is failing on newly created LV +.IP \(bu 2 +\fBPR\fP \fI\%#44131\fP: (\fIrallytime\fP) Back\-port \fI\%#44029\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#44124\fP: (\fIrallytime\fP) [2016.11] Merge forward from 2016.11.8 to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#44122\fP: (\fIcachedout\fP) Add note about GPG signing to PR template +.IP \(bu 2 +\fBPR\fP \fI\%#44110\fP: (\fIroaldnefs\fP) Format fix code example local returner doc +.IP \(bu 2 +\fBPR\fP \fI\%#44097\fP: (\fIgtmanfred\fP) OpenNebula does not require the template_id to be specified +.IP \(bu 2 +\fBPR\fP \fI\%#44093\fP: (\fIgtmanfred\fP) don\(aqt filter if return is not a dict +.IP \(bu 2 +\fBPR\fP \fI\%#44029\fP: (\fImsummers42\fP) addresses issue \fI\%#43307\fP, +.nf +disk.format_ +.fi + to disk.format +| refs: \fI\%#44131\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44028\fP: (\fIrallytime\fP) Back\-port \fI\%#44011\fP to 2016.11.8 +.IP \(bu 2 +\fBPR\fP \fI\%#44011\fP: (\fICh3LL\fP) Security Fixes for 2016.11.8 +| refs: \fI\%#44028\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +88a776d9d2 Merge pull request \fI\%#44151\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +6aa8f03a4a Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +0cd493b691 Merge pull request \fI\%#44131\fP from rallytime/\fI\%bp\-44029\fP +.INDENT 2.0 +.IP \(bu 2 +bebf301976 fixed test addressing issue \fI\%#43307\fP, +.nf +disk.format_ +.fi + to disk.format +.IP \(bu 2 +b4ba7ae2fc addresses issue \fI\%#43307\fP, +.nf +disk.format_ +.fi + to disk.format +.UNINDENT +.IP \(bu 2 +3a68e356f8 Merge pull request \fI\%#44093\fP from gtmanfred/\fI\%fix\-44087\fP +.INDENT 2.0 +.IP \(bu 2 +5455c5053b fix pylint +.IP \(bu 2 +f749cafa25 don\(aqt filter if return is not a dict +.UNINDENT +.IP \(bu 2 +c785d7a847 Merge pull request \fI\%#44122\fP from cachedout/gpg_pr_template +.INDENT 2.0 +.IP \(bu 2 +e41e3d76be Typo fix +.IP \(bu 2 +37c7980880 Add note about GPG signing to PR template +.UNINDENT +.IP \(bu 2 +bf90ea1f51 Merge pull request \fI\%#44124\fP from rallytime/merge\-2016.11 +.INDENT 2.0 +.IP \(bu 2 +59861291c8 Merge branch \(aq2016.11.8\(aq into \(aq2016.11\(aq +.INDENT 2.0 +.IP \(bu 2 +57623e2abe Merge pull request \fI\%#44028\fP from rallytime/\fI\%bp\-44011\fP +.INDENT 2.0 +.IP \(bu 2 +89e084bda3 Do not allow IDs with null bytes in decoded payloads +.IP \(bu 2 +206ae23f15 Don\(aqt allow path separators in minion ID +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +13f3ffa83a Merge pull request \fI\%#44097\fP from gtmanfred/openneb +.INDENT 2.0 +.IP \(bu 2 +c29655b2c2 Merge branch \(aq2016.11\(aq into openneb +.IP \(bu 2 +bd2490b149 OpenNebula does not require the template_id to be specified +.UNINDENT +.IP \(bu 2 +ac3e4df964 Merge pull request \fI\%#44110\fP from roaldnefs/fix\-doc\-local\-returner +.INDENT 2.0 +.IP \(bu 2 +efd58f7594 Merge branch \(aq2016.11\(aq into fix\-doc\-local\-returner +.IP \(bu 2 +881f1822f2 Format fix code example local returner doc +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43933\fP: (\fIgtmanfred\fP) if expect_minions is passed use that instead +@ \fI2017\-10\-18T16:43:39Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43918\fP: (\fImwerickso\fP) subset argument does not work with saltmod.state +| refs: \fI\%#43933\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0b47eb7242 Merge pull request \fI\%#43933\fP from gtmanfred/2017.7 +.IP \(bu 2 +272dcc6ba5 add inline comment about popping expect_minions +.IP \(bu 2 +b615ce1762 if expect_minions is passed use that instead +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44081\fP: (\fIskizunov\fP) Windows: Fix usage of pkgrepo state +@ \fI2017\-10\-18T16:16:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +36da1a7fac Merge pull request \fI\%#44081\fP from skizunov/develop3 +.IP \(bu 2 +351d16840b Move strip_uri to salt/utils/pkg/deb.py +.IP \(bu 2 +f54c7a6f01 Windows: Fix usage of pkgrepo state +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43913\fP: (\fItwangboy\fP) Fix \fIunit.templates.test_jinja\fP for Windows +@ \fI2017\-10\-17T21:09:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +afcaa0c591 Merge pull request \fI\%#43913\fP from twangboy/win_fix_test_jinja +.IP \(bu 2 +a4e2d8059d Fix \fIunit.templates.test_jinja\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43917\fP: (\fItwangboy\fP) Fix \fIunit.test_pillar\fP for Windows +@ \fI2017\-10\-17T21:06:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +fc5754c6a1 Merge pull request \fI\%#43917\fP from twangboy/win_unit_test_pillar +.IP \(bu 2 +00dbba5712 Fix \fIunit.test_pillar\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44133\fP: (\fIcachedout\fP) Fix typos in parallel states docs +@ \fI2017\-10\-17T15:24:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +6252f82f58 Merge pull request \fI\%#44133\fP from cachedout/fix_paralell_docs +.IP \(bu 2 +8d1c1e21f0 Fix typos in paralell states docs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44135\fP: (\fItimfreund\fP) Insert missing verb in gitfs walkthrough +@ \fI2017\-10\-17T14:32:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +0d3f5db867 Merge pull request \fI\%#44135\fP from timfreund/insert_missing_verb +.IP \(bu 2 +9557504b75 Insert missing verb in gitfs walkthrough +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44055\fP: (\fInasenbaer13\fP) Activate jid_queue also for SingleMinions to workaround (Backport) +@ \fI2017\-10\-16T20:14:52Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#43860\fP: (\fInasenbaer13\fP) Activate jid_queue also for SingleMinions (occurs on reconnect) +| refs: \fI\%#44055\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a9700f6061 Merge pull request \fI\%#44055\fP from eyj/jid_queue +.IP \(bu 2 +4bdd5bbf6b Merge branch \(aq2017.7\(aq into jid_queue +.IP \(bu 2 +facef2227d Merge branch \(aq2017.7\(aq into jid_queue +.IP \(bu 2 +2fedcec6bb Merge branch \(aq2017.7\(aq into jid_queue +.IP \(bu 2 +255aa94c64 Activate jid_queue also for SingleMinions to workaround 0mq reconnection issues +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44125\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2017.7.2 to 2017.7 +@ \fI2017\-10\-16T20:02:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#44027\fP: (\fIrallytime\fP) Back\-port \fI\%#44012\fP to 2017.7.2 +.IP \(bu 2 +\fBPR\fP \fI\%#44012\fP: (\fICh3LL\fP) Security Fixes for 2017.7.2 +| refs: \fI\%#44027\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2fba45cd3f Merge pull request \fI\%#44125\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +c4ae4a6b50 Merge branch \(aq2017.7.2\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +5d719a2219 Merge pull request \fI\%#44027\fP from rallytime/\fI\%bp\-44012\fP +.IP \(bu 2 +f7824e41f3 Don\(aqt allow path separators in minion ID +.IP \(bu 2 +44060dc9c1 Do not allow IDs with null bytes in decoded payloads +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44029\fP: (\fImsummers42\fP) addresses issue \fI\%#43307\fP, +.nf +disk.format_ +.fi + to disk.format +| refs: \fI\%#44131\fP +@ \fI2017\-10\-16T19:59:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43307\fP: (\fImarek\-knappe\fP) Filesystem creation is failing on newly created LV +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +68974aa74d Merge pull request \fI\%#44029\fP from msummers42/2017.7 +.IP \(bu 2 +16e1c1dfc8 fixed test addressing issue \fI\%#43307\fP, +.nf +disk.format_ +.fi + to disk.format +.IP \(bu 2 +3d597db51c Merge branch \(aq2017.7\(aq into 2017.7 +.IP \(bu 2 +18fb0be96a addresses issue \fI\%#43307\fP, +.nf +disk.format_ +.fi + to disk.format +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44079\fP: (\fIskizunov\fP) opkg: Fix usage with pkgrepo.managed +@ \fI2017\-10\-16T19:58:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +d0bbe65ffa Merge pull request \fI\%#44079\fP from skizunov/develop2 +.IP \(bu 2 +0614d1af30 Merge branch \(aq2017.7\(aq into develop2 +.IP \(bu 2 +b6b12fe495 opkg: Fix usage with pkgrepo.managed +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44090\fP: (\fIpratik705\fP) Fix create_attach_volumes salt\-cloud action for gcp +@ \fI2017\-10\-16T19:04:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +22a8253595 Merge pull request \fI\%#44090\fP from pratik705/fix\-create_attach_volumes_salt\-cloud_action\-GCP +.IP \(bu 2 +3eefd334c5 Fixed "create_attach_volumes" salt\-cloud action for GCP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44121\fP: (\fIbenediktwerner\fP) Fixed code snippet in unit testing documentation +@ \fI2017\-10\-16T18:28:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +888e5f51a2 Merge pull request \fI\%#44121\fP from benediktwerner/2017.7 +.IP \(bu 2 +1319c822bd Fixed code snippet in unit testing doc +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44098\fP: (\fItwangboy\fP) Return multiprocessing queue in LogSetupMock class +@ \fI2017\-10\-16T18:14:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +9fe94d7843 Merge pull request \fI\%#44098\fP from twangboy/win_mock_test_parsers +.IP \(bu 2 +cc43ca27af Return multiprocessing queue in LogSetupMock class +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44118\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-10\-16T17:01:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43581\fP: (\fIjcourington\fP) cherrypy stats issue +| refs: \fI\%#44021\fP +.IP \(bu 2 +\fBPR\fP \fI\%#44092\fP: (\fItechhat\fP) Made sure that unicoded data is sent to sha256() +.IP \(bu 2 +\fBPR\fP \fI\%#44030\fP: (\fIrallytime\fP) [2016.11] Merge forward from 2016.3 to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#44025\fP: (\fIdayid\fP) Typo correction of lover to lower +.IP \(bu 2 +\fBPR\fP \fI\%#44021\fP: (\fIwhiteinge\fP) Also catch cpstats AttributeError for bad CherryPy release ~5.6.0 +.IP \(bu 2 +\fBPR\fP \fI\%#44010\fP: (\fICh3LL\fP) Security Fixes for 2016.3.8 +.IP \(bu 2 +\fBPR\fP \fI\%#43977\fP: (\fICh3LL\fP) Add Security Notes to 2016.3.8 Release Notes +.IP \(bu 2 +\fBPR\fP \fI\%#42655\fP: (\fIwhiteinge\fP) Reenable cpstats for rest_cherrypy +| refs: \fI\%#44021\fP +.IP \(bu 2 +\fBPR\fP \fI\%#33806\fP: (\fIcachedout\fP) Work around upstream cherrypy bug +| refs: \fI\%#42655\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0ee04eaf1d Merge pull request \fI\%#44118\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +bbec47afbc Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +c960ca32c2 Merge pull request \fI\%#44092\fP from techhat/awsunicode +.INDENT 2.0 +.IP \(bu 2 +bbd9db4d00 One more encoding +.IP \(bu 2 +0e8b325667 Apparently __salt_system_encoding__ is a thing +.IP \(bu 2 +1e7211838d Use system encoding +.IP \(bu 2 +1af21bbe5e Made sure that unicoded data is sent to sha256() +.UNINDENT +.IP \(bu 2 +d89c317d96 Merge pull request \fI\%#44021\fP from whiteinge/cpstats\-attribute\-error +.INDENT 2.0 +.IP \(bu 2 +bf14e5f578 Also catch cpstats AttributeError for bad CherryPy release ~5.6.0 +.UNINDENT +.IP \(bu 2 +bbdabe242a Merge pull request \fI\%#44025\fP from dayid/lover_typo +.INDENT 2.0 +.IP \(bu 2 +385980c21a Merge branch \(aq2016.11\(aq of \fI\%https://github.com/saltstack/salt\fP into lover_typo +.IP \(bu 2 +266dc00a23 Typo correction of lover to lower +.UNINDENT +.IP \(bu 2 +d8f3891a5e Merge pull request \fI\%#44030\fP from rallytime/merge\-2016.11 +.INDENT 2.0 +.IP \(bu 2 +53eaf0d75c Merge branch \(aq2016.3\(aq into \(aq2016.11\(aq +.IP \(bu 2 +64fd839377 Merge pull request \fI\%#44010\fP from Ch3LL/2016.3.7_follow_up +.INDENT 2.0 +.IP \(bu 2 +9a00302cd8 fix 2016.3.7 release notes merge conflict +.IP \(bu 2 +63da1214db Do not allow IDs with null bytes in decoded payloads +.IP \(bu 2 +ee792581fc Don\(aqt allow path separators in minion ID +.IP \(bu 2 +8aab65c718 fix 2016.3.7 release notes merge conflict +.UNINDENT +.IP \(bu 2 +bd73dcb02c Merge pull request \fI\%#43977\fP from Ch3LL/3.8_sec +.IP \(bu 2 +5fb3f5f6b1 Add Security Notes to 2016.3.8 Release Notes +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44099\fP: (\fItwangboy\fP) Skip Master, Minion, and Syndic parser tests +@ \fI2017\-10\-16T16:07:00Z\fP +.INDENT 2.0 +.IP \(bu 2 +28fa097b9b Merge pull request \fI\%#44099\fP from twangboy/win_skip_test_parsers +.IP \(bu 2 +caf086c05a Skip Master, Minion, and Syndic parser tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44106\fP: (\fIroaldnefs\fP) Fix mattermost returner documentation +@ \fI2017\-10\-16T13:12:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +dbf112ead7 Merge pull request \fI\%#44106\fP from roaldnefs/fix\-doc\-mattermost_returner +.IP \(bu 2 +b3761a0401 Fix doc indentation in mattermost_returner +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44054\fP: (\fInasenbaer13\fP) Backport of missing delete_on_termination +@ \fI2017\-10\-13T15:45:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#43859\fP: (\fInasenbaer13\fP) Add missing delete_on_termination passthrough. Adapt docs. +| refs: \fI\%#44054\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +fd2c51b76c Merge pull request \fI\%#44054\fP from eyj/boto_lc +.IP \(bu 2 +34d4629a64 Merge branch \(aq2017.7\(aq into boto_lc +.IP \(bu 2 +9efd63526a Adapted documentation of delete_on_termination parameter +.IP \(bu 2 +eb2bfd047b Add missing delete_on_termination passthrough. Adapt docs. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44076\fP: (\fICh3LL\fP) Add spm shell tests +@ \fI2017\-10\-13T14:32:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +b61ed96268 Merge pull request \fI\%#44076\fP from Ch3LL/spm_test +.IP \(bu 2 +d2e91c33bd Add spm shell tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44051\fP: (\fItwangboy\fP) Fix some documentation formatting issues in the win_dacl state +@ \fI2017\-10\-12T15:40:17Z\fP +.INDENT 2.0 +.IP \(bu 2 +e38f313ac0 Merge pull request \fI\%#44051\fP from twangboy/win_fix_docs_dacl +.IP \(bu 2 +377d6b6171 Fix some docs in the win_dacl state module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44066\fP: (\fICh3LL\fP) Add Known CherryPy Issue to 2017.7.2 Release Notes +@ \fI2017\-10\-12T15:18:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +a85837d72b Merge pull request \fI\%#44066\fP from Ch3LL/cherry_release +.IP \(bu 2 +8e597fcce9 Add Known CherryPy Issue to 2017.7.2 Release Notes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43889\fP: (\fICorvinM\fP) Fix issue with using roster_defaults with flat or cloud rosters. +@ \fI2017\-10\-11T23:22:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43643\fP: (\fIdoublez13\fP) salt\-ssh: multiple targets fails after upgrade to 2017.7 +| refs: \fI\%#43889\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43449\fP: (\fIecgg\fP) salt\-ssh \-L with hosts down or unreachable returns wrong results +| refs: \fI\%#43889\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +fcab77ac7b Merge pull request \fI\%#43889\fP from CorvinM/issue43449 +.IP \(bu 2 +fefd28d896 Add futureproofing to roster_defaults to support roster dictionary options +.IP \(bu 2 +aebe76b6f8 Fix issue with using roster_defaults with flat or cloud rosters. fixes \fI\%#43449\fP fixes \fI\%#43643\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44031\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-10\-11T22:03:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43945\fP: (\fIbobrik\fP) kmod.present doesn\(aqt work with compiled\-in modules +.IP \(bu 2 +\fBISSUE\fP \fI\%#42947\fP: (\fIrossengeorgiev\fP) Zenoss state changes production state even when test=true +| refs: \fI\%#43968\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#2291\fP: (\fIscott\-w\fP) Extend pkg to install from file +.IP \(bu 2 +\fBPR\fP \fI\%#44023\fP: (\fICh3LL\fP) Add 2016.11.9 Release Note File +.IP \(bu 2 +\fBPR\fP \fI\%#44019\fP: (\fIbenediktwerner\fP) Added missing docs to the tutorial index and fixed spelling mistake +.IP \(bu 2 +\fBPR\fP \fI\%#44011\fP: (\fICh3LL\fP) Security Fixes for 2016.11.8 +| refs: \fI\%#44028\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43991\fP: (\fICh3LL\fP) Add Security Notes to 2016.3.8 Release Notes +.IP \(bu 2 +\fBPR\fP \fI\%#43976\fP: (\fICh3LL\fP) Add Security Notes to 2016.11.8 Release Notes +.IP \(bu 2 +\fBPR\fP \fI\%#43973\fP: (\fIterminalmage\fP) Fix grains.has_value when value is False +.IP \(bu 2 +\fBPR\fP \fI\%#43968\fP: (\fIrossengeorgiev\fP) fix zenoss state module not respecting test=true +.IP \(bu 2 +\fBPR\fP \fI\%#43962\fP: (\fIbobrik\fP) Report built\-in modiles in kmod.available, fixes \fI\%#43945\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43960\fP: (\fIcro\fP) Require that bindpw be non\-empty when auth.ldap.anonymous is False +.IP \(bu 2 +\fBPR\fP \fI\%#43955\fP: (\fImeaksh\fP) Enable a new \(aq\-\-with\-salt\-version\(aq parameter for the "setup.py" script +.IP \(bu 2 +\fBPR\fP \fI\%#43916\fP: (\fIdereckson\fP) Fix typo in salt\-cloud scaleway documentation +.IP \(bu 2 +\fBPR\fP \fI\%#43888\fP: (\fIrallytime\fP) Back\-port \fI\%#43841\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43841\fP: (\fIaustinpapp\fP) add \-n with netstat so we don\(aqt resolve IPs +| refs: \fI\%#43888\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43776\fP: (\fICh3LL\fP) [2016.11] Bump latest and previous versions +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3ad1c6d1d9 Merge pull request \fI\%#44031\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +1d4a6c3949 Lint: Fixup undefined variable errors +.IP \(bu 2 +788ad0609a Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +0dbf41e79e Merge pull request \fI\%#44011\fP from Ch3LL/2016.11.7_follow_up +.INDENT 2.0 +.IP \(bu 2 +c0149101c0 Do not allow IDs with null bytes in decoded payloads +.IP \(bu 2 +19481423dd Don\(aqt allow path separators in minion ID +.UNINDENT +.IP \(bu 2 +d61300df20 Merge pull request \fI\%#44023\fP from Ch3LL/11.9rn +.INDENT 2.0 +.IP \(bu 2 +7f9015eb41 Add 2016.11.9 Release Note File +.UNINDENT +.IP \(bu 2 +9ff53bf63a Merge pull request \fI\%#44019\fP from benediktwerner/2016.11 +.INDENT 2.0 +.IP \(bu 2 +bc53598027 Fixed spelling mistake in salt_bootstrap tutorial +.IP \(bu 2 +6c30344824 Added missing tutorial docs to the tutorial index +.UNINDENT +.IP \(bu 2 +364523f5f8 Merge pull request \fI\%#43955\fP from meaksh/2016.11\-\fI\%fix\-2291\fP +.INDENT 2.0 +.IP \(bu 2 +a81b78381b Merge branch \(aq2016.11\(aq into 2016.11\-\fI\%fix\-2291\fP +.IP \(bu 2 +44bc91bb98 Enable \(aq\-\-with\-salt\-version\(aq parameter for setup.py script +.UNINDENT +.IP \(bu 2 +fec714b91d Merge pull request \fI\%#43962\fP from bobrik/kmod\-built\-in +.INDENT 2.0 +.IP \(bu 2 +95ab901553 Report built\-in modiles in kmod.available, fixes \fI\%#43945\fP +.UNINDENT +.IP \(bu 2 +e434c39c4e Merge pull request \fI\%#43960\fP from cro/ldap_nopw_bind2 +.INDENT 2.0 +.IP \(bu 2 +962a20cf4b Require that bindpw be non\-empty if auth.ldap.anonymous=False +.IP \(bu 2 +9df3d91d8f Release notes blurb for change to bindpw requirements +.UNINDENT +.IP \(bu 2 +e9dfda2177 Merge pull request \fI\%#43991\fP from Ch3LL/3.8_sec_2 +.INDENT 2.0 +.IP \(bu 2 +1977df8462 Add Security Notes to 2016.3.8 Release Notes +.UNINDENT +.IP \(bu 2 +2346d2691e Merge pull request \fI\%#43968\fP from rossengeorgiev/fix\-zenoss\-prod_state +.INDENT 2.0 +.IP \(bu 2 +e6d31c1ea6 fix zenoss state module not respecting test=true +.UNINDENT +.IP \(bu 2 +8d56a5ac45 Merge pull request \fI\%#43776\fP from Ch3LL/2016.11.8_docs +.INDENT 2.0 +.IP \(bu 2 +f72bc00000 [2016.11] Bump latest and previous versions +.UNINDENT +.IP \(bu 2 +21bf71c3f5 Merge pull request \fI\%#43976\fP from Ch3LL/11.8_sec +.INDENT 2.0 +.IP \(bu 2 +f0c3184288 Add Security Notes to 2016.11.8 Release Notes +.UNINDENT +.IP \(bu 2 +1d5397ab5b Merge pull request \fI\%#43973\fP from terminalmage/fix\-grains.has_value +.INDENT 2.0 +.IP \(bu 2 +bf45ae6e6a Fix grains.has_value when value is False +.UNINDENT +.IP \(bu 2 +9ac3f2ea7b Merge pull request \fI\%#43888\fP from rallytime/\fI\%bp\-43841\fP +.INDENT 2.0 +.IP \(bu 2 +87d676f08a add \-n with netstat so we don\(aqt resolve +.UNINDENT +.IP \(bu 2 +f880ac4c08 Merge pull request \fI\%#43916\fP from dereckson/fix\-typo\-cloud\-scaleway +.INDENT 2.0 +.IP \(bu 2 +15b8b8a9f4 Fix typo in salt\-cloud scaleway documentation +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44045\fP: (\fIisbm\fP) Bugfix: always return a string "list" on unknown job target type. +@ \fI2017\-10\-11T21:58:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#2017\fP: (\fIthekuffs\fP) Add additional Esky / Freezing documentation. +.IP \(bu 2 +\fBPR\fP \fI\%#2015\fP: (\fIthekuffs\fP) Esky / bbfreeze support +| refs: \fI\%#2017\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +5db1e8c6ca Merge pull request \fI\%#44045\fP from isbm/isbm\-tgttype\-\fI\%fix\-2017\fP\-port +.IP \(bu 2 +471ff35c2f Bugfix: always return a string "list" on unknown job target type. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44026\fP: (\fIrallytime\fP) Back\-port \fI\%#43950\fP to 2017.7 +@ \fI2017\-10\-11T15:27:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43949\fP: (\fIarthurlogilab\fP) [logger] [sentry] KeyError: \(aqSENTRY_PROJECT\(aq +| refs: \fI\%#43950\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43950\fP: (\fIarthurlogilab\fP) [log/sentry] avoid KeyError: \(aqSENTRY_PROJECT\(aq +| refs: \fI\%#44026\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6c8f7fd5ec Merge pull request \fI\%#44026\fP from rallytime/\fI\%bp\-43950\fP +.IP \(bu 2 +a37e0bad62 [log/sentry] avoid KeyError: \(aqSENTRY_PROJECT\(aq +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44012\fP: (\fICh3LL\fP) Security Fixes for 2017.7.2 +| refs: \fI\%#44027\fP +@ \fI2017\-10\-10T20:04:08Z\fP +.INDENT 2.0 +.IP \(bu 2 +369ee8a132 Merge pull request \fI\%#44012\fP from Ch3LL/2017.7.1_follow_up +.IP \(bu 2 +92e05cf1c0 Don\(aqt allow path separators in minion ID +.IP \(bu 2 +70133aa305 Do not allow IDs with null bytes in decoded payloads +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44024\fP: (\fICh3LL\fP) Add 2017.7.3 Release Note File +@ \fI2017\-10\-10T20:03:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +4fe029a0ab Merge pull request \fI\%#44024\fP from Ch3LL/7.3rn +.IP \(bu 2 +027f509368 Add 2017.7.3 Release Note File +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43998\fP: (\fIunthought\fP) Fix gce make_master +@ \fI2017\-10\-10T20:01:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43997\fP: (\fIunthought\fP) gce cloud provider breaks for make_master: True +| refs: \fI\%#43998\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e484d16817 Merge pull request \fI\%#43998\fP from unthought/fix\-gce\-make_master +.IP \(bu 2 +6e9f0fa24e Fix GCE provider: #create returns bootstrap result +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#44016\fP: (\fIterminalmage\fP) Fix on_header callback when not redirecting and no Content\-Type present +@ \fI2017\-10\-10T19:59:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#44013\fP: (\fIDenisBY\fP) pkgrepo.managed broken in 2017.7.2 +| refs: \fI\%#44016\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +82b92d54b3 Merge pull request \fI\%#44016\fP from terminalmage/issue44013 +.IP \(bu 2 +d594b95f92 No need to set a specific encoding if one hasn\(aqt been provided via the headers +.IP \(bu 2 +425ede4b84 Fix on_header callback when not redirecting and no Content\-Type present +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43952\fP: (\fIt0fik\fP) add requisites to stateconf ( backport \fI\%#43920\fP) +@ \fI2017\-10\-10T13:03:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +bd879eb66e Merge pull request \fI\%#43952\fP from jdsieci/2017.7_add_requisites_to_stateconf +.IP \(bu 2 +9994c64670 Merge branch \(aq2017.7\(aq into 2017.7_add_requisites_to_stateconf +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43777\fP: (\fICh3LL\fP) [2017.7] Bump latest and previous versions +@ \fI2017\-10\-09T17:21:57Z\fP +.INDENT 2.0 +.IP \(bu 2 +a4358dfa36 Merge pull request \fI\%#43777\fP from Ch3LL/2017.7.2_docs +.IP \(bu 2 +410c624f7a [2017.7] Bump latest and previous versions +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43978\fP: (\fICh3LL\fP) Add Security Notes to 2017.7.2 Release Notes +@ \fI2017\-10\-09T17:20:04Z\fP +.INDENT 2.0 +.IP \(bu 2 +2a064c1a72 Merge pull request \fI\%#43978\fP from Ch3LL/7.2_sec +.IP \(bu 2 +57fd6f7bcb Add Security Notes to 2017.7.2 Release Notes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43932\fP: (\fItechhat\fP) Don\(aqt try to modify dict while looping through it +@ \fI2017\-10\-06T21:20:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +d9530e3c52 Merge pull request \fI\%#43932\fP from techhat/moddict +.IP \(bu 2 +4a77560646 Don\(aqt try to modify dict while looping through it +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43956\fP: (\fIterminalmage\fP) Fix fileclient\(aqs get_url when redirecting to a redirect +@ \fI2017\-10\-06T21:19:41Z\fP +.INDENT 2.0 +.IP \(bu 2 +39893a1dab Merge pull request \fI\%#43956\fP from terminalmage/fix\-get_url\-redirects +.IP \(bu 2 +9a4f6a260f Fix fileclient\(aqs get_url when redirecting to a redirect +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43943\fP: (\fItwangboy\fP) Fix \fIunit.utils.test_utils\fP for Windows +@ \fI2017\-10\-06T19:35:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +1baf286719 Merge pull request \fI\%#43943\fP from twangboy/win_unit_test_utils +.IP \(bu 2 +254dac7723 Fix \fIunit.utils.test_utils\fP for Windows +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +89200ff28e rebase from 2017.7.2 +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43939\fP: (\fIterminalmage\fP) Fix typo in log message +@ \fI2017\-10\-05T23:20:04Z\fP +.INDENT 2.0 +.IP \(bu 2 +a8f1750323 Merge pull request \fI\%#43939\fP from terminalmage/fix\-typo +.IP \(bu 2 +29d8cf4f26 Fix typo in log message +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43910\fP: (\fIterminalmage\fP) Don\(aqt put unserializable dict.keys() into state return +@ \fI2017\-10\-05T20:33:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43909\fP: (\fIfrogunder\fP) state.highstate not working on py3 setup +| refs: \fI\%#43910\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43605\fP: (\fIcruscio\fP) Module.Run: Passed invalid arguments to state.apply: can\(aqt serialize dict_keys([\(aqtask.create_task\(aq]) +| refs: \fI\%#43910\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +1a718eb1ed Merge pull request \fI\%#43910\fP from terminalmage/issue43605 +.IP \(bu 2 +042e092ac8 Don\(aqt put unserializable dict.keys() into state return +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43927\fP: (\fIrallytime\fP) Back\-port \fI\%#43907\fP to 2017.7 +@ \fI2017\-10\-05T20:10:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#41894\fP: (\fIDR3EVR8u8c\fP) Salt\-cloud can\(aqt resize root volume with public ami images +| refs: \fI\%#43907\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#39257\fP: (\fIaig787\fP) Using del_root_vol_on_destroy option in salt\-cloud gives IndexError +| refs: \fI\%#43907\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43907\fP: (\fIrichardsimko\fP) Make sure EBS volume exists before querying +| refs: \fI\%#43927\fP +.IP \(bu 2 +\fBPR\fP \fI\%#33115\fP: (\fIrbjorklin\fP) Fix override of ec2 volumetype +| refs: \fI\%#43907\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a7a59868c8 Merge pull request \fI\%#43927\fP from rallytime/\fI\%bp\-43907\fP +.IP \(bu 2 +f62e8ca87f Make sure volume exists before querying +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43934\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-10\-05T20:07:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43373\fP: (\fIrgcosma\fP) use keyword breaks sls_id +| refs: \fI\%#43707\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43884\fP: (\fIUtahDave\fP) Update SaltConf banner per Rhett\(aqs request +.IP \(bu 2 +\fBPR\fP \fI\%#43869\fP: (\fIterminalmage\fP) Only join cmd if it\(aqs not a string +.IP \(bu 2 +\fBPR\fP \fI\%#43707\fP: (\fIterminalmage\fP) Add missing support for use/use_in requisites to state.sls_id +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +4fcd4709ea Merge pull request \fI\%#43934\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +eaca3291e2 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +2ab7549d48 Merge pull request \fI\%#43884\fP from UtahDave/2016.11local +.INDENT 2.0 +.IP \(bu 2 +e3b2857285 Merge branch \(aq2016.11\(aq into 2016.11local +.UNINDENT +.IP \(bu 2 +4b882d4272 Merge pull request \fI\%#43869\fP from terminalmage/issue43522 +.INDENT 2.0 +.IP \(bu 2 +fe28b0d4fb Only join cmd if it\(aqs not a string +.IP \(bu 2 +8c671fd0c1 Update SaltConf banner per Rhett\(aqs request +.UNINDENT +.IP \(bu 2 +a2161efda3 Merge pull request \fI\%#43707\fP from terminalmage/issue43373 +.INDENT 2.0 +.IP \(bu 2 +3ebde1895f Merge branch \(aq2016.11\(aq into issue43373 +.IP \(bu 2 +e580ed4caa Merge branch \(aq2016.11\(aq into issue43373 +.IP \(bu 2 +5b3be6e8af Fix failing unit test +.IP \(bu 2 +f73764481b Add missing support for use/use_in requisites to state.sls_id +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43886\fP: (\fItechhat\fP) Fix object_to_dict in azure +@ \fI2017\-10\-05T19:33:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43658\fP: (\fIkvnaveen\fP) KeyError: \(aqas_dict\(aq [DEBUG ] LazyLoaded nested.output +| refs: \fI\%#43886\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +7d174172a0 Merge pull request \fI\%#43886\fP from techhat/azuredict +.IP \(bu 2 +223a1eea83 Fix object_to_dict in azure +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43899\fP: (\fIgtmanfred\fP) enable tox for tests +@ \fI2017\-10\-04T15:08:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +7038248820 Merge pull request \fI\%#43899\fP from gtmanfred/2017.7 +.IP \(bu 2 +51eca1a6bd enable tox for tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43828\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-10\-04T13:10:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#43807\fP: (\fIterminalmage\fP) cmdmod: Don\(aqt list\-ify string commands on Windows +.IP \(bu 2 +\fBPR\fP \fI\%#43768\fP: (\fIvutny\fP) Fix Pylint deprecated option warnings +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a5abe33e1c Merge pull request \fI\%#43828\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +2ff02e4320 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +85b3aa332a Merge pull request \fI\%#43807\fP from terminalmage/issue43522 +.INDENT 2.0 +.IP \(bu 2 +d8708bf698 cmdmod: Don\(aqt list\-ify string commands on Windows +.UNINDENT +.IP \(bu 2 +ea8d273c2b Merge pull request \fI\%#43768\fP from vutny/fix\-pylint\-deprecation\-warnings +.INDENT 2.0 +.IP \(bu 2 +f8b3fa9da1 Merge branch \(aq2016.11\(aq into fix\-pylint\-deprecation\-warnings +.IP \(bu 2 +651ed16ad3 Fix Pylint deprecated option warnings +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43854\fP: (\fIkeesbos\fP) Map __env__ in git_pillar before sanity checks +@ \fI2017\-10\-02T20:44:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#43656\fP: (\fIkeesbos\fP) Git pillar fixes +| refs: \fI\%#43854\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +36b0b1174b Merge pull request \fI\%#43854\fP from keesbos/2017.7 +.IP \(bu 2 +fba9c9a935 Map __env__ in git_pillar before sanity checks +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43847\fP: (\fIcachedout\fP) Fix to module.run +@ \fI2017\-10\-02T19:25:03Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#17\fP: (\fIthatch45\fP) Modules need to be autodocumenting +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c81e8457b8 Merge pull request \fI\%#43847\fP from cachedout/module_run_compare +.IP \(bu 2 +b11f8c8f29 Merge pull request \fI\%#17\fP from terminalmage/pr\-43847 +.INDENT 2.0 +.IP \(bu 2 +93eaba7c54 Use six.iterkeys() instead of dict.keys() +.IP \(bu 2 +5d56a03a67 Improve failures for module.run states +.UNINDENT +.IP \(bu 2 +71780beb5a Merge branch \(aq2017.7\(aq into module_run_compare +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43844\fP: (\fIgarethgreenaway\fP) [2017.7] Changes to states/file.py and states/archived.py +@ \fI2017\-10\-01T09:08:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43819\fP: (\fImephi42\fP) archive.extracted shows the http password in the comment field on failure +| refs: \fI\%#43844\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +dd01e0ce67 Merge pull request \fI\%#43844\fP from garethgreenaway/43819_redact_url_additions +.IP \(bu 2 +c58c72aff9 When using URLs in archive.extracted, on failure the username & password is in the exception. Calling salt.utils.url.redact_http_basic_auth to ensure the credentials are redacted. +.INDENT 2.0 +.IP \(bu 2 +f0b985cbbe Merge branch \(aqmodule_run_compare\(aq of \fI\%ssh://github.com/cachedout/salt\fP into module_run_compare +.INDENT 2.0 +.IP \(bu 2 +aefc773c2f Merge branch \(aq2017.7\(aq into module_run_compare +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43840\fP: (\fItwangboy\fP) Fix \fIunit.states.test_augeas\fP for Windows +@ \fI2017\-09\-29T21:53:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +1f52546eab Merge pull request \fI\%#43840\fP from twangboy/win_fix_test_augeas +.IP \(bu 2 +fd1d6c31de Fix \fIunit.states.test_augeas\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43801\fP: (\fIterminalmage\fP) Properly handle UNC paths in salt.utils.path.readlink() +@ \fI2017\-09\-29T09:58:02Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43553\fP: (\fIdafyddj\fP) Vagrant setup (Windows guest) broken on upgrade to 2017.7 +| refs: \fI\%#43801\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c6fd2cd452 Merge pull request \fI\%#43801\fP from terminalmage/issue43553 +.IP \(bu 2 +66e6e89dc7 Properly handle UNC paths in salt.utils.path.readlink() +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43800\fP: (\fICh3LL\fP) Add note to nitrogen release notes about pip for cent6 +@ \fI2017\-09\-28T17:36:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +7304907db6 Merge pull request \fI\%#43800\fP from Ch3LL/update_7.0 +.IP \(bu 2 +50779c3b1c Add note to nitrogen release notes about pip for cent6 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43779\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_state\fP for Windows +@ \fI2017\-09\-28T14:27:03Z\fP +.INDENT 2.0 +.IP \(bu 2 +6f687fdcff Merge pull request \fI\%#43779\fP from twangboy/win_fix_test_state +.IP \(bu 2 +a64fe75816 Use os agnostic paths +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43782\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_virt\fP for Windows +@ \fI2017\-09\-28T14:25:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +db0f569f7a Merge pull request \fI\%#43782\fP from twangboy/win_fix_test_virt +.IP \(bu 2 +7192332758 Fix \fIunit.modules.test_virt\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43723\fP: (\fInicholasmhughes\fP) Fix ini_manage error and change handling +@ \fI2017\-09\-28T09:52:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +dd4fc52f1e Merge pull request \fI\%#43723\fP from nicholasmhughes/ini_manage\-error\-handling +.IP \(bu 2 +d68c5c4be0 prevent exception when test=True +.IP \(bu 2 +cfe37916c3 handling changes per section +.IP \(bu 2 +1c484f6ad5 prevent exception when test=True +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43781\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_status\fP for Windows +@ \fI2017\-09\-28T09:06:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +5e29507c21 Merge pull request \fI\%#43781\fP from twangboy/win_fix_test_status +.IP \(bu 2 +16ae8253c1 Mock which, use os.linesep for cmd.run return +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43785\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_znc\fP for Windows +@ \fI2017\-09\-28T08:56:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +05c78ae649 Merge pull request \fI\%#43785\fP from twangboy/win_fix_test_znc +.IP \(bu 2 +7d90721f6b Merge branch \(aq2017.7\(aq into win_fix_test_znc +.IP \(bu 2 +228e74c8e3 Fix \fIunit.modules.test_znc\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43786\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_zypper\fP for Windows +@ \fI2017\-09\-28T08:51:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +10ddb8491c Merge pull request \fI\%#43786\fP from twangboy/win_fix_test_zypper +.IP \(bu 2 +1c05e37a66 Merge branch \(aq2017.7\(aq into win_fix_test_zypper +.IP \(bu 2 +aafec7ab0e Fix \fIunit.modules.test_zypper\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43773\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-09\-28T08:48:39Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#40311\fP: (\fIcralston0\fP) \-\-hide\-timeout used with \-\-output json \-\-static produces unparseable JSON +| refs: \fI\%#43772\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43772\fP: (\fIgtmanfred\fP) dont print Minion not responding with quiet +.IP \(bu 2 +\fBPR\fP \fI\%#43747\fP: (\fIrallytime\fP) Add GPG Verification section to Contributing Docs +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +9615ca32d5 Merge pull request \fI\%#43773\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +f7035ed7da Merge branch \(aq2017.7\(aq into merge\-2017.7 +.IP \(bu 2 +dfef4a722c Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +1a8cc60bb4 Merge pull request \fI\%#43772\fP from gtmanfred/2016.11 +.INDENT 2.0 +.IP \(bu 2 +0194c60960 dont print Minion not responding with quiet +.UNINDENT +.IP \(bu 2 +9dee896fb9 Merge pull request \fI\%#43747\fP from rallytime/gpg\-verification +.INDENT 2.0 +.IP \(bu 2 +7a70de19f4 Merge branch \(aq2016.11\(aq into gpg\-verification +.IP \(bu 2 +23bb4a5dde Add GPG Verification section to Contributing Docs +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43784\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_win_service\fP +@ \fI2017\-09\-28T03:14:39Z\fP +.INDENT 2.0 +.IP \(bu 2 +9a9cc69d55 Merge pull request \fI\%#43784\fP from twangboy/win_fix_test_win_service +.IP \(bu 2 +058e50e530 Fix \fIunit.modules.test_win_service\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43774\fP: (\fIThe\-Loeki\fP) typo fix aka what is a \(aqmasterarpi\(aq +@ \fI2017\-09\-27T18:52:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +1254da1df5 Merge pull request \fI\%#43774\fP from The\-Loeki/patch\-1 +.IP \(bu 2 +84bbe85e60 typo fix aka what is a \(aqmasterarpi\(aq +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43732\fP: (\fItwangboy\fP) Skip \fIunit.stats.test_mac_packages\fP on Windows +@ \fI2017\-09\-27T14:48:08Z\fP +.INDENT 2.0 +.IP \(bu 2 +3f888753d4 Merge pull request \fI\%#43732\fP from twangboy/win_skip_mac_pkg_tests +.IP \(bu 2 +1c01e06097 Only skip test on Windows +.IP \(bu 2 +ec99a3ce3c Fix lint error +.IP \(bu 2 +61f8a2f7ff Skip mac specific tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43761\fP: (\fICh3LL\fP) Release Notes for 2017.7.2 +@ \fI2017\-09\-27T14:34:52Z\fP +.INDENT 2.0 +.IP \(bu 2 +fb86935d99 Merge pull request \fI\%#43761\fP from Ch3LL/release_2017.7.2 +.IP \(bu 2 +caf5795856 add mac patch notes +.IP \(bu 2 +3d5fce0955 Add 2017.7.2 Release Notes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43767\fP: (\fItwangboy\fP) Skip \fIunit.modules.test_snapper\fP on Windows +@ \fI2017\-09\-27T14:10:27Z\fP +.INDENT 2.0 +.IP \(bu 2 +5ea603cf16 Merge pull request \fI\%#43767\fP from twangboy/win_skip_test_snapper +.IP \(bu 2 +b41b9c8378 Skip snapper tests on Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43759\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-09\-27T13:30:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43729\fP: (\fIThe\-Loeki\fP) Docker events engine broken on newer docker.py +| refs: \fI\%#43733\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43650\fP: (\fIrallytime\fP) Review contributing documentation and the merge\-forward process +| refs: \fI\%#43727\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#42706\fP: (\fIblarghmatey\fP) Parallel Cache Failure +| refs: \fI\%#43018\fP \fI\%#43159\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#42082\fP: (\fIstamak\fP) [salt.utils.gitfs ][CRITICAL] Invalid gitfs configuration parameter \(aqsaltenv\(aq in remote git+ssh://git@ourgitserver/ourgitrepo.git. +| refs: \fI\%#43458\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43733\fP: (\fIterminalmage\fP) Allow docker_events engine to work with newer docker\-py +.IP \(bu 2 +\fBPR\fP \fI\%#43727\fP: (\fIrallytime\fP) Revise "Contributing" docs: merge\-forwards/release branches explained! +.IP \(bu 2 +\fBPR\fP \fI\%#43458\fP: (\fIterminalmage\fP) Fix missing PER_REMOTE_ONLY in cache.clear_git_lock runner +.IP \(bu 2 +\fBPR\fP \fI\%#43018\fP: (\fIjubrad\fP) Update state.py +| refs: \fI\%#43159\fP \fI\%#43727\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +77c2c7cbf7 Merge pull request \fI\%#43759\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +120f49f2c4 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +1cc3ad1c8d Merge pull request \fI\%#43733\fP from terminalmage/issue43729 +.INDENT 2.0 +.IP \(bu 2 +6e5c99bda0 Allow docker_events engine to work with newer docker\-py +.UNINDENT +.IP \(bu 2 +5d38be4ff7 Merge pull request \fI\%#43458\fP from terminalmage/issue42082 +.INDENT 2.0 +.IP \(bu 2 +5f90812b12 Fix missing PER_REMOTE_ONLY in cache.clear_git_lock runner +.UNINDENT +.IP \(bu 2 +023a563657 Merge pull request \fI\%#43727\fP from rallytime/\fI\%fix\-43650\fP +.INDENT 2.0 +.IP \(bu 2 +babad12d83 Revise "Contributing" docs: merge\-forwards/release branches explained! +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43748\fP: (\fIrallytime\fP) Add message to boto_kinesis modules if boto libs are missing +@ \fI2017\-09\-27T13:19:33Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43737\fP: (\fIsyedaali\fP) salt.loaded.int.module.boto_kinesis.__virtual__() is wrongly returning \fINone\fP\&. It should either return \fITrue\fP, \fIFalse\fP or a new name. If you\(aqre the developer of the module \(aqboto_kinesis\(aq, please fix this. +| refs: \fI\%#43748\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +5c203df056 Merge pull request \fI\%#43748\fP from rallytime/\fI\%fix\-43737\fP +.IP \(bu 2 +5a2593dbd3 Add message to boto_kinesis modules if boto libs are missing +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43731\fP: (\fItwangboy\fP) Fix \fIunit.beacons.test_status\fP for Windows +@ \fI2017\-09\-26T16:25:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +2581098595 Merge pull request \fI\%#43731\fP from twangboy/win_unit_beacons_test_status +.IP \(bu 2 +dc1b36b7e2 Change expected return for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43724\fP: (\fIbrejoc\fP) Improved delete_deployment test for kubernetes module +@ \fI2017\-09\-26T16:19:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +10f3d47498 Merge pull request \fI\%#43724\fP from brejoc/2017.7.kubernetes_delete_test +.IP \(bu 2 +85b0a8c401 Improved delete_deployment test for kubernetes module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43734\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_poudriere\fP for Windows +@ \fI2017\-09\-26T14:13:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +13cc27bdab Merge pull request \fI\%#43734\fP from twangboy/win_unit_test_poudriere +.IP \(bu 2 +922e60fa67 Add os agnostic paths +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43742\fP: (\fIterminalmage\fP) Fix incorrect value in docstring +@ \fI2017\-09\-26T13:55:00Z\fP +.INDENT 2.0 +.IP \(bu 2 +41aeee7ac8 Merge pull request \fI\%#43742\fP from terminalmage/fix\-docstring +.IP \(bu 2 +553335b1c9 Fix incorrect value in docstring +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#41998\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_environ\fP for Windows +@ \fI2017\-09\-26T12:25:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +d78b9a3294 Merge pull request \fI\%#41998\fP from twangboy/win_unit_test_environ +.IP \(bu 2 +d73ef44cf6 Mock with uppercase KEY +.IP \(bu 2 +048e16883f Use uppercase KEY +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#42036\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_file\fP for Windows +@ \fI2017\-09\-26T12:23:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +7fbbea3806 Merge pull request \fI\%#42036\fP from twangboy/win_unit_test_file +.IP \(bu 2 +056f3bb4c0 Use with to open temp file +.IP \(bu 2 +352fe69e35 Clarify the purpose of the for loop +.IP \(bu 2 +b55172d5dc Split by Windows and Linux style line endings +.IP \(bu 2 +e20aa5c39b Fix line, use os.sep instead of os.linesep +.IP \(bu 2 +d5f27901e3 Fix additional bytestring issue +.IP \(bu 2 +716e99c453 Fix py3 bytestring problems +.IP \(bu 2 +543610570c Fix bytestring issues, fix errored tests +.IP \(bu 2 +9fe83a34a5 Remove old variable declaration +.IP \(bu 2 +c5cf5e92c1 Fix many tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43557\fP: (\fIclan\fP) disable modify yaml constructor +@ \fI2017\-09\-25T14:03:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +a81d4b8d8d Merge pull request \fI\%#43557\fP from clan/yaml +.IP \(bu 2 +485471c8a7 Merge branch \(aq2017.7\(aq into yaml +.IP \(bu 2 +da15658304 remove modify yaml constructor +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43566\fP: (\fIdamon\-atkins\fP) 2017.7 update salt.utils.files.safe_filepath func +@ \fI2017\-09\-25T13:58:29Z\fP +.INDENT 2.0 +.IP \(bu 2 +b5beec16e8 Merge pull request \fI\%#43566\fP from damon\-atkins/2017.7_update_safe_filename_func +.IP \(bu 2 +c7a652784a remove blank line at end of file +.IP \(bu 2 +e97651d49b Merge branch \(aq2017.7\(aq into 2017.7_update_safe_filename_func +.IP \(bu 2 +3b4c1bbf7f Merge branch \(aq2017.7\(aq into 2017.7_update_safe_filename_func +.IP \(bu 2 +4c88c80ef9 Merge branch \(aq2017.7\(aq into 2017.7_update_safe_filename_func +.IP \(bu 2 +4171d11838 utils.files.safe_filepath add support to override the os default directory separator +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43712\fP: (\fIwedge\-jarrad\fP) Ignore retcode on call to grep in selinux.py module +@ \fI2017\-09\-25T13:56:17Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43711\fP: (\fIwedge\-jarrad\fP) fcontext_get_policy emits command error if policy doesn\(aqt exist +| refs: \fI\%#43712\fP \fI\%#43712\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3bb337cf6a Merge pull request \fI\%#43712\fP from wedge\-jarrad/\fI\%fix\-43711\fP +.IP \(bu 2 +96c1ef48e6 Ignore retcode on call to grep in selinux.py module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43716\fP: (\fIgaborn57\fP) Corrected custom port handling +@ \fI2017\-09\-25T13:44:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43659\fP: (\fIgaborn57\fP) unable to retrieve pillar data in postgres db +| refs: \fI\%#43716\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +5b7411e335 Merge pull request \fI\%#43716\fP from gaborn57/2017.7 +.IP \(bu 2 +78137c0860 Corrected custom port handling +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43700\fP: (\fIrklaren\fP) Ensure salt\-cloud with libvirt provider does not write low level errors to stderr +@ \fI2017\-09\-25T01:47:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#43684\fP: (\fIrklaren\fP) salt\-cloud libvirt updates +| refs: \fI\%#43700\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6bbd50c453 Merge pull request \fI\%#43700\fP from rklaren/fix\-libvirt\-stderr\-spam +.IP \(bu 2 +88530c4cb6 Lint fixes +.IP \(bu 2 +235bec492e salt\-cloud + libvirt: Mention Fedora 26 support +.IP \(bu 2 +9aecf5f847 Remove stderr spam when using salt\-cloud with libvirt +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43702\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-09\-25T01:26:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +437ac03801 Merge pull request \fI\%#43702\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +132b1b343b Merge branch \(aq2017.7\(aq into merge\-2017.7 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43681\fP: (\fIterminalmage\fP) Backport the non\-fileclient changes from PR 43518 to 2017.7 +@ \fI2017\-09\-22T19:27:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#38971\fP: (\fImorganwillcock\fP) archive.extracted: lots of unnecessary file transferring, copying, and hashing +| refs: \fI\%#43681\fP \fI\%#43518\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43518\fP: (\fIterminalmage\fP) Reduce unnecessary file downloading in archive/file states +| refs: \fI\%#43681\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +47cd8723c6 Merge pull request \fI\%#43681\fP from terminalmage/issue38971\-2017.7 +.IP \(bu 2 +91edf865e2 Merge branch \(aq2017.7\(aq into issue38971\-2017.7 +.IP \(bu 2 +84f34c93be Backport the non\-fileclient changes from PR 43518 to 2017.7 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43687\fP: (\fImkurtak\fP) yumpkg.py: install calls list_repo_pkgs only if wildcard is used in pkg name +@ \fI2017\-09\-22T19:23:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43396\fP: (\fImkurtak\fP) yumpkg pkg.installed slowed down due to wildcard namig support +| refs: \fI\%#43687\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0a1c5185f5 Merge pull request \fI\%#43687\fP from mkurtak/\fI\%fix\-43396\fP +.IP \(bu 2 +b1e64b11fb yumpkg.py: install calls list_repo_pkgs only if wildcard in pkg name is used +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43467\fP: (\fIDmitryKuzmenko\fP) Bugs/43124 users regex +@ \fI2017\-09\-22T19:21:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43124\fP: (\fIUtahDave\fP) publisher_acl with regex on username not working and has no documentation +| refs: \fI\%#43467\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3a79549af4 Merge pull request \fI\%#43467\fP from DSRCorporation/bugs/43124_users_regex +.IP \(bu 2 +14bf2dd8ff Support regex in publisher_acl. +.IP \(bu 2 +9fe32f8b6e Regex support for user names in external_auth config. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43670\fP: (\fIDmitryKuzmenko\fP) Fix for \fIlist\fP and \fIcontains\fP redis cache logic. +@ \fI2017\-09\-22T17:56:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43381\fP: (\fIV3XATI0N\fP) Sharing minion data cache causes false errors in returns +| refs: \fI\%#43670\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43648\fP: (\fIrallytime\fP) Handle VPC/Subnet ID not found errors in boto_vpc module +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0e86266b93 Merge pull request \fI\%#43670\fP from DSRCorporation/bugs/43381_redis_cache_fix +.IP \(bu 2 +1c979d5809 Update redis cache \fIcontains\fP logic to use more efficient \fIsismember\fP\&. +.IP \(bu 2 +039d236948 Fixed \fIlist\fP and \fIcontains\fP redis cache logic. +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +6e5cf65d65 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.IP \(bu 2 +f46c858f25 Merge pull request \fI\%#43648\fP from rallytime/handle\-boto\-vpc\-errors +.INDENT 2.0 +.IP \(bu 2 +54842b5012 Handle VPC/Subnet ID not found errors in boto_vpc module +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43697\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-09\-22T17:31:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42165\fP: (\fIarount\fP) top_file_merging_strategy: merge does not works +| refs: \fI\%#43415\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#2\fP: (\fIthatch45\fP) salt job queries +.IP \(bu 2 +\fBPR\fP \fI\%#43677\fP: (\fIterminalmage\fP) Fix RST headers for runners (2016.11 branch) +.IP \(bu 2 +\fBPR\fP \fI\%#43673\fP: (\fIrallytime\fP) Back\-port \fI\%#43652\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43672\fP: (\fIrallytime\fP) Back\-port \fI\%#43415\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43663\fP: (\fImoio\fP) multiprocessing minion option: documentation fixes (develop) +| refs: \fI\%#43661\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43661\fP: (\fImoio\fP) multiprocessing minion option: documentation fixes (2016.11) +.IP \(bu 2 +\fBPR\fP \fI\%#43652\fP: (\fIVertigoRay\fP) Salt Repo has Deb 9 and 8 +| refs: \fI\%#43673\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43646\fP: (\fIbrejoc\fP) Added tests for pid\-file deletion in DaemonMixIn +.IP \(bu 2 +\fBPR\fP \fI\%#43591\fP: (\fIrallytime\fP) [2016.11] Merge forward from 2016.11.8 to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43575\fP: (\fIakissa\fP) Fix CSR not recreated if key changes +.IP \(bu 2 +\fBPR\fP \fI\%#43572\fP: (\fIvutny\fP) cloud.action: list_nodes_min returns all EC2 instances +.IP \(bu 2 +\fBPR\fP \fI\%#43550\fP: (\fItwangboy\fP) Fix preinstall script on OSX for 2016.11.8 +.IP \(bu 2 +\fBPR\fP \fI\%#43534\fP: (\fItwangboy\fP) Fixes removal of double\-quotes by shlex_split in winrepo for 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43508\fP: (\fIrallytime\fP) Back\-port \fI\%#43333\fP to 2016.11.8 +.IP \(bu 2 +\fBPR\fP \fI\%#43434\fP: (\fIrallytime\fP) Add 2016.11.8 release notes +.IP \(bu 2 +\fBPR\fP \fI\%#43415\fP: (\fImattLLVW\fP) Fix env_order in state.py +| refs: \fI\%#43672\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43333\fP: (\fIdamon\-atkins\fP) Docs are wrong cache_dir (bool) and cache_file (str) cannot be passed as params + 1 bug +| refs: \fI\%#43508\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +aa47da35dd Merge pull request \fI\%#43697\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +cbae45bec4 Lint: Remove extra line at end of file +.IP \(bu 2 +fca4e5563a Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.IP \(bu 2 +9dba34aa06 Merge pull request \fI\%#43575\fP from akissa/fix\-csr\-not\-recreated\-if\-key\-changes +.INDENT 2.0 +.IP \(bu 2 +b1b4dafd39 Fix CSR not recreated if key changes +.UNINDENT +.IP \(bu 2 +1d4fa48209 Merge pull request \fI\%#43672\fP from rallytime/\fI\%bp\-43415\fP +.INDENT 2.0 +.IP \(bu 2 +3fb42bc238 Fix env_order in state.py +.UNINDENT +.IP \(bu 2 +ff832ee607 Merge pull request \fI\%#43673\fP from rallytime/\fI\%bp\-43652\fP +.INDENT 2.0 +.IP \(bu 2 +d91c47c6f0 Salt Repo has Deb 9 and 8 +.UNINDENT +.IP \(bu 2 +365cb9fba8 Merge pull request \fI\%#43677\fP from terminalmage/runners\-docs\-2016.11 +.INDENT 2.0 +.IP \(bu 2 +2fd88e94fa Fix RST headers for runners (2016.11 branch) +.UNINDENT +.IP \(bu 2 +be38239e5d Merge pull request \fI\%#43534\fP from twangboy/win_fix_pkg.install_2016.11 +.INDENT 2.0 +.IP \(bu 2 +1546c1ca04 Add posix=False to call to salt.utils.shlex_split +.UNINDENT +.IP \(bu 2 +0d3fd3d374 Merge pull request \fI\%#43661\fP from moio/2016.11\-multiprocessing\-doc\-fix +.INDENT 2.0 +.IP \(bu 2 +625eabb83f multiprocessing minion option: documentation fixes +.UNINDENT +.IP \(bu 2 +6b4516c025 Merge pull request \fI\%#43646\fP from brejoc/2016.11.4\-pidfile\-tests +.INDENT 2.0 +.IP \(bu 2 +96f39a420b Fixed linting +.IP \(bu 2 +08fba98735 Fixed several issues with the test +.IP \(bu 2 +3a089e450f Added tests for pid\-file deletion in DaemonMixIn +.UNINDENT +.IP \(bu 2 +cfb1625741 Merge pull request \fI\%#43591\fP from rallytime/merge\-2016.11 +.INDENT 2.0 +.IP \(bu 2 +57b9d642c2 Merge branch \(aq2016.11.8\(aq into \(aq2016.11\(aq +.INDENT 2.0 +.IP \(bu 2 +e83421694f Merge pull request \fI\%#43550\fP from twangboy/osx_fix_preinstall_2016.11.8 +.INDENT 2.0 +.IP \(bu 2 +1b0a4d39d2 Fix logic in \fI/etc/paths.d/salt\fP detection +.UNINDENT +.IP \(bu 2 +a648f75949 Merge pull request \fI\%#43508\fP from rallytime/\fI\%bp\-43333\fP +.INDENT 2.0 +.IP \(bu 2 +d4981a2717 Update doco +.IP \(bu 2 +a7c8b9e048 Update win_pkg.py +.IP \(bu 2 +1d6dc6fb72 Docs are wrong cache_dir (bool) and cache_file (str) cannot be passed on the cli (\fI\%#2\fP) +.UNINDENT +.IP \(bu 2 +e7009877bc Merge pull request \fI\%#43434\fP from rallytime/2016.11.8\-release\-notes +.INDENT 2.0 +.IP \(bu 2 +68f529ee5e Add 2016.11.8 release notes +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +8671b91f62 Merge pull request \fI\%#43572\fP from vutny/fix\-salt\-cloud\-list\-min\-instance\-set +.INDENT 2.0 +.IP \(bu 2 +21966e7ce8 cloud.action: list_nodes_min returns all instances +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43314\fP: (\fItwangboy\fP) Fix \fIunit.utils.test_verify\fP for Windows +@ \fI2017\-09\-21T22:26:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +e6dc4d64df Merge pull request \fI\%#43314\fP from twangboy/win_fix_unit.utils.test_verify +.IP \(bu 2 +9ada7f626c Merge branch \(aq2017.7\(aq into win_fix_unit.utils.test_verify +.IP \(bu 2 +c0dc3f73ef Use sys.platform instead of salt.utils to detect Windows +.IP \(bu 2 +e496d28cbf Fix \fIunit.utils.test_verify\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43680\fP: (\fIvernondcole\fP) correct default value for salt.cache.Cache +@ \fI2017\-09\-21T20:09:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43599\fP: (\fIvernondcole\fP) Incorrect default for salt.cache.Cache() if opts does not define "cache" +| refs: \fI\%#43680\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ec34df2c27 Merge pull request \fI\%#43680\fP from vernondcole/fix\-salt.cache.Cache\-default +.IP \(bu 2 +292f8c79b8 correct default value for salt.cache.Cache +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43530\fP: (\fItwangboy\fP) Fixes removal of double\-quotes by shlex_split in winrepo +@ \fI2017\-09\-21T18:04:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +99d9d784b1 Merge pull request \fI\%#43530\fP from twangboy/win_fix_pkg.install +.IP \(bu 2 +7f59119f95 Merge branch \(aq2017.7\(aq into win_fix_pkg.install +.IP \(bu 2 +f146399f7a Use posix=False for shlex.split +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43671\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2017.7.2 to 2017.7 +@ \fI2017\-09\-21T16:39:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +12b5e62d81 Merge pull request \fI\%#43671\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +a401166bd5 Merge branch \(aq2017.7.2\(aq into \(aq2017.7\(aq +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43676\fP: (\fIterminalmage\fP) Fix RST headers for runners (2017.7 branch) +@ \fI2017\-09\-21T16:36:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +e3a2fbc2a3 Merge pull request \fI\%#43676\fP from terminalmage/runners\-docs\-2017.7 +.IP \(bu 2 +9b74634b23 Fix badly\-formatted RST in mattermost runner docstring +.IP \(bu 2 +c0a79c70a4 Fix RST headers for runners (2017.7 branch) +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43235\fP: (\fIbrejoc\fP) Improve delete_deployment handling +@ \fI2017\-09\-20T21:33:33Z\fP +.INDENT 2.0 +.IP \(bu 2 +d02953ce6a Merge pull request \fI\%#43235\fP from brejoc/improve\-async\-operation\-handling\-in\-kubernetes\-module +.IP \(bu 2 +4e8da3045f Fixed logic for windows fallback +.IP \(bu 2 +3b1cb884b9 Merge branch \(aq2017.7\(aq into improve\-async\-operation\-handling\-in\-kubernetes\-module +.IP \(bu 2 +d1b5ec098c Merge branch \(aq2017.7\(aq into improve\-async\-operation\-handling\-in\-kubernetes\-module +.IP \(bu 2 +35cf69bc50 Moved exception Salt core +.IP \(bu 2 +7431ec64e3 Removed unused sys import +.IP \(bu 2 +0c71da95f6 Using salt method to identify MS Windows, single instead of double quotes +.IP \(bu 2 +20619b24c4 Fixed test for delete_deployment +.IP \(bu 2 +91076bbafa Merge branch \(aq2017.7\(aq into improve\-async\-operation\-handling\-in\-kubernetes\-module +.IP \(bu 2 +7b600e2832 Added pylint\-disable statements and import for salt.ext.six.moves.range +.IP \(bu 2 +99fe138325 Code styling and added log message for timeout +.IP \(bu 2 +dcd8d4f639 Merge branch \(aq2017.7\(aq into improve\-async\-operation\-handling\-in\-kubernetes\-module +.IP \(bu 2 +702a058c38 Fixed linting +.IP \(bu 2 +3fe623778e Added Windows fallback +.IP \(bu 2 +52b1cb8147 Compatibility with Python3.6 +.IP \(bu 2 +767af9bb4f Added timeout for checking the deployment +.IP \(bu 2 +32d7d34fe5 First simple draft for the deletion verification +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43554\fP: (\fItwangboy\fP) Win fix chocolatey +@ \fI2017\-09\-20T16:06:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +73cb0c27b5 Merge pull request \fI\%#43554\fP from twangboy/win_fix_chocolatey +.IP \(bu 2 +e04acb6216 Merge branch \(aq2017.7\(aq into win_fix_chocolatey +.IP \(bu 2 +56be5c35eb Improve logic for handling chocolatey states +.IP \(bu 2 +bcbf7b4e68 Add logic for test=True +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43625\fP: (\fIgtmanfred\fP) results and columns are lists for mysql returns +@ \fI2017\-09\-20T15:42:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43598\fP: (\fIdavidvon\fP) Passed invalid arguments to mysql.file_query: unsupported operand type(s) for +=: \(aqint\(aq and \(aqtuple\(aq +| refs: \fI\%#43625\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ed7eeaaafb Merge pull request \fI\%#43625\fP from gtmanfred/2017.7 +.IP \(bu 2 +f84b50a06b results and columns are lists for mysql returns +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43587\fP: (\fIrallytime\fP) Add reason to linux_acl state loading failure +@ \fI2017\-09\-19T16:26:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43560\fP: (\fIsmitelli\fP) salt.states.linux_acl requires setfacl/getacl binaries but this is not obvious +| refs: \fI\%#43580\fP \fI\%#43587\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43580\fP: (\fIgarethgreenaway\fP) Updating ACL module and state module documentation +| refs: \fI\%#43587\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +1bda4832ef Merge pull request \fI\%#43587\fP from rallytime/fix\-virtual +.IP \(bu 2 +e5297e3869 Add reason to linux_acl state loading failure +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43584\fP: (\fIcachedout\fP) Enhance engines docs +@ \fI2017\-09\-18T20:40:57Z\fP +.INDENT 2.0 +.IP \(bu 2 +2e19533e3c Merge pull request \fI\%#43584\fP from cachedout/engines_doc_clarification +.IP \(bu 2 +634536b0ff Merge branch \(aq2017.7\(aq into engines_doc_clarification +.IP \(bu 2 +1a619708c1 Enhance engines docs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43519\fP: (\fIterminalmage\fP) Fix incorrect handling of pkg virtual and os_family grain +@ \fI2017\-09\-18T20:35:01Z\fP +.INDENT 2.0 +.IP \(bu 2 +50b134ef4c Merge pull request \fI\%#43519\fP from terminalmage/fix\-aptpkg +.IP \(bu 2 +0e3c447567 Fix incorrect handling of pkg virtual and os_family grain +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43520\fP: (\fIclan\fP) _search_name is \(aq\(aq if acl type is other +@ \fI2017\-09\-18T20:33:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +dd953f36ae Merge pull request \fI\%#43520\fP from clan/acl +.IP \(bu 2 +54216177c1 _search_name is \(aq\(aq if acl type is other +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43561\fP: (\fIwedge\-jarrad\fP) Clean up doc formatting in selinux state & module +@ \fI2017\-09\-18T20:28:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +ad9663a7fc Merge pull request \fI\%#43561\fP from wedge\-jarrad/selinux\-doc\-cleanup +.IP \(bu 2 +1bd263cd51 Clean up doc formatting in selinux state & module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43580\fP: (\fIgarethgreenaway\fP) Updating ACL module and state module documentation +| refs: \fI\%#43587\fP +@ \fI2017\-09\-18T20:11:26Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43560\fP: (\fIsmitelli\fP) salt.states.linux_acl requires setfacl/getacl binaries but this is not obvious +| refs: \fI\%#43580\fP \fI\%#43587\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +cc3d9c1a01 Merge pull request \fI\%#43580\fP from garethgreenaway/43560_update_linux_acl_documentation +.IP \(bu 2 +e63fae4c91 Merge branch \(aq2017.7\(aq into 43560_update_linux_acl_documentation +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43523\fP: (\fIskizunov\fP) Add back lost logic for multifunc_ordered +@ \fI2017\-09\-18T17:46:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#38168\fP: (\fIskizunov\fP) Add support for a multi\-func job using same func more than once +| refs: \fI\%#43523\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +bf7b23316f Merge pull request \fI\%#43523\fP from skizunov/develop2 +.IP \(bu 2 +fb579321a9 Add back lost logic for multifunc_ordered +.INDENT 2.0 +.IP \(bu 2 +117a0ddbbc Updating the documentation to call out the requirement for the getfacl and setfacl binaries +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +49f25b9f19 Lint +.IP \(bu 2 +31d17c0124 Fix typo found by @s0undt3ch +.IP \(bu 2 +5dba74d2cb Fix to module.run [WIP] +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43526\fP: (\fIDmitryKuzmenko\fP) Forward events to all masters syndic connected to +@ \fI2017\-09\-18T16:54:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43447\fP: (\fIUtahDave\fP) When using Syndic with Multi Master the top level master doesn\(aqt reliably get returns from lower minion. +| refs: \fI\%#43526\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e29efecf4f Merge pull request \fI\%#43526\fP from DSRCorporation/bugs/43447_syndic_events_forwarding +.IP \(bu 2 +64d6109654 Merge branch \(aq2017.7\(aq into bugs/43447_syndic_events_forwarding +.IP \(bu 2 +3b2a529385 Merge branch \(aq2017.7\(aq into bugs/43447_syndic_events_forwarding +.IP \(bu 2 +0e4a744d95 Forward events to all masters syndic connected to. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43330\fP: (\fIterminalmage\fP) Fix reactor regression + unify reactor config schema +@ \fI2017\-09\-18T16:46:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43077\fP: (\fIManoj2087\fP) Issue with deleting key via wheel +| refs: \fI\%#43330\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +56b671e087 Merge pull request \fI\%#43330\fP from terminalmage/issue43077 +.IP \(bu 2 +a7b4e1f782 Simplify client logic +.IP \(bu 2 +b85c8510c7 Improve the reactor documentation +.IP \(bu 2 +20f6f3cc39 Include a better example for reactor in master conf file +.IP \(bu 2 +4243a2211d Rewrite the reactor unit tests +.IP \(bu 2 +9db3f5ae6d Unify reactor configuration, fix caller reactors +.IP \(bu 2 +34b6c3b65f Un\-deprecate passing kwargs outside of \(aqkwarg\(aq param +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43505\fP: (\fIrallytime\fP) Back\-port \fI\%#43483\fP to 2017.7 +@ \fI2017\-09\-15T21:22:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#33793\fP: (\fImstarostik\fP) states.ssh_auth adds bogus newline before newly added keys +| refs: \fI\%#43483\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43483\fP: (\fI3add3287\fP) Handle bogus newline before newly added keys +| refs: \fI\%#43505\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +078d5d17de Merge pull request \fI\%#43505\fP from rallytime/\fI\%bp\-43483\fP +.IP \(bu 2 +c68dd5b8a4 Lint: fix spacing +.IP \(bu 2 +406f61ac9a Fix indentation from tabs to spaces +.IP \(bu 2 +923ec62771 Copy paste typo +.IP \(bu 2 +6f6619242f Fix checking for newline on end of file by properly checking the last byte of the file if the file is non empty. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43491\fP: (\fIrallytime\fP) Back\-port \fI\%#43465\fP to 2017.7 +@ \fI2017\-09\-15T18:24:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43464\fP: (\fIpsagers\fP) acme.cert state: IOError on failure to create a new certificate +| refs: \fI\%#43465\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43465\fP: (\fIpsagers\fP) acme.cert: avoid IOError on failure. +| refs: \fI\%#43491\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a6df3f2acc Merge pull request \fI\%#43491\fP from rallytime/\fI\%bp\-43465\fP +.IP \(bu 2 +3118faca0a acme.cert: avoid IOError on failure. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43492\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-09\-15T18:23:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43386\fP: (\fIrajvidhimar\fP) Scheduler\(aqs job_kwargs not working as expected. +| refs: \fI\%#43442\fP \fI\%#43443\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43267\fP: (\fIbrejoc\fP) OSError \- Can\(aqt delete PIDfile when not root +| refs: \fI\%#43366\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43223\fP: (\fIrallytime\fP) Properly deprecate describe_route_table function in boto_vpc module +| refs: \fI\%#43445\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43461\fP: (\fItwangboy\fP) Add \fI/norestart\fP switch to vcredist install +.IP \(bu 2 +\fBPR\fP \fI\%#43456\fP: (\fIrallytime\fP) Add Neon to version list +.IP \(bu 2 +\fBPR\fP \fI\%#43445\fP: (\fIrallytime\fP) Bump deprecation warning for boto_vpc.describe_route_table +| refs: \fI\%#43456\fP \fI\%#43456\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43442\fP: (\fIgarethgreenaway\fP) [2016.11] Fixes to scheduler __pub values in kwargs +.IP \(bu 2 +\fBPR\fP \fI\%#43441\fP: (\fImeaksh\fP) Use $HOME to get the user home directory instead using \(aq~\(aq char +.IP \(bu 2 +\fBPR\fP \fI\%#43432\fP: (\fIrallytime\fP) Back\-port \fI\%#43419\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43419\fP: (\fIgtmanfred\fP) make cache dirs when spm starts +| refs: \fI\%#43432\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43366\fP: (\fIbrejoc\fP) Catching error when PIDfile cannot be deleted +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3620c15c9a Merge pull request \fI\%#43492\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +4251ce5a27 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +f2b86fa2db Merge pull request \fI\%#43461\fP from twangboy/win_norestart +.INDENT 2.0 +.IP \(bu 2 +2d269d1a76 Change all comment markers to \(aq#\(aq +.IP \(bu 2 +d80aea16cb Handle ErrorCodes returned by VCRedist installer +.IP \(bu 2 +fb31e9a530 Add /norestart switch to vcredist install +.UNINDENT +.IP \(bu 2 +90e8ca9c36 Merge pull request \fI\%#43366\fP from brejoc/2016.11.pidfile\-fix +.INDENT 2.0 +.IP \(bu 2 +6e3eb76c79 Removed unused format argument +.IP \(bu 2 +daf4948b3d Catching error when PIDfile cannot be deleted +.UNINDENT +.IP \(bu 2 +a6c458607a Merge pull request \fI\%#43442\fP from garethgreenaway/43386_2016_11_schedule_kwargs_pub +.INDENT 2.0 +.IP \(bu 2 +e637ecbe86 Merge branch \(aq2016.11\(aq into 43386_2016_11_schedule_kwargs_pub +.IP \(bu 2 +6114df8dc3 Adding a small check to ensure we do not continue to populate kwargs with __pub_ items from the kwargs item. +.UNINDENT +.IP \(bu 2 +3c429299f9 Merge pull request \fI\%#43456\fP from rallytime/43445_follow_up +.INDENT 2.0 +.IP \(bu 2 +35c1d8898d Add Neon to version list +.UNINDENT +.IP \(bu 2 +6db7a721c0 Merge pull request \fI\%#43441\fP from meaksh/2016.11\-salt\-bash\-completion\-fix +.INDENT 2.0 +.IP \(bu 2 +be4f26ab21 Use $HOME to get the user home directory instead using \(aq~\(aq char +.UNINDENT +.IP \(bu 2 +05fff44a50 Merge pull request \fI\%#43445\fP from rallytime/bump\-deprecation\-warning +.INDENT 2.0 +.IP \(bu 2 +c91cd1c6d9 Bump deprecation warning for boto_vpc.describe_route_table +.UNINDENT +.IP \(bu 2 +c57dc5f0e3 Merge pull request \fI\%#43432\fP from rallytime/\fI\%bp\-43419\fP +.INDENT 2.0 +.IP \(bu 2 +c471a29527 make cache dirs when spm starts +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43513\fP: (\fIhaam3r\fP) Issue \fI\%#43479\fP No runners.config in 2017.7 branch +@ \fI2017\-09\-15T14:58:27Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43479\fP: (\fIhaam3r\fP) Mattermost runner failing to retrieve config values due to unavailable config runner +| refs: \fI\%#43513\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +8a90c7059b Merge pull request \fI\%#43513\fP from haam3r/2017.7 +.IP \(bu 2 +58f7d051c9 Issue \fI\%#43479\fP No runners.config in 2017.7 branch +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43431\fP: (\fImattLLVW\fP) Fix /etc/hosts not being modified when hostname is changed +@ \fI2017\-09\-13T18:35:55Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42926\fP: (\fInixjdm\fP) network.system not setting hostname in hosts file, preventing sudo. +| refs: \fI\%#43431\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c3d9e2d9b2 Merge pull request \fI\%#43431\fP from mattLLVW/fix\-hosts\-deb +.IP \(bu 2 +c6320b1dff Merge branch \(aq2017.7\(aq into fix\-hosts\-deb +.IP \(bu 2 +a3b2e19149 Fix /etc/hosts not being modified when hostname is changed +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43403\fP: (\fItwangboy\fP) Proper timestamp conversion in \fIredis.lastsave\fP +@ \fI2017\-09\-12T21:18:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +a09f289fbb Merge pull request \fI\%#43403\fP from twangboy/win_fix_redismod +.IP \(bu 2 +f6da23e1aa Properly handle timestamp conversion +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43463\fP: (\fItwangboy\fP) Add \fI/norestart\fP switch to vcredist installer +@ \fI2017\-09\-12T20:29:27Z\fP +.INDENT 2.0 +.IP \(bu 2 +0eaa5acb72 Merge pull request \fI\%#43463\fP from twangboy/win_norestart_2017.7 +.IP \(bu 2 +6984b8fd60 Add /norestart to vcredist installer +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43443\fP: (\fIgarethgreenaway\fP) [2017.7] Fixes to scheduler __pub values in kwargs +@ \fI2017\-09\-12T18:14:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43386\fP: (\fIrajvidhimar\fP) Scheduler\(aqs job_kwargs not working as expected. +| refs: \fI\%#43442\fP \fI\%#43443\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2fc237a806 Merge pull request \fI\%#43443\fP from garethgreenaway/43386_2017_7_schedule_kwargs_pub +.IP \(bu 2 +a29a9855a6 Fixing typo. +.IP \(bu 2 +2681b7d3fa Merge branch \(aq2017.7\(aq into 43386_2017_7_schedule_kwargs_pub +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#41547\fP: (\fImirceaulinic\fP) Override proxy minion opts with pillar data +@ \fI2017\-09\-11T21:47:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#39775\fP: (\fImirceaulinic\fP) Proxy \fImine_interval\fP config ignored +| refs: \fI\%#41547\fP \fI\%#41547\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +5378ac7756 Merge pull request \fI\%#41547\fP from cloudflare/px_merge_pillar_opts +.IP \(bu 2 +aad39ba665 Document the new opts +.IP \(bu 2 +cdc0d9674a Allow disabling the mines details merge +.IP \(bu 2 +732b63b0b9 Merge mine details whenever possible +.IP \(bu 2 +96b31d5643 Override proxy opts with pillar data when required +.IP \(bu 2 +fd499887f9 Define new proxy merge pillar in opts... opts +.IP \(bu 2 +abab6fd91c Override minion opts with pillar data +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#41943\fP: (\fItwangboy\fP) Fix \fIunit.returners.test_local_cache\fP for Windows +@ \fI2017\-09\-11T21:34:03Z\fP +.INDENT 2.0 +.IP \(bu 2 +08d102c869 Merge pull request \fI\%#41943\fP from twangboy/win_unit_test_local_cache +.IP \(bu 2 +3777b34572 Merge branch \(aq2017.7\(aq into win_unit_test_local_cache +.IP \(bu 2 +35b79ecde6 Remove \fIcur\fP variable, use time.time() in comparison +.IP \(bu 2 +9b61533b09 Get more accurate currnet time in local_cache +.IP \(bu 2 +844e3f65bc Fix unit tests for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43424\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_hosts\fP for Windows +@ \fI2017\-09\-11T21:28:41Z\fP +.INDENT 2.0 +.IP \(bu 2 +50ab79f0cb Merge pull request \fI\%#43424\fP from twangboy/win_unit_test_hosts +.IP \(bu 2 +90dcf8287c Fix \fIunit.modules.test_hosts\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#42652\fP: (\fIskizunov\fP) Fix loader.py\(aqs raw_mod() to look in all module dirs +@ \fI2017\-09\-11T19:43:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +0f0ed5a093 Merge pull request \fI\%#42652\fP from skizunov/develop3 +.IP \(bu 2 +d82e406f15 Fix loader.py\(aqs raw_mod() to look in all module dirs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43438\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-09\-11T18:33:39Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43387\fP: (\fIaogier\fP) genesis.bootstrap debootstrap fails if no qemu specified +| refs: \fI\%#43390\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43338\fP: (\fILEMNX\fP) virtualenv never\-download +| refs: \fI\%#43356\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43086\fP: (\fIaogier\fP) pylint: Instance of \(aqtuple\(aq has no \(aqextend\(aq member (no\-member) +| refs: \fI\%#43105\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#2\fP: (\fIthatch45\fP) salt job queries +.IP \(bu 2 +\fBPR\fP \fI\%#43390\fP: (\fIaogier\fP) better qemu_static parameter mangle in deboostrap management, tests +.IP \(bu 2 +\fBPR\fP \fI\%#43356\fP: (\fIgtmanfred\fP) never\-download got readded +.IP \(bu 2 +\fBPR\fP \fI\%#43333\fP: (\fIdamon\-atkins\fP) Docs are wrong cache_dir (bool) and cache_file (str) cannot be passed as params + 1 bug +| refs: \fI\%#43508\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43325\fP: (\fIdoesitblend\fP) mine_interval option is minutes not seconds +.IP \(bu 2 +\fBPR\fP \fI\%#43105\fP: (\fIaogier\fP) groupadd module: string does not have attribute \(aqextend\(aq, plus homogeneous \fIcmd\fP parm building +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ca091bc8a4 Merge pull request \fI\%#43438\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +ef7b4242c3 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +57cccd75d0 Merge pull request \fI\%#43390\fP from aogier/43387\-genesis\-qemu +.INDENT 2.0 +.IP \(bu 2 +496f14a7e7 forgot to mock the proper one +.IP \(bu 2 +51c7a1ba00 only check if static_qemu is_executable() +.IP \(bu 2 +70642e495d better qemu_static parameter mangle in deboostrap management, tests +.UNINDENT +.IP \(bu 2 +6106aec696 Merge pull request \fI\%#43356\fP from gtmanfred/2016.11 +.INDENT 2.0 +.IP \(bu 2 +3f19b247f3 Add handler.messages back in for test comparison +.IP \(bu 2 +9911b04208 fix test +.IP \(bu 2 +3c6ae99a77 never\-download got readded +.UNINDENT +.IP \(bu 2 +e638fac54e Merge pull request \fI\%#43325\fP from doesitblend/salt\-mine\-doc\-fix +.INDENT 2.0 +.IP \(bu 2 +1e94d0ac3a Lint: Remove trailing whitespace +.IP \(bu 2 +51af8f8757 Fix mine_interval phrasing in default file +.IP \(bu 2 +ba0cdd4536 Fix phrasing for mine_interval description +.IP \(bu 2 +9ff03c2d43 Update Salt Mine documentation to show that the mine_interval option is configured in minutes. +.UNINDENT +.IP \(bu 2 +fc587f784a Merge pull request \fI\%#43105\fP from aogier/43086\-no\-member +.INDENT 2.0 +.IP \(bu 2 +5111cf8bad Merge branch \(aq2016.11\(aq into 43086\-no\-member +.UNINDENT +.IP \(bu 2 +d97a680372 Merge pull request \fI\%#43333\fP from damon\-atkins/2016.11 +.INDENT 2.0 +.IP \(bu 2 +92de2bb498 Update doco +.IP \(bu 2 +fc9c61d12e Update win_pkg.py +.IP \(bu 2 +c91fc14704 Merge branch \(aq2016.11\(aq into 2016.11 +.IP \(bu 2 +cb3af2bbbd Docs are wrong cache_dir (bool) and cache_file (str) cannot be passed on the cli (\fI\%#2\fP) +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +42a118ff56 fixed cmd composition and unified his making across module +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +3fd59ed369 Adding a small check to ensure we do not continue to populate kwargs with __pub_ items from the kwargs item. +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43320\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_alternatives\fP for Windows +@ \fI2017\-09\-11T17:28:00Z\fP +.INDENT 2.0 +.IP \(bu 2 +a9592dd3e2 Merge pull request \fI\%#43320\fP from twangboy/win_fix_alternatives +.IP \(bu 2 +a909813fa5 Remove unused import (lint) +.IP \(bu 2 +3ef8d714cb Fix unit tests to mock salt.utils.path.readlink +.IP \(bu 2 +c0d81aa1ce Use salt.utils.path.readlink +.IP \(bu 2 +7c4460164b Fix alternatives for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43363\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_ini_manage\fP for Windows +@ \fI2017\-09\-11T17:10:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +9b89e49846 Merge pull request \fI\%#43363\fP from twangboy/scratch_ini_tests +.IP \(bu 2 +a94319a082 Make sure formatting of TEST_FILE_CONTENT matches original +.IP \(bu 2 +6263bc8983 Remove print statement +.IP \(bu 2 +79cd3831ae Fix empty value preserved test +.IP \(bu 2 +85997391f1 Is this handled the same on Linux and Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43421\fP: (\fIgtmanfred\fP) Revert "Reduce fileclient.get_file latency by merging _file_find and … +@ \fI2017\-09\-11T17:07:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +673ce387c1 Merge pull request \fI\%#43421\fP from gtmanfred/compat +.IP \(bu 2 +f85bf8c18f Revert "Reduce fileclient.get_file latency by merging _file_find and _file_hash" +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43415\fP: (\fImattLLVW\fP) Fix env_order in state.py +| refs: \fI\%#43672\fP +@ \fI2017\-09\-11T15:18:08Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42165\fP: (\fIarount\fP) top_file_merging_strategy: merge does not works +| refs: \fI\%#43415\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +47d982fd37 Merge pull request \fI\%#43415\fP from mattLLVW/fix\-env\-order +.IP \(bu 2 +f6313a1b2c Merge branch \(aq2017.7\(aq into fix\-env\-order +.IP \(bu 2 +e93a962980 Fix env_order in state.py +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43422\fP: (\fItwangboy\fP) Fix \fIunit.cloud.clouds.test_ec2\fP for Windows +@ \fI2017\-09\-11T15:17:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +e89e23a32e Merge pull request \fI\%#43422\fP from twangboy/win_unit_cloud_ec2 +.IP \(bu 2 +1379627334 Fix \fIunit.cloud.clouds.test_ec2\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43423\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_gem\fP for Windows +@ \fI2017\-09\-11T15:15:28Z\fP +.INDENT 2.0 +.IP \(bu 2 +54f833ac59 Merge pull request \fI\%#43423\fP from twangboy/win_unit_test_gem +.IP \(bu 2 +b2cea18d13 Fix \fIunit.modules.test_gem\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43419\fP: (\fIgtmanfred\fP) make cache dirs when spm starts +| refs: \fI\%#43432\fP +@ \fI2017\-09\-11T13:42:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +b3116109e5 Merge pull request \fI\%#43419\fP from gtmanfred/2017.7 +.IP \(bu 2 +58378866e5 make cache dirs when spm starts +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43371\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-09\-08T15:39:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43348\fP: (\fI9maf4you\fP) network.managed doesn\(aqt work on CentOS 7 +| refs: \fI\%#43359\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#43295\fP: (\fIV3XATI0N\fP) salt.cache.redis_cache does not actually work. +| refs: \fI\%#43329\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#35840\fP: (\fIjunovitch\fP) preserve_minion_cache is broken in 2016.3+ +| refs: \fI\%#42903\fP \fI\%#42903\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43361\fP: (\fIrallytime\fP) Back\-port \fI\%#43329\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43360\fP: (\fIterminalmage\fP) Fix failing tests in Fedora +.IP \(bu 2 +\fBPR\fP \fI\%#43359\fP: (\fIgtmanfred\fP) ipaddr_start ipaddr_end for el7 +.IP \(bu 2 +\fBPR\fP \fI\%#43329\fP: (\fIjohnj\fP) Fix \fI\%#43295\fP, better handling of consul initialization +| refs: \fI\%#43361\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43247\fP: (\fIrallytime\fP) Back\-port various mention bot settings to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43244\fP: (\fIrallytime\fP) Update release branch section with a few more details +.IP \(bu 2 +\fBPR\fP \fI\%#43206\fP: (\fIrallytime\fP) Always notify tkwilliams when changes occur on boto files +| refs: \fI\%#43247\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43183\fP: (\fIbasepi\fP) Add basepi to userBlacklist for mention bot +| refs: \fI\%#43247\fP +.IP \(bu 2 +\fBPR\fP \fI\%#42923\fP: (\fIrallytime\fP) Always notify ryan\-lane when changes occur on boto files +| refs: \fI\%#43247\fP +.IP \(bu 2 +\fBPR\fP \fI\%#42903\fP: (\fIjunovitch\fP) Fix \(aqpreserve_minion_cache: True\(aq functionality (fixes \fI\%#35840\fP) +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +9b27473763 Merge pull request \fI\%#43371\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +7b07b58396 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +0c986f5eba Merge pull request \fI\%#43361\fP from rallytime/\fI\%bp\-43329\fP +.INDENT 2.0 +.IP \(bu 2 +b09e5b4379 Fix \fI\%#43295\fP, better handling of consul initialization issues +.UNINDENT +.IP \(bu 2 +22287439e6 Merge pull request \fI\%#42903\fP from junovitch/issue\-35840\-fix\-preserve\-minion\-cache\-2016.11 +.INDENT 2.0 +.IP \(bu 2 +c9d4fdbd45 Merge branch \(aq2016.11\(aq into issue\-35840\-fix\-preserve\-minion\-cache\-2016.11 +.IP \(bu 2 +93a68e32a5 Merge branch \(aq2016.11\(aq into issue\-35840\-fix\-preserve\-minion\-cache\-2016.11 +.IP \(bu 2 +079f097985 Fix \(aqpreserve_minion_cache: True\(aq functionality (fixes \fI\%#35840\fP) +.UNINDENT +.IP \(bu 2 +4860e10757 Merge pull request \fI\%#43360\fP from terminalmage/sj\-496 +.INDENT 2.0 +.IP \(bu 2 +433bca14b1 Fix KeyError in yumpkg configparser code on Python 3 +.IP \(bu 2 +f6c16935d8 Move \-\-showduplicates before repository\-packages +.UNINDENT +.IP \(bu 2 +4ba2dbe41e Merge pull request \fI\%#43244\fP from rallytime/release\-branch\-clarifications +.INDENT 2.0 +.IP \(bu 2 +0d5a46dbaa Update release branch section with a few more details +.UNINDENT +.IP \(bu 2 +1a012eb3d7 Merge pull request \fI\%#43359\fP from gtmanfred/ipaddr +.INDENT 2.0 +.IP \(bu 2 +23d9abb560 ipaddr_start ipaddr_end for el7 +.UNINDENT +.IP \(bu 2 +8f88111be8 Merge pull request \fI\%#43247\fP from rallytime/mentionbot\-backports +.INDENT 2.0 +.IP \(bu 2 +2b85757d73 Always notify tkwilliams when changes occur on boto files +.IP \(bu 2 +40b5a29f90 Add basepi to userBlacklist for mention bot +.IP \(bu 2 +bad8f56969 Always notify ryan\-lane when changes occur on boto files +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43398\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_mount\fP for Windows +@ \fI2017\-09\-08T13:39:29Z\fP +.INDENT 2.0 +.IP \(bu 2 +97f05ff603 Merge pull request \fI\%#43398\fP from twangboy/win_fix_test_mount +.IP \(bu 2 +4a8d7e522c Fix tests, Use full path to salt.utils.which +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43399\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_pam\fP for Windows +@ \fI2017\-09\-08T13:37:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +6a4cc5c1b0 Merge pull request \fI\%#43399\fP from twangboy/win_fix_test_pam +.IP \(bu 2 +6257aa964a Fix \fIunit.modules.test_pam\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43400\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_parted\fP for Windows +@ \fI2017\-09\-08T13:37:00Z\fP +.INDENT 2.0 +.IP \(bu 2 +2b5cfae3f8 Merge pull request \fI\%#43400\fP from twangboy/win_unit_test_parted +.IP \(bu 2 +8e3e897ee2 Fix \fIunit.modules.test_parted\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43401\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_pw_group\fP for Windows +@ \fI2017\-09\-08T13:35:45Z\fP +.INDENT 2.0 +.IP \(bu 2 +332deeb013 Merge pull request \fI\%#43401\fP from twangboy/win_unit_test_pw_group +.IP \(bu 2 +78e39a1b9d Fix \fIunit.modules.test_pw_group\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43402\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_qemu_nbd\fP for Windows +@ \fI2017\-09\-08T13:34:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +c0f54bfef1 Merge pull request \fI\%#43402\fP from twangboy/win_unit_test_qemu_nbd +.IP \(bu 2 +531ce8022b Fix \fIunit.modules.test_qemu_nbd\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43404\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_seed\fP for Windows +@ \fI2017\-09\-08T13:32:41Z\fP +.INDENT 2.0 +.IP \(bu 2 +be88fbb45f Merge pull request \fI\%#43404\fP from twangboy/win_unit_test_seed +.IP \(bu 2 +6ceb895a84 Use os.path.join for paths +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43301\fP: (\fItwangboy\fP) Fix \fIunit.test_spm\fP for Windows +@ \fI2017\-09\-08T13:24:35Z\fP +.INDENT 2.0 +.IP \(bu 2 +612c6a8756 Merge pull request \fI\%#43301\fP from twangboy/win_fix_unit_test_spm +.IP \(bu 2 +8608a6b303 Merge branch \(aq2017.7\(aq into win_fix_unit_test_spm +.IP \(bu 2 +b8da04c04d Add Mike\(aqs changes +.IP \(bu 2 +f36efbd6a7 Fix \fIunit.test_spm\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43372\fP: (\fIskizunov\fP) Fix system.set_system_time when no hw clock is present +@ \fI2017\-09\-07T17:45:33Z\fP +.INDENT 2.0 +.IP \(bu 2 +f959113694 Merge pull request \fI\%#43372\fP from skizunov/develop5 +.IP \(bu 2 +281e471853 Fix system.set_system_time when no hw clock is present +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43193\fP: (\fIjettero\fP) Prevent spurious "Template does not exist" error +@ \fI2017\-09\-06T20:16:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#39516\fP: (\fIjettero\fP) Prevent spurious "Template does not exist" error +| refs: \fI\%#43193\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6d13535ed0 Merge pull request \fI\%#43193\fP from jettero/template\-dne\-again +.IP \(bu 2 +cde8aed2cf Merge branch \(aq2017.7\(aq into template\-dne\-again +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43159\fP: (\fIjubrad\fP) Bp 43018 +@ \fI2017\-09\-05T22:29:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42706\fP: (\fIblarghmatey\fP) Parallel Cache Failure +| refs: \fI\%#43018\fP \fI\%#43159\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43172\fP: (\fIrallytime\fP) Move new utils/__init__.py funcs to utils.files.py +.IP \(bu 2 +\fBPR\fP \fI\%#43056\fP: (\fIdamon\-atkins\fP) safe_filename_leaf(file_basename) and safe_filepath(file_path_name) +| refs: \fI\%#43159\fP \fI\%#43172\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43018\fP: (\fIjubrad\fP) Update state.py +| refs: \fI\%#43159\fP \fI\%#43727\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +015cbc57d9 Merge pull request \fI\%#43159\fP from jubrad/\fI\%bp\-43018\fP +.IP \(bu 2 +25419a56db Merge branch \(aq2017.7\(aq into \fI\%bp\-43018\fP +.IP \(bu 2 +971b4c0890 Merge branch \(aq2017.7\(aq into \fI\%bp\-43018\fP +.IP \(bu 2 +4f8e6c65e5 access safe_filename_leaf through utils.files, changed in \fI\%#43172\fP +.IP \(bu 2 +42064883ea state.py remove unused urllib import +.IP \(bu 2 +4957268b37 update state.py to use safe_filename_leaf +.IP \(bu 2 +b8ead879ed Fixing lint issues +.IP \(bu 2 +446457d017 Swapping \fIfrom\fP for \fIimport\fP +.IP \(bu 2 +fb80e17400 state.py: fix import and utf8 encode before quote +.IP \(bu 2 +1dcf167bb7 Update state.py +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43232\fP: (\fIterminalmage\fP) Improve inheritance in salt.utils.gitfs +@ \fI2017\-09\-05T20:37:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +6e1b541b46 Merge pull request \fI\%#43232\fP from terminalmage/gitfs\-inheritance +.IP \(bu 2 +53bd3a3e23 Improve inheritance in salt.utils.gitfs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43238\fP: (\fIs0undt3ch\fP) Include the line number by default on the log file format +@ \fI2017\-09\-05T20:31:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +086b220091 Merge pull request \fI\%#43238\fP from s0undt3ch/2017.7 +.IP \(bu 2 +630a1db3ab Include the line number by default on the log file format +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43294\fP: (\fItwangboy\fP) Win build scripts +@ \fI2017\-09\-05T20:12:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +09dc58cde5 Merge pull request \fI\%#43294\fP from twangboy/win_build_scripts +.IP \(bu 2 +9979ccb613 Remove Py2 and Py3 in the same run +.IP \(bu 2 +a5d9f85db6 Modifications to build scripts +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43322\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-09\-05T18:21:26Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#43312\fP: (\fIlordcirth\fP) cron docs: Remind user to use quotes for special strings +.IP \(bu 2 +\fBPR\fP \fI\%#43290\fP: (\fIlordcirth\fP) Clarify file.py docs +.IP \(bu 2 +\fBPR\fP \fI\%#43277\fP: (\fIrallytime\fP) Add CODEOWNERS file +.IP \(bu 2 +\fBPR\fP \fI\%#43274\fP: (\fIterminalmage\fP) Use six.integer_types instead of int +.IP \(bu 2 +\fBPR\fP \fI\%#43271\fP: (\fItwangboy\fP) Fix minor formatting issue +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +21ab306ef4 Merge pull request \fI\%#43322\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +b1062f8c15 Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.INDENT 2.0 +.IP \(bu 2 +02867fdcd2 Merge pull request \fI\%#43277\fP from rallytime/owners\-file +.INDENT 2.0 +.IP \(bu 2 +2b4da0f0e7 Add CODEOWNERS file +.UNINDENT +.IP \(bu 2 +1c1c484479 Merge pull request \fI\%#43312\fP from lordcirth/fix\-cron\-docs +.INDENT 2.0 +.IP \(bu 2 +ec94a13750 cron docs: Remind user to use quotes for special strings +.UNINDENT +.IP \(bu 2 +0d1ed4b750 Merge pull request \fI\%#43290\fP from lordcirth/fix\-file\-path\-docs +.INDENT 2.0 +.IP \(bu 2 +14a4591854 file.py docs: correct group and mode +.IP \(bu 2 +d4214ca283 file.py docs: specify absolute paths +.UNINDENT +.IP \(bu 2 +26ff89539e Merge pull request \fI\%#43274\fP from terminalmage/fix\-int\-types +.INDENT 2.0 +.IP \(bu 2 +d533877743 Use six.integer_types instead of int +.UNINDENT +.IP \(bu 2 +cf21f91fb2 Merge pull request \fI\%#43271\fP from twangboy/win_fix_pkg.install +.INDENT 2.0 +.IP \(bu 2 +91b062f564 Fix formatting issue, spaces surrounding + +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43324\fP: (\fItwangboy\fP) Fix \fIunit.modules.test_chef\fP for Windows +@ \fI2017\-09\-05T16:40:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +62429c547d Merge pull request \fI\%#43324\fP from twangboy/fix_unit.modules.test_chef +.IP \(bu 2 +5bd5ea042a Fix \fIunit.modules.test_chef\fP for Windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43268\fP: (\fIrallytime\fP) Back\-port \fI\%#43237\fP to 2017.7 +@ \fI2017\-09\-01T18:17:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#43237\fP: (\fItimka\fP) .utils.aws.get_location() expects a dict +| refs: \fI\%#43268\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +367668a0a3 Merge pull request \fI\%#43268\fP from rallytime/\fI\%bp\-43237\fP +.IP \(bu 2 +047ad07da4 .utils.aws.get_location() expects a dict +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43270\fP: (\fIrallytime\fP) [2017.7] Merge forward from 2016.11 to 2017.7 +@ \fI2017\-09\-01T18:09:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42279\fP: (\fIdafyddj\fP) win_lgpo matches multiple policies due to startswith() +| refs: \fI\%#43116\fP \fI\%#43116\fP \fI\%#43154\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43228\fP: (\fItwangboy\fP) Win fix pkg.install +.IP \(bu 2 +\fBPR\fP \fI\%#43191\fP: (\fIviktorkrivak\fP) Fix apache.config with multiple statement +.IP \(bu 2 +\fBPR\fP \fI\%#43154\fP: (\fIlomeroe\fP) Backport \fI\%#43116\fP to 2016.11 +.IP \(bu 2 +\fBPR\fP \fI\%#43116\fP: (\fIlomeroe\fP) Fix 42279 in develop +| refs: \fI\%#43154\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +02504dd363 Merge pull request \fI\%#43270\fP from rallytime/merge\-2017.7 +.IP \(bu 2 +f8b025f6dc Merge branch \(aq2016.11\(aq into \(aq2017.7\(aq +.IP \(bu 2 +3a0b02f3ae Merge pull request \fI\%#43228\fP from twangboy/win_fix_pkg.install +.INDENT 2.0 +.IP \(bu 2 +13dfabb1ce Fix regex statement, add \fI\&.\fP +.IP \(bu 2 +31ff69f0ad Add underscore to regex search +.IP \(bu 2 +3cf2b6575c Fix spelling +.IP \(bu 2 +ed030a35a5 Use regex to detect salt\-minion install +.IP \(bu 2 +e5daff495a Fix pkg.install +.UNINDENT +.IP \(bu 2 +b4c689dff5 Merge pull request \fI\%#43191\fP from viktorkrivak/fix\-apache\-config\-multi\-entity +.INDENT 2.0 +.IP \(bu 2 +c15bcbe1cc Merge remote\-tracking branch \(aqupstream/2016.11\(aq into fix\-apache\-config\-multi\-entity +.IP \(bu 2 +4164047951 Fix apache.config with multiple statement At this moment when you post more than one statement in config only last is used. Also file is rewrited multiple times until last statement is written. Example: salt \(aq*\(aq apache.config /etc/httpd/conf.d/ports.conf config="[{\(aqListen\(aq: \(aq8080\(aq}, {\(aqProxy\(aq: "Something"}]" Ends only with Proxy Something and ignore Listen 8080, This patch fix this issue. +.UNINDENT +.IP \(bu 2 +b90e59ede9 Merge pull request \fI\%#43154\fP from lomeroe/\fI\%bp\-43116\fP\-2016.11 +.IP \(bu 2 +8f593b0b02 verify that files exist before trying to remove them, win_file.remove raises an exception if the file does not exist +.IP \(bu 2 +33a30bac06 correcting bad format statement in search for policy to be disabled +.IP \(bu 2 +acc3d7ac82 correct fopen calls from salt.utils for 2016.11\(aqs utils function +.IP \(bu 2 +2da1cdd109 lint fix +.IP \(bu 2 +61bd12c0de track xml namespace to ensure policies w/duplicate IDs or Names do not conflict +.IP \(bu 2 +f232bed9f9 add additional checks for ADM policies that have the same ADMX policy ID (\fI\%#42279\fP) +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43283\fP: (\fIDmitryKuzmenko\fP) Fix ldap token groups auth. +@ \fI2017\-09\-01T17:49:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42459\fP: (\fIiavael\fP) Broken ldap groups retrieval in salt.auth.ldap after upgrade to 2017.7 +| refs: \fI\%#43283\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ece0e393ef Merge pull request \fI\%#43283\fP from DSRCorporation/bugs/42459_broken_ldap_groups +.IP \(bu 2 +3ad6911210 Fix for tests: don\(aqt require \(aqgroups\(aq in the eauth token. +.IP \(bu 2 +1f104cf85b Fix ldap token groups auth. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43149\fP: (\fIBenoitKnecht\fP) Fix iptables.get_rules when rules contain \-\-nfmask or \-\-ctmask +@ \fI2017\-09\-01T15:57:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +4f023c4cb6 Merge pull request \fI\%#43149\fP from BenoitKnecht/2017.7.1 +.IP \(bu 2 +3c1ddc9bde modules: iptables: correctly parse \fI\-\-nfmask\fP/\fI\-\-ctmask\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43265\fP: (\fIgtmanfred\fP) make sure meta\-data grains work on ec2 +@ \fI2017\-09\-01T15:31:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43258\fP: (\fInomeelnoj\fP) metadata_server_grains problems +| refs: \fI\%#43265\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +cf2b75bb86 Merge pull request \fI\%#43265\fP from gtmanfred/2017.7 +.IP \(bu 2 +04dd8ebedb make sure meta\-data grains work on ec2 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43299\fP: (\fItwangboy\fP) Fix \fIunit.netapi.rest_cherrypy.test_tools\fP for Windows +@ \fI2017\-09\-01T15:13:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +618b221895 Merge pull request \fI\%#43299\fP from twangboy/win_fix_netapi_cherrypy +.IP \(bu 2 +fd74acb603 Merge branch \(aq2017.7\(aq into win_fix_netapi_cherrypy +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43300\fP: (\fItwangboy\fP) Fix \fIunit.netapi.rest_tornado.test_handlers\fP for Windows +@ \fI2017\-09\-01T13:10:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +aee654da92 Merge pull request \fI\%#43300\fP from twangboy/win_fix_netapi_rest_tornado +.IP \(bu 2 +c93d2ed386 Use os.sep instead of \(aq/\(aq +.IP \(bu 2 +3fbf24b91a Use os.sep instead of \(aq/\(aq +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43278\fP: (\fIgtmanfred\fP) bootstrap can come from dunders +@ \fI2017\-08\-31T13:31:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#43259\fP: (\fImahesh21\fP) NameError: global name \(aq__opts__\(aq is not defined +| refs: \fI\%#43266\fP +.IP \(bu 2 +\fBPR\fP \fI\%#43266\fP: (\fIgtmanfred\fP) switch virtualbox cloud driver to use __utils__ +| refs: \fI\%#43278\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +aed2975979 Merge pull request \fI\%#43278\fP from gtmanfred/virtualbox +.IP \(bu 2 +c4ae2de30f bootstrap can come from dunders +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#42975\fP: (\fIbrejoc\fP) Added unit tests for Kubernetes module +@ \fI2017\-08\-30T20:30:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +479e0e06ac Merge pull request \fI\%#42975\fP from brejoc/tests\-for\-kubernetes\-module +.IP \(bu 2 +fdad9177b5 Merge branch \(aq2017.7\(aq into tests\-for\-kubernetes\-module +.IP \(bu 2 +c227cb25ad Skipping test on ImportError +.IP \(bu 2 +bd76a870ce Dunder vars are now defined via setup_loader_modules +.IP \(bu 2 +3c99e61637 Renamed test to match new convention +.IP \(bu 2 +caf78d206d Fixed imports for pytest +.IP \(bu 2 +c8e98c8d8a Added unit tests for Kubernetes module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#43176\fP: (\fIterminalmage\fP) docker_image states: Handle Hub images prefixed with "docker.io/" +@ \fI2017\-08\-30T20:08:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#42935\fP: (\fIBenjaminSchubert\fP) docker_image.present always ends up failing even on correct result. +| refs: \fI\%#43176\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ca7df1d4cf Merge pull request \fI\%#43176\fP from terminalmage/issue42935 +.IP \(bu 2 +df18a89836 Lint: Remove unused import +.IP \(bu 2 +7279f98e92 docker_image states: Handle Hub images prefixed with "docker.io/" +.IP \(bu 2 +f7c945f6e4 Prevent spurious "Template does not exist" error +.UNINDENT +.UNINDENT .SS Salt 2016.11.0 Release Notes \- Codename Carbon .SS New Features .SS Docker Introspection and Configuration @@ -373970,6 +404854,14 @@ def __virtual__(): .UNINDENT .UNINDENT .sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fBsalt.utils.is_proxy()\fP has been renamed to +\fBsalt.utils.platform.is_proxy\fP as of the Oxygen release. +.UNINDENT +.UNINDENT +.sp The try/except block above exists because grains are processed very early in the proxy minion startup process, sometimes earlier than the proxy key in the \fB__opts__\fP dictionary is populated. diff --git a/doc/man/spm.1 b/doc/man/spm.1 index 1b4e5779e5..f9e59044a8 100644 --- a/doc/man/spm.1 +++ b/doc/man/spm.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SPM" "1" "Jan 24, 2018" "2017.7.3" "Salt" +.TH "SPM" "1" "Feb 23, 2018" "2018.3.0" "Salt" .SH NAME spm \- Salt Package Manager Command . diff --git a/doc/ref/configuration/master.rst b/doc/ref/configuration/master.rst index 87af51320f..b554496710 100644 --- a/doc/ref/configuration/master.rst +++ b/doc/ref/configuration/master.rst @@ -1398,7 +1398,7 @@ comparison, then by globbing, then by full-string regex matching. This should still be considered a less than secure option, due to the fact that trust is based on just the requesting minion id. -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 For security reasons the file must be readonly except for it's owner. If :conf_master:`permissive_pki_access` is ``True`` the owning group can also have write access, but if Salt is running as ``root`` it must be a member of that group. @@ -1423,7 +1423,7 @@ membership in the :conf_master:`autosign_file` and the ``autosign_grains_dir`` ----------------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``not defined`` @@ -1920,7 +1920,7 @@ Set additional directories to search for runner modules. ``utils_dirs`` --------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``[]`` @@ -2130,7 +2130,7 @@ the cloud profile or master config file, no templating will be performed. ``jinja_env`` ------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``{}`` @@ -2166,7 +2166,7 @@ The default options are: ``jinja_sls_env`` ----------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``{}`` @@ -2236,7 +2236,7 @@ be used if you had not set the line_statement and line_comment options: ``jinja_trim_blocks`` --------------------- -.. deprecated:: Oxygen +.. deprecated:: 2018.3.0 Replaced by :conf_master:`jinja_env` and :conf_master:`jinja_sls_env` .. versionadded:: 2014.1.0 @@ -2256,7 +2256,7 @@ to the Jinja environment init variable ``trim_blocks``. ``jinja_lstrip_blocks`` ----------------------- -.. deprecated:: Oxygen +.. deprecated:: 2018.3.0 Replaced by :conf_master:`jinja_env` and :conf_master:`jinja_sls_env` .. versionadded:: 2014.1.0 @@ -2666,7 +2666,7 @@ Example: ``roots_update_interval`` ************************* -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``60`` @@ -2853,7 +2853,7 @@ gitfs remotes. ``gitfs_disable_saltenv_mapping`` ********************************* -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``False`` @@ -2876,7 +2876,7 @@ parameters `. ``gitfs_ref_types`` ******************* -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``['branch', 'tag', 'sha']`` @@ -2908,7 +2908,7 @@ are mapped as saltenvs: *************************** .. versionadded:: 2014.7.0 -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 Renamed from ``gitfs_env_whitelist`` to ``gitfs_saltenv_whitelist`` Default: ``[]`` @@ -2931,7 +2931,7 @@ information can be found in the :ref:`GitFS Walkthrough *************************** .. versionadded:: 2014.7.0 -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 Renamed from ``gitfs_env_blacklist`` to ``gitfs_saltenv_blacklist`` Default: ``[]`` @@ -2983,7 +2983,7 @@ they were created by a different master. ``gitfs_update_interval`` ************************* -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``60`` @@ -3298,7 +3298,7 @@ bookmark should be used as the ``base`` environment. ************************** .. versionadded:: 2014.7.0 -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 Renamed from ``hgfs_env_whitelist`` to ``hgfs_saltenv_whitelist`` Default: ``[]`` @@ -3328,7 +3328,7 @@ blacklist will be exposed as fileserver environments. ************************** .. versionadded:: 2014.7.0 -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 Renamed from ``hgfs_env_blacklist`` to ``hgfs_saltenv_blacklist`` Default: ``[]`` @@ -3357,7 +3357,7 @@ blacklist will be exposed as fileserver environments. ``hgfs_update_interval`` ************************ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``60`` @@ -3525,7 +3525,7 @@ also be configured on a per-remote basis, see :conf_master:`here *************************** .. versionadded:: 2014.7.0 -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 Renamed from ``svnfs_env_whitelist`` to ``svnfs_saltenv_whitelist`` Default: ``[]`` @@ -3555,7 +3555,7 @@ will be exposed as fileserver environments. *************************** .. versionadded:: 2014.7.0 -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 Renamed from ``svnfs_env_blacklist`` to ``svnfs_saltenv_blacklist`` Default: ``[]`` @@ -3584,7 +3584,7 @@ will be exposed as fileserver environments. ``svnfs_update_interval`` ************************* -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``60`` @@ -3690,7 +3690,7 @@ exposed. ``minionfs_update_interval`` **************************** -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``60`` @@ -3719,7 +3719,7 @@ examples. ``azurefs_update_interval`` *************************** -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``60`` @@ -3741,7 +3741,7 @@ See the :mod:`s3fs documentation ` for usage examples. ``s3fs_update_interval`` ************************ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``60`` diff --git a/doc/ref/configuration/minion.rst b/doc/ref/configuration/minion.rst index 3ebc562531..cdd45a98de 100644 --- a/doc/ref/configuration/minion.rst +++ b/doc/ref/configuration/minion.rst @@ -138,7 +138,7 @@ name) is set in the :conf_minion:`master` configuration setting. ``master_tops_first`` --------------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``False`` @@ -340,7 +340,7 @@ option on the Salt master. ``source_interface_name`` ------------------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The name of the interface to use when establishing the connection to the Master. @@ -379,7 +379,7 @@ Configuration example: ``source_address`` ------------------ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The source IP address or the domain name to be used when connecting the Minion to the Master. @@ -404,7 +404,7 @@ Configuration example: ``source_ret_port`` ------------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The source port to be used when connecting the Minion to the Master ret server. @@ -427,7 +427,7 @@ Configuration example: ``source_publish_port`` ----------------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The source port to be used when connecting the Minion to the Master publish server. @@ -1358,7 +1358,7 @@ The password used for HTTP proxy access. ``docker.compare_container_networks`` ------------------------------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``{'static': ['Aliases', 'Links', 'IPAMConfig'], 'automatic': ['IPAddress', 'Gateway', 'GlobalIPv6Address', 'IPv6Gateway']}`` @@ -1938,7 +1938,7 @@ enabled and can be disabled by changing this value to ``False``. ``saltenv`` ----------- -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 Renamed from ``environment`` to ``saltenv``. If ``environment`` is used, ``saltenv`` will take its value. If both are used, ``environment`` will be ignored and ``saltenv`` will be used. @@ -1957,7 +1957,7 @@ environments is to isolate via the top file. ``lock_saltenv`` ---------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``False`` @@ -2489,7 +2489,7 @@ minion's pki directory. ``autosign_grains`` ------------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``not defined`` @@ -2682,7 +2682,7 @@ executed in a thread. ``process_count_max`` ------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Default: ``-1`` diff --git a/doc/ref/modules/all/index.rst b/doc/ref/modules/all/index.rst index 49a9deb5c0..b916e9ae53 100644 --- a/doc/ref/modules/all/index.rst +++ b/doc/ref/modules/all/index.rst @@ -277,6 +277,7 @@ execution modules napalm_users napalm_yang_mod netaddress + netbox netbsd_sysctl netbsdservice netscaler diff --git a/doc/ref/modules/all/salt.modules.netbox.rst b/doc/ref/modules/all/salt.modules.netbox.rst new file mode 100644 index 0000000000..f020177e85 --- /dev/null +++ b/doc/ref/modules/all/salt.modules.netbox.rst @@ -0,0 +1,7 @@ +========================== +salt.modules.netbox module +========================== + +.. automodule:: salt.modules.netbox + :members: + diff --git a/doc/ref/states/requisites.rst b/doc/ref/states/requisites.rst index 4abf7440ba..f55fd6c031 100644 --- a/doc/ref/states/requisites.rst +++ b/doc/ref/states/requisites.rst @@ -257,7 +257,7 @@ large groups of states easily in any requisite statement. require_any ~~~~~~~~~~~ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The use of ``require_any`` demands that one of the required states executes before the dependent state. The state containing the ``require_any`` requisite is defined as the @@ -380,7 +380,7 @@ to Salt ensuring that the service is running. watch_any ~~~~~~~~~ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The state containing the ``watch_any`` requisite is defined as the watching state. The states specified in the ``watch_any`` statement are defined as the watched @@ -517,7 +517,7 @@ The ``onfail`` requisite is applied in the same way as ``require`` as ``watch``: onfail_any ~~~~~~~~~~ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The ``onfail_any`` requisite allows for reactions to happen strictly as a response to the failure of at least one other state. This can be used in a number of ways, such as @@ -616,7 +616,7 @@ if any of the watched states changes. onchanges_any ~~~~~~~~~~~~~ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The ``onchanges_any`` requisite makes a state only apply one of the required states generates changes, and if one of the watched state's "result" is ``True``. This can be diff --git a/doc/ref/states/writing.rst b/doc/ref/states/writing.rst index 78b181ddf7..05b4934add 100644 --- a/doc/ref/states/writing.rst +++ b/doc/ref/states/writing.rst @@ -156,7 +156,7 @@ A State Module must return a dict containing the following keys/values: in test mode without applying the change, ``False`` can be returned. - **comment:** A list of strings or a single string summarizing the result. - Note that support for lists of strings is available as of Salt Oxygen. + Note that support for lists of strings is available as of Salt 2018.3.0. Lists of strings will be joined with newlines to form the final comment; this is useful to allow multiple comments from subparts of a state. Prefer to keep line lengths short (use multiple lines as needed), diff --git a/doc/topics/cloud/azurearm.rst b/doc/topics/cloud/azurearm.rst index df4c45dced..4bf0c14acd 100644 --- a/doc/topics/cloud/azurearm.rst +++ b/doc/topics/cloud/azurearm.rst @@ -15,9 +15,16 @@ More information about Azure is located at `http://www.windowsazure.com/ Dependencies ============ -* `Microsoft Azure SDK for Python `_ >= 2.0rc6 -* `Microsoft Azure Storage SDK for Python `_ >= 0.32 -* `AutoRest swagger generator Python client runtime (Azure-specific module) `_ >= 0.4 +* `azure `_ >= 2.0.0rc6 +* `azure-common `_ >= 1.1.4 +* `azure-mgmt `_ >= 0.30.0rc6 +* `azure-mgmt-compute `_ >= 0.33.0 +* `azure-mgmt-network `_ >= 0.30.0rc6 +* `azure-mgmt-resource `_ >= 0.30.0 +* `azure-mgmt-storage `_ >= 0.30.0rc6 +* `azure-mgmt-web `_ >= 0.30.0rc6 +* `azure-storage `_ >= 0.32.0 +* `msrestazure `_ >= 0.4.21 * A Microsoft Azure account * `Salt `_ diff --git a/doc/topics/cloud/misc.rst b/doc/topics/cloud/misc.rst index b485d28909..8d7a745687 100644 --- a/doc/topics/cloud/misc.rst +++ b/doc/topics/cloud/misc.rst @@ -392,7 +392,7 @@ script, a cloud profile using ``file_map`` might look like: Running Pre-Flight Commands =========================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 To execute specified preflight shell commands on a VM before the deploy script is run, use the ``preflight_cmds`` option. These must be defined as a list in a cloud @@ -413,7 +413,7 @@ These commands will run in sequence **before** the bootstrap script is executed. Force Minion Config =================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The ``force_minion_config`` option requests the bootstrap process to overwrite an existing minion configuration file and public/private key files. diff --git a/doc/topics/cloud/saltify.rst b/doc/topics/cloud/saltify.rst index a65f3e5add..ac89e374c7 100644 --- a/doc/topics/cloud/saltify.rst +++ b/doc/topics/cloud/saltify.rst @@ -89,7 +89,7 @@ to it can be verified with Salt: Destroy Options --------------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 For obvious reasons, the ``destroy`` action does not actually vaporize hardware. If the salt master is connected, it can tear down parts of the client machines. @@ -113,7 +113,7 @@ and can execute the following options: Wake On LAN ----------- -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 In addition to connecting a hardware machine to a Salt master, you have the option of sending a wake-on-LAN diff --git a/doc/topics/cloud/vmware.rst b/doc/topics/cloud/vmware.rst index d502185e88..cb58073195 100644 --- a/doc/topics/cloud/vmware.rst +++ b/doc/topics/cloud/vmware.rst @@ -286,7 +286,7 @@ Set up an initial profile at ``/etc/salt/cloud.profiles`` or eagerly_scrub Specifies whether the disk should be rewrite with zeros during thick provisioning or not. Default is ``eagerly_scrub: False``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 controller Specify the SCSI controller label to which this disk should be attached. This should be specified only when creating both the specified SCSI diff --git a/doc/topics/development/contributing.rst b/doc/topics/development/contributing.rst index ed4fd2aa12..3c21c9b9c0 100644 --- a/doc/topics/development/contributing.rst +++ b/doc/topics/development/contributing.rst @@ -223,7 +223,7 @@ branches, and dot release branches. .. note:: GitHub will open pull requests against Salt's main branch, ``develop``, - byndefault. Be sure to check which branch is selected when creating the + by default. Be sure to check which branch is selected when creating the pull request. The Develop Branch diff --git a/doc/topics/development/conventions/formulas.rst b/doc/topics/development/conventions/formulas.rst index 4d65817b10..9a95da88ce 100644 --- a/doc/topics/development/conventions/formulas.rst +++ b/doc/topics/development/conventions/formulas.rst @@ -58,7 +58,7 @@ States. GitFS is a quick and natural way to use Formulas. 3. Restart the Salt master. -Beginning with the Oxygen release, using formulas with GitFS is now much more +Beginning with the 2018.3.0 release, using formulas with GitFS is now much more convenient for deployments which use many different fileserver environments (i.e. saltenvs). Using the :ref:`all_saltenvs ` parameter, files from a single git branch/tag will appear in all environments. @@ -1258,7 +1258,7 @@ target platform, and any other installation or usage instructions or tips. A sample skeleton for the ``README.rst`` file: -.. code-block:: rest +.. code-block:: restructuredtext === foo @@ -1266,10 +1266,10 @@ A sample skeleton for the ``README.rst`` file: Install and configure the FOO service. - .. note:: + **NOTE** - See the full `Salt Formulas installation and usage instructions - `_. + See the full `Salt Formulas installation and usage instructions + `_. Available states ================ @@ -1298,7 +1298,7 @@ A sample skeleton for the `CHANGELOG.rst` file: :file:`CHANGELOG.rst`: -.. code-block:: rest +.. code-block:: restructuredtext foo formula =========== diff --git a/doc/topics/jinja/index.rst b/doc/topics/jinja/index.rst index 86d8102a9c..caa7da9d13 100644 --- a/doc/topics/jinja/index.rst +++ b/doc/topics/jinja/index.rst @@ -834,7 +834,7 @@ Returns: ---------- .. versionadded:: 2017.7.0 -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Renamed from ``str_to_num`` to ``to_num``. Converts a string to its numerical value. @@ -882,7 +882,7 @@ Example: -------------------- .. versionadded:: 2017.7.0 -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Renamed from ``json_decode_list`` to ``json_encode_list``. When you encode something you get bytes, and when you decode, you get your locale's encoding (usually a ``unicode`` type). This filter was incorrectly-named @@ -911,7 +911,7 @@ Returns: -------------------- .. versionadded:: 2017.7.0 -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Renamed from ``json_decode_dict`` to ``json_encode_dict``. When you encode something you get bytes, and when you decode, you get your locale's encoding (usually a ``unicode`` type). This filter was incorrectly-named @@ -942,7 +942,7 @@ Returns: --------------- .. versionadded:: 2017.7.0 -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Renamed from ``rand_str`` to ``random_hash`` to more accurately describe what the filter does. ``rand_str`` will be supported until the Neon release. @@ -1384,7 +1384,7 @@ Example: .. code-block:: jinja - {{ 'www.google.com' | dns_check }} + {{ 'www.google.com' | dns_check(port=443) }} Returns: diff --git a/doc/topics/master_tops/index.rst b/doc/topics/master_tops/index.rst index f5f268cacf..c387abd252 100644 --- a/doc/topics/master_tops/index.rst +++ b/doc/topics/master_tops/index.rst @@ -89,6 +89,6 @@ bare-bones example: .. note:: If a master_tops module returns :ref:`top file ` data for a given minion, it will be added to the states configured in the top file. It - will *not* replace it altogether. The Oxygen release adds additional + will *not* replace it altogether. The 2018.3.0 release adds additional functionality allowing a minion to treat master_tops as the single source of truth, irrespective of the top file. diff --git a/doc/topics/orchestrate/orchestrate_runner.rst b/doc/topics/orchestrate/orchestrate_runner.rst index cbf2ced7d7..4771ff1d47 100644 --- a/doc/topics/orchestrate/orchestrate_runner.rst +++ b/doc/topics/orchestrate/orchestrate_runner.rst @@ -263,16 +263,16 @@ To execute with pillar data. Return Codes in Runner/Wheel Jobs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 State (``salt.state``) jobs are able to report failure via the :ref:`state return dictionary `. Remote execution (``salt.function``) jobs are able to report failure by setting a ``retcode`` key in the ``__context__`` dictionary. However, runner (``salt.runner``) and wheel (``salt.wheel``) jobs would only report a ``False`` result when the -runner/wheel function raised an exception. As of the Oxygen release, it is now -possible to set a retcode in runner and wheel functions just as you can do in -remote execution functions. Here is some example pseudocode: +runner/wheel function raised an exception. As of the 2018.3.0 release, it is +now possible to set a retcode in runner and wheel functions just as you can do +in remote execution functions. Here is some example pseudocode: .. code-block:: python @@ -332,10 +332,9 @@ Given the above setup, the orchestration will be carried out as follows: 3. Finally, the ``ceph`` SLS target will be executed on all minions which have a grain called ``role`` with a value of ``storage``. - .. note:: - Remember, salt-run is always executed on the master. + Remember, salt-run is *always* executed on the master. .. _orchestrate-runner-parsing-results-programatically: @@ -591,11 +590,11 @@ loadable and parsable format: } -The Oxygen release includes a couple fixes to make parsing this data easier and +The 2018.3.0 release includes a couple fixes to make parsing this data easier and more accurate. The first is the ability to set a :ref:`return code ` in a custom runner or wheel function, as noted above. The second is a change to how failures are included -in the return data. Prior to the Oxygen release, minions that failed a +in the return data. Prior to the 2018.3.0 release, minions that failed a ``salt.state`` orchestration job would show up in the ``comment`` field of the return data, in a human-readable string that was not easily parsed. They are now included in the ``changes`` dictionary alongside the minions that @@ -603,3 +602,32 @@ succeeded. In addition, ``salt.function`` jobs which failed because the :ref:`fail function ` returned ``False`` used to handle their failures in the same way ``salt.state`` jobs did, and this has likewise been corrected. + + +Running States on the Master without a Minion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The orchestrate runner can be used to execute states on the master without +using a minion. For example, assume that ``salt://foo.sls`` contains the +following SLS: + +.. code-block:: yaml + + /etc/foo.conf: + file.managed: + - source: salt://files/foo.conf + - mode: 0600 + +In this case, running ``salt-run state.orchestrate foo`` would be the +equivalent of running a ``state.sls foo``, but it would execute on the master +only, and would not require a minion daemon to be running on the master. + +This is not technically orchestration, but it can be useful in certain use +cases. + +Limitations +^^^^^^^^^^^ + +Only one SLS target can be run at a time using this method, while using +:py:func:`state.sls ` allows for multiple SLS files to +be passed in a comma-separated list. diff --git a/doc/topics/proxyminion/index.rst b/doc/topics/proxyminion/index.rst index c398020f72..d4b1934f96 100644 --- a/doc/topics/proxyminion/index.rst +++ b/doc/topics/proxyminion/index.rst @@ -157,7 +157,8 @@ will need to be restarted to pick up any changes. A corresponding utility funct In addition, a salt.utils helper function called `is_proxy()` was added to make it easier to tell when the running minion is a proxy minion. **NOTE: This -function was renamed to salt.utils.platform.is_proxy() for the Oxygen release** +function was renamed to salt.utils.platform.is_proxy() for the 2018.3.0 +release** New in 2015.8 ------------- diff --git a/doc/topics/reactor/index.rst b/doc/topics/reactor/index.rst index de5df946ac..5763763f42 100644 --- a/doc/topics/reactor/index.rst +++ b/doc/topics/reactor/index.rst @@ -115,11 +115,10 @@ Name Description ============================== ================================================================================== .. note:: - The ``local`` and ``caller`` reaction types will be renamed for the Oxygen - release. These reaction types were named after Salt's internal client - interfaces, and are not intuitively named. Both ``local`` and ``caller`` - will continue to work in Reactor SLS files, but for the Oxygen release the - documentation will be updated to reflect the new preferred naming. + The ``local`` and ``caller`` reaction types will likely be renamed in a + future release. These reaction types were named after Salt's internal + client interfaces, and are not intuitively named. Both ``local`` and + ``caller`` will continue to work in Reactor SLS files, however. Where to Put Reactor SLS Files ============================== diff --git a/doc/topics/releases/2016.11.9.rst b/doc/topics/releases/2016.11.9.rst index f330b9ae2b..69c261c437 100644 --- a/doc/topics/releases/2016.11.9.rst +++ b/doc/topics/releases/2016.11.9.rst @@ -2,7 +2,7 @@ Salt 2016.11.9 Release Notes ============================ -Version 2016.11.9 is a bugfix release for :ref:`2016.11.0 `.] +Version 2016.11.9 is a bugfix release for :ref:`2016.11.0 `. Changes for v2016.11.8..v2016.11.9 ---------------------------------------------------------------- diff --git a/doc/topics/releases/2017.7.4.rst b/doc/topics/releases/2017.7.4.rst new file mode 100644 index 0000000000..b5f371050a --- /dev/null +++ b/doc/topics/releases/2017.7.4.rst @@ -0,0 +1,112 @@ +=========================== +Salt 2017.7.4 Release Notes +=========================== + +Version 2017.7.4 is a bugfix release for :ref:`2017.7.0 `. + +Changes for v2017.7.3..v2017.7.4 +--------------------------------------------------------------- + +Extended changelog courtesy of Todd Stansell (https://github.com/tjstansell/salt-changelogs): + +*Generated at: 2018-02-16T16:44:38Z* + +Statistics: + +- Total Merges: **7** +- Total Issue references: **4** +- Total PR references: **11** + +Changes: + + +- **PR** `#46066`_: (*rallytime*) Pin tornado version in requirements file + @ *2018-02-16T16:40:05Z* + + - **ISSUE** `#45790`_: (*bdarnell*) Test with Tornado 5.0b1 + | refs: `#46066`_ + * 32f3d00e44 Merge pull request `#46066`_ from rallytime/pin-tornado + * 6dc1a3b9dc Pin tornado version in requirements file + +- **PR** `#46036`_: (*terminalmage*) git.latest: Fix regression with identity file usage + @ *2018-02-16T13:57:23Z* + + * 85761ee650 Merge pull request `#46036`_ from terminalmage/issue43769 + * e2140d9a84 Mock the ssh.key_is_encrypted utils func + + * 169924b3fe Move ssh.key_is_encrypted to a utils module temporarily + + * 54f4d78f7a Only keep ssh.py in the Windows installer + + * 5f04531e1b Keep ssh state and execution modules in the installer + + * f2b69f703d git.latest: Fix regression with identity file usage + +- **PR** `#46009`_: (*Ch3LL*) Add 2017.7.4 Release Notes with PRs + @ *2018-02-13T16:40:30Z* + + * 6d534c6e7e Merge pull request `#46009`_ from Ch3LL/rn_7.4 + * ac0baf4b34 Add 2017.7.4 Release Notes with PRs + +- **PR** `#45981`_: (*gtmanfred*) use local config for vault when masterless + @ *2018-02-13T15:22:01Z* + + - **ISSUE** `#45976`_: (*grobinson-blockchain*) 6a5e0f9 introduces regression that breaks Vault module for salt masterless + | refs: `#45981`_ + * ca76a0b328 Merge pull request `#45981`_ from gtmanfred/2017.7.3 + * 0d448457dc apparently local is not set by default + + * 2a92f4bc16 use local config for vault when masterless + +- **PR** `#45953`_: (*rallytime*) Back-port `#45928`_ to 2017.7.3 + @ *2018-02-09T22:29:10Z* + + - **ISSUE** `#45915`_: (*MatthiasKuehneEllerhold*) 2017.7.3: Salt-SSH & Vault Pillar: Permission denied "minion.pem" + | refs: `#45928`_ + - **PR** `#45928`_: (*garethgreenaway*) [2017.7] Fixing vault when used with pillar over salt-ssh + | refs: `#45953`_ + * 6530649dbc Merge pull request `#45953`_ from rallytime/`bp-45928`_-2017.7.3 + * 85363189d1 Fixing vault when used with pillar over salt-ssh + +- **PR** `#45934`_: (*rallytime*) Back-port `#45902`_ to 2017.7.3 + @ *2018-02-09T16:31:08Z* + + - **ISSUE** `#45893`_: (*CrackerJackMack*) archive.extracted ValueError "No path specified" in 2017.7.3 + | refs: `#45902`_ + - **PR** `#45902`_: (*terminalmage*) Check the effective saltenv for cached archive + | refs: `#45934`_ + * fb378cebb0 Merge pull request `#45934`_ from rallytime/`bp-45902`_ + * bb83e8b345 Add regression test for issue 45893 + + * cdda66d759 Remove duplicated section in docstring and fix example + + * 4b6351cda6 Check the effective saltenv for cached archive + +- **PR** `#45935`_: (*rallytime*) Back-port `#45742`_ to 2017.7.3 + @ *2018-02-09T14:02:26Z* + + - **PR** `#45742`_: (*marccardinal*) list.copy() is not compatible with python 2.7 + | refs: `#45935`_ + * 0d74151c71 Merge pull request `#45935`_ from rallytime/`bp-45742`_ + * 6a0b5f7af3 Removed the chained copy + + * ad1150fad4 list.copy() is not compatible with python 2.7 + + +.. _`#45742`: https://github.com/saltstack/salt/pull/45742 +.. _`#45790`: https://github.com/saltstack/salt/issues/45790 +.. _`#45893`: https://github.com/saltstack/salt/issues/45893 +.. _`#45902`: https://github.com/saltstack/salt/pull/45902 +.. _`#45915`: https://github.com/saltstack/salt/issues/45915 +.. _`#45928`: https://github.com/saltstack/salt/pull/45928 +.. _`#45934`: https://github.com/saltstack/salt/pull/45934 +.. _`#45935`: https://github.com/saltstack/salt/pull/45935 +.. _`#45953`: https://github.com/saltstack/salt/pull/45953 +.. _`#45976`: https://github.com/saltstack/salt/issues/45976 +.. _`#45981`: https://github.com/saltstack/salt/pull/45981 +.. _`#46009`: https://github.com/saltstack/salt/pull/46009 +.. _`#46036`: https://github.com/saltstack/salt/pull/46036 +.. _`#46066`: https://github.com/saltstack/salt/pull/46066 +.. _`bp-45742`: https://github.com/saltstack/salt/pull/45742 +.. _`bp-45902`: https://github.com/saltstack/salt/pull/45902 +.. _`bp-45928`: https://github.com/saltstack/salt/pull/45928 diff --git a/doc/topics/releases/2017.7.5.rst b/doc/topics/releases/2017.7.5.rst new file mode 100644 index 0000000000..05401a001a --- /dev/null +++ b/doc/topics/releases/2017.7.5.rst @@ -0,0 +1,5 @@ +=========================== +Salt 2017.7.5 Release Notes +=========================== + +Version 2017.7.5 is a bugfix release for :ref:`2017.7.0 `. diff --git a/doc/topics/releases/oxygen.rst b/doc/topics/releases/2018.3.0.rst similarity index 97% rename from doc/topics/releases/oxygen.rst rename to doc/topics/releases/2018.3.0.rst index 99742e8eb8..9ef219621d 100644 --- a/doc/topics/releases/oxygen.rst +++ b/doc/topics/releases/2018.3.0.rst @@ -1,8 +1,8 @@ -:orphan: +.. _release-2018-3-0: -==================================== -Salt Release Notes - Codename Oxygen -==================================== +============================================= +Salt 2018.3.0 Release Notes - Codename Oxygen +============================================= Lots of Docker Improvements --------------------------- @@ -79,7 +79,7 @@ with release Neon. The functions have been moved as follows: -- ``salt.utils.appendproctitle``: use ``salt.utils.process.appendproctitle`` +- ``salt.utils.appendproctitle``: use ``salt.utils.process.appendproctitle`` instead. - ``salt.utils.daemonize``: use ``salt.utils.process.daemonize`` instead. - ``salt.utils.daemonize_if``: use ``salt.utils.process.daemonize_if`` instead. @@ -94,22 +94,22 @@ The functions have been moved as follows: - ``salt.utils.is_hex``: use ``salt.utils.stringutils.is_hex`` instead. - ``salt.utils.is_bin_str``: use ``salt.utils.stringutils.is_bin_str`` instead. - ``salt.utils.rand_string``: use ``salt.utils.stringutils.random`` instead. -- ``salt.utils.contains_whitespace``: use +- ``salt.utils.contains_whitespace``: use ``salt.utils.stringutils.contains_whitespace`` instead. -- ``salt.utils.build_whitespace_split_regex``: use +- ``salt.utils.build_whitespace_split_regex``: use ``salt.utils.stringutils.build_whitespace_split_regex`` instead. - ``salt.utils.expr_match``: use ``salt.utils.stringutils.expr_match`` instead. -- ``salt.utils.check_whitelist_blacklist``: use +- ``salt.utils.check_whitelist_blacklist``: use ``salt.utils.stringutils.check_whitelist_blacklist`` instead. -- ``salt.utils.check_include_exclude``: use +- ``salt.utils.check_include_exclude``: use ``salt.utils.stringutils.check_include_exclude`` instead. - ``salt.utils.print_cli``: use ``salt.utils.stringutils.print_cli`` instead. - ``salt.utils.clean_kwargs``: use ``salt.utils.args.clean_kwargs`` instead. -- ``salt.utils.invalid_kwargs``: use ``salt.utils.args.invalid_kwargs`` +- ``salt.utils.invalid_kwargs``: use ``salt.utils.args.invalid_kwargs`` instead. - ``salt.utils.shlex_split``: use ``salt.utils.args.shlex_split`` instead. - ``salt.utils.arg_lookup``: use ``salt.utils.args.arg_lookup`` instead. -- ``salt.utils.argspec_report``: use ``salt.utils.args.argspec_report`` +- ``salt.utils.argspec_report``: use ``salt.utils.args.argspec_report`` instead. - ``salt.utils.split_input``: use ``salt.utils.args.split_input`` instead. - ``salt.utils.test_mode``: use ``salt.utils.args.test_mode`` instead. @@ -118,7 +118,7 @@ The functions have been moved as follows: - ``salt.utils.which_bin``: use ``salt.utils.path.which_bin`` instead. - ``salt.utils.path_join``: use ``salt.utils.path.join`` instead. - ``salt.utils.check_or_die``: use ``salt.utils.path.check_or_die`` instead. -- ``salt.utils.sanitize_win_path_string``: use +- ``salt.utils.sanitize_win_path_string``: use ``salt.utils.path.sanitize_win_path`` instead. - ``salt.utils.rand_str``: use ``salt.utils.hashutils.random_hash`` instead. - ``salt.utils.get_hash``: use ``salt.utils.hashutils.get_hash`` instead. @@ -128,9 +128,9 @@ The functions have been moved as follows: - ``salt.utils.is_darwin``: use ``salt.utils.platform.is_darwin`` instead. - ``salt.utils.is_sunos``: use ``salt.utils.platform.is_sunos`` instead. - ``salt.utils.is_smartos``: use ``salt.utils.platform.is_smartos`` instead. -- ``salt.utils.is_smartos_globalzone``: use +- ``salt.utils.is_smartos_globalzone``: use ``salt.utils.platform.is_smartos_globalzone`` instead. -- ``salt.utils.is_smartos_zone``: use ``salt.utils.platform.is_smartos_zone`` +- ``salt.utils.is_smartos_zone``: use ``salt.utils.platform.is_smartos_zone`` instead. - ``salt.utils.is_freebsd``: use ``salt.utils.platform.is_freebsd`` instead. - ``salt.utils.is_netbsd``: use ``salt.utils.platform.is_netbsd`` instead. @@ -147,55 +147,55 @@ The functions have been moved as follows: - ``salt.utils.is_bin_file``: use ``salt.utils.files.is_binary`` instead. - ``salt.utils.list_files``: use ``salt.utils.files.list_files`` instead. - ``salt.utils.safe_walk``: use ``salt.utils.files.safe_walk`` instead. -- ``salt.utils.st_mode_to_octal``: use ``salt.utils.files.st_mode_to_octal`` +- ``salt.utils.st_mode_to_octal``: use ``salt.utils.files.st_mode_to_octal`` instead. -- ``salt.utils.normalize_mode``: use ``salt.utils.files.normalize_mode`` +- ``salt.utils.normalize_mode``: use ``salt.utils.files.normalize_mode`` instead. -- ``salt.utils.human_size_to_bytes``: use +- ``salt.utils.human_size_to_bytes``: use ``salt.utils.files.human_size_to_bytes`` instead. - ``salt.utils.backup_minion``: use ``salt.utils.files.backup_minion`` instead. - ``salt.utils.str_version_to_evr``: use ``salt.utils.pkg.rpm.version_to_evr`` instead. -- ``salt.utils.parse_docstring``: use ``salt.utils.doc.parse_docstring`` +- ``salt.utils.parse_docstring``: use ``salt.utils.doc.parse_docstring`` instead. - ``salt.utils.compare_versions``: use ``salt.utils.versions.compare`` instead. - ``salt.utils.version_cmp``: use ``salt.utils.versions.version_cmp`` instead. - ``salt.utils.warn_until``: use ``salt.utils.versions.warn_until`` instead. -- ``salt.utils.kwargs_warn_until``: use +- ``salt.utils.kwargs_warn_until``: use ``salt.utils.versions.kwargs_warn_until`` instead. -- ``salt.utils.get_color_theme``: use ``salt.utils.color.get_color_theme`` +- ``salt.utils.get_color_theme``: use ``salt.utils.color.get_color_theme`` instead. - ``salt.utils.get_colors``: use ``salt.utils.color.get_colors`` instead. - ``salt.utils.gen_state_tag``: use ``salt.utils.state.gen_tag`` instead. -- ``salt.utils.search_onfail_requisites``: use +- ``salt.utils.search_onfail_requisites``: use ``salt.utils.state.search_onfail_requisites`` instead. -- ``salt.utils.check_state_result``: use ``salt.utils.state.check_result`` +- ``salt.utils.check_state_result``: use ``salt.utils.state.check_result`` instead. - ``salt.utils.get_user``: use ``salt.utils.user.get_user`` instead. - ``salt.utils.get_uid``: use ``salt.utils.user.get_uid`` instead. -- ``salt.utils.get_specific_user``: use ``salt.utils.user.get_specific_user`` +- ``salt.utils.get_specific_user``: use ``salt.utils.user.get_specific_user`` instead. - ``salt.utils.chugid``: use ``salt.utils.user.chugid`` instead. -- ``salt.utils.chugid_and_umask``: use ``salt.utils.user.chugid_and_umask`` +- ``salt.utils.chugid_and_umask``: use ``salt.utils.user.chugid_and_umask`` instead. -- ``salt.utils.get_default_group``: use ``salt.utils.user.get_default_group`` +- ``salt.utils.get_default_group``: use ``salt.utils.user.get_default_group`` instead. -- ``salt.utils.get_group_list``: use ``salt.utils.user.get_group_list`` +- ``salt.utils.get_group_list``: use ``salt.utils.user.get_group_list`` instead. -- ``salt.utils.get_group_dict``: use ``salt.utils.user.get_group_dict`` +- ``salt.utils.get_group_dict``: use ``salt.utils.user.get_group_dict`` instead. - ``salt.utils.get_gid_list``: use ``salt.utils.user.get_gid_list`` instead. - ``salt.utils.get_gid``: use ``salt.utils.user.get_gid`` instead. -- ``salt.utils.enable_ctrl_logoff_handler``: use +- ``salt.utils.enable_ctrl_logoff_handler``: use ``salt.utils.win_functions.enable_ctrl_logoff_handler`` instead. - ``salt.utils.traverse_dict``: use ``salt.utils.data.traverse_dict`` instead. -- ``salt.utils.traverse_dict_and_list``: use +- ``salt.utils.traverse_dict_and_list``: use ``salt.utils.data.traverse_dict_and_list`` instead. - ``salt.utils.filter_by``: use ``salt.utils.data.filter_by`` instead. - ``salt.utils.subdict_match``: use ``salt.utils.data.subdict_match`` instead. - ``salt.utils.substr_in_list``: use ``salt.utils.data.substr_in_list`` instead. - ``salt.utils.is_dictlist``: use ``salt.utils.data.is_dictlist``. -- ``salt.utils.repack_dictlist``: use ``salt.utils.data.repack_dictlist`` +- ``salt.utils.repack_dictlist``: use ``salt.utils.data.repack_dictlist`` instead. - ``salt.utils.compare_dicts``: use ``salt.utils.data.compare_dicts`` instead. - ``salt.utils.compare_lists``: use ``salt.utils.data.compare_lists`` instead. @@ -208,33 +208,33 @@ The functions have been moved as follows: - ``salt.utils.isorted``: use ``salt.utils.data.sorted_ignorecase`` instead. - ``salt.utils.is_true``: use ``salt.utils.data.is_true`` instead. - ``salt.utils.mysql_to_dict``: use ``salt.utils.data.mysql_to_dict`` instead. -- ``salt.utils.simple_types_filter``: use +- ``salt.utils.simple_types_filter``: use ``salt.utils.data.simple_types_filter`` instead. - ``salt.utils.ip_bracket``: use ``salt.utils.zeromq.ip_bracket`` instead. - ``salt.utils.gen_mac``: use ``salt.utils.network.gen_mac`` instead. -- ``salt.utils.mac_str_to_bytes``: use ``salt.utils.network.mac_str_to_bytes`` +- ``salt.utils.mac_str_to_bytes``: use ``salt.utils.network.mac_str_to_bytes`` instead. - ``salt.utils.refresh_dns``: use ``salt.utils.network.refresh_dns`` instead. - ``salt.utils.dns_check``: use ``salt.utils.network.dns_check`` instead. -- ``salt.utils.get_context``: use ``salt.utils.templates.get_context`` instead. -- ``salt.utils.get_master_key``: use ``salt.utils.master.get_master_key`` +- ``salt.utils.get_context``: use ``salt.utils.stringutils.get_context`` instead. +- ``salt.utils.get_master_key``: use ``salt.utils.master.get_master_key`` instead. -- ``salt.utils.get_values_of_matching_keys``: use +- ``salt.utils.get_values_of_matching_keys``: use ``salt.utils.master.get_values_of_matching_keys`` instead. - ``salt.utils.date_cast``: use ``salt.utils.dateutils.date_cast`` instead. - ``salt.utils.date_format``: use ``salt.utils.dateutils.strftime`` instead. -- ``salt.utils.total_seconds``: use ``salt.utils.dateutils.total_seconds`` +- ``salt.utils.total_seconds``: use ``salt.utils.dateutils.total_seconds`` instead. - ``salt.utils.find_json``: use ``salt.utils.json.find_json`` instead. - ``salt.utils.import_json``: use ``salt.utils.json.import_json`` instead. -- ``salt.utils.namespaced_function``: use +- ``salt.utils.namespaced_function``: use ``salt.utils.functools.namespaced_function`` instead. -- ``salt.utils.alias_function``: use ``salt.utils.functools.alias_function`` +- ``salt.utils.alias_function``: use ``salt.utils.functools.alias_function`` instead. - ``salt.utils.profile_func``: use ``salt.utils.profile.profile_func`` instead. -- ``salt.utils.activate_profile``: use ``salt.utils.profile.activate_profile`` +- ``salt.utils.activate_profile``: use ``salt.utils.profile.activate_profile`` instead. -- ``salt.utils.output_profile``: use ``salt.utils.profile.output_profile`` +- ``salt.utils.output_profile``: use ``salt.utils.profile.output_profile`` instead. State and Execution Module Support for ``docker run`` Functionality @@ -353,7 +353,7 @@ Prior to this release, fileservers would be updated as part of a dedicated performed. This tied the update interval to the :conf_master:`loop_interval` config option, and also forced all fileservers to update at the same interval. -Oxygen adds the following configuration options for the various fileserver +2018.3.0 adds the following configuration options for the various fileserver backends: - :conf_master:`roots_update_interval` @@ -1680,8 +1680,8 @@ Utils Deprecations The ``salt.utils.cloud.py`` file had the following change: -- The ``fire_event`` function now requires a ``sock_dir`` argument. It was previously - optional. +- The ``fire_event`` function now requires a ``sock_dir`` argument. It was + previously optional. Other Miscellaneous Deprecations ================================ @@ -1690,9 +1690,9 @@ The ``version.py`` file had the following changes: - The ``rc_info`` function was removed. Please use ``pre_info`` instead. -Warnings for moving away from the ``env`` option were removed. ``saltenv`` should be -used instead. The removal of these warnings does not have a behavior change. Only -the warning text was removed. +Warnings for moving away from the ``env`` option were removed. ``saltenv`` +should be used instead. The removal of these warnings does not have a behavior +change. Only the warning text was removed. Sentry Log Handler ------------------ @@ -1705,6 +1705,6 @@ RAET transport -------------- We haven't been doing development on RAET for quite some time and decided that -Oxygen is the time to announce the deprecation. RAET support will be removed in -Neon. Please consider to move to ``zeromq`` or ``tcp`` transport instead of +2018.3.0 is the time to announce the deprecation. RAET support will be removed +in Neon. Please consider to move to ``zeromq`` or ``tcp`` transport instead of ``raet``. diff --git a/doc/topics/releases/index.rst b/doc/topics/releases/index.rst index 694f1bf2aa..40d73cea80 100644 --- a/doc/topics/releases/index.rst +++ b/doc/topics/releases/index.rst @@ -20,6 +20,7 @@ Previous Releases :maxdepth: 1 :glob: + 2018.3.* 2017.7.* 2016.11.* 2016.3.* diff --git a/doc/topics/releases/releasecandidate.rst b/doc/topics/releases/releasecandidate.rst index 60918d6ac3..db14777026 100644 --- a/doc/topics/releases/releasecandidate.rst +++ b/doc/topics/releases/releasecandidate.rst @@ -8,7 +8,7 @@ Installing/Testing a Salt Release Candidate It's time for a new feature release of Salt! Follow the instructions below to install the latest release candidate of Salt, and try :ref:`all the shiny new -features `! Be sure to report any bugs you find on `Github +features `! Be sure to report any bugs you find on `Github `_. Installing Using Packages @@ -47,14 +47,14 @@ You can install a release candidate of Salt using `Salt Bootstrap .. code-block:: bash curl -o install_salt.sh -L https://bootstrap.saltstack.com - sudo sh install_salt.sh -P git v2017.7.0rc1 + sudo sh install_salt.sh -P git v2018.3.0rc1 If you want to also install a master using Salt Bootstrap, use the ``-M`` flag: .. code-block:: bash curl -o install_salt.sh -L https://bootstrap.saltstack.com - sudo sh install_salt.sh -P -M git v2017.7.0rc1 + sudo sh install_salt.sh -P -M git v2018.3.0rc1 If you want to install only a master and not a minion using Salt Bootstrap, use the ``-M`` and ``-N`` flags: @@ -62,13 +62,13 @@ the ``-M`` and ``-N`` flags: .. code-block:: bash curl -o install_salt.sh -L https://bootstrap.saltstack.com - sudo sh install_salt.sh -P -M -N git v2017.7.0rc1 + sudo sh install_salt.sh -P -M -N git v2018.3.0rc1 Installing Using PyPI ===================== Installing from the `source archive -`_ on +`_ on `PyPI `_ is fairly straightforward. .. note:: @@ -106,4 +106,4 @@ Then install salt using the following command: .. code-block:: bash - sudo pip install salt==2017.7.0rc1 + sudo pip install salt==2018.3.0rc1 diff --git a/doc/topics/releases/version_numbers.rst b/doc/topics/releases/version_numbers.rst index 0e98393ae1..11f5bc5f5b 100644 --- a/doc/topics/releases/version_numbers.rst +++ b/doc/topics/releases/version_numbers.rst @@ -34,7 +34,7 @@ Assigned codenames: - Boron: ``2016.3.0`` - Carbon: ``2016.11.0`` - Nitrogen: ``2017.7.0`` -- Oxygen: ``TBD`` +- Oxygen: ``2018.3.0`` - Fluorine: ``TBD`` Example @@ -69,10 +69,10 @@ Example arguments for `git checkout`: +------------+----------------------------------------------------------------------------+ | v2016.11.1 | Tag signaling the commit that the 2016.11.1 release is based on. | +------------+----------------------------------------------------------------------------+ - -Further reading on `release branch and develop branch + +Further reading on `release branch and develop branch `_. - + Influence of the `git checkout` argument on `git describe`: +------------+----------------------------+-----------------------------------------------+ @@ -97,4 +97,4 @@ Some details of v2016.11.1-220-g9a1550d (from `git describe` after `git checkout |220 | Commits on top of the most recent tag, relative to your local git fetch | +---------------+-------------------------------------------------------------------------+ |gf2eb3dc | 'g' + git SHA ("abbreviated name") of the most recent commit | - +---------------+-------------------------------------------------------------------------+ \ No newline at end of file + +---------------+-------------------------------------------------------------------------+ diff --git a/doc/topics/slots/index.rst b/doc/topics/slots/index.rst index 30ba45d87d..ebb0dc1f46 100644 --- a/doc/topics/slots/index.rst +++ b/doc/topics/slots/index.rst @@ -4,7 +4,7 @@ Slots ===== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 .. note:: This functionality is under development and could be changed in the future releases diff --git a/doc/topics/tutorials/autoaccept_grains.rst b/doc/topics/tutorials/autoaccept_grains.rst index b48cd7ee5c..45b29c5fb7 100644 --- a/doc/topics/tutorials/autoaccept_grains.rst +++ b/doc/topics/tutorials/autoaccept_grains.rst @@ -4,7 +4,7 @@ Autoaccept minions from Grains ============================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 To automatically accept minions based on certain characteristics, e.g. the ``uuid`` you can specify certain grain values on the salt master. Minions with matching grains diff --git a/doc/topics/tutorials/gitfs.rst b/doc/topics/tutorials/gitfs.rst index 9b45875ccc..74fd67c568 100644 --- a/doc/topics/tutorials/gitfs.rst +++ b/doc/topics/tutorials/gitfs.rst @@ -196,7 +196,7 @@ master: - gitfs .. note:: - ``git`` also works here. Prior to the Oxygen release, *only* ``git`` + ``git`` also works here. Prior to the 2018.3.0 release, *only* ``git`` would work. 2. Specify one or more ``git://``, ``https://``, ``file://``, or ``ssh://`` @@ -314,9 +314,9 @@ configured gitfs remotes): * :conf_master:`gitfs_privkey` (**pygit2 only**, new in 2014.7.0) * :conf_master:`gitfs_passphrase` (**pygit2 only**, new in 2014.7.0) * :conf_master:`gitfs_refspecs` (new in 2017.7.0) -* :conf_master:`gitfs_disable_saltenv_mapping` (new in Oxygen) -* :conf_master:`gitfs_ref_types` (new in Oxygen) -* :conf_master:`gitfs_update_interval` (new in Oxygen) +* :conf_master:`gitfs_disable_saltenv_mapping` (new in 2018.3.0) +* :conf_master:`gitfs_ref_types` (new in 2018.3.0) +* :conf_master:`gitfs_update_interval` (new in 2018.3.0) .. note:: pygit2 only supports disabling SSL verification in versions 0.23.2 and @@ -370,7 +370,7 @@ tremendous amount of customization. Here's some example usage: ``name``, ``saltenv``, and ``all_saltenvs`` parameters, which are only available to per-remote configurations. - The ``all_saltenvs`` parameter is new in the Oxygen release. + The ``all_saltenvs`` parameter is new in the 2018.3.0 release. In the example configuration above, the following is true: @@ -526,7 +526,7 @@ would only fetch branches and tags (the default). Global Remotes ============== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The ``all_saltenvs`` per-remote configuration parameter overrides the logic Salt uses to map branches/tags to fileserver environments (i.e. saltenvs). This @@ -553,7 +553,7 @@ single branch. Update Intervals ================ -Prior to the Oxygen release, GitFS would update its fileserver backends as part +Prior to the 2018.3.0 release, GitFS would update its fileserver backends as part of a dedicated "maintenance" process, in which various routine maintenance tasks were performed. This tied the update interval to the :conf_master:`loop_interval` config option, and also forced all fileservers to diff --git a/doc/topics/tutorials/libcloud.rst b/doc/topics/tutorials/libcloud.rst index a66c2e4e76..d3f86972d0 100644 --- a/doc/topics/tutorials/libcloud.rst +++ b/doc/topics/tutorials/libcloud.rst @@ -4,7 +4,7 @@ Using Apache Libcloud for declarative and procedural multi-cloud orchestration ============================================================================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 .. note:: diff --git a/doc/topics/tutorials/minionfs.rst b/doc/topics/tutorials/minionfs.rst index 4aa7c56453..f98f0ea0b5 100644 --- a/doc/topics/tutorials/minionfs.rst +++ b/doc/topics/tutorials/minionfs.rst @@ -86,8 +86,8 @@ option on the master: - minionfs .. note:: - ``minion`` also works here. Prior to the Oxygen release, *only* ``minion`` - would work. + ``minion`` also works here. Prior to the 2018.3.0 release, *only* + ``minion`` would work. Also, as described earlier, ``file_recv: True`` is needed to enable the master to receive files pushed from minions. As always, changes to the diff --git a/doc/topics/utils/index.rst b/doc/topics/utils/index.rst index 34d48144eb..fa01c3695a 100644 --- a/doc/topics/utils/index.rst +++ b/doc/topics/utils/index.rst @@ -81,7 +81,7 @@ the ``foo`` utility module with a ``__virtual__`` function. def bar(): return 'baz' -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Instantiating objects from classes declared in util modules works with Master side modules, such as Runners, Outputters, etc. diff --git a/doc/topics/windows/windows-package-manager.rst b/doc/topics/windows/windows-package-manager.rst index 20ed60baf6..033ccc9b30 100644 --- a/doc/topics/windows/windows-package-manager.rst +++ b/doc/topics/windows/windows-package-manager.rst @@ -302,25 +302,30 @@ can define multiple versions for the same piece of software. The lines following the version are indented two more spaces and contain all the information needed to install that package. -.. warning:: The package name and the ``full_name`` must be unique to all - other packages in the software repository. +.. warning:: + The package name and the ``full_name`` must be unique to all other packages + in the software repository. The version line is the version for the package to be installed. It is used when you need to install a specific version of a piece of software. -.. warning:: The version must be enclosed in quotes, otherwise the yaml parser - will remove trailing zeros. +.. warning:: + The version must be enclosed in quotes, otherwise the yaml parser will + remove trailing zeros. + +.. note:: + There are unique situations where previous versions are unavailable. Take + Google Chrome for example. There is only one url provided for a standalone + installation of Google Chrome. -.. note:: There are unique situations where previous versions are unavailable. - Take Google Chrome for example. There is only one url provided for a - standalone installation of Google Chrome. (https://dl.google.com/edgedl/chrome/install/GoogleChromeStandaloneEnterprise.msi) + When a new version is released, the url just points to the new version. To handle situations such as these, set the version to `latest`. Salt will install the version of Chrome at the URL and report that version. Here's an example: -.. code-block:: bash +.. code-block:: yaml chrome: latest: @@ -335,200 +340,237 @@ you need to install a specific version of a piece of software. Available parameters are as follows: -:param str full_name: The Full Name for the software as shown in "Programs and - Features" in the control panel. You can also get this information by - installing the package manually and then running ``pkg.list_pkgs``. Here's - an example of the output from ``pkg.list_pkgs``: +:param str full_name: + The Full Name for the software as shown in "Programs and Features" in the + control panel. You can also get this information by installing the package + manually and then running ``pkg.list_pkgs``. Here's an example of the output + from ``pkg.list_pkgs``: -.. code-block:: bash + .. code-block:: bash - salt 'test-2008' pkg.list_pkgs - test-2008 - ---------- - 7-Zip 9.20 (x64 edition): - 9.20.00.0 - Microsoft .NET Framework 4 Client Profile: - 4.0.30319,4.0.30319 - Microsoft .NET Framework 4 Extended: - 4.0.30319,4.0.30319 - Microsoft Visual C++ 2008 Redistributable - x64 9.0.21022: - 9.0.21022 - Mozilla Firefox 17.0.1 (x86 en-US): - 17.0.1 - Mozilla Maintenance Service: - 17.0.1 - NSClient++ (x64): - 0.3.8.76 - Notepad++: - 6.4.2 - Salt Minion 0.16.0: - 0.16.0 + salt 'test-2008' pkg.list_pkgs + test-2008 + ---------- + 7-Zip 9.20 (x64 edition): + 9.20.00.0 + Microsoft .NET Framework 4 Client Profile: + 4.0.30319,4.0.30319 + Microsoft .NET Framework 4 Extended: + 4.0.30319,4.0.30319 + Microsoft Visual C++ 2008 Redistributable - x64 9.0.21022: + 9.0.21022 + Mozilla Firefox 17.0.1 (x86 en-US): + 17.0.1 + Mozilla Maintenance Service: + 17.0.1 + NSClient++ (x64): + 0.3.8.76 + Notepad++: + 6.4.2 + Salt Minion 0.16.0: + 0.16.0 -Notice the Full Name for Firefox: Mozilla Firefox 17.0.0 (x86 en-US). That's -exactly what's in the ``full_name`` parameter in the software definition file. + Notice the Full Name for Firefox: ``Mozilla Firefox 17.0.0 (x86 en-US)``. + That's exactly what's in the ``full_name`` parameter in the software + definition file. -If any of the software insalled on the machine matches one of the software -definition files in the repository the full_name will be automatically renamed -to the package name. The example below shows the ``pkg.list_pkgs`` for a -machine that already has Mozilla Firefox 17.0.1 installed. + If any of the software installed on the machine matches one of the software + definition files in the repository, the full_name will be automatically + renamed to the package name. The example below shows the ``pkg.list_pkgs`` + for a machine that already has Mozilla Firefox 17.0.1 installed. -.. code-block:: bash + .. code-block:: bash + + test-2008: + ---------- + 7zip: + 9.20.00.0 + Microsoft .NET Framework 4 Client Profile: + 4.0.30319,4.0.30319 + Microsoft .NET Framework 4 Extended: + 4.0.30319,4.0.30319 + Microsoft Visual C++ 2008 Redistributable - x64 9.0.21022: + 9.0.21022 + Mozilla Maintenance Service: + 17.0.1 + Notepad++: + 6.4.2 + Salt Minion 0.16.0: + 0.16.0 + firefox: + 17.0.1 + nsclient: + 0.3.9.328 + + .. important:: + The version number and ``full_name`` need to match the output from + ``pkg.list_pkgs`` so that the status can be verified when running a + highstate. + + .. note:: + It is still possible to successfully install packages using + ``pkg.install``, even if the ``full_name`` or the version number don't + match. However, this can make troubleshooting issues difficult, so be + careful. + + .. tip:: + To force salt to display the full name when there's already an existing + package definition file on the system, you can pass a bogus ``saltenv`` + parameter to the command like so: ``pkg.list_pkgs saltenv=NotARealEnv`` + +:param str installer: + The path to the ``.exe`` or ``.msi`` to use to install the package. This can + be a path or a URL. If it is a URL or a salt path (``salt://``), the package + will be cached locally and then executed. If it is a path to a file on disk + or a file share, it will be executed directly. + + .. note:: + If storing software in the same location as the winrepo it is best + practice to place each installer in its own directory rather than the + root of winrepo. Then you can place your package definition file in the + same directory. It is best practice to name the file ``init.sls``. This + will be picked up by ``pkg.refresh_db`` and processed properly. + +:param str install_flags: + Any flags that need to be passed to the installer to make it perform a + silent install. These can often be found by adding ``/?`` or ``/h`` when + running the installer from the command-line. A great resource for finding + these silent install flags can be found on the WPKG project's wiki_: + + .. warning:: + Salt will not return if the installer is waiting for user input so it is + imperative that the software package being installed has the ability to + install silently. + +:param str uninstaller: + The path to the program used to uninstall this software. This can be the + path to the same `exe` or `msi` used to install the software. It can also be + a GUID. You can find this value in the registry under the following keys: + + - Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall + - Software\\Wow6432None\\Microsoft\\Windows\\CurrentVersion\\Uninstall + +:param str uninstall_flags: + Any flags that need to be passed to the uninstaller to make it perform a + silent uninstall. These can often be found by adding ``/?`` or ``/h`` when + running the uninstaller from the command-line. A great resource for finding + these silent install flags can be found on the WPKG project's wiki_: + + .. warning:: + Salt will not return if the uninstaller is waiting for user input so it + is imperative that the software package being uninstalled has the + ability to uninstall silently. + + Here are some examples of installer and uninstaller settings: + + .. code-block:: yaml - test-2008: - ---------- 7zip: - 9.20.00.0 - Microsoft .NET Framework 4 Client Profile: - 4.0.30319,4.0.30319 - Microsoft .NET Framework 4 Extended: - 4.0.30319,4.0.30319 - Microsoft Visual C++ 2008 Redistributable - x64 9.0.21022: - 9.0.21022 - Mozilla Maintenance Service: - 17.0.1 - Notepad++: - 6.4.2 - Salt Minion 0.16.0: - 0.16.0 - firefox: - 17.0.1 - nsclient: - 0.3.9.328 + '9.20.00.0': + installer: salt://win/repo/7zip/7z920-x64.msi + full_name: 7-Zip 9.20 (x64 edition) + reboot: False + install_flags: '/qn /norestart' + msiexec: True + uninstaller: '{23170F69-40C1-2702-0920-000001000000}' + uninstall_flags: '/qn /norestart' -.. important:: The version number and ``full_name`` need to match the output - from ``pkg.list_pkgs`` so that the status can be verified when running - highstate. + Alternatively the ``uninstaller`` can also simply repeat the URL of an msi + file: -.. note:: It is still possible to successfully install packages using - ``pkg.install`` even if they don't match. This can make troubleshooting - difficult so be careful. + .. code-block:: yaml -:param str installer: The path to the ``.exe`` or ``.msi`` to use to install the - package. This can be a path or a URL. If it is a URL or a salt path - (salt://), the package will be cached locally and then executed. If it is a - path to a file on disk or a file share, it will be executed directly. + 7zip: + '9.20.00.0': + installer: salt://win/repo/7zip/7z920-x64.msi + full_name: 7-Zip 9.20 (x64 edition) + reboot: False + install_flags: '/qn /norestart' + msiexec: True + uninstaller: salt://win/repo/7zip/7z920-x64.msi + uninstall_flags: '/qn /norestart' -:param str install_flags: Any flags that need to be passed to the installer to - make it perform a silent install. These can often be found by adding ``/?`` - or ``/h`` when running the installer from the command-line. A great resource - for finding these silent install flags can be found on the WPKG project's wiki_: +:param msiexec: + This tells salt to use ``msiexec /i`` to install the package and + ``msiexec /x`` to uninstall. This is for ``.msi`` installations. Possible + options are: True, False or the path to ``msiexec.exe`` on your system -Salt will not return if the installer is waiting for user input so these are -important. + .. code-block:: yaml -:param str uninstaller: The path to the program used to uninstall this software. - This can be the path to the same `exe` or `msi` used to install the - software. It can also be a GUID. You can find this value in the registry - under the following keys: + 7zip: + '9.20.00.0': + installer: salt://win/repo/7zip/7z920-x64.msi + full_name: 7-Zip 9.20 (x64 edition) + reboot: False + install_flags: '/qn /norestart' + msiexec: 'C:\Windows\System32\msiexec.exe' + uninstaller: salt://win/repo/7zip/7z920-x64.msi + uninstall_flags: '/qn /norestart' - - Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall - - Software\\Wow6432None\\Microsoft\\Windows\\CurrentVersion\\Uninstall +:param bool allusers: + This parameter is specific to ``.msi`` installations. It tells ``msiexec`` + to install the software for all users. The default is ``True``. -:param str uninstall_flags: Any flags that need to be passed to the uninstaller - to make it perform a silent uninstall. These can often be found by adding - ``/?`` or ``/h`` when running the uninstaller from the command-line. A great - resource for finding these silent install flags can be found on the WPKG - project's wiki_: +:param bool cache_dir: + If ``True`` and the installer URL begins with ``salt://``, the entire + directory where the installer resides will be recursively cached. This is + useful for installers that depend on other files in the same directory for + installation. -Salt will not return if the uninstaller is waiting for user input so these are -important. - -Here are some examples of installer and uninstaller settings: - -.. code-block:: yaml - - 7zip: - '9.20.00.0': - installer: salt://win/repo/7zip/7z920-x64.msi - full_name: 7-Zip 9.20 (x64 edition) - reboot: False - install_flags: '/qn /norestart' - msiexec: True - uninstaller: '{23170F69-40C1-2702-0920-000001000000}' - uninstall_flags: '/qn /norestart' - -Alternatively the ``uninstaller`` can also simply repeat the URL of the msi file. - -.. code-block:: yaml - - 7zip: - '9.20.00.0': - installer: salt://win/repo/7zip/7z920-x64.msi - full_name: 7-Zip 9.20 (x64 edition) - reboot: False - install_flags: '/qn /norestart' - msiexec: True - uninstaller: salt://win/repo/7zip/7z920-x64.msi - uninstall_flags: '/qn /norestart' - -:param msiexec: This tells salt to use ``msiexec /i`` to install the - package and ``msiexec /x`` to uninstall. This is for `.msi` installations. - Possible options are: True, False or path to msiexec on your system - - 7zip: - '9.20.00.0': - installer: salt://win/repo/7zip/7z920-x64.msi - full_name: 7-Zip 9.20 (x64 edition) - reboot: False - install_flags: '/qn /norestart' - msiexec: 'C:\Windows\System32\msiexec.exe' - uninstaller: salt://win/repo/7zip/7z920-x64.msi - uninstall_flags: '/qn /norestart' - -:param str arch: This selects which ``msiexec.exe`` to use. Possible values: - ``x86``, ``x64`` - -:param bool allusers: This parameter is specific to `.msi` installations. It - tells `msiexec` to install the software for all users. The default is True. - -:param bool cache_dir: If true when installer URL begins with salt://, the - entire directory where the installer resides will be recursively cached. - This is useful for installers that depend on other files in the same - directory for installation. + .. warning:: + Be aware that all files and directories in the same location as the + installer file will be copied down to the minion. If you place your + installer file in the root of winrepo (``/srv/salt/win/repo-ng``) and + ``cache_dir: True`` the entire contents of winrepo will be cached to + the minion. Therefore, it is best practice to place your installer files + in a subdirectory if they are to be stored in winrepo. :param str cache_file: - When installer URL begins with salt://, this indicates single file to copy - down for use with the installer. Copied to the same location as the - installer. Use this over ``cache_dir`` if there are many files in the + When the installer URL begins with ``salt://``, this indicates a single file + to copy down for use with the installer. It is copied to the same location + as the installer. Use this over ``cache_dir`` if there are many files in the directory and you only need a specific file and don't want to cache additional files that may reside in the installer directory. -Here's an example for a software package that has dependent files: + Here's an example for a software package that has dependent files: -.. code-block:: yaml + .. code-block:: yaml - sqlexpress: - '12.0.2000.8': - installer: 'salt://win/repo/sqlexpress/setup.exe' - full_name: Microsoft SQL Server 2014 Setup (English) - reboot: False - install_flags: '/ACTION=install /IACCEPTSQLSERVERLICENSETERMS /Q' - cache_dir: True + sqlexpress: + '12.0.2000.8': + installer: 'salt://win/repo/sqlexpress/setup.exe' + full_name: Microsoft SQL Server 2014 Setup (English) + reboot: False + install_flags: '/ACTION=install /IACCEPTSQLSERVERLICENSETERMS /Q' + cache_dir: True -:param bool use_scheduler: If true, windows will use the task scheduler to run - the installation. This is useful for running the salt installation itself as - the installation process kills any currently running instances of salt. +:param bool use_scheduler: + If ``True``, Windows will use the task scheduler to run the installation. + This is useful for running the Salt installation itself as the installation + process kills any currently running instances of Salt. -:param str source_hash: This tells salt to compare a hash sum of the installer -to the provided hash sum before execution. The value can be formatted as -``hash_algorithm=hash_sum``, or it can be a URI to a file containing the hash -sum. -For a list of supported algorithms, see the `hashlib documentation -`_. +:param str source_hash: + This tells Salt to compare a hash sum of the installer to the provided hash + sum before execution. The value can be formatted as + ``=``, or it can be a URI to a file containing the + hash sum. -Here's an example of source_hash usage: + For a list of supported algorithms, see the `hashlib documentation + `_. -.. code-block:: yaml + Here's an example of source_hash usage: - messageanalyzer: - '4.0.7551.0': - full_name: 'Microsoft Message Analyzer' - installer: 'salt://win/repo/messageanalyzer/MessageAnalyzer64.msi' - install_flags: '/quiet /norestart' - uninstaller: '{1CC02C23-8FCD-487E-860C-311EC0A0C933}' - uninstall_flags: '/quiet /norestart' - msiexec: True - source_hash: 'sha1=62875ff451f13b10a8ff988f2943e76a4735d3d4' + .. code-block:: yaml + + messageanalyzer: + '4.0.7551.0': + full_name: 'Microsoft Message Analyzer' + installer: 'salt://win/repo/messageanalyzer/MessageAnalyzer64.msi' + install_flags: '/quiet /norestart' + uninstaller: '{1CC02C23-8FCD-487E-860C-311EC0A0C933}' + uninstall_flags: '/quiet /norestart' + msiexec: True + source_hash: 'sha1=62875ff451f13b10a8ff988f2943e76a4735d3d4' :param bool reboot: Not implemented diff --git a/requirements/base.txt b/requirements/base.txt index 4e735d3a21..1a16e368d0 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -3,6 +3,6 @@ msgpack-python>0.3 PyYAML MarkupSafe requests>=1.0.0 -tornado>=4.2.1 +tornado>=4.2.1,<5.0 # Required by Tornado to handle threads stuff. futures>=2.0 diff --git a/salt/auth/__init__.py b/salt/auth/__init__.py index 03e213c033..a451b333b0 100644 --- a/salt/auth/__init__.py +++ b/salt/auth/__init__.py @@ -389,7 +389,7 @@ class LoadAuth(object): def check_authentication(self, load, auth_type, key=None, show_username=False): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Go through various checks to see if the token/eauth/user can be authenticated. diff --git a/salt/auth/file.py b/salt/auth/file.py index 38e02ed672..89715f5c6c 100644 --- a/salt/auth/file.py +++ b/salt/auth/file.py @@ -2,7 +2,7 @@ ''' Provide authentication using local files -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The `file` auth module allows simple authentication via local files. Different filetypes are supported, including: diff --git a/salt/auth/ldap.py b/salt/auth/ldap.py index 20a9fc5777..84d5f83b1d 100644 --- a/salt/auth/ldap.py +++ b/salt/auth/ldap.py @@ -12,6 +12,8 @@ from salt.ext import six # Import salt libs from salt.exceptions import CommandExecutionError, SaltInvocationError +import salt.utils.stringutils +import salt.utils.data log = logging.getLogger(__name__) # Import third party libs @@ -39,6 +41,7 @@ __defopts__ = {'auth.ldap.basedn': '', 'auth.ldap.persontype': 'person', 'auth.ldap.groupclass': 'posixGroup', 'auth.ldap.activedirectory': False, + 'auth.ldap.freeipa': False, 'auth.ldap.minion_stripdomains': [], } @@ -290,10 +293,10 @@ def auth(username, password): if bind: log.debug('LDAP authentication successful') - return True - else: - log.error('LDAP _bind authentication FAILED') - return False + return bind + + log.error('LDAP _bind authentication FAILED') + return False def groups(username, **kwargs): @@ -312,14 +315,7 @@ def groups(username, **kwargs): ''' group_list = [] - - # If bind credentials are configured, use them instead of user's - if _config('binddn', mandatory=False) and _config('bindpw', mandatory=False): - bind = _bind_for_search(anonymous=_config('anonymous', mandatory=False)) - else: - bind = _bind(username, kwargs.get('password', ''), - anonymous=_config('auth_by_group_membership_only', mandatory=False) - and _config('anonymous', mandatory=False)) + bind = auth(username, kwargs.get('password', None)) if bind: log.debug('ldap bind to determine group membership succeeded!') @@ -331,7 +327,7 @@ def groups(username, **kwargs): _config('persontype')) user_dn_results = bind.search_s(_config('basedn'), ldap.SCOPE_SUBTREE, - get_user_dn_search, ['distinguishedName']) + get_user_dn_search, [str('distinguishedName')]) # future lint: disable=blacklisted-function except Exception as e: log.error('Exception thrown while looking up user DN in AD: %s', e) return group_list @@ -346,13 +342,13 @@ def groups(username, **kwargs): search_results = bind.search_s(_config('basedn'), ldap.SCOPE_SUBTREE, ldap_search_string, - [_config('accountattributename'), 'cn']) + [salt.utils.stringutils.to_str(_config('accountattributename')), str('cn')]) # future lint: disable=blacklisted-function except Exception as e: log.error('Exception thrown while retrieving group membership in AD: %s', e) return group_list for _, entry in search_results: if 'cn' in entry: - group_list.append(entry['cn'][0]) + group_list.append(salt.utils.stringutils.to_unicode(entry['cn'][0])) log.debug('User %s is a member of groups: %s', username, group_list) elif _config('freeipa'): @@ -362,11 +358,11 @@ def groups(username, **kwargs): search_results = bind.search_s(search_base, ldap.SCOPE_SUBTREE, search_string, - [_config('accountattributename'), 'cn', _config('groupattribute'), 'cn']) + [salt.utils.stringutils.to_str(_config('accountattributename')), str('cn')]) # future lint: disable=blacklisted-function for entry, result in search_results: for user in result[_config('accountattributename'), _config('groupattribute')]: - if username == user.split(',')[0].split('=')[-1]: + if username == salt.utils.stringutils.to_unicode(user).split(',')[0].split('=')[-1]: group_list.append(entry.split(',')[0].split('=')[-1]) log.debug('User %s is a member of groups: %s', username, group_list) @@ -384,14 +380,16 @@ def groups(username, **kwargs): search_results = bind.search_s(search_base, ldap.SCOPE_SUBTREE, search_string, - [_config('accountattributename'), 'cn', _config('groupattribute')]) + [salt.utils.stringutils.to_str(_config('accountattributename')), + str('cn'), # future lint: disable=blacklisted-function + salt.utils.stringutils.to_str(_config('groupattribute'))]) for _, entry in search_results: - if username in entry[_config('accountattributename')]: - group_list.append(entry['cn'][0]) + if username in salt.utils.data.decode(entry[_config('accountattributename')]): + group_list.append(salt.utils.stringutils.to_unicode(entry['cn'][0])) for user, entry in search_results: - if username == user.split(',')[0].split('=')[-1]: - for group in entry[_config('groupattribute')]: - group_list.append(group.split(',')[0].split('=')[-1]) + if username == salt.utils.stringutils.to_unicode(user).split(',')[0].split('=')[-1]: + for group in salt.utils.data.decode(entry[_config('groupattribute')]): + group_list.append(salt.utils.stringutils.to_unicode(group).split(',')[0].split('=')[-1]) log.debug('User %s is a member of groups: %s', username, group_list) # Only test user auth on first call for job. @@ -445,7 +443,7 @@ def __expand_ldap_entries(entries, opts=None): search_results = bind.search_s(search_base, ldap.SCOPE_SUBTREE, search_string, - ['cn']) + [str('cn')]) # future lint: disable=blacklisted-function for ldap_match in search_results: try: minion_id = ldap_match[1]['cn'][0].lower() diff --git a/salt/beacons/aix_account.py b/salt/beacons/aix_account.py index a21f9a0d1c..5d7d13d29a 100644 --- a/salt/beacons/aix_account.py +++ b/salt/beacons/aix_account.py @@ -2,7 +2,7 @@ ''' Beacon to fire event when we notice a AIX user is locked due to many failed login attempts. -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: none ''' diff --git a/salt/beacons/napalm_beacon.py b/salt/beacons/napalm_beacon.py index 71381150d0..1d447b3612 100644 --- a/salt/beacons/napalm_beacon.py +++ b/salt/beacons/napalm_beacon.py @@ -3,7 +3,7 @@ NAPALM functions ================ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Watch NAPALM functions and fire events on specific triggers. diff --git a/salt/cache/localfs.py b/salt/cache/localfs.py index 3003eeeaf1..58aea7c1ec 100644 --- a/salt/cache/localfs.py +++ b/salt/cache/localfs.py @@ -14,6 +14,7 @@ from __future__ import absolute_import, print_function, unicode_literals import logging import os import os.path +import errno import shutil import tempfile @@ -45,13 +46,14 @@ def store(bank, key, data, cachedir): Store information in a file. ''' base = os.path.join(cachedir, os.path.normpath(bank)) - if not os.path.isdir(base): - try: - os.makedirs(base) - except OSError as exc: + try: + os.makedirs(base) + except OSError as exc: + if exc.errno != errno.EEXIST: raise SaltCacheError( - 'The cache directory, {0}, does not exist and could not be ' - 'created: {1}'.format(base, exc) + 'The cache directory, {0}, could not be created: {1}'.format( + base, exc + ) ) outfile = os.path.join(base, '{0}.p'.format(key)) diff --git a/salt/cli/daemons.py b/salt/cli/daemons.py index ac1e22dd7a..d90286c1ea 100644 --- a/salt/cli/daemons.py +++ b/salt/cli/daemons.py @@ -119,11 +119,12 @@ class Master(salt.utils.parsers.MasterOptionParser, DaemonsMixin): # pylint: di Creates a master server ''' def _handle_signals(self, signum, sigframe): # pylint: disable=unused-argument - # escalate signal to the process manager processes - self.master.process_manager.stop_restarting() - self.master.process_manager.send_signal_to_processes(signum) - # kill any remaining processes - self.master.process_manager.kill_children() + if hasattr(self.master, 'process_manager'): # IofloMaster has no process manager + # escalate signal to the process manager processes + self.master.process_manager.stop_restarting() + self.master.process_manager.send_signal_to_processes(signum) + # kill any remaining processes + self.master.process_manager.kill_children() super(Master, self)._handle_signals(signum, sigframe) def prepare(self): @@ -151,7 +152,6 @@ class Master(salt.utils.parsers.MasterOptionParser, DaemonsMixin): # pylint: di os.path.join(self.config['cachedir'], 'jobs'), os.path.join(self.config['cachedir'], 'proc'), self.config['sock_dir'], - self.config['key_dir'], self.config['token_dir'], self.config['syndic_dir'], self.config['sqlite_queue_dir'], @@ -166,7 +166,7 @@ class Master(salt.utils.parsers.MasterOptionParser, DaemonsMixin): # pylint: di self.config['user'], permissive=self.config['permissive_pki_access'], root_dir=self.config['root_dir'], - sensitive_dirs=[self.config['pki_dir'], self.config['key_dir']], + pki_dir=self.config['pki_dir'], ) # Clear out syndics from cachedir for syndic_file in os.listdir(self.config['syndic_dir']): @@ -234,7 +234,8 @@ class Minion(salt.utils.parsers.MinionOptionParser, DaemonsMixin): # pylint: di def _handle_signals(self, signum, sigframe): # pylint: disable=unused-argument # escalate signal to the process manager processes - self.minion.stop(signum) + if hasattr(self.minion, 'stop'): + self.minion.stop(signum) super(Minion, self)._handle_signals(signum, sigframe) # pylint: disable=no-member @@ -287,7 +288,7 @@ class Minion(salt.utils.parsers.MinionOptionParser, DaemonsMixin): # pylint: di self.config['user'], permissive=self.config['permissive_pki_access'], root_dir=self.config['root_dir'], - sensitive_dirs=[self.config['pki_dir']], + pki_dir=self.config['pki_dir'], ) except OSError as error: self.environment_failure(error) @@ -392,7 +393,7 @@ class Minion(salt.utils.parsers.MinionOptionParser, DaemonsMixin): # pylint: di :param exitmsg ''' self.action_log_info('Shutting down') - if hasattr(self, 'minion'): + if hasattr(self, 'minion') and hasattr(self.minion, 'destroy'): self.minion.destroy() super(Minion, self).shutdown( exitcode, ('The Salt {0} is shutdown. {1}'.format( @@ -469,7 +470,7 @@ class ProxyMinion(salt.utils.parsers.ProxyMinionOptionParser, DaemonsMixin): # self.config['user'], permissive=self.config['permissive_pki_access'], root_dir=self.config['root_dir'], - sensitive_dirs=[self.config['pki_dir']], + pki_dir=self.config['pki_dir'], ) except OSError as error: self.environment_failure(error) @@ -578,7 +579,7 @@ class Syndic(salt.utils.parsers.SyndicOptionParser, DaemonsMixin): # pylint: di self.config['user'], permissive=self.config['permissive_pki_access'], root_dir=self.config['root_dir'], - sensitive_dirs=[self.config['pki_dir']], + pki_dir=self.config['pki_dir'], ) except OSError as error: self.environment_failure(error) diff --git a/salt/cli/salt.py b/salt/cli/salt.py index fb59b7e0d0..3e17b8645a 100644 --- a/salt/cli/salt.py +++ b/salt/cli/salt.py @@ -10,6 +10,7 @@ import os import salt.utils.job import salt.utils.parsers import salt.utils.stringutils +import salt.log from salt.utils.args import yamlify_arg from salt.utils.verify import verify_log from salt.exceptions import ( @@ -38,9 +39,10 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser): import salt.client self.parse_args() - # Setup file logging! - self.setup_logfile_logger() - verify_log(self.config) + if self.config['log_level'] not in ('quiet', ): + # Setup file logging! + self.setup_logfile_logger() + verify_log(self.config) try: # We don't need to bail on config file permission errors @@ -82,7 +84,7 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser): if 'token' in self.config: import salt.utils.files try: - with salt.utils.files.fopen(os.path.join(self.config['key_dir'], '.root_key'), 'r') as fp_: + with salt.utils.files.fopen(os.path.join(self.config['cachedir'], '.root_key'), 'r') as fp_: kwargs['key'] = fp_.readline() except IOError: kwargs['token'] = self.config['token'] diff --git a/salt/client/__init__.py b/salt/client/__init__.py index 45ee27a76a..cdc1ce499d 100644 --- a/salt/client/__init__.py +++ b/salt/client/__init__.py @@ -57,11 +57,6 @@ from salt.exceptions import ( # Import third party libs from salt.ext import six # pylint: disable=import-error -try: - import zmq - HAS_ZMQ = True -except ImportError: - HAS_ZMQ = False # Try to import range from https://github.com/ytoolshed/range HAS_RANGE = False @@ -194,11 +189,11 @@ class LocalClient(object): # The username may contain '\' if it is in Windows # 'DOMAIN\username' format. Fix this for the keyfile path. key_user = key_user.replace('\\', '_') - keyfile = os.path.join(self.opts['key_dir'], + keyfile = os.path.join(self.opts['cachedir'], '.{0}_key'.format(key_user)) try: # Make sure all key parent directories are accessible - salt.utils.verify.check_path_traversal(self.opts['key_dir'], + salt.utils.verify.check_path_traversal(self.opts['cachedir'], key_user, self.skip_perm_errors) with salt.utils.files.fopen(keyfile, 'r') as key: diff --git a/salt/client/mixins.py b/salt/client/mixins.py index 29b6077661..6561e6dfba 100644 --- a/salt/client/mixins.py +++ b/salt/client/mixins.py @@ -384,7 +384,11 @@ class SyncClientMixin(object): # Initialize a context for executing the method. with tornado.stack_context.StackContext(self.functions.context_dict.clone): - data['return'] = self.functions[fun](*args, **kwargs) + func = self.functions[fun] + try: + data['return'] = func(*args, **kwargs) + except TypeError as exc: + data['return'] = '\nPassed invalid arguments: {0}\n\nUsage:\n{1}'.format(exc, func.__doc__) try: data['success'] = self.context.get('retcode', 0) == 0 except AttributeError: diff --git a/salt/client/ssh/__init__.py b/salt/client/ssh/__init__.py index b795d51f05..c2f8e17fb5 100644 --- a/salt/client/ssh/__init__.py +++ b/salt/client/ssh/__init__.py @@ -60,11 +60,7 @@ try: HAS_WINSHELL = False except ImportError: HAS_WINSHELL = False -try: - import zmq - HAS_ZMQ = True -except ImportError: - HAS_ZMQ = False +from salt.utils.zeromq import zmq # The directory where salt thin is deployed DEFAULT_THIN_DIR = '/var/tmp/.%%USER%%_%%FQDNUUID%%_salt' @@ -161,17 +157,17 @@ do py_cmd_path=`"$py_cmd" -c \ 'from __future__ import print_function; import sys; print(sys.executable);'` - cmdpath=$(command -v $py_cmd 2>/dev/null || which $py_cmd 2>/dev/null) + cmdpath=`command -v $py_cmd 2>/dev/null || which $py_cmd 2>/dev/null` if file $cmdpath | grep "shell script" > /dev/null then ex_vars="'PATH', 'LD_LIBRARY_PATH', 'MANPATH', \ 'XDG_DATA_DIRS', 'PKG_CONFIG_PATH'" - export $($py_cmd -c \ + export `$py_cmd -c \ "from __future__ import print_function; import sys; import os; map(sys.stdout.write, ['{{{{0}}}}={{{{1}}}} ' \ - .format(x, os.environ[x]) for x in [$ex_vars]])") + .format(x, os.environ[x]) for x in [$ex_vars]])"` exec $SUDO PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH \ MANPATH=$MANPATH XDG_DATA_DIRS=$XDG_DATA_DIRS \ PKG_CONFIG_PATH=$PKG_CONFIG_PATH \ @@ -214,7 +210,7 @@ class SSH(object): def __init__(self, opts): self.__parsed_rosters = {SSH.ROSTER_UPDATE_FLAG: True} pull_sock = os.path.join(opts['sock_dir'], 'master_event_pull.ipc') - if os.path.exists(pull_sock) and HAS_ZMQ: + if os.path.exists(pull_sock) and zmq: self.event = salt.utils.event.get_event( 'master', opts['sock_dir'], @@ -444,7 +440,7 @@ class SSH(object): if target.get('passwd', False) or self.opts['ssh_passwd']: self._key_deploy_run(host, target, False) return ret - if ret[host].get('stderr', '').count('Permission denied'): + if (ret[host].get('stderr') or '').count('Permission denied'): target = self.targets[host] # permission denied, attempt to auto deploy ssh key print(('Permission denied for host {0}, do you want to deploy ' @@ -662,7 +658,9 @@ class SSH(object): host = next(six.iterkeys(ret)) self.cache_job(jid, host, ret[host], fun) if self.event: - _, data = next(six.iteritems(ret)) + id_, data = next(six.iteritems(ret)) + if 'id' not in data: + data['id'] = id_ data['jid'] = jid # make the jid in the payload the same as the jid in the tag self.event.fire_event( data, @@ -755,7 +753,7 @@ class SSH(object): self.cache_job(jid, host, ret[host], fun) ret = self.key_deploy(host, ret) - if isinstance(ret[host], dict) and ret[host].get('stderr', '').startswith('ssh:'): + if isinstance(ret[host], dict) and (ret[host].get('stderr') or '').startswith('ssh:'): ret[host] = ret[host]['stderr'] if not isinstance(ret[host], dict): @@ -773,7 +771,9 @@ class SSH(object): outputter, self.opts) if self.event: - _, data = next(six.iteritems(ret)) + id_, data = next(six.iteritems(ret)) + if 'id' not in data: + data['id'] = id_ data['jid'] = jid # make the jid in the payload the same as the jid in the tag self.event.fire_event( data, @@ -880,6 +880,7 @@ class Single(object): # Pre apply changeable defaults self.minion_opts = { 'grains_cache': True, + 'log_file': 'salt-call.log', } self.minion_opts.update(opts.get('ssh_minion_opts', {})) if minion_opts is not None: @@ -889,7 +890,6 @@ class Single(object): 'root_dir': os.path.join(self.thin_dir, 'running_data'), 'id': self.id, 'sock_dir': '/', - 'log_file': 'salt-call.log', 'fileserver_list_cache_time': 3, }) self.minion_config = salt.serializers.yaml.serialize(self.minion_opts) diff --git a/salt/client/ssh/wrapper/__init__.py b/salt/client/ssh/wrapper/__init__.py index c5d1b5708f..04d751b51a 100644 --- a/salt/client/ssh/wrapper/__init__.py +++ b/salt/client/ssh/wrapper/__init__.py @@ -125,7 +125,7 @@ class FunctionWrapper(object): 'stderr': stderr, 'retcode': retcode} try: - ret = salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict) + ret = salt.utils.json.loads(stdout) if len(ret) < 2 and 'local' in ret: ret = ret['local'] ret = ret.get('return', {}) diff --git a/salt/client/ssh/wrapper/state.py b/salt/client/ssh/wrapper/state.py index d3bd209236..89b444f139 100644 --- a/salt/client/ssh/wrapper/state.py +++ b/salt/client/ssh/wrapper/state.py @@ -197,7 +197,7 @@ def sls(mods, saltenv='base', test=None, exclude=None, **kwargs): # Read in the JSON data and return the data structure try: - return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict) + return salt.utils.json.loads(stdout) except Exception as e: log.error("JSON Render failed for: %s\n%s", stdout, stderr) log.error(six.text_type(e)) @@ -341,7 +341,7 @@ def low(data, **kwargs): # Read in the JSON data and return the data structure try: - return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict) + return salt.utils.json.loads(stdout) except Exception as e: log.error("JSON Render failed for: %s\n%s", stdout, stderr) log.error(six.text_type(e)) @@ -432,7 +432,7 @@ def high(data, **kwargs): # Read in the JSON data and return the data structure try: - return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict) + return salt.utils.json.loads(stdout) except Exception as e: log.error("JSON Render failed for: %s\n%s", stdout, stderr) log.error(six.text_type(e)) @@ -677,7 +677,7 @@ def highstate(test=None, **kwargs): # Read in the JSON data and return the data structure try: - return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict) + return salt.utils.json.loads(stdout) except Exception as e: log.error("JSON Render failed for: %s\n%s", stdout, stderr) log.error(six.text_type(e)) @@ -760,7 +760,7 @@ def top(topfn, test=None, **kwargs): # Read in the JSON data and return the data structure try: - return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict) + return salt.utils.json.loads(stdout) except Exception as e: log.error("JSON Render failed for: %s\n%s", stdout, stderr) log.error(six.text_type(e)) @@ -1133,7 +1133,7 @@ def single(fun, name, test=None, **kwargs): # Read in the JSON data and return the data structure try: - return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict) + return salt.utils.json.loads(stdout) except Exception as e: log.error("JSON Render failed for: %s\n%s", stdout, stderr) log.error(six.text_type(e)) diff --git a/salt/cloud/clouds/aliyun.py b/salt/cloud/clouds/aliyun.py index 4ae2749fe1..9d81e12dcc 100644 --- a/salt/cloud/clouds/aliyun.py +++ b/salt/cloud/clouds/aliyun.py @@ -823,7 +823,7 @@ def query(params=None): content = request.text - result = salt.utils.json.loads(content, object_hook=salt.utils.data.encode_dict) + result = salt.utils.json.loads(content) if 'Code' in result: raise SaltCloudSystemExit( pprint.pformat(result.get('Message', {})) diff --git a/salt/cloud/clouds/azurearm.py b/salt/cloud/clouds/azurearm.py index 759c7ef6ae..2fa9f8cfe4 100644 --- a/salt/cloud/clouds/azurearm.py +++ b/salt/cloud/clouds/azurearm.py @@ -10,9 +10,16 @@ Azure ARM Cloud Module The Azure ARM cloud module is used to control access to Microsoft Azure Resource Manager :depends: - * `Microsoft Azure SDK for Python `_ >= 2.0rc6 - * `Microsoft Azure Storage SDK for Python `_ >= 0.32 - * `AutoRest swagger generator Python client runtime (Azure-specific module) `_ >= 0.4 + * `azure `_ >= 2.0.0rc6 + * `azure-common `_ >= 1.1.4 + * `azure-mgmt `_ >= 0.30.0rc6 + * `azure-mgmt-compute `_ >= 0.33.0 + * `azure-mgmt-network `_ >= 0.30.0rc6 + * `azure-mgmt-resource `_ >= 0.30.0 + * `azure-mgmt-storage `_ >= 0.30.0rc6 + * `azure-mgmt-web `_ >= 0.30.0rc6 + * `azure-storage `_ >= 0.32.0 + * `msrestazure `_ >= 0.4.21 :configuration: Required provider parameters: @@ -774,6 +781,25 @@ def create_network_interface(call=None, kwargs=None): ip_kwargs = {} ip_configurations = None + if 'load_balancer_backend_address_pools' in kwargs: + pool_dicts = kwargs['load_balancer_backend_address_pools'] + if isinstance(pool_dicts, dict): + pool_ids = [] + for load_bal, be_pools in pool_dicts.items(): + for pool in be_pools: + try: + lbbep_data = netconn.load_balancer_backend_address_pools.get( + kwargs['resource_group'], + load_bal, + pool, + ) + pool_ids.append({'id': lbbep_data.as_dict()['id']}) + except CloudError as exc: + log.error('There was a cloud error: %s', six.text_type(exc)) + except KeyError as exc: + log.error('There was an error getting the Backend Pool ID: %s', six.text_type(exc)) + ip_kwargs['load_balancer_backend_address_pools'] = pool_ids + if 'private_ip_address' in kwargs.keys(): ip_kwargs['private_ip_address'] = kwargs['private_ip_address'] ip_kwargs['private_ip_allocation_method'] = IPAllocationMethod.static @@ -930,6 +956,11 @@ def request_instance(vm_): compute_models, 'VirtualMachineSizeTypes' ) + subscription_id = config.get_cloud_config_value( + 'subscription_id', + get_configured_provider(), __opts__, search_global=False + ) + if vm_.get('driver') is None: vm_['driver'] = 'azurearm' @@ -1039,6 +1070,24 @@ def request_instance(vm_): ) os_kwargs['admin_password'] = vm_password + availability_set = config.get_cloud_config_value( + 'availability_set', + vm_, + __opts__, + search_global=False, + default=None + ) + if availability_set is not None and isinstance(availability_set, six.string_types): + availability_set = { + 'id': '/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Compute/availabilitySets/{2}'.format( + subscription_id, + vm_['resource_group'], + availability_set + ) + } + else: + availability_set = None + cloud_env = _get_cloud_environment() storage_endpoint_suffix = cloud_env.suffixes.storage_endpoint @@ -1147,7 +1196,10 @@ def request_instance(vm_): img_pub, img_off, img_sku, img_ver = vm_['image'].split('|') source_image = None os_type = None - os_disk = None + os_disk = OSDisk( + create_option=DiskCreateOptionTypes.from_image, + disk_size_gb=vm_.get('os_disk_size_gb') + ) img_ref = ImageReference( publisher=img_pub, offer=img_off, @@ -1235,6 +1287,7 @@ def request_instance(vm_): NetworkInterfaceReference(vm_['iface_id']), ], ), + availability_set=availability_set, ) __utils__['cloud.fire_event']( @@ -1257,15 +1310,15 @@ def request_instance(vm_): parameters=params ) vm_create.wait() + vm_result = vm_create.result() + vm_result = vm_result.as_dict() if custom_extension: create_or_update_vmextension(kwargs=custom_extension) except CloudError as exc: __utils__['azurearm.log_cloud_error']('compute', exc.message) + vm_result = {} - try: - return show_instance(vm_['name'], call='action') - except CloudError: - return {} + return vm_result def create(vm_): @@ -1304,7 +1357,12 @@ def create(vm_): log.info('Creating Cloud VM %s in %s', vm_['name'], location) - request_instance(vm_=vm_) + vm_request = request_instance(vm_=vm_) + + if not vm_request or 'error' in vm_request: + err_message = 'Error creating VM {0}! ({1})'.format(vm_['name'], six.text_type(vm_request)) + log.error(err_message) + raise SaltCloudSystemExit(err_message) def _query_node_data(name, bootstrap_interface): ''' diff --git a/salt/cloud/clouds/cloudstack.py b/salt/cloud/clouds/cloudstack.py index 34b2fc7850..35c255fe3d 100644 --- a/salt/cloud/clouds/cloudstack.py +++ b/salt/cloud/clouds/cloudstack.py @@ -42,10 +42,11 @@ from salt.ext import six # pylint: disable=import-error try: from libcloud.compute.drivers.cloudstack import CloudStackNetwork - # This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0. - # However, older versions of libcloud must still be supported with this work-around. - # This work-around can be removed when the required minimum version of libcloud is - # 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen). + # This work-around for Issue #32743 is no longer needed for libcloud >= + # 1.4.0. However, older versions of libcloud must still be supported with + # this work-around. This work-around can be removed when the required + # minimum version of libcloud is 2.0.0 (See PR #40837 - which is + # implemented in Salt 2018.3.0). if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'): # See https://github.com/saltstack/salt/issues/32743 import libcloud.security diff --git a/salt/cloud/clouds/dimensiondata.py b/salt/cloud/clouds/dimensiondata.py index a915800b21..ca0d8a47ea 100644 --- a/salt/cloud/clouds/dimensiondata.py +++ b/salt/cloud/clouds/dimensiondata.py @@ -32,7 +32,7 @@ from salt.utils.versions import LooseVersion as _LooseVersion # Import libcloud try: import libcloud - from libcloud.compute.base import NodeState + from libcloud.compute.base import NodeDriver, NodeState from libcloud.compute.base import NodeAuthPassword from libcloud.compute.types import Provider from libcloud.compute.providers import get_driver @@ -40,10 +40,11 @@ try: from libcloud.loadbalancer.types import Provider as Provider_lb from libcloud.loadbalancer.providers import get_driver as get_driver_lb - # This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0. - # However, older versions of libcloud must still be supported with this work-around. - # This work-around can be removed when the required minimum version of libcloud is - # 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen). + # This work-around for Issue #32743 is no longer needed for libcloud >= + # 1.4.0. However, older versions of libcloud must still be supported with + # this work-around. This work-around can be removed when the required + # minimum version of libcloud is 2.0.0 (See PR #40837 - which is + # implemented in Salt 2018.3.0). if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'): # See https://github.com/saltstack/salt/issues/32743 import libcloud.security @@ -52,9 +53,6 @@ try: except ImportError: HAS_LIBCLOUD = False -# Import generic libcloud functions -# from salt.cloud.libcloudfuncs import * - # Import salt.cloud libs from salt.cloud.libcloudfuncs import * # pylint: disable=redefined-builtin,wildcard-import,unused-wildcard-import from salt.utils.functools import namespaced_function @@ -217,7 +215,6 @@ def create(vm_): log.info('Creating Cloud VM %s', vm_['name']) conn = get_conn() - rootPw = NodeAuthPassword(vm_['auth']) location = conn.ex_get_location_by_id(vm_['location']) images = conn.list_images(location=location) @@ -248,15 +245,13 @@ def create(vm_): kwargs = { 'name': vm_['name'], 'image': image, - 'auth': rootPw, 'ex_description': vm_['description'], 'ex_network_domain': network_domain, 'ex_vlan': vlan, 'ex_is_started': vm_['is_started'] } - event_data = kwargs.copy() - del event_data['auth'] + event_data = _to_event_data(kwargs) __utils__['cloud.fire_event']( 'event', @@ -267,6 +262,10 @@ def create(vm_): transport=__opts__['transport'] ) + # Initial password (excluded from event payload) + initial_password = NodeAuthPassword(vm_['auth']) + kwargs['auth'] = initial_password + try: data = conn.create_node(**kwargs) except Exception as exc: @@ -280,7 +279,7 @@ def create(vm_): return False try: - data = salt.utils.cloud.wait_for_ip( + data = __utils__['cloud.wait_for_ip']( _query_node_data, update_args=(vm_, data), timeout=config.get_cloud_config_value( @@ -306,7 +305,7 @@ def create(vm_): ip_address = preferred_ip(vm_, data.public_ips) log.debug('Using IP address %s', ip_address) - if salt.utils.cloud.get_salt_interface(vm_, __opts__) == 'private_ips': + if __utils__['cloud.get_salt_interface'](vm_, __opts__) == 'private_ips': salt_ip_address = preferred_ip(vm_, data.private_ips) log.info('Salt interface set to: %s', salt_ip_address) else: @@ -322,7 +321,7 @@ def create(vm_): vm_['ssh_host'] = ip_address vm_['password'] = vm_['auth'] - ret = salt.utils.cloud.bootstrap(vm_, __opts__) + ret = __utils__['cloud.bootstrap'](vm_, __opts__) ret.update(data.__dict__) @@ -414,11 +413,13 @@ def create_lb(kwargs=None, call=None): log.debug('Network Domain: %s', network_domain.id) lb_conn.ex_set_current_network_domain(network_domain.id) + event_data = _to_event_data(kwargs) + __utils__['cloud.fire_event']( 'event', 'create load_balancer', 'salt/cloud/loadbalancer/creating', - args=kwargs, + args=event_data, sock_dir=__opts__['sock_dir'], transport=__opts__['transport'] ) @@ -427,11 +428,13 @@ def create_lb(kwargs=None, call=None): name, port, protocol, algorithm, members ) + event_data = _to_event_data(kwargs) + __utils__['cloud.fire_event']( 'event', 'created load_balancer', 'salt/cloud/loadbalancer/created', - args=kwargs, + args=event_data, sock_dir=__opts__['sock_dir'], transport=__opts__['transport'] ) @@ -573,3 +576,46 @@ def get_lb_conn(dd_driver=None): 'Missing dimensiondata_driver for get_lb_conn method.' ) return get_driver_lb(Provider_lb.DIMENSIONDATA)(user_id, key, region=region) + + +def _to_event_data(obj): + ''' + Convert the specified object into a form that can be serialised by msgpack as event data. + + :param obj: The object to convert. + ''' + + if obj is None: + return None + if isinstance(obj, bool): + return obj + if isinstance(obj, int): + return obj + if isinstance(obj, float): + return obj + if isinstance(obj, str): + return obj + if isinstance(obj, bytes): + return obj + if isinstance(obj, dict): + return obj + + if isinstance(obj, NodeDriver): # Special case for NodeDriver (cyclic references) + return obj.name + + if isinstance(obj, list): + return [_to_event_data(item) for item in obj] + + event_data = {} + for attribute_name in dir(obj): + if attribute_name.startswith('_'): + continue + + attribute_value = getattr(obj, attribute_name) + + if callable(attribute_value): # Strip out methods + continue + + event_data[attribute_name] = _to_event_data(attribute_value) + + return event_data diff --git a/salt/cloud/clouds/ec2.py b/salt/cloud/clouds/ec2.py index 1fcefb7c8d..0cb5e234ad 100644 --- a/salt/cloud/clouds/ec2.py +++ b/salt/cloud/clouds/ec2.py @@ -200,8 +200,7 @@ def get_dependencies(): ''' deps = { 'requests': HAS_REQUESTS, - 'm2crypto': HAS_M2, - 'pycrypto': HAS_PYCRYPTO + 'pycrypto or m2crypto': HAS_M2 or HAS_PYCRYPTO } return config.check_driver_dependencies( __virtualname__, diff --git a/salt/cloud/clouds/gce.py b/salt/cloud/clouds/gce.py index 29f059c7a5..75109491be 100644 --- a/salt/cloud/clouds/gce.py +++ b/salt/cloud/clouds/gce.py @@ -70,10 +70,11 @@ try: ResourceInUseError, ResourceNotFoundError, ) - # This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0. - # However, older versions of libcloud must still be supported with this work-around. - # This work-around can be removed when the required minimum version of libcloud is - # 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen). + # This work-around for Issue #32743 is no longer needed for libcloud >= + # 1.4.0. However, older versions of libcloud must still be supported with + # this work-around. This work-around can be removed when the required + # minimum version of libcloud is 2.0.0 (See PR #40837 - which is + # implemented in Salt 2018.3.0). if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'): # See https://github.com/saltstack/salt/issues/32743 import libcloud.security diff --git a/salt/cloud/clouds/opennebula.py b/salt/cloud/clouds/opennebula.py index 4b6ade6bf8..b98d254f57 100644 --- a/salt/cloud/clouds/opennebula.py +++ b/salt/cloud/clouds/opennebula.py @@ -758,7 +758,7 @@ def get_template_image(kwargs=None, call=None): ''' Returns a template's image from the given template name. - .. versionadded:: oxygen + .. versionadded:: 2018.3.0 .. code-block:: bash @@ -921,7 +921,7 @@ def _get_device_template(disk, disk_info, template=None): ''' Returns the template format to create a disk in open nebula - .. versionadded:: oxygen + .. versionadded:: 2018.3.0 ''' def _require_disk_opts(*args): diff --git a/salt/cloud/clouds/openstack.py b/salt/cloud/clouds/openstack.py index 4fd63643bf..62ef280410 100644 --- a/salt/cloud/clouds/openstack.py +++ b/salt/cloud/clouds/openstack.py @@ -355,7 +355,7 @@ def _get_ips(node, addr_type='public'): ret = [] for _, interface in node.addresses.items(): for addr in interface: - if addr_type in ('floating', 'fixed') and addr_type == addr['OS-EXT-IPS:type']: + if addr_type in ('floating', 'fixed') and addr_type == addr.get('OS-EXT-IPS:type'): ret.append(addr['addr']) elif addr_type == 'public' and __utils__['cloud.is_public_ip'](addr['addr']): ret.append(addr['addr']) diff --git a/salt/cloud/clouds/qingcloud.py b/salt/cloud/clouds/qingcloud.py index 64118f0da9..a6b423de38 100644 --- a/salt/cloud/clouds/qingcloud.py +++ b/salt/cloud/clouds/qingcloud.py @@ -188,7 +188,7 @@ def query(params=None): log.debug(request.url) content = request.text - result = salt.utils.json.loads(content, object_hook=salt.utils.data.encode_dict) + result = salt.utils.json.loads(content) # print('response:') # pprint.pprint(result) diff --git a/salt/cloud/clouds/saltify.py b/salt/cloud/clouds/saltify.py index 5a474e1c3d..c9cc281b42 100644 --- a/salt/cloud/clouds/saltify.py +++ b/salt/cloud/clouds/saltify.py @@ -9,7 +9,7 @@ The Saltify module is designed to install Salt on a remote machine, virtual or bare metal, using SSH. This module is useful for provisioning machines which are already installed, but not Salted. -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 The wake_on_lan capability, and actions destroy, reboot, and query functions were added. Use of this module requires some configuration in cloud profile and provider @@ -88,7 +88,7 @@ def avail_images(call=None): returns a list of available profiles. - ..versionadded:: Oxygen + ..versionadded:: 2018.3.0 ''' vm_ = get_configured_provider() @@ -118,7 +118,7 @@ def list_nodes(call=None): returns a list of dictionaries of defined standard fields. - ..versionadded:: Oxygen + ..versionadded:: 2018.3.0 ''' nodes = _list_nodes_full(call) @@ -164,7 +164,7 @@ def list_nodes_full(call=None): for 'saltify' minions, returns dict of grains (enhanced). - ..versionadded:: Oxygen + ..versionadded:: 2018.3.0 ''' ret = _list_nodes_full(call) @@ -399,7 +399,7 @@ def _verify(vm_): def destroy(name, call=None): ''' Destroy a node. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Disconnect a minion from the master, and remove its keys. @@ -489,7 +489,7 @@ def reboot(name, call=None): ''' Reboot a saltify minion. - ..versionadded:: Oxygen + ..versionadded:: 2018.3.0 name The name of the VM to reboot. diff --git a/salt/cloud/clouds/vagrant.py b/salt/cloud/clouds/vagrant.py index 778f0eeb14..a24170c78a 100644 --- a/salt/cloud/clouds/vagrant.py +++ b/salt/cloud/clouds/vagrant.py @@ -10,7 +10,7 @@ Use of this module requires some configuration in cloud profile and provider files as described in the :ref:`Getting Started with Vagrant ` documentation. -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' diff --git a/salt/cloud/clouds/xen.py b/salt/cloud/clouds/xen.py index 5823fd7cc9..0b79d4dfb9 100644 --- a/salt/cloud/clouds/xen.py +++ b/salt/cloud/clouds/xen.py @@ -565,11 +565,6 @@ def create(vm_): record = {} ret = {} - # Since using "provider: " is deprecated, alias provider - # to use driver: "driver: " - if 'provider' in vm_: - vm_['driver'] = vm_.pop('provider') - # fire creating event __utils__['cloud.fire_event']( 'event', diff --git a/salt/config/__init__.py b/salt/config/__init__.py index 0fa40af4d9..3847ba7ada 100644 --- a/salt/config/__init__.py +++ b/salt/config/__init__.py @@ -197,9 +197,6 @@ VALID_OPTS = { # The directory used to store public key data 'pki_dir': six.string_types, - # The directory to store authentication keys of a master's local environment. - 'key_dir': six.string_types, - # A unique identifier for this daemon 'id': six.string_types, @@ -284,6 +281,7 @@ VALID_OPTS = { # Location of the files a minion should look for. Set to 'local' to never ask the master. 'file_client': six.string_types, + 'local': bool, # When using a local file_client, this parameter is used to allow the client to connect to # a master for remote execution. @@ -1250,6 +1248,7 @@ DEFAULT_MINION_OPTS = { 'base': [salt.syspaths.BASE_THORIUM_ROOTS_DIR], }, 'file_client': 'remote', + 'local': False, 'use_master_when_local': False, 'file_roots': { 'base': [salt.syspaths.BASE_FILE_ROOTS_DIR, @@ -1500,7 +1499,6 @@ DEFAULT_MASTER_OPTS = { 'archive_jobs': False, 'root_dir': salt.syspaths.ROOT_DIR, 'pki_dir': os.path.join(salt.syspaths.CONFIG_DIR, 'pki', 'master'), - 'key_dir': os.path.join(salt.syspaths.CONFIG_DIR, 'key'), 'key_cache': '', 'cachedir': os.path.join(salt.syspaths.CACHE_DIR, 'master'), 'file_roots': { @@ -1530,6 +1528,7 @@ DEFAULT_MASTER_OPTS = { 'pillarenv': None, 'default_top': 'base', 'file_client': 'local', + 'local': True, # Update intervals 'roots_update_interval': DEFAULT_INTERVAL, @@ -1816,7 +1815,6 @@ DEFAULT_MASTER_OPTS = { 'schedule': {}, 'auth_events': True, 'minion_data_cache_events': True, - 'enable_ssh': False, 'enable_ssh_minions': False, } @@ -2316,6 +2314,12 @@ def prepend_root_dir(opts, path_options): path = tmp_path_root_dir else: path = tmp_path_def_root_dir + elif salt.utils.platform.is_windows() and not os.path.splitdrive(path)[0]: + # In windows, os.path.isabs resolves '/' to 'C:\\' or whatever + # the root drive is. This elif prevents the next from being + # hit, so that the root_dir is prefixed in cases where the + # drive is not prefixed on a config option + pass elif os.path.isabs(path): # Absolute path (not default or overriden root_dir) # No prepending required @@ -2503,7 +2507,7 @@ def syndic_config(master_config_path, opts.update(syndic_opts) # Prepend root_dir to other paths prepend_root_dirs = [ - 'pki_dir', 'key_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules', + 'pki_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules', 'autosign_file', 'autoreject_file', 'token_dir', 'autosign_grains_dir' ] for config_key in ('log_file', 'key_logfile', 'syndic_log_file'): @@ -3651,7 +3655,7 @@ def _adjust_log_file_override(overrides, default_log_file): if overrides.get('log_dir'): # Adjust log_file if a log_dir override is introduced if overrides.get('log_file'): - if not os.path.abspath(overrides['log_file']): + if not os.path.isabs(overrides['log_file']): # Prepend log_dir if log_file is relative overrides['log_file'] = os.path.join(overrides['log_dir'], overrides['log_file']) @@ -3940,7 +3944,7 @@ def apply_master_config(overrides=None, defaults=None): # Prepend root_dir to other paths prepend_root_dirs = [ - 'pki_dir', 'key_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules', + 'pki_dir', 'cachedir', 'pidfile', 'sock_dir', 'extension_modules', 'autosign_file', 'autoreject_file', 'token_dir', 'syndic_dir', 'sqlite_queue_dir', 'autosign_grains_dir' ] diff --git a/salt/crypt.py b/salt/crypt.py index 39ba4f9d87..bd82d71ff5 100644 --- a/salt/crypt.py +++ b/salt/crypt.py @@ -806,7 +806,7 @@ class AsyncAuth(object): pubkey_path = os.path.join(self.opts['pki_dir'], self.mpub) pub = get_rsa_pub_key(pubkey_path) if HAS_M2: - payload['token'] = pub.public_encrypt(six.b(self.token), RSA.pkcs1_oaep_padding) + payload['token'] = pub.public_encrypt(self.token, RSA.pkcs1_oaep_padding) else: cipher = PKCS1_OAEP.new(pub) payload['token'] = cipher.encrypt(self.token) @@ -845,7 +845,8 @@ class AsyncAuth(object): log.debug('Decrypting the current master AES key') key = self.get_keys() if HAS_M2: - key_str = key.private_decrypt(six.b(payload['aes']), RSA.pkcs1_oaep_padding) + key_str = key.private_decrypt(payload['aes'], + RSA.pkcs1_oaep_padding) else: cipher = PKCS1_OAEP.new(key) key_str = cipher.decrypt(payload['aes']) @@ -876,7 +877,8 @@ class AsyncAuth(object): else: if 'token' in payload: if HAS_M2: - token = key.private_decrypt(six.b(payload['token']), RSA.pkcs1_oaep_padding) + token = key.private_decrypt(payload['token'], + RSA.pkcs1_oaep_padding) else: token = cipher.decrypt(payload['token']) return key_str, token diff --git a/salt/daemons/flo/__init__.py b/salt/daemons/flo/__init__.py index 07d7e512d4..80c66f6860 100644 --- a/salt/daemons/flo/__init__.py +++ b/salt/daemons/flo/__init__.py @@ -121,6 +121,7 @@ class IofloMinion(object): ''' warn_deprecated() self.opts = opts + self.restart = False def tune_in(self, behaviors=None): ''' diff --git a/salt/daemons/flo/jobber.py b/salt/daemons/flo/jobber.py index 002fb426c9..b180213880 100644 --- a/salt/daemons/flo/jobber.py +++ b/salt/daemons/flo/jobber.py @@ -62,7 +62,10 @@ def jobber_check(self): rms.append(jid) data = self.shells.value[jid] stdout, stderr = data['proc'].communicate() - ret = salt.utils.json.loads(stdout, object_hook=salt.utils.data.encode_dict)['local'] + ret = salt.utils.json.loads( + stdout, + object_hook=salt.utils.data.encode_dict if six.PY2 else None + )['local'] route = {'src': (self.stack.value.local.name, 'manor', 'jid_ret'), 'dst': (data['msg']['route']['src'][0], None, 'remote_cmd')} ret['cmd'] = '_return' diff --git a/salt/daemons/flo/zero.py b/salt/daemons/flo/zero.py index 75c1f9f3ee..bf4e5725ec 100644 --- a/salt/daemons/flo/zero.py +++ b/salt/daemons/flo/zero.py @@ -15,16 +15,12 @@ import errno # Import ioflo libs import ioflo.base.deeding # Import third party libs -try: - import zmq - import salt.master - import salt.crypt - import salt.daemons.masterapi - import salt.payload - import salt.utils.stringutils - HAS_ZMQ = True -except ImportError: - HAS_ZMQ = False +from salt.utils.zeromq import zmq +import salt.master +import salt.crypt +import salt.daemons.masterapi +import salt.payload +import salt.utils.stringutils log = logging.getLogger(__name__) @@ -160,7 +156,7 @@ class SaltZmqPublisher(ioflo.base.deeding.Deed): ''' Set up tracking value(s) ''' - if not HAS_ZMQ: + if not zmq: return self.created = False self.serial = salt.payload.Serial(self.opts.value) diff --git a/salt/daemons/masterapi.py b/salt/daemons/masterapi.py index b4c7526ff8..4fe00934cd 100644 --- a/salt/daemons/masterapi.py +++ b/salt/daemons/masterapi.py @@ -186,11 +186,11 @@ def mk_key(opts, user): # The username may contain '\' if it is in Windows # 'DOMAIN\username' format. Fix this for the keyfile path. keyfile = os.path.join( - opts['key_dir'], '.{0}_key'.format(user.replace('\\', '_')) + opts['cachedir'], '.{0}_key'.format(user.replace('\\', '_')) ) else: keyfile = os.path.join( - opts['key_dir'], '.{0}_key'.format(user) + opts['cachedir'], '.{0}_key'.format(user) ) if os.path.exists(keyfile): diff --git a/salt/daemons/test/minion.flo b/salt/daemons/test/minion.flo index b88d381f9e..02a4e465dd 100644 --- a/salt/daemons/test/minion.flo +++ b/salt/daemons/test/minion.flo @@ -11,7 +11,12 @@ framer minionudpstack be active first start exit do salt raet road stack closer per inode ".salt.road.manor." -framer bootstrap be active first join +framer bootstrap be active first setup + frame setup + enter + do salt raet road usher minion setup per inode ".salt.road.manor." + go join + frame join print Joining... enter @@ -44,7 +49,7 @@ framer bootstrap be active first join frame message print Messaging... enter - do raet road stack messenger to contents "Minion 1 Hello" code 15 \ + do raet road stack messenger with contents "Minion 1 Hello" code 15 \ per inode ".salt.road.manor." go next diff --git a/salt/daemons/test/test_master.py b/salt/daemons/test/test_master.py index ab1e5996bb..d99b9e3000 100644 --- a/salt/daemons/test/test_master.py +++ b/salt/daemons/test/test_master.py @@ -22,6 +22,10 @@ def test(): if not os.path.exists(pkiDirpath): os.makedirs(pkiDirpath) + keyDirpath = os.path.join('/tmp', 'raet', 'testo', 'key') + if not os.path.exists(keyDirpath): + os.makedirs(keyDirpath) + acceptedDirpath = os.path.join(pkiDirpath, 'accepted') if not os.path.exists(acceptedDirpath): os.makedirs(acceptedDirpath) @@ -64,10 +68,12 @@ def test(): client_acl=dict(), publisher_acl=dict(), pki_dir=pkiDirpath, + key_dir=keyDirpath, sock_dir=sockDirpath, cachedir=cacheDirpath, open_mode=True, auto_accept=True, + client_acl_verify=True, ) master = salt.daemons.flo.IofloMaster(opts=opts) diff --git a/salt/daemons/test/test_multimaster.py b/salt/daemons/test/test_multimaster.py index 45c1eb6ac2..88114a9d4c 100644 --- a/salt/daemons/test/test_multimaster.py +++ b/salt/daemons/test/test_multimaster.py @@ -348,8 +348,8 @@ if __name__ == '__main__' and __package__ is None: #console.reinit(verbosity=console.Wordage.concise) - #runAll() # run all unittests + runAll() # run all unittests - runSome() # only run some + #runSome() # only run some #runOne('testParseHostname') diff --git a/salt/daemons/test/test_presence.py b/salt/daemons/test/test_presence.py index 975546726b..e98e8eb698 100644 --- a/salt/daemons/test/test_presence.py +++ b/salt/daemons/test/test_presence.py @@ -5,6 +5,7 @@ Raet Ioflo Behavior Unittests from __future__ import absolute_import, print_function, unicode_literals import sys from salt.ext.six.moves import map +import importlib # pylint: disable=blacklisted-import if sys.version_info < (2, 7): import unittest2 as unittest @@ -40,6 +41,9 @@ class PresenterTestCase(testing.FrameIofloTestCase): ''' Call super if override so House Framer and Frame are setup correctly ''' + behaviors = ['salt.daemons.flo', 'salt.daemons.test.plan'] + for behavior in behaviors: + mod = importlib.import_module(behavior) super(PresenterTestCase, self).setUp() def tearDown(self): diff --git a/salt/daemons/test/test_raetkey.py b/salt/daemons/test/test_raetkey.py index 173de3d614..b4a0218881 100644 --- a/salt/daemons/test/test_raetkey.py +++ b/salt/daemons/test/test_raetkey.py @@ -7,6 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals # pylint: skip-file # pylint: disable=C0103 import sys +import salt.utils.stringutils from salt.ext.six.moves import map if sys.version_info < (2, 7): import unittest2 as unittest @@ -30,12 +31,15 @@ from raet.road import estating, keeping, stacking from salt.key import RaetKey + def setUpModule(): console.reinit(verbosity=console.Wordage.concise) + def tearDownModule(): pass + class BasicTestCase(unittest.TestCase): """""" @@ -47,7 +51,7 @@ class BasicTestCase(unittest.TestCase): pkiDirpath = os.path.join(self.saltDirpath, 'pki') if not os.path.exists(pkiDirpath): - os.makedirs(pkiDirpath) + os.makedirs(pkiDirpath) acceptedDirpath = os.path.join(pkiDirpath, 'accepted') if not os.path.exists(acceptedDirpath): @@ -81,7 +85,7 @@ class BasicTestCase(unittest.TestCase): ) self.mainKeeper = RaetKey(opts=self.opts) - self.baseDirpath = tempfile.mkdtemp(prefix="salt", suffix="base", dir='/tmp') + self.baseDirpath = tempfile.mkdtemp(prefix="salt", suffix="base", dir='/tmp') def tearDown(self): if os.path.exists(self.saltDirpath): @@ -119,9 +123,9 @@ class BasicTestCase(unittest.TestCase): self.opts['auto_accept'] = True self.assertTrue(self.opts['auto_accept']) self.assertDictEqual(self.mainKeeper.all_keys(), {'accepted': [], - 'local': [], - 'rejected': [], - 'pending': []}) + 'local': [], + 'rejected': [], + 'pending': []}) localkeys = self.mainKeeper.read_local() self.assertDictEqual(localkeys, {}) @@ -129,8 +133,9 @@ class BasicTestCase(unittest.TestCase): main = self.createRoadData(name='main', base=self.baseDirpath) self.mainKeeper.write_local(main['prihex'], main['sighex']) localkeys = self.mainKeeper.read_local() - self.assertDictEqual(localkeys, {'priv': main['prihex'], - 'sign': main['sighex']}) + self.assertDictEqual(localkeys, + {'priv': salt.utils.stringutils.to_str(main['prihex']), + 'sign': salt.utils.stringutils.to_str(main['sighex'])}) allkeys = self.mainKeeper.all_keys() self.assertDictEqual(allkeys, {'accepted': [], 'local': [self.localFilepath], @@ -147,39 +152,38 @@ class BasicTestCase(unittest.TestCase): allkeys = self.mainKeeper.all_keys() self.assertDictEqual(allkeys, {'accepted': ['other1', 'other2'], - 'local': [self.localFilepath], - 'pending': [], - 'rejected': []} ) + 'local': [self.localFilepath], + 'pending': [], + 'rejected': []}) remotekeys = self.mainKeeper.read_remote(other1['name']) - self.assertDictEqual(remotekeys, { 'minion_id': 'other1', - 'pub': other1['pubhex'], - 'verify': other1['verhex']} ) + self.assertDictEqual(remotekeys, {'minion_id': 'other1', + 'pub': salt.utils.stringutils.to_str(other1['pubhex']), + 'verify': salt.utils.stringutils.to_str(other1['verhex'])}) remotekeys = self.mainKeeper.read_remote(other2['name']) - self.assertDictEqual(remotekeys, { 'minion_id': 'other2', - 'pub': other2['pubhex'], - 'verify': other2['verhex']} ) + self.assertDictEqual(remotekeys, {'minion_id': 'other2', + 'pub': salt.utils.stringutils.to_str(other2['pubhex']), + 'verify': salt.utils.stringutils.to_str(other2['verhex'])}) listkeys = self.mainKeeper.list_keys() self.assertDictEqual(listkeys, {'accepted': ['other1', 'other2'], 'rejected': [], 'pending': []}) - allremotekeys = self.mainKeeper.read_all_remote() - self.assertDictEqual(allremotekeys, {'other1': - {'verify': other1['verhex'], - 'minion_id': 'other1', - 'acceptance': 'accepted', - 'pub': other1['pubhex'],}, - 'other2': - {'verify': other2['verhex'], - 'minion_id': 'other2', - 'acceptance': 'accepted', - 'pub': other2['pubhex'],} - }) - + self.assertDictEqual(allremotekeys, + {'other1': + {'verify': salt.utils.stringutils.to_str(other1['verhex']), + 'minion_id': 'other1', + 'acceptance': 'accepted', + 'pub': salt.utils.stringutils.to_str(other1['pubhex']), }, + 'other2': + {'verify': salt.utils.stringutils.to_str(other2['verhex']), + 'minion_id': 'other2', + 'acceptance': 'accepted', + 'pub': salt.utils.stringutils.to_str(other2['pubhex']), } + }) def testManualAccept(self): ''' @@ -189,9 +193,9 @@ class BasicTestCase(unittest.TestCase): self.opts['auto_accept'] = False self.assertFalse(self.opts['auto_accept']) self.assertDictEqual(self.mainKeeper.all_keys(), {'accepted': [], - 'local': [], - 'rejected': [], - 'pending': []}) + 'local': [], + 'rejected': [], + 'pending': []}) localkeys = self.mainKeeper.read_local() self.assertDictEqual(localkeys, {}) @@ -199,8 +203,9 @@ class BasicTestCase(unittest.TestCase): main = self.createRoadData(name='main', base=self.baseDirpath) self.mainKeeper.write_local(main['prihex'], main['sighex']) localkeys = self.mainKeeper.read_local() - self.assertDictEqual(localkeys, {'priv': main['prihex'], - 'sign': main['sighex']}) + self.assertDictEqual(localkeys, + {'priv': salt.utils.stringutils.to_str(main['prihex']), + 'sign': salt.utils.stringutils.to_str(main['sighex'])}) allkeys = self.mainKeeper.all_keys() self.assertDictEqual(allkeys, {'accepted': [], 'local': [self.localFilepath], @@ -217,9 +222,9 @@ class BasicTestCase(unittest.TestCase): allkeys = self.mainKeeper.all_keys() self.assertDictEqual(allkeys, {'accepted': [], - 'local': [self.localFilepath], - 'pending': ['other1', 'other2'], - 'rejected': []} ) + 'local': [self.localFilepath], + 'pending': ['other1', 'other2'], + 'rejected': []}) remotekeys = self.mainKeeper.read_remote(other1['name']) self.assertDictEqual(remotekeys, {}) @@ -232,56 +237,60 @@ class BasicTestCase(unittest.TestCase): 'rejected': [], 'pending': ['other1', 'other2']}) - allremotekeys = self.mainKeeper.read_all_remote() - self.assertDictEqual(allremotekeys, {'other1': - {'verify': other1['verhex'], - 'minion_id': 'other1', - 'acceptance': 'pending', - 'pub': other1['pubhex'],}, - 'other2': - {'verify': other2['verhex'], - 'minion_id': 'other2', - 'acceptance': 'pending', - 'pub': other2['pubhex'],} - }) + self.assertDictEqual(allremotekeys, + {'other1': + {'verify': salt.utils.stringutils.to_str(other1['verhex']), + 'minion_id': 'other1', + 'acceptance': 'pending', + 'pub': salt.utils.stringutils.to_str(other1['pubhex']), + }, + 'other2': + {'verify': salt.utils.stringutils.to_str(other2['verhex']), + 'minion_id': 'other2', + 'acceptance': 'pending', + 'pub': salt.utils.stringutils.to_str(other2['pubhex']), + } + }) self.mainKeeper.accept_all() allkeys = self.mainKeeper.all_keys() self.assertDictEqual(allkeys, {'accepted': ['other1', 'other2'], - 'local': [self.localFilepath], - 'pending': [], - 'rejected': []} ) + 'local': [self.localFilepath], + 'pending': [], + 'rejected': []}) remotekeys = self.mainKeeper.read_remote(other1['name']) - self.assertDictEqual(remotekeys, { 'minion_id': 'other1', - 'pub': other1['pubhex'], - 'verify': other1['verhex']} ) + self.assertDictEqual(remotekeys, {'minion_id': 'other1', + 'pub': salt.utils.stringutils.to_str(other1['pubhex']), + 'verify': salt.utils.stringutils.to_str(other1['verhex'])}) remotekeys = self.mainKeeper.read_remote(other2['name']) - self.assertDictEqual(remotekeys, { 'minion_id': 'other2', - 'pub': other2['pubhex'], - 'verify': other2['verhex']} ) + self.assertDictEqual(remotekeys, {'minion_id': 'other2', + 'pub': salt.utils.stringutils.to_str(other2['pubhex']), + 'verify': salt.utils.stringutils.to_str(other2['verhex'])}) listkeys = self.mainKeeper.list_keys() self.assertDictEqual(listkeys, {'accepted': ['other1', 'other2'], 'rejected': [], 'pending': []}) - allremotekeys = self.mainKeeper.read_all_remote() - self.assertDictEqual(allremotekeys, {'other1': - {'verify': other1['verhex'], - 'minion_id': 'other1', - 'acceptance': 'accepted', - 'pub': other1['pubhex'],}, - 'other2': - {'verify': other2['verhex'], - 'minion_id': 'other2', - 'acceptance': 'accepted', - 'pub': other2['pubhex'],} - }) + self.assertDictEqual(allremotekeys, + {'other1': + {'verify': salt.utils.stringutils.to_str(other1['verhex']), + 'minion_id': 'other1', + 'acceptance': 'accepted', + 'pub': salt.utils.stringutils.to_str(other1['pubhex']), + }, + 'other2': + {'verify': salt.utils.stringutils.to_str(other2['verhex']), + 'minion_id': 'other2', + 'acceptance': 'accepted', + 'pub': salt.utils.stringutils.to_str(other2['pubhex']), + } + }) def testDelete(self): ''' @@ -291,9 +300,9 @@ class BasicTestCase(unittest.TestCase): self.opts['auto_accept'] = True self.assertTrue(self.opts['auto_accept']) self.assertDictEqual(self.mainKeeper.all_keys(), {'accepted': [], - 'local': [], - 'rejected': [], - 'pending': []}) + 'local': [], + 'rejected': [], + 'pending': []}) localkeys = self.mainKeeper.read_local() self.assertDictEqual(localkeys, {}) @@ -301,8 +310,9 @@ class BasicTestCase(unittest.TestCase): main = self.createRoadData(name='main', base=self.baseDirpath) self.mainKeeper.write_local(main['prihex'], main['sighex']) localkeys = self.mainKeeper.read_local() - self.assertDictEqual(localkeys, {'priv': main['prihex'], - 'sign': main['sighex']}) + self.assertDictEqual(localkeys, + {'priv': salt.utils.stringutils.to_str(main['prihex']), + 'sign': salt.utils.stringutils.to_str(main['sighex'])}) allkeys = self.mainKeeper.all_keys() self.assertDictEqual(allkeys, {'accepted': [], 'local': [self.localFilepath], @@ -319,70 +329,73 @@ class BasicTestCase(unittest.TestCase): allkeys = self.mainKeeper.all_keys() self.assertDictEqual(allkeys, {'accepted': ['other1', 'other2'], - 'local': [self.localFilepath], - 'pending': [], - 'rejected': []} ) + 'local': [self.localFilepath], + 'pending': [], + 'rejected': []}) remotekeys = self.mainKeeper.read_remote(other1['name']) - self.assertDictEqual(remotekeys, { 'minion_id': 'other1', - 'pub': other1['pubhex'], - 'verify': other1['verhex']} ) + self.assertDictEqual(remotekeys, {'minion_id': 'other1', + 'pub': salt.utils.stringutils.to_str(other1['pubhex']), + 'verify': salt.utils.stringutils.to_str(other1['verhex']), + }) remotekeys = self.mainKeeper.read_remote(other2['name']) - self.assertDictEqual(remotekeys, { 'minion_id': 'other2', - 'pub': other2['pubhex'], - 'verify': other2['verhex']} ) + self.assertDictEqual(remotekeys, {'minion_id': 'other2', + 'pub': salt.utils.stringutils.to_str(other2['pubhex']), + 'verify': salt.utils.stringutils.to_str(other2['verhex']), + }) listkeys = self.mainKeeper.list_keys() self.assertDictEqual(listkeys, {'accepted': ['other1', 'other2'], 'rejected': [], 'pending': []}) - allremotekeys = self.mainKeeper.read_all_remote() - self.assertDictEqual(allremotekeys, {'other1': - {'verify': other1['verhex'], - 'minion_id': 'other1', - 'acceptance': 'accepted', - 'pub': other1['pubhex']}, - 'other2': - {'verify': other2['verhex'], - 'minion_id': 'other2', - 'acceptance': 'accepted', - 'pub': other2['pubhex'],} - }) + self.assertDictEqual(allremotekeys, + {'other1': + {'verify': salt.utils.stringutils.to_str(other1['verhex']), + 'minion_id': 'other1', + 'acceptance': 'accepted', + 'pub': salt.utils.stringutils.to_str(other1['pubhex']) + }, + 'other2': + {'verify': salt.utils.stringutils.to_str(other2['verhex']), + 'minion_id': 'other2', + 'acceptance': 'accepted', + 'pub': salt.utils.stringutils.to_str(other2['pubhex']), + } + }) self.mainKeeper.delete_key(match=other1['name']) allkeys = self.mainKeeper.all_keys() self.assertDictEqual(allkeys, {'accepted': ['other2'], - 'local': [self.localFilepath], - 'pending': [], - 'rejected': []} ) + 'local': [self.localFilepath], + 'pending': [], + 'rejected': []}) remotekeys = self.mainKeeper.read_remote(other1['name']) - self.assertDictEqual(remotekeys, {} ) + self.assertDictEqual(remotekeys, {}) remotekeys = self.mainKeeper.read_remote(other2['name']) - self.assertDictEqual(remotekeys, { 'minion_id': 'other2', - 'pub': other2['pubhex'], - 'verify': other2['verhex']} ) + self.assertDictEqual(remotekeys, {'minion_id': 'other2', + 'pub': salt.utils.stringutils.to_str(other2['pubhex']), + 'verify': salt.utils.stringutils.to_str(other2['verhex'])}) listkeys = self.mainKeeper.list_keys() - self.assertDictEqual(listkeys, {'accepted': [ 'other2'], + self.assertDictEqual(listkeys, {'accepted': ['other2'], 'rejected': [], 'pending': []}) - allremotekeys = self.mainKeeper.read_all_remote() - self.assertDictEqual(allremotekeys, { - 'other2': - {'verify': other2['verhex'], - 'minion_id': 'other2', - 'acceptance': 'accepted', - 'pub': other2['pubhex'],} - }) - + self.assertDictEqual(allremotekeys, + {'other2': + {'verify': salt.utils.stringutils.to_str(other2['verhex']), + 'minion_id': 'other2', + 'acceptance': 'accepted', + 'pub': salt.utils.stringutils.to_str(other2['pubhex']), + } + }) def runOne(test): @@ -393,11 +406,12 @@ def runOne(test): suite = unittest.TestSuite([test]) unittest.TextTestRunner(verbosity=2).run(suite) + def runSome(): ''' Unittest runner ''' - tests = [] + tests = [] names = ['testAutoAccept', 'testManualAccept', 'testDelete'] @@ -407,6 +421,7 @@ def runSome(): suite = unittest.TestSuite(tests) unittest.TextTestRunner(verbosity=2).run(suite) + def runAll(): ''' Unittest runner @@ -416,12 +431,12 @@ def runAll(): unittest.TextTestRunner(verbosity=2).run(suite) + if __name__ == '__main__' and __package__ is None: + # console.reinit(verbosity=console.Wordage.concise) - #console.reinit(verbosity=console.Wordage.concise) + runAll() # run all unittests - runAll() #run all unittests + # runSome() #only run some - #runSome()#only run some - - #runOne('testDelete') + # runOne('testDelete') diff --git a/salt/daemons/test/test_saltkeep.py b/salt/daemons/test/test_saltkeep.py index 8176af1ce6..e548eed93e 100644 --- a/salt/daemons/test/test_saltkeep.py +++ b/salt/daemons/test/test_saltkeep.py @@ -13,10 +13,11 @@ else: # pylint: enable=blacklisted-import import os -import stat -import time -import tempfile import shutil +import socket +import stat +import tempfile +import time from ioflo.aid.odicting import odict from ioflo.aid.timing import StoreTimer @@ -29,6 +30,7 @@ from raet.road import estating, stacking from salt.daemons import salting import salt.utils.kinds as kinds +import salt.utils.stringutils def setUpModule(): @@ -232,20 +234,21 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class os.path.join('main', 'raet', 'main_master'))) self.assertTrue(main.ha, ("0.0.0.0", raeting.RAET_PORT)) self.assertIs(main.keep.auto, raeting.AutoMode.never.value) - self.assertDictEqual(main.keep.loadLocalData(), {'name': mainData['name'], - 'uid': 1, - 'ha': ['127.0.0.1', 7530], - 'iha': None, - 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', - 'dyned': None, - 'sid': 0, - 'puid': 1, - 'aha': ['0.0.0.0', 7530], - 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], - }) + self.assertDictEqual(main.keep.loadLocalData(), + {'name': mainData['name'], + 'uid': 1, + 'ha': ['127.0.0.1', 7530], + 'iha': None, + 'natted': None, + 'fqdn': socket.getfqdn('127.0.0.1'), + 'dyned': None, + 'sid': 0, + 'puid': 1, + 'aha': ['0.0.0.0', 7530], + 'role': mainData['role'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), + }) data1 = self.createRoadData(role='remote1', kind=kinds.APPL_KIND_NAMES[kinds.applKinds.minion], @@ -282,7 +285,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7532], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data1['kind'], @@ -290,8 +293,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data1['role'], 'acceptance': 0, - 'verhex': data1['verhex'], - 'pubhex': data1['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data1['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data1['pubhex']), }, 'remote2_minion': {'name': data2['name'], @@ -300,7 +303,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7533], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data2['kind'], @@ -308,8 +311,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data2['role'], 'acceptance': 0, - 'verhex': data2['verhex'], - 'pubhex': data2['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data2['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data2['pubhex']), } }) @@ -362,14 +365,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7531], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7531], 'role': otherData['role'], - 'sighex': otherData['sighex'], - 'prihex': otherData['prihex'], + 'sighex': salt.utils.stringutils.to_str(otherData['sighex']), + 'prihex': salt.utils.stringutils.to_str(otherData['prihex']), }) data3 = self.createRoadData(role='remote3', @@ -405,7 +408,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7534], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data3['kind'], @@ -413,8 +416,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data3['role'], 'acceptance': 0, - 'verhex': data3['verhex'], - 'pubhex': data3['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data3['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data3['pubhex']), }, 'remote4_minion': { @@ -424,7 +427,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7535], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data4['kind'], @@ -432,8 +435,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data4['role'], 'acceptance': 0, - 'verhex': data4['verhex'], - 'pubhex': data4['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data4['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data4['pubhex']), } }) @@ -477,14 +480,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), }) data1 = self.createRoadData(role='remote1', @@ -520,7 +523,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7532], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data1['kind'], @@ -528,8 +531,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data1['role'], 'acceptance': 1, - 'verhex': data1['verhex'], - 'pubhex': data1['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data1['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data1['pubhex']), }, 'remote2_minion': {'name': data2['name'], @@ -538,7 +541,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7533], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data2['kind'], @@ -546,8 +549,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data2['role'], 'acceptance': 1, - 'verhex': data2['verhex'], - 'pubhex': data2['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data2['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data2['pubhex']), } }) @@ -600,14 +603,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7531], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7531], 'role': otherData['role'], - 'sighex': otherData['sighex'], - 'prihex': otherData['prihex'], + 'sighex': salt.utils.stringutils.to_str(otherData['sighex']), + 'prihex': salt.utils.stringutils.to_str(otherData['prihex']), }) data3 = self.createRoadData(role='remote3', @@ -643,7 +646,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7534], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data3['kind'], @@ -651,8 +654,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data3['role'], 'acceptance': 1, - 'verhex': data3['verhex'], - 'pubhex': data3['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data3['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data3['pubhex']), }, 'remote4_minion': { @@ -662,7 +665,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7535], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data4['kind'], @@ -670,8 +673,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data4['role'], 'acceptance': 1, - 'verhex': data4['verhex'], - 'pubhex': data4['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data4['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data4['pubhex']), } }) @@ -715,13 +718,13 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), 'role': mainData['role'], }) @@ -759,7 +762,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7532], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data1['kind'], @@ -767,8 +770,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data1['role'], 'acceptance': 1, - 'verhex': data1['verhex'], - 'pubhex': data1['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data1['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data1['pubhex']), }, 'remote2_minion': { @@ -778,7 +781,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7533], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data2['kind'], @@ -786,8 +789,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data2['role'], 'acceptance': 1, - 'verhex': data2['verhex'], - 'pubhex': data2['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data2['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data2['pubhex']), } }) @@ -840,14 +843,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7531], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7531], 'role': otherData['role'], - 'sighex': otherData['sighex'], - 'prihex': otherData['prihex'], + 'sighex': salt.utils.stringutils.to_str(otherData['sighex']), + 'prihex': salt.utils.stringutils.to_str(otherData['prihex']), }) data3 = self.createRoadData(role='remote3', @@ -883,7 +886,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7534], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data3['kind'], @@ -891,8 +894,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data3['role'], 'acceptance': 1, - 'verhex': data3['verhex'], - 'pubhex': data3['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data3['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data3['pubhex']), }, 'remote4_minion': { @@ -902,7 +905,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7535], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data4['kind'], @@ -910,8 +913,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data4['role'], 'acceptance': 1, - 'verhex': data4['verhex'], - 'pubhex': data4['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data4['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data4['pubhex']), } }) @@ -955,14 +958,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), }) # add multiple remotes all with same role @@ -1006,7 +1009,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7532], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data1['kind'], @@ -1014,8 +1017,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data1['role'], 'acceptance': 0, - 'verhex': data1['verhex'], - 'pubhex': data1['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data1['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data1['pubhex']), }, 'primary_caller': { @@ -1025,7 +1028,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7533], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data2['kind'], @@ -1033,8 +1036,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data1['role'], 'acceptance': 0, - 'verhex': data1['verhex'], - 'pubhex': data1['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data1['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data1['pubhex']), } }) @@ -1104,14 +1107,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), }) # add multiple remotes all with same role @@ -1149,7 +1152,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7532], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data1['kind'], @@ -1157,8 +1160,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data1['role'], 'acceptance': 1, - 'verhex': data2['verhex'], - 'pubhex': data2['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data2['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data2['pubhex']), }, 'primary_syndic': { @@ -1168,7 +1171,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7533], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data2['kind'], @@ -1176,8 +1179,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data2['role'], 'acceptance': 1, - 'verhex': data2['verhex'], - 'pubhex': data2['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data2['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data2['pubhex']), } }) @@ -1248,14 +1251,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), }) # add multiple remotes all with same role but different keys @@ -1300,7 +1303,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7532], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data1['kind'], @@ -1308,8 +1311,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data1['role'], 'acceptance': 1, - 'verhex': data1['verhex'], - 'pubhex': data1['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data1['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data1['pubhex']), }, 'primary_syndic': { @@ -1319,7 +1322,7 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7533], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'main': False, 'kind': data2['kind'], @@ -1327,8 +1330,8 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'joined': None, 'role': data2['role'], 'acceptance': 1, - 'verhex': data1['verhex'], - 'pubhex': data1['pubhex'], + 'verhex': salt.utils.stringutils.to_str(data1['verhex']), + 'pubhex': salt.utils.stringutils.to_str(data1['pubhex']), } }) @@ -1399,14 +1402,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), }) opts = self.createOpts(role='other', @@ -1441,14 +1444,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7531], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7531], 'role': otherData['role'], - 'sighex': otherData['sighex'], - 'prihex': otherData['prihex'], + 'sighex': salt.utils.stringutils.to_str(otherData['sighex']), + 'prihex': salt.utils.stringutils.to_str(otherData['prihex']), }) self.join(other, main) @@ -1524,14 +1527,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), }) opts = self.createOpts(role='other', @@ -1566,14 +1569,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7531], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7531], 'role': otherData['role'], - 'sighex': otherData['sighex'], - 'prihex': otherData['prihex'], + 'sighex': salt.utils.stringutils.to_str(otherData['sighex']), + 'prihex': salt.utils.stringutils.to_str(otherData['prihex']), }) self.join(other, main) @@ -1645,14 +1648,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), }) opts = self.createOpts(role='other', @@ -1687,13 +1690,13 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7531], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7531], - 'sighex': otherData['sighex'], - 'prihex': otherData['prihex'], + 'sighex': salt.utils.stringutils.to_str(otherData['sighex']), + 'prihex': salt.utils.stringutils.to_str(otherData['prihex']), 'role': otherData['role'], }) @@ -1766,14 +1769,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), }) opts = self.createOpts(role='primary', @@ -1808,14 +1811,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7531], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7531], 'role': other1Data['role'], - 'sighex': other1Data['sighex'], - 'prihex': other1Data['prihex'], + 'sighex': salt.utils.stringutils.to_str(other1Data['sighex']), + 'prihex': salt.utils.stringutils.to_str(other1Data['prihex']), }) self.join(other1, main) @@ -1876,13 +1879,13 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7532], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7532], - 'sighex': other2Data['sighex'], - 'prihex': other2Data['prihex'], + 'sighex': salt.utils.stringutils.to_str(other2Data['sighex']), + 'prihex': salt.utils.stringutils.to_str(other2Data['prihex']), 'role': other2Data['role'], }) @@ -1936,14 +1939,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7532], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7532], 'role': other2Data['role'], - 'sighex': other1Data['sighex'], - 'prihex': other1Data['prihex'], + 'sighex': salt.utils.stringutils.to_str(other1Data['sighex']), + 'prihex': salt.utils.stringutils.to_str(other1Data['prihex']), }) # should join since same role and keys @@ -2021,14 +2024,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7530], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7530], 'role': mainData['role'], - 'sighex': mainData['sighex'], - 'prihex': mainData['prihex'], + 'sighex': salt.utils.stringutils.to_str(mainData['sighex']), + 'prihex': salt.utils.stringutils.to_str(mainData['prihex']), }) opts = self.createOpts(role='primary', @@ -2063,14 +2066,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7531], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7531], 'role': other1Data['role'], - 'sighex': other1Data['sighex'], - 'prihex': other1Data['prihex'], + 'sighex': salt.utils.stringutils.to_str(other1Data['sighex']), + 'prihex': salt.utils.stringutils.to_str(other1Data['prihex']), }) self.join(other1, main) @@ -2130,14 +2133,14 @@ class BasicTestCase(unittest.TestCase): # pylint: disable=moved-test-case-class 'ha': ['127.0.0.1', 7532], 'iha': None, 'natted': None, - 'fqdn': '1.0.0.127.in-addr.arpa', + 'fqdn': socket.getfqdn('127.0.0.1'), 'dyned': None, 'sid': 0, 'puid': 1, 'aha': ['0.0.0.0', 7532], 'role': other2Data['role'], - 'sighex': other2Data['sighex'], - 'prihex': other2Data['prihex'], + 'sighex': salt.utils.stringutils.to_str(other2Data['sighex']), + 'prihex': salt.utils.stringutils.to_str(other2Data['prihex']), }) # should join since open mode @@ -2225,8 +2228,8 @@ if __name__ == '__main__' and __package__ is None: #console.reinit(verbosity=console.Wordage.concise) - #runAll() # run all unittests + runAll() # run all unittests - runSome() # only run some + #runSome() # only run some #runOne('testBootstrapRoleAuto') diff --git a/salt/daemons/test/test_stats.py b/salt/daemons/test/test_stats.py index 9289fd0955..6e23d0fdfb 100644 --- a/salt/daemons/test/test_stats.py +++ b/salt/daemons/test/test_stats.py @@ -5,6 +5,7 @@ Raet Ioflo Behavior Unittests from __future__ import absolute_import, print_function, unicode_literals import sys from salt.ext.six.moves import map +import importlib # pylint: disable=blacklisted-import if sys.version_info < (2, 7): import unittest2 as unittest @@ -43,6 +44,9 @@ class StatsEventerTestCase(testing.FrameIofloTestCase): ''' Call super if override so House Framer and Frame are setup correctly ''' + behaviors = ['salt.daemons.flo', 'salt.daemons.test.plan'] + for behavior in behaviors: + mod = importlib.import_module(behavior) super(StatsEventerTestCase, self).setUp() def tearDown(self): @@ -723,8 +727,8 @@ if __name__ == '__main__' and __package__ is None: # console.reinit(verbosity=console.Wordage.concise) - #runAll() # run all unittests + runAll() # run all unittests - runSome() # only run some + #runSome() # only run some #runOne('testMasterLaneStats') diff --git a/salt/engines/docker_events.py b/salt/engines/docker_events.py index 39b1963747..f8c8dd1502 100644 --- a/salt/engines/docker_events.py +++ b/salt/engines/docker_events.py @@ -41,7 +41,8 @@ def __virtual__(): def start(docker_url='unix://var/run/docker.sock', timeout=CLIENT_TIMEOUT, - tag='salt/engines/docker_events'): + tag='salt/engines/docker_events', + filters=None): ''' Scan for Docker events and fire events @@ -52,10 +53,18 @@ def start(docker_url='unix://var/run/docker.sock', engines: - docker_events: docker_url: unix://var/run/docker.sock + filters: + event: + - start + - stop + - die + - oom The config above sets up engines to listen for events from the Docker daemon and publish them to the Salt event bus. + + For filter reference, see https://docs.docker.com/engine/reference/commandline/events/ ''' if __opts__.get('__role') == 'master': @@ -81,7 +90,7 @@ def start(docker_url='unix://var/run/docker.sock', client = docker.Client(base_url=docker_url, timeout=timeout) try: - events = client.events() + events = client.events(filters=filters) for event in events: data = salt.utils.json.loads(event.decode(__salt_system_encoding__, errors='replace')) # https://github.com/docker/cli/blob/master/cli/command/system/events.go#L109 diff --git a/salt/engines/http_logstash.py b/salt/engines/http_logstash.py index e729c10903..4a92718fdf 100644 --- a/salt/engines/http_logstash.py +++ b/salt/engines/http_logstash.py @@ -6,7 +6,7 @@ HTTP Logstash engine An engine that reads messages from the salt event bus and pushes them onto a logstash endpoint via HTTP requests. -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 .. note:: By default, this engine take everything from the Salt bus and exports into diff --git a/salt/engines/napalm_syslog.py b/salt/engines/napalm_syslog.py index 751f8cd41c..08e1ccfb4a 100644 --- a/salt/engines/napalm_syslog.py +++ b/salt/engines/napalm_syslog.py @@ -173,11 +173,7 @@ from __future__ import absolute_import, print_function, unicode_literals import logging # Import third party libraries -try: - import zmq - HAS_ZMQ = True -except ImportError: - HAS_ZMQ = False +from salt.utils.zeromq import zmq try: # pylint: disable=W0611 @@ -209,7 +205,7 @@ def __virtual__(): ''' Load only if napalm-logs is installed. ''' - if not HAS_NAPALM_LOGS or not HAS_ZMQ: + if not HAS_NAPALM_LOGS or not zmq: return (False, 'napalm_syslog could not be loaded. \ Please install napalm-logs library amd ZeroMQ.') return True diff --git a/salt/exceptions.py b/salt/exceptions.py index 5abfef1dfa..63774c640b 100644 --- a/salt/exceptions.py +++ b/salt/exceptions.py @@ -285,7 +285,7 @@ class SaltRenderError(SaltException): if self.line_num and self.buffer: # Avoid circular import import salt.utils.templates - self.context = salt.utils.templates.get_context( + self.context = salt.utils.stringutils.get_context( self.buffer, self.line_num, marker=marker diff --git a/salt/ext/win_inet_pton.py b/salt/ext/win_inet_pton.py index ba6db461e7..e29da87a5e 100644 --- a/salt/ext/win_inet_pton.py +++ b/salt/ext/win_inet_pton.py @@ -37,7 +37,7 @@ def inet_pton(address_family, ip_string): # This will catch IP Addresses such as 10.1.2 if address_family == socket.AF_INET: try: - ipaddress.ip_address(six.u(ip_string)) + ipaddress.ip_address(six.text_type(ip_string)) except ValueError: raise socket.error('illegal IP address string passed to inet_pton') return socket.inet_aton(ip_string) diff --git a/salt/fileserver/azurefs.py b/salt/fileserver/azurefs.py index a60f2ec336..c266323fbe 100644 --- a/salt/fileserver/azurefs.py +++ b/salt/fileserver/azurefs.py @@ -12,9 +12,9 @@ the Master config file. fileserver_backend: - azurefs -Starting in Oxygen, this fileserver requires the standalone Azure Storage SDK -for Python. Theoretically any version >= v0.20.0 should work, but it was -developed against the v0.33.0 version. +Starting in Salt 2018.3.0, this fileserver requires the standalone Azure +Storage SDK for Python. Theoretically any version >= v0.20.0 should work, but +it was developed against the v0.33.0 version. Each storage container will be mapped to an environment. By default, containers will be mapped to the ``base`` environment. You can override this behavior with diff --git a/salt/fileserver/gitfs.py b/salt/fileserver/gitfs.py index bc89b63269..479f323292 100644 --- a/salt/fileserver/gitfs.py +++ b/salt/fileserver/gitfs.py @@ -14,7 +14,7 @@ Master config file. - gitfs .. note:: - ``git`` also works here. Prior to the Oxygen release, *only* ``git`` + ``git`` also works here. Prior to the 2018.3.0 release, *only* ``git`` would work. The Git fileserver backend supports both pygit2_ and GitPython_, to provide the diff --git a/salt/fileserver/hgfs.py b/salt/fileserver/hgfs.py index 2d04d65e9f..3b15b6bc2d 100644 --- a/salt/fileserver/hgfs.py +++ b/salt/fileserver/hgfs.py @@ -11,7 +11,7 @@ Master config file. - hgfs .. note:: - ``hg`` also works here. Prior to the Oxygen release, *only* ``hg`` would + ``hg`` also works here. Prior to the 2018.3.0 release, *only* ``hg`` would work. After enabling this backend, branches, bookmarks, and tags in a remote diff --git a/salt/fileserver/minionfs.py b/salt/fileserver/minionfs.py index 573ddf0715..53603503a5 100644 --- a/salt/fileserver/minionfs.py +++ b/salt/fileserver/minionfs.py @@ -17,8 +17,8 @@ allowed to push files to the Master), and ``minionfs`` must be added to the - minionfs .. note:: - ``minion`` also works here. Prior to the Oxygen release, *only* ``minion`` - would work. + ``minion`` also works here. Prior to the 2018.3.0 release, *only* + ``minion`` would work. Other minionfs settings include: :conf_master:`minionfs_whitelist`, :conf_master:`minionfs_blacklist`, :conf_master:`minionfs_mountpoint`, and diff --git a/salt/fileserver/svnfs.py b/salt/fileserver/svnfs.py index e354ea33c3..24226a702f 100644 --- a/salt/fileserver/svnfs.py +++ b/salt/fileserver/svnfs.py @@ -13,8 +13,8 @@ Master config file. - svnfs .. note:: - ``svn`` also works here. Prior to the Oxygen release, *only* ``svn`` would - work. + ``svn`` also works here. Prior to the 2018.3.0 release, *only* ``svn`` + would work. This backend assumes a standard svn layout with directories for ``branches``, ``tags``, and ``trunk``, at the repository root. diff --git a/salt/grains/core.py b/salt/grains/core.py index ed21b4922d..cc7c92ca73 100644 --- a/salt/grains/core.py +++ b/salt/grains/core.py @@ -24,6 +24,13 @@ import uuid from errno import EACCES, EPERM import datetime +# pylint: disable=import-error +try: + import dateutil.tz + _DATEUTIL_TZ = True +except ImportError: + _DATEUTIL_TZ = False + __proxyenabled__ = ['*'] __FQDN__ = None @@ -1333,19 +1340,22 @@ def _get_interfaces(): return _INTERFACES -def _parse_os_release(): +def _parse_os_release(os_release_files): ''' - Parse /etc/os-release and return a parameter dictionary + Parse os-release and return a parameter dictionary See http://www.freedesktop.org/software/systemd/man/os-release.html for specification of the file format. ''' - filename = '/etc/os-release' - if not os.path.isfile(filename): - filename = '/usr/lib/os-release' - data = dict() + for filename in os_release_files: + if os.path.isfile(filename): + break + else: + # None of the specified os-release files exist + return data + with salt.utils.files.fopen(filename) as ifile: regex = re.compile('^([\\w]+)=(?:\'|")?(.*?)(?:\'|")?$') for line in ifile: @@ -1540,13 +1550,15 @@ def os_data(): # to be incorrectly set to "Arch". grains['osfullname'] = 'Antergos Linux' elif 'lsb_distrib_id' not in grains: - if os.path.isfile('/etc/os-release') or os.path.isfile('/usr/lib/os-release'): - os_release = _parse_os_release() + os_release = _parse_os_release(['/etc/os-release', '/usr/lib/os-release']) + if os_release: if 'NAME' in os_release: grains['lsb_distrib_id'] = os_release['NAME'].strip() if 'VERSION_ID' in os_release: grains['lsb_distrib_release'] = os_release['VERSION_ID'] - if 'PRETTY_NAME' in os_release: + if 'VERSION_CODENAME' in os_release: + grains['lsb_distrib_codename'] = os_release['VERSION_CODENAME'] + elif 'PRETTY_NAME' in os_release: codename = os_release['PRETTY_NAME'] # https://github.com/saltstack/salt/issues/44108 if os_release['ID'] == 'debian': @@ -1810,7 +1822,7 @@ def os_data(): grains['osrelease_info'] ) os_name = grains['os' if grains.get('os') in ( - 'FreeBSD', 'OpenBSD', 'NetBSD', 'Mac', 'Raspbian') else 'osfullname'] + 'Debian', 'FreeBSD', 'OpenBSD', 'NetBSD', 'Mac', 'Raspbian') else 'osfullname'] grains['osfinger'] = '{0}-{1}'.format( os_name, grains['osrelease'] if os_name in ('Ubuntu',) else grains['osrelease_info'][0]) @@ -1840,6 +1852,8 @@ def locale_info(): grains['locale_info']['defaultlanguage'] = 'unknown' grains['locale_info']['defaultencoding'] = 'unknown' grains['locale_info']['detectedencoding'] = __salt_system_encoding__ + if _DATEUTIL_TZ: + grains['locale_info']['timezone'] = datetime.datetime.now(dateutil.tz.tzlocal()).tzname() return grains @@ -2517,13 +2531,16 @@ def _linux_iqn(): ret = [] initiator = '/etc/iscsi/initiatorname.iscsi' - - if os.path.isfile(initiator): + try: with salt.utils.files.fopen(initiator, 'r') as _iscsi: for line in _iscsi: line = line.strip() if line.startswith('InitiatorName='): ret.append(line.split('=', 1)[1]) + except IOError as ex: + if ex.errno != os.errno.ENOENT: + log.debug("Error while accessing '%s': %s", initiator, ex) + return ret diff --git a/salt/grains/zfs.py b/salt/grains/zfs.py index 85c4e9ec0f..72b867a127 100644 --- a/salt/grains/zfs.py +++ b/salt/grains/zfs.py @@ -7,7 +7,7 @@ ZFS grain provider :depends: salt.utils, salt.module.cmdmod :platform: illumos,freebsd,linux -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' from __future__ import absolute_import, print_function, unicode_literals diff --git a/salt/key.py b/salt/key.py index 19fa60d09f..3b936d2e42 100644 --- a/salt/key.py +++ b/salt/key.py @@ -125,7 +125,7 @@ class KeyCLI(object): if self.opts['eauth']: if 'token' in self.opts: try: - with salt.utils.files.fopen(os.path.join(self.opts['key_dir'], '.root_key'), 'r') as fp_: + with salt.utils.files.fopen(os.path.join(self.opts['cachedir'], '.root_key'), 'r') as fp_: low['key'] = \ salt.utils.stringutils.to_unicode(fp_.readline()) except IOError: @@ -1082,6 +1082,8 @@ class RaetKey(Key): pre_path = os.path.join(pre, minion_id) rej_path = os.path.join(rej, minion_id) # open mode is turned on, force accept the key + pub = salt.utils.stringutils.to_str(pub) + verify = salt.utils.stringutils.to_str(verify) keydata = { 'minion_id': minion_id, 'pub': pub, @@ -1148,7 +1150,7 @@ class RaetKey(Key): verify: ''' path = os.path.join(self.opts['pki_dir'], status, minion_id) - with salt.utils.files.fopen(path, 'r') as fp_: + with salt.utils.files.fopen(path, 'rb') as fp_: keydata = self.serial.loads(fp_.read()) return 'pub: {0}\nverify: {1}'.format( keydata['pub'], @@ -1158,7 +1160,7 @@ class RaetKey(Key): ''' Return a sha256 kingerprint for the key ''' - with salt.utils.files.fopen(path, 'r') as fp_: + with salt.utils.files.fopen(path, 'rb') as fp_: keydata = self.serial.loads(fp_.read()) key = 'pub: {0}\nverify: {1}'.format( keydata['pub'], @@ -1442,7 +1444,7 @@ class RaetKey(Key): if os.path.exists(path): #mode = os.stat(path).st_mode os.chmod(path, stat.S_IWUSR | stat.S_IRUSR) - with salt.utils.files.fopen(path, 'w+') as fp_: + with salt.utils.files.fopen(path, 'w+b') as fp_: fp_.write(self.serial.dumps(keydata)) os.chmod(path, stat.S_IRUSR) os.umask(c_umask) diff --git a/salt/log/handlers/__init__.py b/salt/log/handlers/__init__.py index 8380cb9052..bea9cfe502 100644 --- a/salt/log/handlers/__init__.py +++ b/salt/log/handlers/__init__.py @@ -17,6 +17,7 @@ import logging.handlers # Import salt libs from salt.log.mixins import NewStyleClassMixIn, ExcInfoOnLogLevelFormatMixIn +from salt.ext.six.moves import queue log = logging.getLogger(__name__) @@ -176,9 +177,9 @@ if sys.version_info < (3, 2): ''' try: self.queue.put_nowait(record) - except self.queue.Full: + except queue.Full: sys.stderr.write('[WARNING ] Message queue is full, ' - 'unable to write "{0}" to log', record + 'unable to write "{0}" to log'.format(record) ) def prepare(self, record): diff --git a/salt/log/setup.py b/salt/log/setup.py index e14064e1d0..c06dffa7bf 100644 --- a/salt/log/setup.py +++ b/salt/log/setup.py @@ -120,6 +120,7 @@ __MP_LOGGING_QUEUE = None __MP_LOGGING_QUEUE_PROCESS = None __MP_LOGGING_QUEUE_HANDLER = None __MP_IN_MAINPROCESS = multiprocessing.current_process().name == 'MainProcess' +__MP_MAINPROCESS_ID = None class __NullLoggingHandler(TemporaryLoggingHandler): @@ -822,6 +823,7 @@ def set_multiprocessing_logging_queue(queue): def setup_multiprocessing_logging_listener(opts, queue=None): global __MP_LOGGING_QUEUE_PROCESS global __MP_LOGGING_LISTENER_CONFIGURED + global __MP_MAINPROCESS_ID if __MP_IN_MAINPROCESS is False: # We're not in the MainProcess, return! No logging listener setup shall happen @@ -830,6 +832,11 @@ def setup_multiprocessing_logging_listener(opts, queue=None): if __MP_LOGGING_LISTENER_CONFIGURED is True: return + if __MP_MAINPROCESS_ID is not None and __MP_MAINPROCESS_ID != os.getpid(): + # We're not in the MainProcess, return! No logging listener setup shall happen + return + + __MP_MAINPROCESS_ID = os.getpid() __MP_LOGGING_QUEUE_PROCESS = multiprocessing.Process( target=__process_multiprocessing_logging_queue, args=(opts, queue or get_multiprocessing_logging_queue(),) @@ -967,6 +974,11 @@ def shutdown_multiprocessing_logging_listener(daemonizing=False): if __MP_LOGGING_QUEUE_PROCESS is None: return + + if __MP_MAINPROCESS_ID is not None and __MP_MAINPROCESS_ID != os.getpid(): + # We're not in the MainProcess, return! No logging listener setup shall happen + return + if __MP_LOGGING_QUEUE_PROCESS.is_alive(): logging.getLogger(__name__).debug('Stopping the multiprocessing logging queue listener') try: diff --git a/salt/master.py b/salt/master.py index 82b53153a3..fb704909c8 100644 --- a/salt/master.py +++ b/salt/master.py @@ -24,21 +24,9 @@ import salt.serializers.msgpack # pylint: disable=import-error,no-name-in-module,redefined-builtin from salt.ext import six from salt.ext.six.moves import range +from salt.utils.zeromq import zmq, ZMQDefaultLoop, install_zmq, ZMQ_VERSION_INFO # pylint: enable=import-error,no-name-in-module,redefined-builtin -try: - import zmq - import zmq.eventloop.ioloop - # support pyzmq 13.0.x, TODO: remove once we force people to 14.0.x - if not hasattr(zmq.eventloop.ioloop, 'ZMQIOLoop'): - zmq.eventloop.ioloop.ZMQIOLoop = zmq.eventloop.ioloop.IOLoop - LOOP_CLASS = zmq.eventloop.ioloop.ZMQIOLoop - HAS_ZMQ = True -except ImportError: - import tornado.ioloop - LOOP_CLASS = tornado.ioloop.IOLoop - HAS_ZMQ = False - import tornado.gen # pylint: disable=F0401 # Import salt libs @@ -498,23 +486,13 @@ class Master(SMaster): :param dict: The salt options ''' - if HAS_ZMQ: - # Warn if ZMQ < 3.2 - try: - zmq_version_info = zmq.zmq_version_info() - except AttributeError: - # PyZMQ <= 2.1.9 does not have zmq_version_info, fall back to - # using zmq.zmq_version() and build a version info tuple. - zmq_version_info = tuple( - [int(x) for x in zmq.zmq_version().split('.')] - ) - if zmq_version_info < (3, 2): - log.warning( - 'You have a version of ZMQ less than ZMQ 3.2! There are ' - 'known connection keep-alive issues with ZMQ < 3.2 which ' - 'may result in loss of contact with minions. Please ' - 'upgrade your ZMQ!' - ) + if zmq and ZMQ_VERSION_INFO < (3, 2): + log.warning( + 'You have a version of ZMQ less than ZMQ 3.2! There are ' + 'known connection keep-alive issues with ZMQ < 3.2 which ' + 'may result in loss of contact with minions. Please ' + 'upgrade your ZMQ!' + ) SMaster.__init__(self, opts) def __set_max_open_files(self): @@ -993,9 +971,8 @@ class MWorker(salt.utils.process.SignalHandlingMultiprocessingProcess): Bind to the local port ''' # using ZMQIOLoop since we *might* need zmq in there - if HAS_ZMQ: - zmq.eventloop.ioloop.install() - self.io_loop = LOOP_CLASS() + install_zmq() + self.io_loop = ZMQDefaultLoop() self.io_loop.make_current() for req_channel in self.req_channels: req_channel.post_fork(self._handle_payload, io_loop=self.io_loop) # TODO: cleaner? Maybe lazily? @@ -2028,6 +2005,7 @@ class ClearFuncs(object): ) minions = _res.get('minions', list()) missing = _res.get('missing', list()) + ssh_minions = _res.get('ssh_minions', False) # Check for external auth calls and authenticate auth_type, err_name, key, sensitive_load_keys = self._prep_auth_info(extra) @@ -2095,7 +2073,7 @@ class ClearFuncs(object): payload = self._prep_pub(minions, jid, clear_load, extra, missing) # Send it! - minions.extend(self._send_ssh_pub(payload)) + self._send_ssh_pub(payload, ssh_minions=ssh_minions) self._send_pub(payload) return { @@ -2158,20 +2136,19 @@ class ClearFuncs(object): chan = salt.transport.server.PubServerChannel.factory(opts) chan.publish(load) - def _send_ssh_pub(self, load): + @property + def ssh_client(self): + if not hasattr(self, '_ssh_client'): + self._ssh_client = salt.client.ssh.client.SSHClient(mopts=self.opts) + return self._ssh_client + + def _send_ssh_pub(self, load, ssh_minions=False): ''' - Take a load and send it across the network to connected minions + Take a load and send it across the network to ssh minions ''' - minions = [] - if self.opts['enable_ssh_minions'] is True and isinstance(load['tgt'], six.string_types): - # The isinstances makes sure that syndics work - log.debug('Use SSHClient for rostered minions') - ssh = salt.client.ssh.client.SSHClient() - ssh_minions = ssh._prep_ssh(**load).targets.keys() - if ssh_minions: - minions.extend(ssh_minions) - threading.Thread(target=ssh.cmd, kwargs=load).start() - return minions + if self.opts['enable_ssh_minions'] is True and ssh_minions is True: + log.debug('Send payload to ssh minions') + threading.Thread(target=self.ssh_client.cmd, kwargs=load).start() def _prep_pub(self, minions, jid, clear_load, extra, missing): ''' diff --git a/salt/minion.py b/salt/minion.py index f79dd38f9c..514519f6c1 100644 --- a/salt/minion.py +++ b/salt/minion.py @@ -31,23 +31,11 @@ if six.PY3: else: import salt.ext.ipaddress as ipaddress from salt.ext.six.moves import range +from salt.utils.zeromq import zmq, ZMQDefaultLoop, install_zmq, ZMQ_VERSION_INFO + # pylint: enable=no-name-in-module,redefined-builtin # Import third party libs -try: - import zmq - # TODO: cleanup - import zmq.eventloop.ioloop - # support pyzmq 13.0.x, TODO: remove once we force people to 14.0.x - if not hasattr(zmq.eventloop.ioloop, 'ZMQIOLoop'): - zmq.eventloop.ioloop.ZMQIOLoop = zmq.eventloop.ioloop.IOLoop - LOOP_CLASS = zmq.eventloop.ioloop.ZMQIOLoop - HAS_ZMQ = True -except ImportError: - import tornado.ioloop - LOOP_CLASS = tornado.ioloop.IOLoop - HAS_ZMQ = False - HAS_RANGE = False try: import seco.range @@ -690,7 +678,7 @@ class MinionBase(object): if self.opts['transport'] == 'detect': self.opts['detect_mode'] = True for trans in ('zeromq', 'tcp'): - if trans == 'zeromq' and not HAS_ZMQ: + if trans == 'zeromq' and not zmq: continue self.opts['transport'] = trans pub_channel = salt.transport.client.AsyncPubChannel.factory(self.opts, **factory_kwargs) @@ -793,10 +781,8 @@ class SMinion(MinionBase): # Clean out the proc directory (default /var/cache/salt/minion/proc) if (self.opts.get('file_client', 'remote') == 'remote' or self.opts.get('use_master_when_local', False)): - if self.opts['transport'] == 'zeromq' and HAS_ZMQ: - io_loop = zmq.eventloop.ioloop.ZMQIOLoop() - else: - io_loop = LOOP_CLASS.current() + install_zmq() + io_loop = ZMQDefaultLoop.current() io_loop.run_sync( lambda: self.eval_master(self.opts, failed=True) ) @@ -931,9 +917,8 @@ class MinionManager(MinionBase): self.minions = [] self.jid_queue = [] - if HAS_ZMQ: - zmq.eventloop.ioloop.install() - self.io_loop = LOOP_CLASS.current() + install_zmq() + self.io_loop = ZMQDefaultLoop.current() self.process_manager = ProcessManager(name='MultiMinionProcessManager') self.io_loop.spawn_callback(self.process_manager.run, async=True) @@ -1086,23 +1071,14 @@ class Minion(MinionBase): self.periodic_callbacks = {} if io_loop is None: - if HAS_ZMQ: - zmq.eventloop.ioloop.install() - self.io_loop = LOOP_CLASS.current() + install_zmq() + self.io_loop = ZMQDefaultLoop.current() else: self.io_loop = io_loop # Warn if ZMQ < 3.2 - if HAS_ZMQ: - try: - zmq_version_info = zmq.zmq_version_info() - except AttributeError: - # PyZMQ <= 2.1.9 does not have zmq_version_info, fall back to - # using zmq.zmq_version() and build a version info tuple. - zmq_version_info = tuple( - [int(x) for x in zmq.zmq_version().split('.')] # pylint: disable=no-member - ) - if zmq_version_info < (3, 2): + if zmq: + if ZMQ_VERSION_INFO < (3, 2): log.warning( 'You have a version of ZMQ less than ZMQ 3.2! There are ' 'known connection keep-alive issues with ZMQ < 3.2 which ' @@ -2161,6 +2137,8 @@ class Minion(MinionBase): self.schedule.disable_job(name, persist) elif func == 'postpone_job': self.schedule.postpone_job(name, data) + elif func == 'skip_job': + self.schedule.skip_job(name, data) elif func == 'reload': self.schedule.reload(schedule) elif func == 'list': @@ -2889,9 +2867,8 @@ class SyndicManager(MinionBase): self.jid_forward_cache = set() if io_loop is None: - if HAS_ZMQ: - zmq.eventloop.ioloop.install() - self.io_loop = LOOP_CLASS.current() + install_zmq() + self.io_loop = ZMQDefaultLoop.current() else: self.io_loop = io_loop diff --git a/salt/modules/aix_shadow.py b/salt/modules/aix_shadow.py index 9015c76c2d..dd6e9c9d4c 100644 --- a/salt/modules/aix_shadow.py +++ b/salt/modules/aix_shadow.py @@ -2,7 +2,7 @@ ''' Manage account locks on AIX systems -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: none ''' diff --git a/salt/modules/aptly.py b/salt/modules/aptly.py index 053cdef911..725c096a21 100644 --- a/salt/modules/aptly.py +++ b/salt/modules/aptly.py @@ -2,7 +2,7 @@ ''' Aptly Debian repository manager. -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' # Import python libs from __future__ import absolute_import, print_function, unicode_literals diff --git a/salt/modules/aptpkg.py b/salt/modules/aptpkg.py index 38bda9c922..af07a81638 100644 --- a/salt/modules/aptpkg.py +++ b/salt/modules/aptpkg.py @@ -497,7 +497,7 @@ def install(name=None, Install a specific version of the package, e.g. 1.2.3~0ubuntu0. Ignored if "pkgs" or "sources" is passed. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 version can now contain comparison operators (e.g. ``>1.2.3``, ``<=2.0``, etc.) @@ -518,7 +518,7 @@ def install(name=None, ignored when comparing the currently-installed version to the desired version. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Multiple Package Installation Options: @@ -1086,7 +1086,7 @@ def upgrade(refresh=True, dist_upgrade=False, **kwargs): download_only Only donwload the packages, don't unpack or install them - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 force_conf_new Always install the new version of any configuration files. @@ -2160,7 +2160,7 @@ def mod_repo(repo, saltenv='base', **kwargs): key_text GPG key in string form to add to the APT GPG keyring - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 consolidate : False If ``True``, will attempt to de-duplicate and consolidate sources diff --git a/salt/modules/archive.py b/salt/modules/archive.py index 6c741ef2ea..f9750b938d 100644 --- a/salt/modules/archive.py +++ b/salt/modules/archive.py @@ -157,7 +157,7 @@ def list_(name, re-downloading the archive if the cached copy matches the specified hash. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. _tarfile: https://docs.python.org/2/library/tarfile.html .. _xz: http://tukaani.org/xz/ @@ -1135,7 +1135,7 @@ def is_encrypted(name, clean=False, saltenv='base', source_hash=None): re-downloading the archive if the cached copy matches the specified hash. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Examples: diff --git a/salt/modules/azurearm_compute.py b/salt/modules/azurearm_compute.py new file mode 100644 index 0000000000..6251354a20 --- /dev/null +++ b/salt/modules/azurearm_compute.py @@ -0,0 +1,714 @@ +# -*- coding: utf-8 -*- +''' +Azure (ARM) Compute Execution Module + +.. versionadded:: Fluorine + +:maintainer: +:maturity: new +:depends: + * `azure `_ >= 2.0.0 + * `azure-common `_ >= 1.1.8 + * `azure-mgmt `_ >= 1.0.0 + * `azure-mgmt-compute `_ >= 1.0.0 + * `azure-mgmt-network `_ >= 1.7.1 + * `azure-mgmt-resource `_ >= 1.1.0 + * `azure-mgmt-storage `_ >= 1.0.0 + * `azure-mgmt-web `_ >= 0.32.0 + * `azure-storage `_ >= 0.34.3 + * `msrestazure `_ >= 0.4.21 +:platform: linux + +:configuration: This module requires Azure Resource Manager credentials to be passed as keyword arguments +to every function in order to work properly. + + Required provider parameters: + + if using username and password: + * ``subscription_id`` + * ``username`` + * ``password`` + + if using a service principal: + * ``subscription_id`` + * ``tenant`` + * ``client_id`` + * ``secret`` + + Optional provider parameters: + + **cloud_environment**: Used to point the cloud driver to different API endpoints, such as Azure GovCloud. + Possible values: + * ``AZURE_PUBLIC_CLOUD`` (default) + * ``AZURE_CHINA_CLOUD`` + * ``AZURE_US_GOV_CLOUD`` + * ``AZURE_GERMAN_CLOUD`` + +''' + +# Python libs +from __future__ import absolute_import +import logging + +# Azure libs +HAS_LIBS = False +try: + import azure.mgmt.compute.models # pylint: disable=unused-import + from msrest.exceptions import SerializationError + from msrestazure.azure_exceptions import CloudError + HAS_LIBS = True +except ImportError: + pass + +__virtualname__ = 'azurearm_compute' + +log = logging.getLogger(__name__) + + +def __virtual__(): + if not HAS_LIBS: + return ( + False, + 'The following dependencies are required to use the AzureARM modules: ' + 'Microsoft Azure SDK for Python >= 2.0rc6, ' + 'MS REST Azure (msrestazure) >= 0.4' + ) + + return __virtualname__ + + +def availability_set_create_or_update(name, resource_group, **kwargs): # pylint: disable=invalid-name + ''' + .. versionadded:: Fluorine + + Create or update an availability set. + + :param name: The availability set to create. + + :param resource_group: The resource group name assigned to the + availability set. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.availability_set_create_or_update testset testgroup + + ''' + if 'location' not in kwargs: + rg_props = __salt__['azurearm_resource.resource_group_get']( + resource_group, **kwargs + ) + + if 'error' in rg_props: + log.error( + 'Unable to determine location from resource group specified.' + ) + return False + kwargs['location'] = rg_props['location'] + + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + + # Use VM names to link to the IDs of existing VMs. + if isinstance(kwargs.get('virtual_machines'), list): + vm_list = [] + for vm_name in kwargs.get('virtual_machines'): + vm_instance = __salt__['azurearm_compute.virtual_machine_get']( + name=vm_name, + resource_group=resource_group, + **kwargs + ) + if 'error' not in vm_instance: + vm_list.append({'id': str(vm_instance['id'])}) + kwargs['virtual_machines'] = vm_list + + try: + setmodel = __utils__['azurearm.create_object_model']('compute', 'AvailabilitySet', **kwargs) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({1})'.format(str(exc))} + return result + + try: + av_set = compconn.availability_sets.create_or_update( + resource_group_name=resource_group, + availability_set_name=name, + parameters=setmodel + ) + result = av_set.as_dict() + + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def availability_set_delete(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete an availability set. + + :param name: The availability set to delete. + + :param resource_group: The resource group name assigned to the + availability set. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.availability_set_delete testset testgroup + + ''' + result = False + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + compconn.availability_sets.delete( + resource_group_name=resource_group, + availability_set_name=name + ) + result = True + + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + + return result + + +def availability_set_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get a dictionary representing an availability set's properties. + + :param name: The availability set to get. + + :param resource_group: The resource group name assigned to the + availability set. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.availability_set_get testset testgroup + + ''' + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + av_set = compconn.availability_sets.get( + resource_group_name=resource_group, + availability_set_name=name + ) + result = av_set.as_dict() + + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def availability_sets_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all availability sets within a resource group. + + :param resource_group: The resource group name to list availability + sets within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.availability_sets_list testgroup + + ''' + result = {} + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + avail_sets = __utils__['azurearm.paged_object_to_list']( + compconn.availability_sets.list( + resource_group_name=resource_group + ) + ) + + for avail_set in avail_sets: + result[avail_set['name']] = avail_set + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def availability_sets_list_available_sizes(name, resource_group, **kwargs): # pylint: disable=invalid-name + ''' + .. versionadded:: Fluorine + + List all available virtual machine sizes that can be used to + to create a new virtual machine in an existing availability set. + + :param name: The availability set name to list available + virtual machine sizes within. + + :param resource_group: The resource group name to list available + availability set sizes within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.availability_sets_list_available_sizes testset testgroup + + ''' + result = {} + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + sizes = __utils__['azurearm.paged_object_to_list']( + compconn.availability_sets.list_available_sizes( + resource_group_name=resource_group, + availability_set_name=name + ) + ) + + for size in sizes: + result[size['name']] = size + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machine_capture(name, destination_name, resource_group, prefix='capture-', overwrite=False, **kwargs): + ''' + .. versionadded:: Fluorine + + Captures the VM by copying virtual hard disks of the VM and outputs + a template that can be used to create similar VMs. + + :param name: The name of the virtual machine. + + :param destination_name: The destination container name. + + :param resource_group: The resource group name assigned to the + virtual machine. + + :param prefix: (Default: 'capture-') The captured virtual hard disk's name prefix. + + :param overwrite: (Default: False) Overwrite the destination disk in case of conflict. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machine_capture testvm testcontainer testgroup + + ''' + # pylint: disable=invalid-name + VirtualMachineCaptureParameters = getattr( + azure.mgmt.compute.models, 'VirtualMachineCaptureParameters' + ) + + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + # pylint: disable=invalid-name + vm = compconn.virtual_machines.capture( + resource_group_name=resource_group, + vm_name=name, + parameters=VirtualMachineCaptureParameters( + vhd_prefix=prefix, + destination_container_name=destination_name, + overwrite_vhds=overwrite + ) + ) + vm.wait() + vm_result = vm.result() + result = vm_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machine_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Retrieves information about the model view or the instance view of a + virtual machine. + + :param name: The name of the virtual machine. + + :param resource_group: The resource group name assigned to the + virtual machine. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machine_get testvm testgroup + + ''' + expand = kwargs.get('expand') + + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + # pylint: disable=invalid-name + vm = compconn.virtual_machines.get( + resource_group_name=resource_group, + vm_name=name, + expand=expand + ) + result = vm.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machine_convert_to_managed_disks(name, resource_group, **kwargs): # pylint: disable=invalid-name + ''' + .. versionadded:: Fluorine + + Converts virtual machine disks from blob-based to managed disks. Virtual + machine must be stop-deallocated before invoking this operation. + + :param name: The name of the virtual machine to convert. + + :param resource_group: The resource group name assigned to the + virtual machine. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machine_convert_to_managed_disks testvm testgroup + + ''' + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + # pylint: disable=invalid-name + vm = compconn.virtual_machines.convert_to_managed_disks( + resource_group_name=resource_group, + vm_name=name + ) + vm.wait() + vm_result = vm.result() + result = vm_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machine_deallocate(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Power off a virtual machine and deallocate compute resources. + + :param name: The name of the virtual machine to deallocate. + + :param resource_group: The resource group name assigned to the + virtual machine. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machine_deallocate testvm testgroup + + ''' + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + # pylint: disable=invalid-name + vm = compconn.virtual_machines.deallocate( + resource_group_name=resource_group, + vm_name=name + ) + vm.wait() + vm_result = vm.result() + result = vm_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machine_generalize(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Set the state of a virtual machine to 'generalized'. + + :param name: The name of the virtual machine. + + :param resource_group: The resource group name assigned to the + virtual machine. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machine_generalize testvm testgroup + + ''' + result = False + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + compconn.virtual_machines.generalize( + resource_group_name=resource_group, + vm_name=name + ) + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + + return result + + +def virtual_machines_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all virtual machines within a resource group. + + :param resource_group: The resource group name to list virtual + machines within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machines_list testgroup + + ''' + result = {} + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + vms = __utils__['azurearm.paged_object_to_list']( + compconn.virtual_machines.list( + resource_group_name=resource_group + ) + ) + for vm in vms: # pylint: disable=invalid-name + result[vm['name']] = vm + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machines_list_all(**kwargs): + ''' + .. versionadded:: Fluorine + + List all virtual machines within a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machines_list_all + + ''' + result = {} + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + vms = __utils__['azurearm.paged_object_to_list']( + compconn.virtual_machines.list_all() + ) + for vm in vms: # pylint: disable=invalid-name + result[vm['name']] = vm + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machines_list_available_sizes(name, resource_group, **kwargs): # pylint: disable=invalid-name + ''' + .. versionadded:: Fluorine + + Lists all available virtual machine sizes to which the specified virtual + machine can be resized. + + :param name: The name of the virtual machine. + + :param resource_group: The resource group name assigned to the + virtual machine. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machines_list_available_sizes testvm testgroup + + ''' + result = {} + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + sizes = __utils__['azurearm.paged_object_to_list']( + compconn.virtual_machines.list_available_sizes( + resource_group_name=resource_group, + vm_name=name + ) + ) + for size in sizes: + result[size['name']] = size + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machine_power_off(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Power off (stop) a virtual machine. + + :param name: The name of the virtual machine to stop. + + :param resource_group: The resource group name assigned to the + virtual machine. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machine_power_off testvm testgroup + + ''' + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + # pylint: disable=invalid-name + vm = compconn.virtual_machines.power_off( + resource_group_name=resource_group, + vm_name=name + ) + vm.wait() + vm_result = vm.result() + result = vm_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machine_restart(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Restart a virtual machine. + + :param name: The name of the virtual machine to restart. + + :param resource_group: The resource group name assigned to the + virtual machine. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machine_restart testvm testgroup + + ''' + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + # pylint: disable=invalid-name + vm = compconn.virtual_machines.restart( + resource_group_name=resource_group, + vm_name=name + ) + vm.wait() + vm_result = vm.result() + result = vm_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machine_start(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Power on (start) a virtual machine. + + :param name: The name of the virtual machine to start. + + :param resource_group: The resource group name assigned to the + virtual machine. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machine_start testvm testgroup + + ''' + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + # pylint: disable=invalid-name + vm = compconn.virtual_machines.start( + resource_group_name=resource_group, + vm_name=name + ) + vm.wait() + vm_result = vm.result() + result = vm_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_machine_redeploy(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Redeploy a virtual machine. + + :param name: The name of the virtual machine to redeploy. + + :param resource_group: The resource group name assigned to the + virtual machine. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_compute.virtual_machine_redeploy testvm testgroup + + ''' + compconn = __utils__['azurearm.get_client']('compute', **kwargs) + try: + # pylint: disable=invalid-name + vm = compconn.virtual_machines.redeploy( + resource_group_name=resource_group, + vm_name=name + ) + vm.wait() + vm_result = vm.result() + result = vm_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('compute', str(exc), **kwargs) + result = {'error': str(exc)} + + return result diff --git a/salt/modules/azurearm_network.py b/salt/modules/azurearm_network.py new file mode 100644 index 0000000000..93056cf826 --- /dev/null +++ b/salt/modules/azurearm_network.py @@ -0,0 +1,2751 @@ +# -*- coding: utf-8 -*- +''' +Azure (ARM) Network Execution Module + +.. versionadded:: Fluorine + +:maintainer: +:maturity: new +:depends: + * `azure `_ >= 2.0.0 + * `azure-common `_ >= 1.1.8 + * `azure-mgmt `_ >= 1.0.0 + * `azure-mgmt-compute `_ >= 1.0.0 + * `azure-mgmt-network `_ >= 1.7.1 + * `azure-mgmt-resource `_ >= 1.1.0 + * `azure-mgmt-storage `_ >= 1.0.0 + * `azure-mgmt-web `_ >= 0.32.0 + * `azure-storage `_ >= 0.34.3 + * `msrestazure `_ >= 0.4.21 +:platform: linux + +:configuration: This module requires Azure Resource Manager credentials to be passed as keyword arguments +to every function in order to work properly. + + Required provider parameters: + + if using username and password: + * ``subscription_id`` + * ``username`` + * ``password`` + + if using a service principal: + * ``subscription_id`` + * ``tenant`` + * ``client_id`` + * ``secret`` + + Optional provider parameters: + + **cloud_environment**: Used to point the cloud driver to different API endpoints, such as Azure GovCloud. + Possible values: + * ``AZURE_PUBLIC_CLOUD`` (default) + * ``AZURE_CHINA_CLOUD`` + * ``AZURE_US_GOV_CLOUD`` + * ``AZURE_GERMAN_CLOUD`` + +''' + +# Python libs +from __future__ import absolute_import +import logging + +# Salt libs +from salt.exceptions import SaltInvocationError # pylint: disable=unused-import +try: + from salt.ext.six.moves import range as six_range +except ImportError: + six_range = range + +# Azure libs +HAS_LIBS = False +try: + import azure.mgmt.network.models # pylint: disable=unused-import + from msrest.exceptions import SerializationError + from msrestazure.azure_exceptions import CloudError + HAS_LIBS = True +except ImportError: + pass + +__virtualname__ = 'azurearm_network' + +log = logging.getLogger(__name__) + + +def __virtual__(): + if not HAS_LIBS: + return ( + False, + 'The following dependencies are required to use the AzureARM modules: ' + 'Microsoft Azure SDK for Python >= 2.0rc6, ' + 'MS REST Azure (msrestazure) >= 0.4' + ) + + return __virtualname__ + + +def check_dns_name_availability(name, region, **kwargs): + ''' + .. versionadded:: Fluorine + + Check whether a domain name in the current zone is available for use. + + :param name: The DNS name to query. + + :param region: The region to query for the DNS name in question. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.check_dns_name_availability testdnsname westus + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + check_dns_name = netconn.check_dns_name_availability( + location=region, + domain_name_label=name + ) + result = check_dns_name.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def check_ip_address_availability(ip_address, virtual_network, resource_group, + **kwargs): + ''' + .. versionadded:: Fluorine + + Check that a private ip address is available within the specified + virtual network. + + :param ip_address: The ip_address to query. + + :param virtual_network: The virtual network to query for the IP address + in question. + + :param resource_group: The resource group name assigned to the + virtual network. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.check_ip_address_availability 10.0.0.4 testnet testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + check_ip = netconn.virtual_networks.check_ip_address_availability( + resource_group_name=resource_group, + virtual_network_name=virtual_network, + ip_address=ip_address) + result = check_ip.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def default_security_rule_get(name, security_group, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a default security rule within a security group. + + :param name: The name of the security rule to query. + + :param security_group: The network security group containing the + security rule. + + :param resource_group: The resource group name assigned to the + network security group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.default_security_rule_get DenyAllOutBound testnsg testgroup + + ''' + result = {} + + default_rules = default_security_rules_list( + security_group=security_group, + resource_group=resource_group, + **kwargs + ) + + if isinstance(default_rules, dict) and 'error' in default_rules: + return default_rules + + try: + for default_rule in default_rules: + if default_rule['name'] == name: + result = default_rule + if not result: + result = { + 'error': 'Unable to find {0} in {1}!'.format(name, security_group) + } + except KeyError as exc: + log.error( + 'Unable to find {0} in {1}!'.format(name, security_group) + ) + result = {'error': str(exc)} + + return result + + +def default_security_rules_list(security_group, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List default security rules within a security group. + + :param security_group: The network security group to query. + + :param resource_group: The resource group name assigned to the + network security group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.default_security_rules_list testnsg testgroup + + ''' + result = {} + + secgroup = network_security_group_get( + security_group=security_group, + resource_group=resource_group, + **kwargs + ) + + if 'error' in secgroup: + return secgroup + + try: + result = secgroup['default_security_rules'] + except KeyError as exc: + log.error( + 'No default security rules found for {0}!'.format(security_group) + ) + result = {'error': str(exc)} + + return result + + +def security_rules_list(security_group, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List security rules within a network security group. + + :param security_group: The network security group to query. + + :param resource_group: The resource group name assigned to the + network security group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.security_rules_list testnsg testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + secrules = netconn.security_rules.list( + network_security_group_name=security_group, + resource_group_name=resource_group + ) + result = __utils__['azurearm.paged_object_to_list'](secrules) + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def security_rule_create_or_update(name, access, direction, priority, protocol, security_group, resource_group, + source_address_prefix=None, destination_address_prefix=None, source_port_range=None, + destination_port_range=None, source_address_prefixes=None, + destination_address_prefixes=None, source_port_ranges=None, + destination_port_ranges=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a security rule within a specified network security group. + + :param name: The name of the security rule to create. + + :param access: + 'allow' or 'deny' + + :param direction: + 'inbound' or 'outbound' + + :param priority: + Integer between 100 and 4096 used for ordering rule application. + + :param protocol: + 'tcp', 'udp', or '*' + + :param destination_address_prefix: + The CIDR or destination IP range. Asterix '*' can also be used to match all destination IPs. + Default tags such as 'VirtualNetwork', 'AzureLoadBalancer' and 'Internet' can also be used. + If this is an ingress rule, specifies where network traffic originates from. + + :param destination_port_range: + The destination port or range. Integer or range between 0 and 65535. Asterix '*' + can also be used to match all ports. + + :param source_address_prefix: + The CIDR or source IP range. Asterix '*' can also be used to match all source IPs. + Default tags such as 'VirtualNetwork', 'AzureLoadBalancer' and 'Internet' can also be used. + If this is an ingress rule, specifies where network traffic originates from. + + :param source_port_range: + The source port or range. Integer or range between 0 and 65535. Asterix '*' + can also be used to match all ports. + + :param destination_address_prefixes: + A list of destination_address_prefix values. This parameter overrides destination_address_prefix + and will cause any value entered there to be ignored. + + :param destination_port_ranges: + A list of destination_port_range values. This parameter overrides destination_port_range + and will cause any value entered there to be ignored. + + :param source_address_prefixes: + A list of source_address_prefix values. This parameter overrides source_address_prefix + and will cause any value entered there to be ignored. + + :param source_port_ranges: + A list of source_port_range values. This parameter overrides source_port_range + and will cause any value entered there to be ignored. + + :param security_group: The network security group containing the + security rule. + + :param resource_group: The resource group name assigned to the + network security group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.security_rule_create_or_update testrule1 allow outbound 101 tcp testnsg testgroup \ + source_address_prefix='*' destination_address_prefix=internet source_port_range='*' \ + destination_port_range='1-1024' + + ''' + exclusive_params = [ + ('source_port_ranges', 'source_port_range'), + ('source_address_prefixes', 'source_address_prefix'), + ('destination_port_ranges', 'destination_port_range'), + ('destination_address_prefixes', 'destination_address_prefix'), + ] + + for params in exclusive_params: + # pylint: disable=eval-used + if not eval(params[0]) and not eval(params[1]): + log.error( + 'Either the {0} or {1} parameter must be provided!'.format(params[0], params[1]) + ) + return False + # pylint: disable=eval-used + if eval(params[0]): + # pylint: disable=exec-used + exec('{0} = None'.format(params[1])) + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + rulemodel = __utils__['azurearm.create_object_model']( + 'network', + 'SecurityRule', + name=name, + access=access, + direction=direction, + priority=priority, + protocol=protocol, + source_port_ranges=source_port_ranges, + source_port_range=source_port_range, + source_address_prefixes=source_address_prefixes, + source_address_prefix=source_address_prefix, + destination_port_ranges=destination_port_ranges, + destination_port_range=destination_port_range, + destination_address_prefixes=destination_address_prefixes, + destination_address_prefix=destination_address_prefix, + **kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + secrule = netconn.security_rules.create_or_update( + resource_group_name=resource_group, + network_security_group_name=security_group, + security_rule_name=name, + security_rule_parameters=rulemodel + ) + secrule.wait() + secrule_result = secrule.result() + result = secrule_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def security_rule_delete(security_rule, security_group, resource_group, + **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a security rule within a specified security group. + + :param name: The name of the security rule to delete. + + :param security_group: The network security group containing the + security rule. + + :param resource_group: The resource group name assigned to the + network security group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.security_rule_delete testrule1 testnsg testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + secrule = netconn.security_rules.delete( + network_security_group_name=security_group, + resource_group_name=resource_group, + security_rule_name=security_rule + ) + secrule.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def security_rule_get(security_rule, security_group, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get a security rule within a specified network security group. + + :param name: The name of the security rule to query. + + :param security_group: The network security group containing the + security rule. + + :param resource_group: The resource group name assigned to the + network security group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.security_rule_get testrule1 testnsg testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + secrule = netconn.security_rules.get( + network_security_group_name=security_group, + resource_group_name=resource_group, + security_rule_name=security_rule + ) + result = secrule.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def network_security_group_create_or_update(name, resource_group, **kwargs): # pylint: disable=invalid-name + ''' + .. versionadded:: Fluorine + + Create or update a network security group. + + :param name: The name of the network security group to create. + + :param resource_group: The resource group name assigned to the + network security group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_security_group_create_or_update testnsg testgroup + + ''' + if 'location' not in kwargs: + rg_props = __salt__['azurearm_resource.resource_group_get']( + resource_group, **kwargs + ) + + if 'error' in rg_props: + log.error( + 'Unable to determine location from resource group specified.' + ) + return False + kwargs['location'] = rg_props['location'] + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + secgroupmodel = __utils__['azurearm.create_object_model']('network', 'NetworkSecurityGroup', **kwargs) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + secgroup = netconn.network_security_groups.create_or_update( + resource_group_name=resource_group, + network_security_group_name=name, + parameters=secgroupmodel + ) + secgroup.wait() + secgroup_result = secgroup.result() + result = secgroup_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def network_security_group_delete(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a network security group within a resource group. + + :param name: The name of the network security group to delete. + + :param resource_group: The resource group name assigned to the + network security group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_security_group_delete testnsg testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + secgroup = netconn.network_security_groups.delete( + resource_group_name=resource_group, + network_security_group_name=name + ) + secgroup.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def network_security_group_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a network security group within a resource group. + + :param name: The name of the network security group to query. + + :param resource_group: The resource group name assigned to the + network security group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_security_group_get testnsg testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + secgroup = netconn.network_security_groups.get( + resource_group_name=resource_group, + network_security_group_name=name + ) + result = secgroup.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def network_security_groups_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all network security groups within a resource group. + + :param resource_group: The resource group name to list network security \ + groups within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_security_groups_list testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + secgroups = __utils__['azurearm.paged_object_to_list']( + netconn.network_security_groups.list( + resource_group_name=resource_group + ) + ) + for secgroup in secgroups: + result[secgroup['name']] = secgroup + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def network_security_groups_list_all(**kwargs): # pylint: disable=invalid-name + ''' + .. versionadded:: Fluorine + + List all network security groups within a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_security_groups_list_all + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + secgroups = __utils__['azurearm.paged_object_to_list']( + netconn.network_security_groups.list_all() + ) + for secgroup in secgroups: + result[secgroup['name']] = secgroup + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def subnets_list(virtual_network, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all subnets within a virtual network. + + :param virtual_network: The virtual network name to list subnets within. + + :param resource_group: The resource group name assigned to the + virtual network. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.subnets_list testnet testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + subnets = __utils__['azurearm.paged_object_to_list']( + netconn.subnets.list( + resource_group_name=resource_group, + virtual_network_name=virtual_network + ) + ) + + for subnet in subnets: + result[subnet['name']] = subnet + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def subnet_get(name, virtual_network, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific subnet. + + :param name: The name of the subnet to query. + + :param virtual_network: The virtual network name containing the + subnet. + + :param resource_group: The resource group name assigned to the + virtual network. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.subnet_get testsubnet testnet testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + subnet = netconn.subnets.get( + resource_group_name=resource_group, + virtual_network_name=virtual_network, + subnet_name=name + ) + + result = subnet.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def subnet_create_or_update(name, address_prefix, virtual_network, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a subnet. + + :param name: The name assigned to the subnet being created or updated. + + :param address_prefix: A valid CIDR block within the virtual network. + + :param virtual_network: The virtual network name containing the + subnet. + + :param resource_group: The resource group name assigned to the + virtual network. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.subnet_create_or_update testsubnet \ + '10.0.0.0/24' testnet testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + # Use NSG name to link to the ID of an existing NSG. + if kwargs.get('network_security_group'): + nsg = network_security_group_get( + name=kwargs['network_security_group'], + resource_group=resource_group, + **kwargs + ) + if 'error' not in nsg: + kwargs['network_security_group'] = {'id': str(nsg['id'])} + + # Use Route Table name to link to the ID of an existing Route Table. + if kwargs.get('route_table'): + rt_table = route_table_get( + name=kwargs['route_table'], + resource_group=resource_group, + **kwargs + ) + if 'error' not in rt_table: + kwargs['route_table'] = {'id': str(rt_table['id'])} + + try: + snetmodel = __utils__['azurearm.create_object_model']( + 'network', + 'Subnet', + address_prefix=address_prefix, + resource_group=resource_group, + **kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + subnet = netconn.subnets.create_or_update( + resource_group_name=resource_group, + virtual_network_name=virtual_network, + subnet_name=name, + subnet_parameters=snetmodel, + ) + subnet.wait() + sn_result = subnet.result() + result = sn_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def subnet_delete(name, virtual_network, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a subnet. + + :param name: The name of the subnet to delete. + + :param virtual_network: The virtual network name containing the + subnet. + + :param resource_group: The resource group name assigned to the + virtual network. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.subnet_delete testsubnet testnet testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + subnet = netconn.subnets.delete( + resource_group_name=resource_group, + virtual_network_name=virtual_network, + subnet_name=name + ) + subnet.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def virtual_networks_list_all(**kwargs): + ''' + .. versionadded:: Fluorine + + List all virtual networks within a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.virtual_networks_list_all + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + vnets = __utils__['azurearm.paged_object_to_list'](netconn.virtual_networks.list_all()) + + for vnet in vnets: + result[vnet['name']] = vnet + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def virtual_networks_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all virtual networks within a resource group. + + :param resource_group: The resource group name to list virtual networks + within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.virtual_networks_list testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + vnets = __utils__['azurearm.paged_object_to_list']( + netconn.virtual_networks.list( + resource_group_name=resource_group + ) + ) + + for vnet in vnets: + result[vnet['name']] = vnet + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +# pylint: disable=invalid-name +def virtual_network_create_or_update(name, + address_prefixes, + resource_group, + **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a virtual network. + + :param name: The name assigned to the virtual network being + created or updated. + + :param address_prefixes: A list of CIDR blocks which can be used + by subnets within the virtual network. + + :param resource_group: The resource group name assigned to the + virtual network. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.virtual_network_create_or_update \ + testnet ['10.0.0.0/16'] testgroup + + ''' + if 'location' not in kwargs: + rg_props = __salt__['azurearm_resource.resource_group_get']( + resource_group, **kwargs + ) + + if 'error' in rg_props: + log.error( + 'Unable to determine location from resource group specified.' + ) + return False + kwargs['location'] = rg_props['location'] + + if not isinstance(address_prefixes, list): + log.error( + 'Address prefixes must be specified as a list!' + ) + return False + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + address_space = {'address_prefixes': address_prefixes} + dhcp_options = {'dns_servers': kwargs.get('dns_servers')} + + try: + vnetmodel = __utils__['azurearm.create_object_model']( + 'network', + 'VirtualNetwork', + address_space=address_space, + dhcp_options=dhcp_options, + **kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + vnet = netconn.virtual_networks.create_or_update( + virtual_network_name=name, + resource_group_name=resource_group, + parameters=vnetmodel + ) + vnet.wait() + vnet_result = vnet.result() + result = vnet_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def virtual_network_delete(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a virtual network. + + :param name: The name of the virtual network to delete. + + :param resource_group: The resource group name assigned to the + virtual network + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.virtual_network_delete testnet testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + vnet = netconn.virtual_networks.delete( + virtual_network_name=name, + resource_group_name=resource_group + ) + vnet.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def virtual_network_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific virtual network. + + :param name: The name of the virtual network to query. + + :param resource_group: The resource group name assigned to the + virtual network. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.virtual_network_get testnet testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + vnet = netconn.virtual_networks.get( + virtual_network_name=name, + resource_group_name=resource_group + ) + result = vnet.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def load_balancers_list_all(**kwargs): + ''' + .. versionadded:: Fluorine + + List all load balancers within a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.load_balancers_list_all + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + load_balancers = __utils__['azurearm.paged_object_to_list'](netconn.load_balancers.list_all()) + + for load_balancer in load_balancers: + result[load_balancer['name']] = load_balancer + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def load_balancers_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all load balancers within a resource group. + + :param resource_group: The resource group name to list load balancers + within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.load_balancers_list testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + load_balancers = __utils__['azurearm.paged_object_to_list']( + netconn.load_balancers.list( + resource_group_name=resource_group + ) + ) + + for load_balancer in load_balancers: + result[load_balancer['name']] = load_balancer + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def load_balancer_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific load balancer. + + :param name: The name of the load balancer to query. + + :param resource_group: The resource group name assigned to the + load balancer. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.load_balancer_get testlb testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + load_balancer = netconn.load_balancers.get( + load_balancer_name=name, + resource_group_name=resource_group + ) + result = load_balancer.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def load_balancer_create_or_update(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a load balancer within a specified resource group. + + :param name: The name of the load balancer to create. + + :param resource_group: The resource group name assigned to the + load balancer. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.load_balancer_create_or_update testlb testgroup + + ''' + if 'location' not in kwargs: + rg_props = __salt__['azurearm_resource.resource_group_get']( + resource_group, **kwargs + ) + + if 'error' in rg_props: + log.error( + 'Unable to determine location from resource group specified.' + ) + return False + kwargs['location'] = rg_props['location'] + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + if isinstance(kwargs.get('frontend_ip_configurations'), list): + for idx in six_range(0, len(kwargs['frontend_ip_configurations'])): + # Use Public IP Address name to link to the ID of an existing Public IP + if 'public_ip_address' in kwargs['frontend_ip_configurations'][idx]: + pub_ip = public_ip_address_get( + name=kwargs['frontend_ip_configurations'][idx]['public_ip_address'], + resource_group=resource_group, + **kwargs + ) + if 'error' not in pub_ip: + kwargs['frontend_ip_configurations'][idx]['public_ip_address'] = {'id': str(pub_ip['id'])} + # Use Subnet name to link to the ID of an existing Subnet + elif 'subnet' in kwargs['frontend_ip_configurations'][idx]: + vnets = virtual_networks_list( + resource_group=resource_group, + **kwargs + ) + if 'error' not in vnets: + for vnet in vnets: + subnets = subnets_list( + virtual_network=vnet, + resource_group=resource_group, + **kwargs + ) + if kwargs['frontend_ip_configurations'][idx]['subnet'] in subnets: + kwargs['frontend_ip_configurations'][idx]['subnet'] = { + 'id': str(subnets[kwargs['frontend_ip_configurations'][idx]['subnet']]['id']) + } + break + + id_url = '/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Network/loadBalancers/{2}/{3}/{4}' + + if isinstance(kwargs.get('load_balancing_rules'), list): + for idx in six_range(0, len(kwargs['load_balancing_rules'])): + # Link to sub-objects which might be created at the same time as the load balancer + if 'frontend_ip_configuration' in kwargs['load_balancing_rules'][idx]: + kwargs['load_balancing_rules'][idx]['frontend_ip_configuration'] = { + 'id': id_url.format( + kwargs.get('subscription_id'), + resource_group, + name, + 'frontendIPConfigurations', + kwargs['load_balancing_rules'][idx]['frontend_ip_configuration'] + ) + } + if 'backend_address_pool' in kwargs['load_balancing_rules'][idx]: + kwargs['load_balancing_rules'][idx]['backend_address_pool'] = { + 'id': id_url.format( + kwargs.get('subscription_id'), + resource_group, + name, + 'backendAddressPools', + kwargs['load_balancing_rules'][idx]['backend_address_pool'] + ) + } + if 'probe' in kwargs['load_balancing_rules'][idx]: + kwargs['load_balancing_rules'][idx]['probe'] = { + 'id': id_url.format( + kwargs.get('subscription_id'), + resource_group, + name, + 'probes', + kwargs['load_balancing_rules'][idx]['probe'] + ) + } + + if isinstance(kwargs.get('inbound_nat_rules'), list): + for idx in six_range(0, len(kwargs['inbound_nat_rules'])): + # Link to sub-objects which might be created at the same time as the load balancer + if 'frontend_ip_configuration' in kwargs['inbound_nat_rules'][idx]: + kwargs['inbound_nat_rules'][idx]['frontend_ip_configuration'] = { + 'id': id_url.format( + kwargs.get('subscription_id'), + resource_group, + name, + 'frontendIPConfigurations', + kwargs['inbound_nat_rules'][idx]['frontend_ip_configuration'] + ) + } + + if isinstance(kwargs.get('inbound_nat_pools'), list): + for idx in six_range(0, len(kwargs['inbound_nat_pools'])): + # Link to sub-objects which might be created at the same time as the load balancer + if 'frontend_ip_configuration' in kwargs['inbound_nat_pools'][idx]: + kwargs['inbound_nat_pools'][idx]['frontend_ip_configuration'] = { + 'id': id_url.format( + kwargs.get('subscription_id'), + resource_group, + name, + 'frontendIPConfigurations', + kwargs['inbound_nat_pools'][idx]['frontend_ip_configuration'] + ) + } + + if isinstance(kwargs.get('outbound_nat_rules'), list): + for idx in six_range(0, len(kwargs['outbound_nat_rules'])): + # Link to sub-objects which might be created at the same time as the load balancer + if 'frontend_ip_configuration' in kwargs['outbound_nat_rules'][idx]: + kwargs['outbound_nat_rules'][idx]['frontend_ip_configuration'] = { + 'id': id_url.format( + kwargs.get('subscription_id'), + resource_group, + name, + 'frontendIPConfigurations', + kwargs['outbound_nat_rules'][idx]['frontend_ip_configuration'] + ) + } + if 'backend_address_pool' in kwargs['outbound_nat_rules'][idx]: + kwargs['outbound_nat_rules'][idx]['backend_address_pool'] = { + 'id': id_url.format( + kwargs.get('subscription_id'), + resource_group, + name, + 'backendAddressPools', + kwargs['outbound_nat_rules'][idx]['backend_address_pool'] + ) + } + + try: + lbmodel = __utils__['azurearm.create_object_model']('network', 'LoadBalancer', **kwargs) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + load_balancer = netconn.load_balancers.create_or_update( + resource_group_name=resource_group, + load_balancer_name=name, + parameters=lbmodel + ) + load_balancer.wait() + lb_result = load_balancer.result() + result = lb_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def load_balancer_delete(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a load balancer. + + :param name: The name of the load balancer to delete. + + :param resource_group: The resource group name assigned to the + load balancer. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.load_balancer_delete testlb testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + load_balancer = netconn.load_balancers.delete( + load_balancer_name=name, + resource_group_name=resource_group + ) + load_balancer.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def usages_list(location, **kwargs): + ''' + .. versionadded:: Fluorine + + List subscription network usage for a location. + + :param location: The Azure location to query for network usage. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.usages_list westus + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + result = __utils__['azurearm.paged_object_to_list'](netconn.usages.list(location)) + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def network_interface_delete(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a network interface. + + :param name: The name of the network interface to delete. + + :param resource_group: The resource group name assigned to the + network interface. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_interface_delete test-iface0 testgroup + + ''' + result = False + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + nic = netconn.network_interfaces.delete( + network_interface_name=name, + resource_group_name=resource_group + ) + nic.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def network_interface_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific network interface. + + :param name: The name of the network interface to query. + + :param resource_group: The resource group name assigned to the + network interface. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_interface_get test-iface0 testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + nic = netconn.network_interfaces.get( + network_interface_name=name, + resource_group_name=resource_group + ) + result = nic.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +# pylint: disable=invalid-name +def network_interface_create_or_update(name, ip_configurations, subnet, virtual_network, + resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a network interface within a specified resource group. + + :param name: The name of the network interface to create. + + :param ip_configurations: A list of dictionaries representing valid + NetworkInterfaceIPConfiguration objects. The 'name' key is required at + minimum. At least one IP Configuration must be present. + + :param subnet: The name of the subnet assigned to the network interface. + + :param virtual_network: The name of the virtual network assigned to the subnet. + + :param resource_group: The resource group name assigned to the + virtual network. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_interface_create_or_update test-iface0 [{'name': 'testipconfig1'}] \ + testsubnet testnet testgroup + + ''' + if 'location' not in kwargs: + rg_props = __salt__['azurearm_resource.resource_group_get']( + resource_group, **kwargs + ) + + if 'error' in rg_props: + log.error( + 'Unable to determine location from resource group specified.' + ) + return False + kwargs['location'] = rg_props['location'] + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + # Use NSG name to link to the ID of an existing NSG. + if kwargs.get('network_security_group'): + nsg = network_security_group_get( + name=kwargs['network_security_group'], + resource_group=resource_group, + **kwargs + ) + if 'error' not in nsg: + kwargs['network_security_group'] = {'id': str(nsg['id'])} + + # Use VM name to link to the ID of an existing VM. + if kwargs.get('virtual_machine'): + vm_instance = __salt__['azurearm_compute.virtual_machine_get']( + name=kwargs['virtual_machine'], + resource_group=resource_group, + **kwargs + ) + if 'error' not in vm_instance: + kwargs['virtual_machine'] = {'id': str(vm_instance['id'])} + + # Loop through IP Configurations and build each dictionary to pass to model creation. + if isinstance(ip_configurations, list): + subnet = subnet_get( + name=subnet, + virtual_network=virtual_network, + resource_group=resource_group, + **kwargs + ) + if 'error' not in subnet: + subnet = {'id': str(subnet['id'])} + for ipconfig in ip_configurations: + if 'name' in ipconfig: + ipconfig['subnet'] = subnet + if isinstance(ipconfig.get('application_gateway_backend_address_pools'), list): + # TODO: Add ID lookup for referenced object names + pass + if isinstance(ipconfig.get('load_balancer_backend_address_pools'), list): + # TODO: Add ID lookup for referenced object names + pass + if isinstance(ipconfig.get('load_balancer_inbound_nat_rules'), list): + # TODO: Add ID lookup for referenced object names + pass + if ipconfig.get('public_ip_address'): + pub_ip = public_ip_address_get( + name=ipconfig['public_ip_address'], + resource_group=resource_group, + **kwargs + ) + if 'error' not in pub_ip: + ipconfig['public_ip_address'] = {'id': str(pub_ip['id'])} + + try: + nicmodel = __utils__['azurearm.create_object_model']( + 'network', + 'NetworkInterface', + ip_configurations=ip_configurations, + **kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + interface = netconn.network_interfaces.create_or_update( + resource_group_name=resource_group, + network_interface_name=name, + parameters=nicmodel + ) + interface.wait() + nic_result = interface.result() + result = nic_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def network_interfaces_list_all(**kwargs): + ''' + .. versionadded:: Fluorine + + List all network interfaces within a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_interfaces_list_all + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + nics = __utils__['azurearm.paged_object_to_list'](netconn.network_interfaces.list_all()) + + for nic in nics: + result[nic['name']] = nic + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def network_interfaces_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all network interfaces within a resource group. + + :param resource_group: The resource group name to list network + interfaces within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_interfaces_list testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + nics = __utils__['azurearm.paged_object_to_list']( + netconn.network_interfaces.list( + resource_group_name=resource_group + ) + ) + + for nic in nics: + result[nic['name']] = nic + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +# pylint: disable=invalid-name +def network_interface_get_effective_route_table(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get all route tables for a specific network interface. + + :param name: The name of the network interface to query. + + :param resource_group: The resource group name assigned to the + network interface. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_interface_get_effective_route_table test-iface0 testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + nic = netconn.network_interfaces.get_effective_route_table( + network_interface_name=name, + resource_group_name=resource_group + ) + nic.wait() + tables = nic.result() + tables = tables.as_dict() + result = tables['value'] + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +# pylint: disable=invalid-name +def network_interface_list_effective_network_security_groups(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get all network security groups applied to a specific network interface. + + :param name: The name of the network interface to query. + + :param resource_group: The resource group name assigned to the + network interface. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.network_interface_list_effective_network_security_groups test-iface0 testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + nic = netconn.network_interfaces.list_effective_network_security_groups( + network_interface_name=name, + resource_group_name=resource_group + ) + nic.wait() + groups = nic.result() + groups = groups.as_dict() + result = groups['value'] + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +# pylint: disable=invalid-name +def list_virtual_machine_scale_set_vm_network_interfaces(scale_set, + vm_index, + resource_group, + **kwargs): + ''' + .. versionadded:: Fluorine + + Get information about all network interfaces in a specific virtual machine within a scale set. + + :param scale_set: The name of the scale set to query. + + :param vm_index: The virtual machine index. + + :param resource_group: The resource group name assigned to the + scale set. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.list_virtual_machine_scale_set_vm_network_interfaces testset testvm testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + nics = __utils__['azurearm.paged_object_to_list']( + netconn.network_interfaces.list_virtual_machine_scale_set_vm_network_interfaces( + virtual_machine_scale_set_name=scale_set, + virtualmachine_index=vm_index, + resource_group_name=resource_group + ) + ) + + for nic in nics: + result[nic['name']] = nic + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +# pylint: disable=invalid-name +def list_virtual_machine_scale_set_network_interfaces(scale_set, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get information about all network interfaces within a scale set. + + :param scale_set: The name of the scale set to query. + + :param resource_group: The resource group name assigned to the + scale set. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.list_virtual_machine_scale_set_vm_network_interfaces testset testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + nics = __utils__['azurearm.paged_object_to_list']( + netconn.network_interfaces.list_virtual_machine_scale_set_network_interfaces( + virtual_machine_scale_set_name=scale_set, + resource_group_name=resource_group + ) + ) + + for nic in nics: + result[nic['name']] = nic + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +# pylint: disable=invalid-name +def get_virtual_machine_scale_set_network_interface(name, scale_set, vm_index, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get information about a specfic network interface within a scale set. + + :param name: The name of the network interface to query. + + :param scale_set: The name of the scale set containing the interface. + + :param vm_index: The virtual machine index. + + :param resource_group: The resource group name assigned to the + scale set. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.get_virtual_machine_scale_set_network_interface test-iface0 testset testvm testgroup + + ''' + expand = kwargs.get('expand') + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + nic = netconn.network_interfaces.list_virtual_machine_scale_set_vm_network_interfaces( + network_interface_name=name, + virtual_machine_scale_set_name=scale_set, + virtualmachine_index=vm_index, + resource_group_name=resource_group, + exapnd=expand + ) + + result = nic.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def public_ip_address_delete(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a public IP address. + + :param name: The name of the public IP address to delete. + + :param resource_group: The resource group name assigned to the + public IP address. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.public_ip_address_delete test-pub-ip testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + pub_ip = netconn.public_ip_addresses.delete( + public_ip_address_name=name, + resource_group_name=resource_group + ) + pub_ip.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def public_ip_address_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific public IP address. + + :param name: The name of the public IP address to query. + + :param resource_group: The resource group name assigned to the + public IP address. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.public_ip_address_get test-pub-ip testgroup + + ''' + expand = kwargs.get('expand') + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + pub_ip = netconn.public_ip_addresses.get( + public_ip_address_name=name, + resource_group_name=resource_group, + expand=expand + ) + result = pub_ip.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def public_ip_address_create_or_update(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a public IP address within a specified resource group. + + :param name: The name of the public IP address to create. + + :param resource_group: The resource group name assigned to the + public IP address. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.public_ip_address_create_or_update test-ip-0 testgroup + + ''' + if 'location' not in kwargs: + rg_props = __salt__['azurearm_resource.resource_group_get']( + resource_group, **kwargs + ) + + if 'error' in rg_props: + log.error( + 'Unable to determine location from resource group specified.' + ) + return False + kwargs['location'] = rg_props['location'] + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + pub_ip_model = __utils__['azurearm.create_object_model']('network', 'PublicIPAddress', **kwargs) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + ip = netconn.public_ip_addresses.create_or_update( + resource_group_name=resource_group, + public_ip_address_name=name, + parameters=pub_ip_model + ) + ip.wait() + ip_result = ip.result() + result = ip_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def public_ip_addresses_list_all(**kwargs): + ''' + .. versionadded:: Fluorine + + List all public IP addresses within a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.public_ip_addresses_list_all + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + pub_ips = __utils__['azurearm.paged_object_to_list'](netconn.public_ip_addresses.list_all()) + + for ip in pub_ips: + result[ip['name']] = ip + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def public_ip_addresses_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all public IP addresses within a resource group. + + :param resource_group: The resource group name to list public IP + addresses within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.public_ip_addresses_list testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + pub_ips = __utils__['azurearm.paged_object_to_list']( + netconn.public_ip_addresses.list( + resource_group_name=resource_group + ) + ) + + for ip in pub_ips: + result[ip['name']] = ip + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_filter_rule_delete(name, route_filter, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a route filter rule. + + :param name: The route filter rule to delete. + + :param route_filter: The route filter containing the rule. + + :param resource_group: The resource group name assigned to the + route filter. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_filter_rule_delete test-rule test-filter testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + rule = netconn.route_filter_rules.delete( + resource_group_name=resource_group, + route_filter_name=route_filter, + rule_name=name + ) + rule.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def route_filter_rule_get(name, route_filter, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific route filter rule. + + :param name: The route filter rule to query. + + :param route_filter: The route filter containing the rule. + + :param resource_group: The resource group name assigned to the + route filter. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_filter_rule_get test-rule test-filter testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + rule = netconn.route_filter_rules.get( + resource_group_name=resource_group, + route_filter_name=route_filter, + rule_name=name + ) + + result = rule.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_filter_rule_create_or_update(name, access, communities, route_filter, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a rule within a specified route filter. + + :param name: The name of the rule to create. + + :param access: The access type of the rule. Valid values are 'Allow' and 'Deny'. + + :param communities: A list of BGP communities to filter on. + + :param route_filter: The name of the route filter containing the rule. + + :param resource_group: The resource group name assigned to the + route filter. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_filter_rule_create_or_update \ + test-rule allow "['12076:51006']" test-filter testgroup + + ''' + if not isinstance(communities, list): + log.error( + 'The communities parameter must be a list of strings!' + ) + return False + + if 'location' not in kwargs: + rg_props = __salt__['azurearm_resource.resource_group_get']( + resource_group, **kwargs + ) + + if 'error' in rg_props: + log.error( + 'Unable to determine location from resource group specified.' + ) + return False + kwargs['location'] = rg_props['location'] + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + rule_model = __utils__['azurearm.create_object_model']( + 'network', + 'RouteFilterRule', + access=access, + communities=communities, + **kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + rule = netconn.route_filter_rules.create_or_update( + resource_group_name=resource_group, + route_filter_name=route_filter, + rule_name=name, + route_filter_rule_parameters=rule_model + ) + rule.wait() + rule_result = rule.result() + result = rule_result.as_dict() + except CloudError as exc: + message = str(exc) + if kwargs.get('subscription_id') == str(message).strip(): + message = 'Subscription not authorized for this operation!' + __utils__['azurearm.log_cloud_error']('network', message, **kwargs) + result = {'error': message} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def route_filter_rules_list(route_filter, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all routes within a route filter. + + :param route_filter: The route filter to query. + + :param resource_group: The resource group name assigned to the + route filter. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_filter_rules_list test-filter testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + rules = __utils__['azurearm.paged_object_to_list']( + netconn.route_filter_rules.list_by_route_filter( + resource_group_name=resource_group, + route_filter_name=route_filter + ) + ) + + for rule in rules: + result[rule['name']] = rule + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_filter_delete(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a route filter. + + :param name: The name of the route filter to delete. + + :param resource_group: The resource group name assigned to the + route filter. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_filter_delete test-filter testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + route_filter = netconn.route_filters.delete( + route_filter_name=name, + resource_group_name=resource_group + ) + route_filter.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def route_filter_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific route filter. + + :param name: The name of the route table to query. + + :param resource_group: The resource group name assigned to the + route filter. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_filter_get test-filter testgroup + + ''' + expand = kwargs.get('expand') + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + route_filter = netconn.route_filters.get( + route_filter_name=name, + resource_group_name=resource_group, + expand=expand + ) + result = route_filter.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_filter_create_or_update(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a route filter within a specified resource group. + + :param name: The name of the route filter to create. + + :param resource_group: The resource group name assigned to the + route filter. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_filter_create_or_update test-filter testgroup + + ''' + if 'location' not in kwargs: + rg_props = __salt__['azurearm_resource.resource_group_get']( + resource_group, **kwargs + ) + + if 'error' in rg_props: + log.error( + 'Unable to determine location from resource group specified.' + ) + return False + kwargs['location'] = rg_props['location'] + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + rt_filter_model = __utils__['azurearm.create_object_model']('network', 'RouteFilter', **kwargs) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + rt_filter = netconn.route_filters.create_or_update( + resource_group_name=resource_group, + route_filter_name=name, + route_filter_parameters=rt_filter_model + ) + rt_filter.wait() + rt_result = rt_filter.result() + result = rt_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def route_filters_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all route filters within a resource group. + + :param resource_group: The resource group name to list route + filters within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_filters_list testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + filters = __utils__['azurearm.paged_object_to_list']( + netconn.route_filters.list_by_resource_group( + resource_group_name=resource_group + ) + ) + + for route_filter in filters: + result[route_filter['name']] = route_filter + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_filters_list_all(**kwargs): + ''' + .. versionadded:: Fluorine + + List all route filters within a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_filters_list_all + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + filters = __utils__['azurearm.paged_object_to_list'](netconn.route_filters.list()) + + for route_filter in filters: + result[route_filter['name']] = route_filter + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_delete(name, route_table, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a route from a route table. + + :param name: The route to delete. + + :param route_table: The route table containing the route. + + :param resource_group: The resource group name assigned to the + route table. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_delete test-rt test-rt-table testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + route = netconn.routes.delete( + resource_group_name=resource_group, + route_table_name=route_table, + route_name=name + ) + route.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def route_get(name, route_table, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific route. + + :param name: The route to query. + + :param route_table: The route table containing the route. + + :param resource_group: The resource group name assigned to the + route table. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_get test-rt test-rt-table testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + route = netconn.routes.get( + resource_group_name=resource_group, + route_table_name=route_table, + route_name=name + ) + + result = route.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_create_or_update(name, address_prefix, next_hop_type, route_table, resource_group, + next_hop_ip_address=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a route within a specified route table. + + :param name: The name of the route to create. + + :param address_prefix: The destination CIDR to which the route applies. + + :param next_hop_type: The type of Azure hop the packet should be sent to. Possible values are: + 'VirtualNetworkGateway', 'VnetLocal', 'Internet', 'VirtualAppliance', and 'None'. + + :param next_hop_ip_address: Optional IP address to which packets should be forwarded. Next hop + values are only allowed in routes where the next_hop_type is 'VirtualAppliance'. + + :param route_table: The name of the route table containing the route. + + :param resource_group: The resource group name assigned to the + route table. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_create_or_update test-rt '10.0.0.0/8' test-rt-table testgroup + + ''' + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + rt_model = __utils__['azurearm.create_object_model']( + 'network', + 'Route', + address_prefix=address_prefix, + next_hop_type=next_hop_type, + next_hop_ip_address=next_hop_ip_address, + **kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + route = netconn.routes.create_or_update( + resource_group_name=resource_group, + route_table_name=route_table, + route_name=name, + route_parameters=rt_model + ) + route.wait() + rt_result = route.result() + result = rt_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def routes_list(route_table, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all routes within a route table. + + :param route_table: The route table to query. + + :param resource_group: The resource group name assigned to the + route table. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.routes_list test-rt-table testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + routes = __utils__['azurearm.paged_object_to_list']( + netconn.routes.list( + resource_group_name=resource_group, + route_table_name=route_table + ) + ) + + for route in routes: + result[route['name']] = route + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_table_delete(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a route table. + + :param name: The name of the route table to delete. + + :param resource_group: The resource group name assigned to the + route table. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_table_delete test-rt-table testgroup + + ''' + result = False + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + table = netconn.route_tables.delete( + route_table_name=name, + resource_group_name=resource_group + ) + table.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + + return result + + +def route_table_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific route table. + + :param name: The name of the route table to query. + + :param resource_group: The resource group name assigned to the + route table. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_table_get test-rt-table testgroup + + ''' + expand = kwargs.get('expand') + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + table = netconn.route_tables.get( + route_table_name=name, + resource_group_name=resource_group, + expand=expand + ) + result = table.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_table_create_or_update(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Create or update a route table within a specified resource group. + + :param name: The name of the route table to create. + + :param resource_group: The resource group name assigned to the + route table. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_table_create_or_update test-rt-table testgroup + + ''' + if 'location' not in kwargs: + rg_props = __salt__['azurearm_resource.resource_group_get']( + resource_group, **kwargs + ) + + if 'error' in rg_props: + log.error( + 'Unable to determine location from resource group specified.' + ) + return False + kwargs['location'] = rg_props['location'] + + netconn = __utils__['azurearm.get_client']('network', **kwargs) + + try: + rt_tbl_model = __utils__['azurearm.create_object_model']('network', 'RouteTable', **kwargs) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + table = netconn.route_tables.create_or_update( + resource_group_name=resource_group, + route_table_name=name, + parameters=rt_tbl_model + ) + table.wait() + tbl_result = table.result() + result = tbl_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def route_tables_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all route tables within a resource group. + + :param resource_group: The resource group name to list route + tables within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_tables_list testgroup + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + tables = __utils__['azurearm.paged_object_to_list']( + netconn.route_tables.list( + resource_group_name=resource_group + ) + ) + + for table in tables: + result[table['name']] = table + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def route_tables_list_all(**kwargs): + ''' + .. versionadded:: Fluorine + + List all route tables within a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_network.route_tables_list_all + + ''' + result = {} + netconn = __utils__['azurearm.get_client']('network', **kwargs) + try: + tables = __utils__['azurearm.paged_object_to_list'](netconn.route_tables.list_all()) + + for table in tables: + result[table['name']] = table + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('network', str(exc), **kwargs) + result = {'error': str(exc)} + + return result diff --git a/salt/modules/azurearm_resource.py b/salt/modules/azurearm_resource.py new file mode 100644 index 0000000000..041e61a172 --- /dev/null +++ b/salt/modules/azurearm_resource.py @@ -0,0 +1,1178 @@ +# -*- coding: utf-8 -*- +''' +Azure (ARM) Resource Execution Module + +.. versionadded:: Fluorine + +:maintainer: +:maturity: new +:depends: + * `azure `_ >= 2.0.0 + * `azure-common `_ >= 1.1.8 + * `azure-mgmt `_ >= 1.0.0 + * `azure-mgmt-compute `_ >= 1.0.0 + * `azure-mgmt-network `_ >= 1.7.1 + * `azure-mgmt-resource `_ >= 1.1.0 + * `azure-mgmt-storage `_ >= 1.0.0 + * `azure-mgmt-web `_ >= 0.32.0 + * `azure-storage `_ >= 0.34.3 + * `msrestazure `_ >= 0.4.21 +:platform: linux + +:configuration: This module requires Azure Resource Manager credentials to be passed as keyword arguments +to every function in order to work properly. + + Required provider parameters: + + if using username and password: + * ``subscription_id`` + * ``username`` + * ``password`` + + if using a service principal: + * ``subscription_id`` + * ``tenant`` + * ``client_id`` + * ``secret`` + + Optional provider parameters: + + **cloud_environment**: Used to point the cloud driver to different API endpoints, such as Azure GovCloud. + Possible values: + * ``AZURE_PUBLIC_CLOUD`` (default) + * ``AZURE_CHINA_CLOUD`` + * ``AZURE_US_GOV_CLOUD`` + * ``AZURE_GERMAN_CLOUD`` + +''' + +# Python libs +from __future__ import absolute_import +from json import loads, dumps +import logging + +# Azure libs +HAS_LIBS = False +try: + import azure.mgmt.resource.resources.models # pylint: disable=unused-import + from msrest.exceptions import SerializationError + from msrestazure.azure_exceptions import CloudError + HAS_LIBS = True +except ImportError: + pass + +__virtualname__ = 'azurearm_resource' + +log = logging.getLogger(__name__) + + +def __virtual__(): + if not HAS_LIBS: + return ( + False, + 'The following dependencies are required to use the AzureARM modules: ' + 'Microsoft Azure SDK for Python >= 2.0rc6, ' + 'MS REST Azure (msrestazure) >= 0.4' + ) + + return __virtualname__ + + +def resource_groups_list(**kwargs): + ''' + .. versionadded:: Fluorine + + List all resource groups within a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.resource_groups_list + + ''' + result = {} + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + groups = __utils__['azurearm.paged_object_to_list'](resconn.resource_groups.list()) + + for group in groups: + result[group['name']] = group + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def resource_group_check_existence(name, **kwargs): + ''' + .. versionadded:: Fluorine + + Check for the existence of a named resource group in the current subscription. + + :param name: The resource group name to check. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.resource_group_check_existence testgroup + + ''' + result = False + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + result = resconn.resource_groups.check_existence(name) + + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + + return result + + +def resource_group_get(name, **kwargs): + ''' + .. versionadded:: Fluorine + + Get a dictionary representing a resource group's properties. + + :param name: The resource group name to get. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.resource_group_get testgroup + + ''' + result = {} + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + group = resconn.resource_groups.get(name) + result = group.as_dict() + + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def resource_group_create_or_update(name, location, **kwargs): # pylint: disable=invalid-name + ''' + .. versionadded:: Fluorine + + Create or update a resource group in a given location. + + :param name: The name of the resource group to create or update. + + :param location: The location of the resource group. This value + is not able to be updated once the resource group is created. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.resource_group_create_or_update testgroup westus + + ''' + result = {} + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + resource_group_params = { + 'location': location, + 'managed_by': kwargs.get('managed_by'), + 'tags': kwargs.get('tags'), + } + try: + group = resconn.resource_groups.create_or_update(name, resource_group_params) + result = group.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def resource_group_delete(name, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a resource group from the subscription. + + :param name: The resource group name to delete. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.resource_group_delete testgroup + + ''' + result = False + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + group = resconn.resource_groups.delete(name) + group.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + + return result + + +def deployment_operation_get(operation, deployment, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get a deployment operation within a deployment. + + :param operation: The operation ID of the operation within the deployment. + + :param deployment: The name of the deployment containing the operation. + + :param resource_group: The resource group name assigned to the + deployment. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployment_operation_get XXXXX testdeploy testgroup + + ''' + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + operation = resconn.deployment_operations.get( + resource_group_name=resource_group, + deployment_name=deployment, + operation_id=operation + ) + + result = operation.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def deployment_operations_list(name, resource_group, result_limit=10, **kwargs): + ''' + .. versionadded:: Fluorine + + List all deployment operations within a deployment. + + :param name: The name of the deployment to query. + + :param resource_group: The resource group name assigned to the + deployment. + + :param result_limit: (Default: 10) The limit on the list of deployment + operations. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployment_operations_list testdeploy testgroup + + ''' + result = {} + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + operations = __utils__['azurearm.paged_object_to_list']( + resconn.deployment_operations.list( + resource_group_name=resource_group, + deployment_name=name, + top=result_limit + ) + ) + + for oper in operations: + result[oper['operation_id']] = oper + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def deployment_delete(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a deployment. + + :param name: The name of the deployment to delete. + + :param resource_group: The resource group name assigned to the + deployment. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployment_delete testdeploy testgroup + + ''' + result = False + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + deploy = resconn.deployments.delete( + deployment_name=name, + resource_group_name=resource_group + ) + deploy.wait() + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + + return result + + +def deployment_check_existence(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Check the existence of a deployment. + + :param name: The name of the deployment to query. + + :param resource_group: The resource group name assigned to the + deployment. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployment_check_existence testdeploy testgroup + + ''' + result = False + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + result = resconn.deployments.check_existence( + deployment_name=name, + resource_group_name=resource_group + ) + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + + return result + + +def deployment_create_or_update(name, resource_group, deploy_mode='incremental', + debug_setting='none', deploy_params=None, + parameters_link=None, deploy_template=None, + template_link=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Deploys resources to a resource group. + + :param name: The name of the deployment to create or update. + + :param resource_group: The resource group name assigned to the + deployment. + + :param deploy_mode: The mode that is used to deploy resources. This value can be either + 'incremental' or 'complete'. In Incremental mode, resources are deployed without deleting + existing resources that are not included in the template. In Complete mode, resources + are deployed and existing resources in the resource group that are not included in + the template are deleted. Be careful when using Complete mode as you may + unintentionally delete resources. + + :param debug_setting: The debug setting of the deployment. The permitted values are 'none', + 'requestContent', 'responseContent', or 'requestContent,responseContent'. By logging + information about the request or response, you could potentially expose sensitive data + that is retrieved through the deployment operations. + + :param deploy_params: JSON string containing name and value pairs that define the deployment + parameters for the template. You use this element when you want to provide the parameter + values directly in the request rather than link to an existing parameter file. Use either + the parameters_link property or the deploy_params property, but not both. + + :param parameters_link: The URI of a parameters file. You use this element to link to an existing + parameters file. Use either the parameters_link property or the deploy_params property, but not both. + + :param deploy_template: JSON string of template content. You use this element when you want to pass + the template syntax directly in the request rather than link to an existing template. Use either + the template_link property or the deploy_template property, but not both. + + :param template_link: The URI of the template. Use either the template_link property or the + deploy_template property, but not both. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployment_create_or_update testdeploy testgroup + + ''' + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + + prop_kwargs = {'mode': deploy_mode} + prop_kwargs['debug_setting'] = {'detail_level': debug_setting} + + if deploy_params: + prop_kwargs['parameters'] = deploy_params + else: + if isinstance(parameters_link, dict): + prop_kwargs['parameters_link'] = parameters_link + else: + prop_kwargs['parameters_link'] = {'uri': parameters_link} + + if deploy_template: + prop_kwargs['template'] = deploy_template + else: + if isinstance(template_link, dict): + prop_kwargs['template_link'] = template_link + else: + prop_kwargs['template_link'] = {'uri': template_link} + + deploy_kwargs = kwargs.copy() + deploy_kwargs.update(prop_kwargs) + + try: + deploy_model = __utils__['azurearm.create_object_model']( + 'resource', + 'DeploymentProperties', + **deploy_kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + validate = deployment_validate( + name=name, + resource_group=resource_group, + **deploy_kwargs + ) + if 'error' in validate: + result = validate + else: + deploy = resconn.deployments.create_or_update( + deployment_name=name, + resource_group_name=resource_group, + properties=deploy_model + ) + deploy.wait() + deploy_result = deploy.result() + result = deploy_result.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def deployment_get(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific deployment. + + :param name: The name of the deployment to query. + + :param resource_group: The resource group name assigned to the + deployment. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployment_get testdeploy testgroup + + ''' + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + deploy = resconn.deployments.get( + deployment_name=name, + resource_group_name=resource_group + ) + result = deploy.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def deployment_cancel(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Cancel a deployment if in 'Accepted' or 'Running' state. + + :param name: The name of the deployment to cancel. + + :param resource_group: The resource group name assigned to the + deployment. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployment_cancel testdeploy testgroup + + ''' + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + resconn.deployments.cancel( + deployment_name=name, + resource_group_name=resource_group + ) + result = {'result': True} + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = { + 'error': str(exc), + 'result': False + } + + return result + + +def deployment_validate(name, resource_group, deploy_mode=None, + debug_setting=None, deploy_params=None, + parameters_link=None, deploy_template=None, + template_link=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Validates whether the specified template is syntactically correct + and will be accepted by Azure Resource Manager. + + :param name: The name of the deployment to validate. + + :param resource_group: The resource group name assigned to the + deployment. + + :param deploy_mode: The mode that is used to deploy resources. This value can be either + 'incremental' or 'complete'. In Incremental mode, resources are deployed without deleting + existing resources that are not included in the template. In Complete mode, resources + are deployed and existing resources in the resource group that are not included in + the template are deleted. Be careful when using Complete mode as you may + unintentionally delete resources. + + :param debug_setting: The debug setting of the deployment. The permitted values are 'none', + 'requestContent', 'responseContent', or 'requestContent,responseContent'. By logging + information about the request or response, you could potentially expose sensitive data + that is retrieved through the deployment operations. + + :param deploy_params: JSON string containing name and value pairs that define the deployment + parameters for the template. You use this element when you want to provide the parameter + values directly in the request rather than link to an existing parameter file. Use either + the parameters_link property or the deploy_params property, but not both. + + :param parameters_link: The URI of a parameters file. You use this element to link to an existing + parameters file. Use either the parameters_link property or the deploy_params property, but not both. + + :param deploy_template: JSON string of template content. You use this element when you want to pass + the template syntax directly in the request rather than link to an existing template. Use either + the template_link property or the deploy_template property, but not both. + + :param template_link: The URI of the template. Use either the template_link property or the + deploy_template property, but not both. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployment_validate testdeploy testgroup + + ''' + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + + prop_kwargs = {'mode': deploy_mode} + prop_kwargs['debug_setting'] = {'detail_level': debug_setting} + + if deploy_params: + prop_kwargs['parameters'] = deploy_params + else: + if isinstance(parameters_link, dict): + prop_kwargs['parameters_link'] = parameters_link + else: + prop_kwargs['parameters_link'] = {'uri': parameters_link} + + if deploy_template: + prop_kwargs['template'] = deploy_template + else: + if isinstance(template_link, dict): + prop_kwargs['template_link'] = template_link + else: + prop_kwargs['template_link'] = {'uri': template_link} + + deploy_kwargs = kwargs.copy() + deploy_kwargs.update(prop_kwargs) + + try: + deploy_model = __utils__['azurearm.create_object_model']( + 'resource', + 'DeploymentProperties', + **deploy_kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + local_validation = deploy_model.validate() + if local_validation: + raise local_validation[0] + + deploy = resconn.deployments.validate( + deployment_name=name, + resource_group_name=resource_group, + properties=deploy_model + ) + result = deploy.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def deployment_export_template(name, resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + Exports the template used for the specified deployment. + + :param name: The name of the deployment to query. + + :param resource_group: The resource group name assigned to the + deployment. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployment_export_template testdeploy testgroup + + ''' + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + deploy = resconn.deployments.export_template( + deployment_name=name, + resource_group_name=resource_group + ) + result = deploy.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def deployments_list(resource_group, **kwargs): + ''' + .. versionadded:: Fluorine + + List all deployments within a resource group. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.deployments_list testgroup + + ''' + result = {} + resconn = __utils__['azurearm.get_client']('resource', **kwargs) + try: + deployments = __utils__['azurearm.paged_object_to_list']( + resconn.deployments.list_by_resource_group( + resource_group_name=resource_group + ) + ) + + for deploy in deployments: + result[deploy['name']] = deploy + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def subscriptions_list_locations(subscription_id=None, **kwargs): + ''' + .. versionadded:: Fluorine + + List all locations for a subscription. + + :param subscription_id: The ID of the subscription to query. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.subscriptions_list_locations XXXXXXXX + + ''' + result = {} + + if not subscription_id: + subscription_id = kwargs.get('subscription_id') + elif not kwargs.get('subscription_id'): + kwargs['subscription_id'] = subscription_id + + subconn = __utils__['azurearm.get_client']('subscription', **kwargs) + try: + locations = __utils__['azurearm.paged_object_to_list']( + subconn.subscriptions.list_locations( + subscription_id=kwargs['subscription_id'] + ) + ) + + for loc in locations: + result[loc['name']] = loc + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def subscription_get(subscription_id=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a subscription. + + :param subscription_id: The ID of the subscription to query. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.subscription_get XXXXXXXX + + ''' + result = {} + + if not subscription_id: + subscription_id = kwargs.get('subscription_id') + elif not kwargs.get('subscription_id'): + kwargs['subscription_id'] = subscription_id + + subconn = __utils__['azurearm.get_client']('subscription', **kwargs) + try: + subscription = subconn.subscriptions.get( + subscription_id=kwargs.get('subscription_id') + ) + + result = subscription.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def subscriptions_list(**kwargs): + ''' + .. versionadded:: Fluorine + + List all subscriptions for a tenant. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.subscriptions_list + + ''' + result = {} + subconn = __utils__['azurearm.get_client']('subscription', **kwargs) + try: + subs = __utils__['azurearm.paged_object_to_list'](subconn.subscriptions.list()) + + for sub in subs: + result[sub['subscription_id']] = sub + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def tenants_list(**kwargs): + ''' + .. versionadded:: Fluorine + + List all tenants for your account. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.tenants_list + + ''' + result = {} + subconn = __utils__['azurearm.get_client']('subscription', **kwargs) + try: + tenants = __utils__['azurearm.paged_object_to_list'](subconn.tenants.list()) + + for tenant in tenants: + result[tenant['tenant_id']] = tenant + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def policy_assignment_delete(name, scope, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a policy assignment. + + :param name: The name of the policy assignment to delete. + + :param scope: The scope of the policy assignment. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.policy_assignment_delete testassign \ + /subscriptions/bc75htn-a0fhsi-349b-56gh-4fghti-f84852 + + ''' + result = False + polconn = __utils__['azurearm.get_client']('policy', **kwargs) + try: + # pylint: disable=unused-variable + policy = polconn.policy_assignments.delete( + policy_assignment_name=name, + scope=scope + ) + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + + return result + + +def policy_assignment_create(name, scope, definition_name, **kwargs): + ''' + .. versionadded:: Fluorine + + Create a policy assignment. + + :param name: The name of the policy assignment to create. + + :param scope: The scope of the policy assignment. + + :param definition_name: The name of the policy definition to assign. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.policy_assignment_create testassign \ + /subscriptions/bc75htn-a0fhsi-349b-56gh-4fghti-f84852 testpolicy + + ''' + polconn = __utils__['azurearm.get_client']('policy', **kwargs) + + # "get" doesn't work for built-in policies per https://github.com/Azure/azure-cli/issues/692 + # Uncomment this section when the ticket above is resolved. + # BEGIN + # definition = policy_definition_get( + # name=definition_name, + # **kwargs + # ) + # END + + # Delete this section when the ticket above is resolved. + # BEGIN + definition_list = policy_definitions_list( + **kwargs + ) + if definition_name in definition_list: + definition = definition_list[definition_name] + else: + definition = {'error': 'The policy definition named "{0}" could not be found.'.format(definition_name)} + # END + + if 'error' not in definition: + definition_id = str(definition['id']) + + prop_kwargs = {'policy_definition_id': definition_id} + + policy_kwargs = kwargs.copy() + policy_kwargs.update(prop_kwargs) + + try: + policy_model = __utils__['azurearm.create_object_model']( + 'resource.policy', + 'PolicyAssignment', + **policy_kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + policy = polconn.policy_assignments.create( + scope=scope, + policy_assignment_name=name, + parameters=policy_model + ) + result = policy.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + else: + result = {'error': 'The policy definition named "{0}" could not be found.'.format(definition_name)} + + return result + + +def policy_assignment_get(name, scope, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific policy assignment. + + :param name: The name of the policy assignment to query. + + :param scope: The scope of the policy assignment. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.policy_assignment_get testassign \ + /subscriptions/bc75htn-a0fhsi-349b-56gh-4fghti-f84852 + + ''' + polconn = __utils__['azurearm.get_client']('policy', **kwargs) + try: + policy = polconn.policy_assignments.get( + policy_assignment_name=name, + scope=scope + ) + result = policy.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def policy_assignments_list_for_resource_group(resource_group, **kwargs): # pylint: disable=invalid-name + ''' + .. versionadded:: Fluorine + + List all policy assignments for a resource group. + + :param resource_group: The resource group name to list policy assignments within. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.policy_assignments_list_for_resource_group testgroup + + ''' + result = {} + polconn = __utils__['azurearm.get_client']('policy', **kwargs) + try: + policy_assign = __utils__['azurearm.paged_object_to_list']( + polconn.policy_assignments.list_for_resource_group( + resource_group_name=resource_group, + filter=kwargs.get('filter') + ) + ) + + for assign in policy_assign: + result[assign['name']] = assign + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def policy_assignments_list(**kwargs): + ''' + .. versionadded:: Fluorine + + List all policy assignments for a subscription. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.policy_assignments_list + + ''' + result = {} + polconn = __utils__['azurearm.get_client']('policy', **kwargs) + try: + policy_assign = __utils__['azurearm.paged_object_to_list'](polconn.policy_assignments.list()) + + for assign in policy_assign: + result[assign['name']] = assign + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def policy_definition_create_or_update(name, policy_rule, **kwargs): # pylint: disable=invalid-name + ''' + .. versionadded:: Fluorine + + Create or update a policy definition. + + :param name: The name of the policy definition to create or update. + + :param policy_rule: A dictionary defining the + `policy rule `_. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.policy_definition_create_or_update testpolicy '{...rule definition..}' + + ''' + if not isinstance(policy_rule, dict): + result = {'error': 'The policy rule must be a dictionary!'} + return result + + polconn = __utils__['azurearm.get_client']('policy', **kwargs) + + # Convert OrderedDict to dict + prop_kwargs = {'policy_rule': loads(dumps(policy_rule))} + + policy_kwargs = kwargs.copy() + policy_kwargs.update(prop_kwargs) + + try: + policy_model = __utils__['azurearm.create_object_model']( + 'resource.policy', + 'PolicyDefinition', + **policy_kwargs + ) + except TypeError as exc: + result = {'error': 'The object model could not be built. ({0})'.format(str(exc))} + return result + + try: + policy = polconn.policy_definitions.create_or_update( + policy_definition_name=name, + parameters=policy_model + ) + result = policy.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + except SerializationError as exc: + result = {'error': 'The object model could not be parsed. ({0})'.format(str(exc))} + + return result + + +def policy_definition_delete(name, **kwargs): + ''' + .. versionadded:: Fluorine + + Delete a policy definition. + + :param name: The name of the policy definition to delete. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.policy_definition_delete testpolicy + + ''' + result = False + polconn = __utils__['azurearm.get_client']('policy', **kwargs) + try: + # pylint: disable=unused-variable + policy = polconn.policy_definitions.delete( + policy_definition_name=name + ) + result = True + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + + return result + + +def policy_definition_get(name, **kwargs): + ''' + .. versionadded:: Fluorine + + Get details about a specific policy definition. + + :param name: The name of the policy definition to query. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.policy_definition_get testpolicy + + ''' + polconn = __utils__['azurearm.get_client']('policy', **kwargs) + try: + policy_def = polconn.policy_definitions.get( + policy_definition_name=name + ) + result = policy_def.as_dict() + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result + + +def policy_definitions_list(hide_builtin=False, **kwargs): + ''' + .. versionadded:: Fluorine + + List all policy definitions for a subscription. + + :param hide_builtin: Boolean which will filter out BuiltIn policy definitions from the result. + + CLI Example: + + .. code-block:: bash + + salt-call azurearm_resource.policy_definitions_list + + ''' + result = {} + polconn = __utils__['azurearm.get_client']('policy', **kwargs) + try: + policy_defs = __utils__['azurearm.paged_object_to_list'](polconn.policy_definitions.list()) + + for policy in policy_defs: + if not (hide_builtin and policy['policy_type'] == 'BuiltIn'): + result[policy['name']] = policy + except CloudError as exc: + __utils__['azurearm.log_cloud_error']('resource', str(exc), **kwargs) + result = {'error': str(exc)} + + return result diff --git a/salt/modules/boto_cfn.py b/salt/modules/boto_cfn.py index 7f7e94d3bd..bb7bfcc33b 100644 --- a/salt/modules/boto_cfn.py +++ b/salt/modules/boto_cfn.py @@ -32,12 +32,12 @@ Connection module for Amazon Cloud Formation # keep lint from choking on _get_conn and _cache_id #pylint: disable=E0602 -from __future__ import absolute_import, print_function, unicode_literals - # Import Python libs +from __future__ import absolute_import, print_function, unicode_literals import logging # Import Salt libs +from salt.ext import six import salt.utils.versions log = logging.getLogger(__name__) @@ -72,7 +72,9 @@ def exists(name, region=None, key=None, keyid=None, profile=None): ''' Check to see if a stack exists. - CLI example:: + CLI Example: + + .. code-block:: bash salt myminion boto_cfn.exists mystack region=us-east-1 ''' @@ -94,7 +96,9 @@ def describe(name, region=None, key=None, keyid=None, profile=None): .. versionadded:: 2015.8.0 - CLI example:: + CLI Example: + + .. code-block:: bash salt myminion boto_cfn.describe mystack region=us-east-1 ''' @@ -135,7 +139,9 @@ def create(name, template_body=None, template_url=None, parameters=None, notific ''' Create a CFN stack. - CLI example to create a stack:: + CLI Example: + + .. code-block:: bash salt myminion boto_cfn.create mystack template_url='https://s3.amazonaws.com/bucket/template.cft' \ region=us-east-1 @@ -161,7 +167,9 @@ def update_stack(name, template_body=None, template_url=None, parameters=None, n .. versionadded:: 2015.8.0 - CLI example to update a stack:: + CLI Example: + + .. code-block:: bash salt myminion boto_cfn.update_stack mystack template_url='https://s3.amazonaws.com/bucket/template.cft' \ region=us-east-1 @@ -186,7 +194,9 @@ def delete(name, region=None, key=None, keyid=None, profile=None): ''' Delete a CFN stack. - CLI example to delete a stack:: + CLI Example: + + .. code-block:: bash salt myminion boto_cfn.delete mystack region=us-east-1 ''' @@ -205,7 +215,9 @@ def get_template(name, region=None, key=None, keyid=None, profile=None): ''' Check to see if attributes are set on a CFN stack. - CLI example:: + CLI Example: + + .. code-block:: bash salt myminion boto_cfn.get_template mystack ''' @@ -228,7 +240,9 @@ def validate_template(template_body=None, template_url=None, region=None, key=No .. versionadded:: 2015.8.0 - CLI example:: + CLI Example: + + .. code-block:: bash salt myminion boto_cfn.validate_template mystack-template ''' diff --git a/salt/modules/boto_cloudfront.py b/salt/modules/boto_cloudfront.py index d1d8ab9ce9..6d00ace956 100644 --- a/salt/modules/boto_cloudfront.py +++ b/salt/modules/boto_cloudfront.py @@ -2,7 +2,7 @@ ''' Connection module for Amazon CloudFront -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: boto3 diff --git a/salt/modules/boto_ec2.py b/salt/modules/boto_ec2.py index 249c16f7b4..93911fc307 100644 --- a/salt/modules/boto_ec2.py +++ b/salt/modules/boto_ec2.py @@ -1865,7 +1865,7 @@ def get_all_tags(filters=None, region=None, key=None, keyid=None, profile=None): ''' Describe all tags matching the filter criteria, or all tags in the account otherwise. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 filters (dict) - Additional constraints on which volumes to return. Note that valid filters vary diff --git a/salt/modules/boto_route53.py b/salt/modules/boto_route53.py index 9c457c6e1c..4f2c5ae9b0 100644 --- a/salt/modules/boto_route53.py +++ b/salt/modules/boto_route53.py @@ -343,7 +343,7 @@ def create_healthcheck(ip_addr=None, fqdn=None, region=None, key=None, keyid=Non ''' Create a Route53 healthcheck - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 ip_addr diff --git a/salt/modules/boto_s3.py b/salt/modules/boto_s3.py index 9e497c43de..ef952d8296 100644 --- a/salt/modules/boto_s3.py +++ b/salt/modules/boto_s3.py @@ -2,7 +2,7 @@ ''' Connection module for Amazon S3 using boto3 -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :configuration: This module accepts explicit AWS credentials but can also utilize IAM roles assigned to the instance through Instance Profiles or diff --git a/salt/modules/boto_vpc.py b/salt/modules/boto_vpc.py index 3c875380d9..404f9e7c02 100644 --- a/salt/modules/boto_vpc.py +++ b/salt/modules/boto_vpc.py @@ -2586,6 +2586,7 @@ def describe_route_tables(route_table_id=None, route_table_name=None, 'instance_id': 'Instance', 'interface_id': 'NetworkInterfaceId', 'nat_gateway_id': 'NatGatewayId', + 'vpc_peering_connection_id': 'VpcPeeringConnectionId', } assoc_keys = {'id': 'RouteTableAssociationId', 'main': 'Main', diff --git a/salt/modules/chocolatey.py b/salt/modules/chocolatey.py index 4dc6521fe3..fa33d3a76f 100644 --- a/salt/modules/chocolatey.py +++ b/salt/modules/chocolatey.py @@ -432,7 +432,7 @@ def install(name, execution_timeout (str): Chocolatey execution timeout value you want to pass to the installation process. Default is None. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Returns: str: The output of the ``chocolatey`` command diff --git a/salt/modules/cmdmod.py b/salt/modules/cmdmod.py index d50d266424..4c62deb955 100644 --- a/salt/modules/cmdmod.py +++ b/salt/modules/cmdmod.py @@ -42,7 +42,6 @@ from salt.exceptions import CommandExecutionError, TimedProcTimeoutError, \ SaltInvocationError from salt.log import LOG_LEVELS from salt.ext.six.moves import range, zip -from salt.ext.six.moves import shlex_quote as _cmd_quote # Only available on POSIX systems, nonfatal on windows try: @@ -53,8 +52,10 @@ except ImportError: if salt.utils.platform.is_windows(): from salt.utils.win_runas import runas as win_runas + from salt.utils.win_functions import escape_argument as _cmd_quote HAS_WIN_RUNAS = True else: + from salt.ext.six.moves import shlex_quote as _cmd_quote HAS_WIN_RUNAS = False __proxyenabled__ = ['*'] @@ -67,11 +68,9 @@ log = logging.getLogger(__name__) DEFAULT_SHELL = salt.grains.extra.shell()['shell'] +# Overwriting the cmd python module makes debugging modules with pdb a bit +# harder so lets do it this way instead. def __virtual__(): - ''' - Overwriting the cmd python module makes debugging modules - with pdb a bit harder so lets do it this way instead. - ''' return __virtualname__ @@ -251,6 +250,7 @@ def _run(cmd, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + output_encoding=None, output_loglevel='debug', log_callback=None, runas=None, @@ -284,9 +284,11 @@ def _run(cmd, if _is_valid_shell(shell) is False: log.warning( 'Attempt to run a shell command with what may be an invalid shell! ' - 'Check to ensure that the shell <{0}> is valid for this user.' - .format(shell)) + 'Check to ensure that the shell <%s> is valid for this user.', + shell + ) + output_loglevel = _check_loglevel(output_loglevel) log_callback = _check_cb(log_callback) use_sudo = False @@ -315,6 +317,10 @@ def _run(cmd, # yaml-ified into non-string types cwd = six.text_type(cwd) + if bg: + ignore_retcode = True + use_vt = False + if not salt.utils.platform.is_windows(): if not os.path.isfile(shell) or not os.access(shell, os.X_OK): msg = 'The shell {0} is not available'.format(shell) @@ -351,14 +357,15 @@ def _run(cmd, # checked if blacklisted if '__pub_jid' in kwargs: if not _check_avail(cmd): - msg = 'This shell command is not permitted: "{0}"'.format(cmd) - raise CommandExecutionError(msg) + raise CommandExecutionError( + 'The shell command "{0}" is not permitted'.format(cmd) + ) env = _parse_env(env) for bad_env_key in (x for x, y in six.iteritems(env) if y is None): - log.error('Environment variable \'{0}\' passed without a value. ' - 'Setting value to an empty string'.format(bad_env_key)) + log.error('Environment variable \'%s\' passed without a value. ' + 'Setting value to an empty string', bad_env_key) env[bad_env_key] = '' def _get_stripped(cmd): @@ -370,7 +377,7 @@ def _run(cmd, else: return cmd - if _check_loglevel(output_loglevel) is not None: + if output_loglevel is not None: # Always log the shell commands at INFO unless quiet logging is # requested. The command output is what will be controlled by the # 'loglevel' parameter. @@ -453,10 +460,11 @@ def _run(cmd, elif __grains__['os_family'] in ['Solaris']: env_cmd = ('su', '-', runas, '-c', sys.executable) elif __grains__['os_family'] in ['AIX']: - env_cmd = ('su', runas, '-c', sys.executable) + env_cmd = ('su', '-', runas, '-c', sys.executable) else: env_cmd = ('su', '-s', shell, '-', runas, '-c', sys.executable) - log.debug(log_callback('env command: %s', env_cmd)) + msg = 'env command: {0}'.format(env_cmd) + log.debug(log_callback(msg)) env_bytes = salt.utils.stringutils.to_bytes(subprocess.Popen( env_cmd, stdin=subprocess.PIPE, @@ -474,6 +482,10 @@ def _run(cmd, for k, v in six.iteritems(env_runas) ) env_runas.update(env) + # Fix platforms like Solaris that don't set a USER env var in the + # user's default environment as obtained above. + if env_runas.get('USER') != runas: + env_runas['USER'] = runas env = env_runas except ValueError: raise CommandExecutionError( @@ -538,8 +550,7 @@ def _run(cmd, try: _umask = int(_umask, 8) except ValueError: - msg = 'Invalid umask: \'{0}\''.format(umask) - raise CommandExecutionError(msg) + raise CommandExecutionError("Invalid umask: '{0}'".format(umask)) else: _umask = None @@ -588,7 +599,7 @@ def _run(cmd, msg = ( 'Unable to run command \'{0}\' with the context \'{1}\', ' 'reason: '.format( - cmd if _check_loglevel(output_loglevel) is not None + cmd if output_loglevel is not None else 'REDACTED', kwargs ) @@ -616,21 +627,43 @@ def _run(cmd, ret['retcode'] = 1 return ret - try: - out = proc.stdout.decode(__salt_system_encoding__) - except AttributeError: - out = '' - except UnicodeDecodeError: - log.error('UnicodeDecodeError while decoding output of cmd {0}'.format(cmd)) - out = proc.stdout.decode(__salt_system_encoding__, 'replace') + if output_encoding is not None: + log.debug('Decoding output from command %s using %s encoding', + cmd, output_encoding) try: - err = proc.stderr.decode(__salt_system_encoding__) - except AttributeError: + out = salt.utils.stringutils.to_unicode( + proc.stdout, + encoding=output_encoding) + except TypeError: + # stdout is None + out = '' + except UnicodeDecodeError: + out = salt.utils.stringutils.to_unicode( + proc.stdout, + encoding=output_encoding, + errors='replace') + log.error( + 'Failed to decode stdout from command %s, non-decodable ' + 'characters have been replaced', cmd + ) + + try: + err = salt.utils.stringutils.to_unicode( + proc.stderr, + encoding=output_encoding) + except TypeError: + # stderr is None err = '' except UnicodeDecodeError: - log.error('UnicodeDecodeError while decoding error of cmd {0}'.format(cmd)) - err = proc.stderr.decode(__salt_system_encoding__, 'replace') + err = salt.utils.stringutils.to_unicode( + proc.stderr, + encoding=output_encoding, + errors='replace') + log.error( + 'Failed to decode stderr from command %s, non-decodable ' + 'characters have been replaced', cmd + ) if rstrip: if out is not None: @@ -647,7 +680,7 @@ def _run(cmd, to = '' if timeout: to = ' (timeout: {0}s)'.format(timeout) - if _check_loglevel(output_loglevel) is not None: + if output_loglevel is not None: msg = 'Running {0} in VT{1}'.format(cmd, to) log.debug(log_callback(msg)) stdout, stderr = '', '' @@ -697,9 +730,8 @@ def _run(cmd, ret['retcode'] = 1 break except salt.utils.vt.TerminalException as exc: - log.error( - 'VT: {0}'.format(exc), - exc_info_on_loglevel=logging.DEBUG) + log.error('VT: %s', exc, + exc_info_on_loglevel=logging.DEBUG) ret = {'retcode': 1, 'pid': '2'} break # only set stdout on success as we already mangled in other @@ -723,12 +755,33 @@ def _run(cmd, except NameError: # Ignore the context error during grain generation pass + + # Log the output + if output_loglevel is not None: + if not ignore_retcode and ret['retcode'] != 0: + if output_loglevel < LOG_LEVELS['error']: + output_loglevel = LOG_LEVELS['error'] + msg = ( + 'Command \'{0}\' failed with return code: {1}'.format( + cmd, + ret['retcode'] + ) + ) + log.error(log_callback(msg)) + if ret['stdout']: + log.log(output_loglevel, 'stdout: {0}'.format(log_callback(ret['stdout']))) + if ret['stderr']: + log.log(output_loglevel, 'stderr: {0}'.format(log_callback(ret['stderr']))) + if ret['retcode']: + log.log(output_loglevel, 'retcode: {0}'.format(ret['retcode'])) + return ret def _run_quiet(cmd, cwd=None, stdin=None, + output_encoding=None, runas=None, shell=DEFAULT_SHELL, python_shell=False, @@ -749,6 +802,7 @@ def _run_quiet(cmd, cwd=cwd, stdin=stdin, stderr=subprocess.STDOUT, + output_encoding=output_encoding, output_loglevel='quiet', log_callback=None, shell=shell, @@ -778,14 +832,14 @@ def _run_all_quiet(cmd, saltenv='base', pillarenv=None, pillar_override=None, - output_loglevel=None, + output_encoding=None, success_retcodes=None): ''' Helper for running commands quietly for minion startup. Returns a dict of return data. - output_loglevel argument is ignored. This is here for when we alias + output_loglevel argument is ignored. This is here for when we alias cmd.run_all directly to _run_all_quiet in certain chicken-and-egg situations where modules need to work both before and after the __salt__ dictionary is populated (cf dracr.py) @@ -797,6 +851,7 @@ def _run_all_quiet(cmd, shell=shell, python_shell=python_shell, env=env, + output_encoding=output_encoding, output_loglevel='quiet', log_callback=None, template=template, @@ -821,6 +876,7 @@ def run(cmd, template=None, rstrip=True, umask=None, + output_encoding=None, output_loglevel='debug', log_callback=None, hide_output=False, @@ -839,127 +895,118 @@ def run(cmd, r''' Execute the passed command and return the output as a string - Note that ``env`` represents the environment variables for the command, and - should be formatted as a dict, or a YAML string which resolves to a dict. - :param str cmd: The command to run. ex: ``ls -lart /home`` - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the - command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input. + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - :param str runas: User to run command as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str group: Group to run command as. Not currently supported on Windows. :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 - :param str shell: Shell to execute under. Defaults to the system default - shell. + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. :param bool python_shell: If ``False``, let python handle the positional - arguments. Set to ``True`` to use shell features, such as pipes or - redirection. + arguments. Set to ``True`` to use shell features, such as pipes or + redirection. :param bool bg: If ``True``, run command in background and do not await or - deliver it's results + deliver it's results - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.run 'some command' env='{"FOO": "bar"}' :param bool clean_env: Attempt to clean out all other shell environment - variables and set only those provided in the 'env' argument to this - function. + variables and set only those provided in the 'env' argument to this + function. - :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) - to $PATH + :param str prepend_path: $PATH segment to prepend (trailing ':' not + necessary) to $PATH - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is - returned. + returned. :param str umask: The umask (in octal) to use when running the command. - :param str output_loglevel: Control the loglevel at which the output from - the command is logged to the minion log. + :param str output_encoding: Control the encoding used to decode the + command's output. - .. note:: - The command being run will still be logged at the ``debug`` - loglevel regardless, unless ``quiet`` is used for this value. + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the - return data. + return data. - .. note:: - This is separate from ``output_loglevel``, which only handles how - Salt logs to the minion log. + .. note:: + This is separate from ``output_loglevel``, which only handles how + Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output - more interactively to the console and the logs. This is experimental. + more interactively to the console and the logs. This is experimental. :param bool encoded_cmd: Specify if the supplied command is encoded. - Only applies to shell 'powershell'. + Only applies to shell 'powershell'. :param bool raise_err: If ``True`` and the command has a nonzero exit code, - a CommandExecutionError exception will be raised. + a CommandExecutionError exception will be raised. .. warning:: This function does not process commands through a shell @@ -1002,7 +1049,7 @@ def run(cmd, A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive - information must be read from standard input.: + information must be read from standard input. .. code-block:: bash @@ -1033,6 +1080,7 @@ def run(cmd, template=template, rstrip=rstrip, umask=umask, + output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, @@ -1079,6 +1127,7 @@ def shell(cmd, template=None, rstrip=True, umask=None, + output_encoding=None, output_loglevel='debug', log_callback=None, hide_output=False, @@ -1097,124 +1146,113 @@ def shell(cmd, .. versionadded:: 2015.5.0 - :param str cmd: The command to run. ex: 'ls -lart /home' + :param str cmd: The command to run. ex: ``ls -lart /home`` - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the - command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input. + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - :param str runas: User to run command as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str group: Group to run command as. Not currently supported on Windows. :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 :param int shell: Shell to execute under. Defaults to the system default - shell. + shell. :param bool bg: If True, run command in background and do not await or - deliver its results + deliver its results - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.shell 'some command' env='{"FOO": "bar"}' :param bool clean_env: Attempt to clean out all other shell environment - variables and set only those provided in the 'env' argument to this - function. + variables and set only those provided in the 'env' argument to this + function. :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) - to $PATH + to $PATH - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is - returned. + returned. :param str umask: The umask (in octal) to use when running the command. - :param str output_loglevel: Control the loglevel at which the output from - the command is logged to the minion log. + :param str output_encoding: Control the encoding used to decode the + command's output. - .. note:: - The command being run will still be logged at the ``debug`` - loglevel regardless, unless ``quiet`` is used for this value. + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the - return data. + return data. - .. note:: - This is separate from ``output_loglevel``, which only handles how - Salt logs to the minion log. + .. note:: + This is separate from ``output_loglevel``, which only handles how + Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 - :param int timeout: A timeout in seconds for the executed process to return. + :param int timeout: A timeout in seconds for the executed process to + return. :param bool use_vt: Use VT utils (saltstack) to stream the command output - more interactively to the console and the logs. This is experimental. + more interactively to the console and the logs. This is experimental. .. warning:: - This passes the cmd argument directly to the shell - without any further processing! Be absolutely sure that you - have properly sanitized the command passed to this function - and do not use untrusted inputs. - - .. note:: - - ``env`` represents the environment variables for the command, and - should be formatted as a dict, or a YAML string which resolves to a dict. + This passes the cmd argument directly to the shell without any further + processing! Be absolutely sure that you have properly sanitized the + command passed to this function and do not use untrusted inputs. :param list success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -1244,7 +1282,7 @@ def shell(cmd, A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive - information must be read from standard input.: + information must be read from standard input. .. code-block:: bash @@ -1275,6 +1313,7 @@ def shell(cmd, template=template, rstrip=rstrip, umask=umask, + output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, hide_output=hide_output, @@ -1302,6 +1341,7 @@ def run_stdout(cmd, template=None, rstrip=True, umask=None, + output_encoding=None, output_loglevel='debug', log_callback=None, hide_output=False, @@ -1317,115 +1357,108 @@ def run_stdout(cmd, ''' Execute a command, and only return the standard out - :param str cmd: The command to run. ex: 'ls -lart /home' + :param str cmd: The command to run. ex: ``ls -lart /home`` - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the - command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input.: + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - :param str runas: User to run command as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 :param str group: Group to run command as. Not currently supported on Windows. - :param str shell: Shell to execute under. Defaults to the system default shell. + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. :param bool python_shell: If False, let python handle the positional - arguments. Set to True to use shell features, such as pipes or redirection + arguments. Set to True to use shell features, such as pipes or + redirection. - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.run_stdout 'some command' env='{"FOO": "bar"}' :param bool clean_env: Attempt to clean out all other shell environment - variables and set only those provided in the 'env' argument to this - function. + variables and set only those provided in the 'env' argument to this + function. :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) - to $PATH + to $PATH - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is - returned. + returned. :param str umask: The umask (in octal) to use when running the command. - :param str output_loglevel: Control the loglevel at which the output from - the command is logged to the minion log. + :param str output_encoding: Control the encoding used to decode the + command's output. - .. note:: - The command being run will still be logged at the ``debug`` - loglevel regardless, unless ``quiet`` is used for this value. + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the - return data. + return data. - .. note:: - This is separate from ``output_loglevel``, which only handles how - Salt logs to the minion log. + .. note:: + This is separate from ``output_loglevel``, which only handles how + Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 - :param int timeout: A timeout in seconds for the executed process to return. + :param int timeout: A timeout in seconds for the executed process to + return. :param bool use_vt: Use VT utils (saltstack) to stream the command output - more interactively to the console and the logs. This is experimental. - - .. note:: - ``env`` represents the environment variables for the command, and - should be formatted as a dict, or a YAML string which resolves to a dict. + more interactively to the console and the logs. This is experimental. :param list success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -1449,7 +1482,7 @@ def run_stdout(cmd, A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive - information must be read from standard input.: + information must be read from standard input. .. code-block:: bash @@ -1470,6 +1503,7 @@ def run_stdout(cmd, template=template, rstrip=rstrip, umask=umask, + output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, @@ -1481,26 +1515,6 @@ def run_stdout(cmd, success_retcodes=success_retcodes, **kwargs) - log_callback = _check_cb(log_callback) - - lvl = _check_loglevel(output_loglevel) - if lvl is not None: - if not ignore_retcode and ret['retcode'] != 0: - if lvl < LOG_LEVELS['error']: - lvl = LOG_LEVELS['error'] - msg = ( - 'Command \'{0}\' failed with return code: {1}'.format( - cmd, - ret['retcode'] - ) - ) - log.error(log_callback(msg)) - if ret['stdout']: - log.log(lvl, 'stdout: {0}'.format(log_callback(ret['stdout']))) - if ret['stderr']: - log.log(lvl, 'stderr: {0}'.format(log_callback(ret['stderr']))) - if ret['retcode']: - log.log(lvl, 'retcode: {0}'.format(ret['retcode'])) return ret['stdout'] if not hide_output else '' @@ -1516,6 +1530,7 @@ def run_stderr(cmd, template=None, rstrip=True, umask=None, + output_encoding=None, output_loglevel='debug', log_callback=None, hide_output=False, @@ -1531,116 +1546,108 @@ def run_stderr(cmd, ''' Execute a command and only return the standard error - :param str cmd: The command to run. ex: 'ls -lart /home' + :param str cmd: The command to run. ex: ``ls -lart /home`` - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the - command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input.: + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - :param str runas: User to run command as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 :param str group: Group to run command as. Not currently supported on Windows. - :param str shell: Shell to execute under. Defaults to the system default - shell. + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. :param bool python_shell: If False, let python handle the positional - arguments. Set to True to use shell features, such as pipes or redirection + arguments. Set to True to use shell features, such as pipes or + redirection. - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.run_stderr 'some command' env='{"FOO": "bar"}' :param bool clean_env: Attempt to clean out all other shell environment - variables and set only those provided in the 'env' argument to this - function. + variables and set only those provided in the 'env' argument to this + function. - :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) - to $PATH + :param str prepend_path: $PATH segment to prepend (trailing ':' not + necessary) to $PATH - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is - returned. + returned. :param str umask: The umask (in octal) to use when running the command. - :param str output_loglevel: Control the loglevel at which the output from - the command is logged to the minion log. + :param str output_encoding: Control the encoding used to decode the + command's output. - .. note:: - The command being run will still be logged at the ``debug`` - loglevel regardless, unless ``quiet`` is used for this value. + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the - return data. + return data. - .. note:: - This is separate from ``output_loglevel``, which only handles how - Salt logs to the minion log. + .. note:: + This is separate from ``output_loglevel``, which only handles how + Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 - :param int timeout: A timeout in seconds for the executed process to return. + :param int timeout: A timeout in seconds for the executed process to + return. :param bool use_vt: Use VT utils (saltstack) to stream the command output - more interactively to the console and the logs. This is experimental. - - .. note:: - ``env`` represents the environment variables for the command, and - should be formatted as a dict, or a YAML string which resolves to a dict. + more interactively to the console and the logs. This is experimental. :param list success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -1664,7 +1671,7 @@ def run_stderr(cmd, A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive - information must be read from standard input.: + information must be read from standard input. .. code-block:: bash @@ -1685,6 +1692,7 @@ def run_stderr(cmd, template=template, rstrip=rstrip, umask=umask, + output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, @@ -1696,26 +1704,6 @@ def run_stderr(cmd, success_retcodes=success_retcodes, **kwargs) - log_callback = _check_cb(log_callback) - - lvl = _check_loglevel(output_loglevel) - if lvl is not None: - if not ignore_retcode and ret['retcode'] != 0: - if lvl < LOG_LEVELS['error']: - lvl = LOG_LEVELS['error'] - msg = ( - 'Command \'{0}\' failed with return code: {1}'.format( - cmd, - ret['retcode'] - ) - ) - log.error(log_callback(msg)) - if ret['stdout']: - log.log(lvl, 'stdout: {0}'.format(log_callback(ret['stdout']))) - if ret['stderr']: - log.log(lvl, 'stderr: {0}'.format(log_callback(ret['stderr']))) - if ret['retcode']: - log.log(lvl, 'retcode: {0}'.format(ret['retcode'])) return ret['stderr'] if not hide_output else '' @@ -1731,6 +1719,7 @@ def run_all(cmd, template=None, rstrip=True, umask=None, + output_encoding=None, output_loglevel='debug', log_callback=None, hide_output=False, @@ -1748,138 +1737,130 @@ def run_all(cmd, ''' Execute the passed command and return a dict of return data - :param str cmd: The command to run. ex: 'ls -lart /home' + :param str cmd: The command to run. ex: ``ls -lart /home`` - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the - command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input.: + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - :param str runas: User to run command as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 :param str group: Group to run command as. Not currently supported on Windows. - :param str shell: Shell to execute under. Defaults to the system default - shell. + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. :param bool python_shell: If False, let python handle the positional - arguments. Set to True to use shell features, such as pipes or redirection + arguments. Set to True to use shell features, such as pipes or + redirection. - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.run_all 'some command' env='{"FOO": "bar"}' :param bool clean_env: Attempt to clean out all other shell environment - variables and set only those provided in the 'env' argument to this - function. + variables and set only those provided in the 'env' argument to this + function. - :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) - to $PATH + :param str prepend_path: $PATH segment to prepend (trailing ':' not + necessary) to $PATH - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is - returned. + returned. :param str umask: The umask (in octal) to use when running the command. - :param str output_loglevel: Control the loglevel at which the output from - the command is logged to the minion log. + :param str output_encoding: Control the encoding used to decode the + command's output. - .. note:: - The command being run will still be logged at the ``debug`` - loglevel regardless, unless ``quiet`` is used for this value. + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the - return data. + return data. - .. note:: - This is separate from ``output_loglevel``, which only handles how - Salt logs to the minion log. + .. note:: + This is separate from ``output_loglevel``, which only handles how + Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 - :param int timeout: A timeout in seconds for the executed process to return. + :param int timeout: A timeout in seconds for the executed process to + return. :param bool use_vt: Use VT utils (saltstack) to stream the command output - more interactively to the console and the logs. This is experimental. - - .. note:: - ``env`` represents the environment variables for the command, and - should be formatted as a dict, or a YAML string which resolves to a dict. + more interactively to the console and the logs. This is experimental. :param bool encoded_cmd: Specify if the supplied command is encoded. - Only applies to shell 'powershell'. + Only applies to shell 'powershell'. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param bool redirect_stderr: If set to ``True``, then stderr will be - redirected to stdout. This is helpful for cases where obtaining both the - retcode and output is desired, but it is not desired to have the output - separated into both stdout and stderr. + redirected to stdout. This is helpful for cases where obtaining both + the retcode and output is desired, but it is not desired to have the + output separated into both stdout and stderr. .. versionadded:: 2015.8.2 :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 :param bool bg: If ``True``, run command in background and do not await or - deliver it's results + deliver its results - .. versionadded:: 2016.3.6 + .. versionadded:: 2016.3.6 :param list success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -1903,7 +1884,7 @@ def run_all(cmd, A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive - information must be read from standard input.: + information must be read from standard input. .. code-block:: bash @@ -1926,6 +1907,7 @@ def run_all(cmd, template=template, rstrip=rstrip, umask=umask, + output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, @@ -1938,27 +1920,6 @@ def run_all(cmd, success_retcodes=success_retcodes, **kwargs) - log_callback = _check_cb(log_callback) - - lvl = _check_loglevel(output_loglevel) - if lvl is not None: - if not ignore_retcode and ret['retcode'] != 0: - if lvl < LOG_LEVELS['error']: - lvl = LOG_LEVELS['error'] - msg = ( - 'Command \'{0}\' failed with return code: {1}'.format( - cmd, - ret['retcode'] - ) - ) - log.error(log_callback(msg)) - if ret['stdout']: - log.log(lvl, 'stdout: {0}'.format(log_callback(ret['stdout']))) - if ret['stderr']: - log.log(lvl, 'stderr: {0}'.format(log_callback(ret['stderr']))) - if ret['retcode']: - log.log(lvl, 'retcode: {0}'.format(ret['retcode'])) - if hide_output: ret['stdout'] = ret['stderr'] = '' return ret @@ -1975,6 +1936,7 @@ def retcode(cmd, clean_env=False, template=None, umask=None, + output_encoding=None, output_loglevel='debug', log_callback=None, timeout=None, @@ -1988,100 +1950,94 @@ def retcode(cmd, ''' Execute a shell command and return the command's return code. - :param str cmd: The command to run. ex: 'ls -lart /home' + :param str cmd: The command to run. ex: ``ls -lart /home`` - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the - command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input.: + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - :param str runas: User to run command as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 :param str group: Group to run command as. Not currently supported on Windows. - :param str shell: Shell to execute under. Defaults to the system default - shell. + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. :param bool python_shell: If False, let python handle the positional - arguments. Set to True to use shell features, such as pipes or redirection + arguments. Set to True to use shell features, such as pipes or + redirection. - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.retcode 'some command' env='{"FOO": "bar"}' :param bool clean_env: Attempt to clean out all other shell environment - variables and set only those provided in the 'env' argument to this - function. + variables and set only those provided in the 'env' argument to this + function. :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is - returned. + returned. :param str umask: The umask (in octal) to use when running the command. + :param str output_encoding: Control the encoding used to decode the + command's output. + + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + :param str output_loglevel: Control the loglevel at which the output from - the command is logged. Note that the command being run will still be logged - (loglevel: DEBUG) regardless, unless ``quiet`` is used for this value. + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. - .. note:: - ``env`` represents the environment variables for the command, and - should be formatted as a dict, or a YAML string which resolves to a dict. - :rtype: int :rtype: None :returns: Return Code as an int or None if there was an exception. @@ -2108,7 +2064,7 @@ def retcode(cmd, A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive - information must be read from standard input.: + information must be read from standard input. .. code-block:: bash @@ -2126,6 +2082,7 @@ def retcode(cmd, clean_env=clean_env, template=template, umask=umask, + output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, @@ -2136,22 +2093,6 @@ def retcode(cmd, password=password, success_retcodes=success_retcodes, **kwargs) - - log_callback = _check_cb(log_callback) - - lvl = _check_loglevel(output_loglevel) - if lvl is not None: - if not ignore_retcode and ret['retcode'] != 0: - if lvl < LOG_LEVELS['error']: - lvl = LOG_LEVELS['error'] - msg = ( - 'Command \'{0}\' failed with return code: {1}'.format( - cmd, - ret['retcode'] - ) - ) - log.error(log_callback(msg)) - log.log(lvl, 'output: {0}'.format(log_callback(ret['stdout']))) return ret['retcode'] @@ -2166,7 +2107,7 @@ def _retcode_quiet(cmd, clean_env=False, template=None, umask=None, - output_loglevel='quiet', + output_encoding=None, log_callback=None, timeout=None, reset_system_locale=True, @@ -2177,8 +2118,8 @@ def _retcode_quiet(cmd, success_retcodes=None, **kwargs): ''' - Helper for running commands quietly for minion startup. - Returns same as retcode + Helper for running commands quietly for minion startup. Returns same as + the retcode() function. ''' return retcode(cmd, cwd=cwd, @@ -2191,7 +2132,8 @@ def _retcode_quiet(cmd, clean_env=clean_env, template=template, umask=umask, - output_loglevel=output_loglevel, + output_encoding=output_encoding, + output_loglevel='quiet', log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, @@ -2214,6 +2156,7 @@ def script(source, env=None, template=None, umask=None, + output_encoding=None, output_loglevel='debug', log_callback=None, hide_output=False, @@ -2234,110 +2177,109 @@ def script(source, programming language. :param str source: The location of the script to download. If the file is - located on the master in the directory named spam, and is called eggs, the - source string is salt://spam/eggs + located on the master in the directory named spam, and is called eggs, + the source string is salt://spam/eggs - :param str args: String of command line args to pass to the script. Only - used if no args are specified as part of the `name` argument. To pass a - string containing spaces in YAML, you will need to doubly-quote it: - "arg1 'arg two' arg3" + :param str args: String of command line args to pass to the script. Only + used if no args are specified as part of the `name` argument. To pass a + string containing spaces in YAML, you will need to doubly-quote it: - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + .. code-block:: bash + + salt myminion cmd.script salt://foo.sh "arg1 'arg two' arg3" + + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the - command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input.: + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - :param str runas: User to run script as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 :param str group: Group to run script as. Not currently supported on Windows. - :param str shell: Shell to execute under. Defaults to the system default - shell. + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. :param bool python_shell: If False, let python handle the positional - arguments. Set to True to use shell features, such as pipes or redirection + arguments. Set to True to use shell features, such as pipes or + redirection. - :param bool bg: If True, run script in background and do not await or deliver it's results + :param bool bg: If True, run script in background and do not await or + deliver it's results - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.script 'some command' env='{"FOO": "bar"}' :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param str umask: The umask (in octal) to use when running the command. - :param str output_loglevel: Control the loglevel at which the output from - the command is logged to the minion log. + :param str output_encoding: Control the encoding used to decode the + command's output. - .. note:: - The command being run will still be logged at the ``debug`` - loglevel regardless, unless ``quiet`` is used for this value. + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the - return data. + return data. - .. note:: - This is separate from ``output_loglevel``, which only handles how - Salt logs to the minion log. + .. note:: + This is separate from ``output_loglevel``, which only handles how + Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 - :param int timeout: If the command has not terminated after timeout seconds, - send the subprocess sigterm, and if sigterm is ignored, follow up with - sigkill + :param int timeout: If the command has not terminated after timeout + seconds, send the subprocess sigterm, and if sigterm is ignored, follow + up with sigkill :param bool use_vt: Use VT utils (saltstack) to stream the command output - more interactively to the console and the logs. This is experimental. + more interactively to the console and the logs. This is experimental. :param list success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -2366,10 +2308,8 @@ def script(source, __salt__['file.remove'](path) except (SaltInvocationError, CommandExecutionError) as exc: log.error( - 'cmd.script: Unable to clean tempfile \'{0}\': {1}'.format( - path, - exc - ) + 'cmd.script: Unable to clean tempfile \'%s\': %s', + path, exc, exc_info_on_loglevel=logging.DEBUG ) if '__env__' in kwargs: @@ -2425,6 +2365,7 @@ def script(source, ret = _run(path + ' ' + six.text_type(args) if args else path, cwd=cwd, stdin=stdin, + output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, runas=runas, @@ -2465,6 +2406,7 @@ def script_retcode(source, timeout=None, reset_system_locale=True, saltenv='base', + output_encoding=None, output_loglevel='debug', log_callback=None, use_vt=False, @@ -2484,104 +2426,94 @@ def script_retcode(source, Only evaluate the script return code and do not block for terminal output :param str source: The location of the script to download. If the file is - located on the master in the directory named spam, and is called eggs, the - source string is salt://spam/eggs + located on the master in the directory named spam, and is called eggs, + the source string is salt://spam/eggs :param str args: String of command line args to pass to the script. Only - used if no args are specified as part of the `name` argument. To pass a - string containing spaces in YAML, you will need to doubly-quote it: "arg1 - 'arg two' arg3" + used if no args are specified as part of the `name` argument. To pass a + string containing spaces in YAML, you will need to doubly-quote it: + "arg1 'arg two' arg3" - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the - command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input.: + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - :param str runas: User to run script as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - .. versionadded:: 2016.3.0 + .. versionadded:: 2016.3.0 :param str group: Group to run script as. Not currently supported on Windows. - :param str shell: Shell to execute under. Defaults to the system default - shell. + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. :param bool python_shell: If False, let python handle the positional - arguments. Set to True to use shell features, such as pipes or redirection + arguments. Set to True to use shell features, such as pipes or + redirection. - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.script_retcode 'some command' env='{"FOO": "bar"}' :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param str umask: The umask (in octal) to use when running the command. + :param str output_encoding: Control the encoding used to decode the + command's output. + + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + :param str output_loglevel: Control the loglevel at which the output from - the command is logged to the minion log. + the command is logged to the minion log. - .. note:: - The command being run will still be logged at the ``debug`` - loglevel regardless, unless ``quiet`` is used for this value. + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. - :param bool quiet: The command will be executed quietly, meaning no log - entries of the actual command or its return data. This is deprecated as of - the **2014.1.0** release, and is being replaced with ``output_loglevel: - quiet``. + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. - :param int timeout: If the command has not terminated after timeout seconds, - send the subprocess sigterm, and if sigterm is ignored, follow up with - sigkill + :param int timeout: If the command has not terminated after timeout + seconds, send the subprocess sigterm, and if sigterm is ignored, follow + up with sigkill :param bool use_vt: Use VT utils (saltstack) to stream the command output - more interactively to the console and the logs. This is experimental. + more interactively to the console and the logs. This is experimental. :param list success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -2599,7 +2531,7 @@ def script_retcode(source, A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive - information must be read from standard input.: + information must be read from standard input. .. code-block:: bash @@ -2623,6 +2555,7 @@ def script_retcode(source, timeout=timeout, reset_system_locale=reset_system_locale, saltenv=saltenv, + output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, use_vt=use_vt, @@ -2771,6 +2704,7 @@ def run_chroot(root, template=None, rstrip=True, umask=None, + output_encoding=None, output_loglevel='quiet', log_callback=None, hide_output=False, @@ -2788,15 +2722,7 @@ def run_chroot(root, This function runs :mod:`cmd.run_all ` wrapped within a chroot, with dev and proc mounted in the chroot - root - Path to the root of the jail to use. - - cmd - The command to run. ex: 'ls -lart /home' - - cwd - The current working directory to execute the command in. defaults to - /root + :param str root: Path to the root of the jail to use. stdin A string of standard input can be specified for the command to be run using @@ -2812,90 +2738,97 @@ def run_chroot(root, shell Shell to execute under. Defaults to the system default shell. - python_shell - If False, let python handle the positional arguments. Set to True - to use shell features, such as pipes or redirection + :param str cmd: The command to run. ex: ``ls -lart /home`` - env - A list of environment variables to be set prior to execution. - Example: + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). - .. code-block:: yaml + :parar str stdin: A string of standard input can be specified for the + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. - .. warning:: + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. + :param bool python_shell: If False, let python handle the positional + arguments. Set to True to use shell features, such as pipes or + redirection. - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': + :param dict env: Environment variables to be set prior to execution. - .. code-block:: yaml + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" + .. code-block:: bash - One can still use the existing $PATH by using a bit of Jinja: + salt myminion cmd.run_chroot 'some command' env='{"FOO": "bar"}' - .. code-block:: jinja + :param dict clean_env: Attempt to clean out all other shell environment + variables and set only those provided in the 'env' argument to this + function. - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} + :param str template: If this setting is applied then the named templating + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} - - clean_env: - Attempt to clean out all other shell environment variables and set - only those provided in the 'env' argument to this function. - - template - If this setting is applied then the named templating engine will be - used to render the downloaded file. Currently jinja, mako, and wempy - are supported - - rstrip + :param bool rstrip: Strip all whitespace off the end of output before it is returned. - umask + :param str umask: The umask (in octal) to use when running the command. - output_loglevel : quiet - Control the loglevel at which the output from the command is logged to - the minion log. + :param str output_encoding: Control the encoding used to decode the + command's output. + + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. - hide_output : False - If ``True``, suppress stdout and stderr in the return data. + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. + + :param bool hide_output: If ``True``, suppress stdout and stderr in the + return data. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 - timeout + :param int timeout: A timeout in seconds for the executed process to return. - use_vt + :param bool use_vt: Use VT utils (saltstack) to stream the command output more - interactively to the console and the logs. - This is experimental. - + interactively to the console and the logs. This is experimental. success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -2941,6 +2874,7 @@ CLI Example: template=template, rstrip=rstrip, umask=umask, + output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, @@ -3030,7 +2964,7 @@ def shells(): else: ret.append(line) except OSError: - log.error("File '{0}' was not found".format(shells_fn)) + log.error("File '%s' was not found", shells_fn) return ret @@ -3157,7 +3091,7 @@ def shell_info(shell, list_modules=False): newenv = os.environ if ('HOME' not in newenv) and (not salt.utils.platform.is_windows()): newenv['HOME'] = os.path.expanduser('~') - log.debug('HOME environment set to {0}'.format(newenv['HOME'])) + log.debug('HOME environment set to %s', newenv['HOME']) try: proc = salt.utils.timed_subprocess.TimedProc( shell_data, @@ -3221,6 +3155,7 @@ def powershell(cmd, template=None, rstrip=True, umask=None, + output_encoding=None, output_loglevel='debug', hide_output=False, timeout=None, @@ -3259,9 +3194,6 @@ def powershell(cmd, have properly sanitized the command passed to this function and do not use untrusted inputs. - Note that ``env`` represents the environment variables for the command, and - should be formatted as a dict, or a YAML string which resolves to a dict. - In addition to the normal ``cmd.run`` parameters, this command offers the ``depth`` parameter to change the Windows default depth for the ``ConvertTo-JSON`` powershell command. The Windows default is 2. If you need @@ -3274,107 +3206,100 @@ def powershell(cmd, :param str cmd: The powershell command to run. - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input.: + where sensitive information must be read from standard input. - :param str runas: User to run command as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 - :param str shell: Shell to execute under. Defaults to the system default - shell. + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. :param bool python_shell: If False, let python handle the positional - arguments. Set to True to use shell features, such as pipes or redirection + arguments. Set to True to use shell features, such as pipes or + redirection. - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.powershell 'some command' env='{"FOO": "bar"}' :param bool clean_env: Attempt to clean out all other shell environment - variables and set only those provided in the 'env' argument to this - function. + variables and set only those provided in the 'env' argument to this + function. :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is - returned. + returned. :param str umask: The umask (in octal) to use when running the command. - :param str output_loglevel: Control the loglevel at which the output from - the command is logged to the minion log. + :param str output_encoding: Control the encoding used to decode the + command's output. - .. note:: - The command being run will still be logged at the ``debug`` - loglevel regardless, unless ``quiet`` is used for this value. + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the - return data. + return data. - .. note:: - This is separate from ``output_loglevel``, which only handles how - Salt logs to the minion log. + .. note:: + This is separate from ``output_loglevel``, which only handles how + Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output - more interactively to the console and the logs. This is experimental. + more interactively to the console and the logs. This is experimental. :param bool reset_system_locale: Resets the system locale - :param bool ignore_retcode: Ignore the return code - :param str saltenv: The salt environment to use. Default is 'base' :param int depth: The number of levels of contained objects to be included. @@ -3384,8 +3309,8 @@ def powershell(cmd, .. versionadded:: 2016.3.4 :param bool encode_cmd: Encode the command before executing. Use in cases - where characters may be dropped or incorrectly converted when executed. - Default is False. + where characters may be dropped or incorrectly converted when executed. + Default is False. :param list success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -3416,7 +3341,7 @@ def powershell(cmd, if encode_cmd: # Convert the cmd to UTF-16LE without a BOM and base64 encode. # Just base64 encoding UTF-8 or including a BOM is not valid. - log.debug('Encoding PowerShell command \'{0}\''.format(cmd)) + log.debug('Encoding PowerShell command \'%s\'', cmd) cmd_utf16 = cmd.decode('utf-8').encode('utf-16le') cmd = base64.standard_b64encode(cmd_utf16) encoded_cmd = True @@ -3441,6 +3366,7 @@ def powershell(cmd, template=template, rstrip=rstrip, umask=umask, + output_encoding=output_encoding, output_loglevel=output_loglevel, hide_output=hide_output, timeout=timeout, @@ -3471,6 +3397,7 @@ def powershell_all(cmd, template=None, rstrip=True, umask=None, + output_encoding=None, output_loglevel='debug', quiet=False, timeout=None, @@ -3485,62 +3412,64 @@ def powershell_all(cmd, success_retcodes=None, **kwargs): ''' - Execute the passed PowerShell command and return a dictionary with a result field - representing the output of the command, as well as other fields - showing us what the PowerShell invocation wrote to ``stderr``, the process id, - and the exit code of the invocation. + Execute the passed PowerShell command and return a dictionary with a result + field representing the output of the command, as well as other fields + showing us what the PowerShell invocation wrote to ``stderr``, the process + id, and the exit code of the invocation. - This function appends ``| ConvertTo-JSON`` to the command before actually invoking powershell. + This function appends ``| ConvertTo-JSON`` to the command before actually + invoking powershell. - An unquoted empty string is not valid JSON, but it's very normal for the Powershell - output to be exactly that. Therefore, we do not attempt to - parse empty Powershell output (which would - result in an exception). Instead we treat this as a special case and one of two things - will happen: - * If the value of the ``force_list`` paramater - is ``True`` then the ``result`` field of the return dictionary will be an empty list. - * If the value of the ``force_list`` paramater is ``False``, then the return dictionary - **will not have a result key added to it**. We aren't setting ``result`` to ``None`` in this - case, because ``None`` is the Python representation of "null" in JSON. (We likewise can't use - ``False`` for the equivalent reason.) + An unquoted empty string is not valid JSON, but it's very normal for the + Powershell output to be exactly that. Therefore, we do not attempt to parse + empty Powershell output (which would result in an exception). Instead we + treat this as a special case and one of two things will happen: - If Powershell's output is not an empty string and Python cannot parse its content, - then a ``CommandExecutionError`` exception will be raised. + - If the value of the ``force_list`` paramater is ``True``, then the + ``result`` field of the return dictionary will be an empty list. - If Powershell's output is not an empty string, Python is able to parse its content, - and the type of the resulting Python object is other than ``list`` then one of two things - will happen: - * If the value of the ``force_list`` paramater is ``True``, then the ``result`` field - will be a singleton list - with the Python object as its sole member. - * If the value of the ``force_list`` paramater is ``False``, then the value of - ``result`` will be - the unmodified Python object. + - If the value of the ``force_list`` paramater is ``False``, then the + return dictionary **will not have a result key added to it**. We aren't + setting ``result`` to ``None`` in this case, because ``None`` is the + Python representation of "null" in JSON. (We likewise can't use ``False`` + for the equivalent reason.) - If Powershell's output is not an empty string, Python is able to parse its content, - and the type of the resulting Python object is ``list``, then the value of ``result`` - will be the unmodified Python object. The ``force_list`` paramater has no effect in this case. + If Powershell's output is not an empty string and Python cannot parse its + content, then a ``CommandExecutionError`` exception will be raised. - .. Note:: - An example of why the ``force_list`` paramater is useful is as follows: The - Powershell command - ``dir x | Convert-ToJson`` results in + If Powershell's output is not an empty string, Python is able to parse its + content, and the type of the resulting Python object is other than ``list`` + then one of two things will happen: - * no output when x is an empty directory. - * a dictionary object when x contains just one item. - * a list of dictionary objects when x contains multiple items. + - If the value of the ``force_list`` paramater is ``True``, then the + ``result`` field will be a singleton list with the Python object as its + sole member. - By setting ``force_list`` to ``True`` we will always end up with a list of dictionary items, - representing files, - no matter how many files x contains. - Conversely, if ``force_list`` is ``False``, we will end up with no ``result`` key in our - return dictionary - when x is an - empty directory, and a dictionary object when x contains just one file. + - If the value of the ``force_list`` paramater is ``False``, then the value + of ``result`` will be the unmodified Python object. - If you want a similar function but with a raw - textual result instead of a Python dictionary, - you should use ``cmd.run_all`` in combination with ``shell=powershell``. + If Powershell's output is not an empty string, Python is able to parse its + content, and the type of the resulting Python object is ``list``, then the + value of ``result`` will be the unmodified Python object. The + ``force_list`` paramater has no effect in this case. + + .. note:: + An example of why the ``force_list`` paramater is useful is as + follows: The Powershell command ``dir x | Convert-ToJson`` results in + + - no output when x is an empty directory. + - a dictionary object when x contains just one item. + - a list of dictionary objects when x contains multiple items. + + By setting ``force_list`` to ``True`` we will always end up with a + list of dictionary items, representing files, no matter how many files + x contains. Conversely, if ``force_list`` is ``False``, we will end + up with no ``result`` key in our return dictionary when x is an empty + directory, and a dictionary object when x contains just one file. + + If you want a similar function but with a raw textual result instead of a + Python dictionary, you should use ``cmd.run_all`` in combination with + ``shell=powershell``. The remaining fields in the return dictionary are described in more detail in the ``Returns`` section. @@ -3552,17 +3481,13 @@ def powershell_all(cmd, salt '*' cmd.run_all '$PSVersionTable.CLRVersion' shell=powershell salt '*' cmd.run_all 'Get-NetTCPConnection' shell=powershell - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. warning:: - This passes the cmd argument directly to PowerShell - without any further processing! Be absolutely sure that you - have properly sanitized the command passed to this function - and do not use untrusted inputs. - - Note that ``env`` represents the environment variables for the command, and - should be formatted as a dict, or a YAML string which resolves to a dict. + This passes the cmd argument directly to PowerShell without any further + processing! Be absolutely sure that you have properly sanitized the + command passed to this function and do not use untrusted inputs. In addition to the normal ``cmd.run`` parameters, this command offers the ``depth`` parameter to change the Windows default depth for the @@ -3576,92 +3501,96 @@ def powershell_all(cmd, :param str cmd: The powershell command to run. - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the - command to be run using the ``stdin`` parameter. This can be useful in cases - where sensitive information must be read from standard input.: + command to be run using the ``stdin`` parameter. This can be useful in + cases where sensitive information must be read from standard input. - :param str runas: User to run command as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. + parameter will be ignored on non-Windows platforms. - :param str shell: Shell to execute under. Defaults to the system default - shell. + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. :param bool python_shell: If False, let python handle the positional - arguments. Set to True to use shell features, such as pipes or redirection + arguments. Set to True to use shell features, such as pipes or + redirection. - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.powershell_all 'some command' env='{"FOO": "bar"}' :param bool clean_env: Attempt to clean out all other shell environment - variables and set only those provided in the 'env' argument to this - function. + variables and set only those provided in the 'env' argument to this + function. :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is - returned. + returned. :param str umask: The umask (in octal) to use when running the command. - :param str output_loglevel: Control the loglevel at which the output from - the command is logged. Note that the command being run will still be logged - (loglevel: DEBUG) regardless, unless ``quiet`` is used for this value. + :param str output_encoding: Control the encoding used to decode the + command's output. - :param int timeout: A timeout in seconds for the executed process to return. + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. + + :param int timeout: A timeout in seconds for the executed process to + return. :param bool use_vt: Use VT utils (saltstack) to stream the command output - more interactively to the console and the logs. This is experimental. + more interactively to the console and the logs. This is experimental. :param bool reset_system_locale: Resets the system locale - :param bool ignore_retcode: Ignore the return code + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. :param str saltenv: The salt environment to use. Default is 'base' @@ -3670,11 +3599,11 @@ def powershell_all(cmd, it takes for the command to complete for some commands. eg: ``dir`` :param bool encode_cmd: Encode the command before executing. Use in cases - where characters may be dropped or incorrectly converted when executed. - Default is False. + where characters may be dropped or incorrectly converted when executed. + Default is False. - :param bool force_list: The purpose of this paramater is described in the preamble - of this function's documentation. Default value is False. + :param bool force_list: The purpose of this paramater is described in the + preamble of this function's documentation. Default value is False. :param list success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -3688,8 +3617,8 @@ def powershell_all(cmd, result For a complete description of this field, please refer to this function's preamble. **This key will not be added to the dictionary - when force_list is False and Powershell's output - is the empty string.** + when force_list is False and Powershell's output is the empty + string.** stderr What the PowerShell invocation wrote to ``stderr``. pid @@ -3728,7 +3657,7 @@ def powershell_all(cmd, if encode_cmd: # Convert the cmd to UTF-16LE without a BOM and base64 encode. # Just base64 encoding UTF-8 or including a BOM is not valid. - log.debug('Encoding PowerShell command \'{0}\''.format(cmd)) + log.debug('Encoding PowerShell command \'%s\'', cmd) cmd_utf16 = cmd.decode('utf-8').encode('utf-16le') cmd = base64.standard_b64encode(cmd_utf16) encoded_cmd = True @@ -3746,6 +3675,7 @@ def powershell_all(cmd, template=template, rstrip=rstrip, umask=umask, + output_encoding=output_encoding, output_loglevel=output_loglevel, quiet=quiet, timeout=timeout, @@ -3804,6 +3734,7 @@ def run_bg(cmd, template=None, umask=None, timeout=None, + output_encoding=None, output_loglevel='debug', log_callback=None, reset_system_locale=True, @@ -3818,32 +3749,19 @@ def run_bg(cmd, Execute the passed command in the background and return it's PID - Note that ``env`` represents the environment variables for the command, and - should be formatted as a dict, or a YAML string which resolves to a dict. - .. note:: - If the init system is systemd and the backgrounded task should run even if the salt-minion process - is restarted, prepend ``systemd-run --scope`` to the command. This will reparent the process in its - own scope separate from salt-minion, and will not be affected by restarting the minion service. + If the init system is systemd and the backgrounded task should run even + if the salt-minion process is restarted, prepend ``systemd-run + --scope`` to the command. This will reparent the process in its own + scope separate from salt-minion, and will not be affected by restarting + the minion service. - :param str cmd: The command to run. ex: 'ls -lart /home' + :param str cmd: The command to run. ex: ``ls -lart /home`` - :param str cwd: The current working directory to execute the command in. - Defaults to the home directory of the user specified by ``runas``. - - :param str output_loglevel: Control the loglevel at which the output from - the command is logged. Note that the command being run will still be logged - (loglevel: DEBUG) regardless, unless ``quiet`` is used for this value. - - :param str runas: User to run command as. If running on a Windows minion you - must also pass a password. The target user account must be in the - Administrators group. - - :param str password: Windows only. Required when specifying ``runas``. This - parameter will be ignored on non-Windows platforms. - - .. versionadded:: 2016.3.0 + :param str cwd: The directory from which to execute the command. Defaults + to the home directory of the user specified by ``runas`` (or the user + under which Salt is running if ``runas`` is not specified). :param str group: Group to run command as. Not currently supported on Windows. @@ -3851,62 +3769,75 @@ def run_bg(cmd, :param str shell: Shell to execute under. Defaults to the system default shell. + :param str output_encoding: Control the encoding used to decode the + command's output. + + .. note:: + This should not need to be used in most cases. By default, Salt + will try to use the encoding detected from the system locale, and + will fall back to UTF-8 if this fails. This should only need to be + used in cases where the output of the command is encoded in + something other than the system locale or UTF-8. + + To see the encoding Salt has detected from the system locale, check + the `locale` line in the output of :py:func:`test.versions_report + `. + + .. versionadded:: 2018.3.0 + + :param str output_loglevel: Control the loglevel at which the output from + the command is logged to the minion log. + + .. note:: + The command being run will still be logged at the ``debug`` + loglevel regardless, unless ``quiet`` is used for this value. + + :param bool ignore_retcode: If the exit code of the command is nonzero, + this is treated as an error condition, and the output from the command + will be logged to the minion log. However, there are some cases where + programs use the return code for signaling and a nonzero exit code + doesn't necessarily mean failure. Pass this argument as ``True`` to + skip logging the output if the command has a nonzero exit code. + + :param str runas: Specify an alternate user to run the command. The default + behavior is to run as the user under which Salt is running. If running + on a Windows minion you must also use the ``password`` argument, and + the target user account must be in the Administrators group. + + :param str password: Windows only. Required when specifying ``runas``. This + parameter will be ignored on non-Windows platforms. + + .. versionadded:: 2016.3.0 + + :param str shell: Specify an alternate shell. Defaults to the system's + default shell. + :param bool python_shell: If False, let python handle the positional - arguments. Set to True to use shell features, such as pipes or redirection + arguments. Set to True to use shell features, such as pipes or + redirection. - :param list env: A list of environment variables to be set prior to - execution. + :param dict env: Environment variables to be set prior to execution. - Example: + .. note:: + When passing environment variables on the CLI, they should be + passed as the string representation of a dictionary. - .. code-block:: yaml + .. code-block:: bash - salt://scripts/foo.sh: - cmd.script: - - env: - - BATCH: 'yes' - - .. warning:: - - The above illustrates a common PyYAML pitfall, that **yes**, - **no**, **on**, **off**, **true**, and **false** are all loaded as - boolean ``True`` and ``False`` values, and must be enclosed in - quotes to be used as strings. More info on this (and other) PyYAML - idiosyncrasies can be found :ref:`here `. - - Variables as values are not evaluated. So $PATH in the following - example is a literal '$PATH': - - .. code-block:: yaml - - salt://scripts/bar.sh: - cmd.script: - - env: "PATH=/some/path:$PATH" - - One can still use the existing $PATH by using a bit of Jinja: - - .. code-block:: jinja - - {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} - - mycommand: - cmd.run: - - name: ls -l / - - env: - - PATH: {{ [current_path, '/my/special/bin']|join(':') }} + salt myminion cmd.run_bg 'some command' env='{"FOO": "bar"}' :param bool clean_env: Attempt to clean out all other shell environment - variables and set only those provided in the 'env' argument to this - function. + variables and set only those provided in the 'env' argument to this + function. - :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) - to $PATH + :param str prepend_path: $PATH segment to prepend (trailing ':' not + necessary) to $PATH - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating - engine will be used to render the downloaded file. Currently jinja, mako, - and wempy are supported + engine will be used to render the downloaded file. Currently jinja, + mako, and wempy are supported. :param str umask: The umask (in octal) to use when running the command. @@ -3914,16 +3845,16 @@ def run_bg(cmd, .. warning:: - This function does not process commands through a shell - unless the python_shell flag is set to True. This means that any + This function does not process commands through a shell unless the + ``python_shell`` argument is set to ``True``. This means that any shell-specific functionality such as 'echo' or the use of pipes, - redirection or &&, should either be migrated to cmd.shell or - have the python_shell=True flag set here. + redirection or &&, should either be migrated to cmd.shell or have the + python_shell=True flag set here. - The use of python_shell=True means that the shell will accept _any_ input - including potentially malicious commands such as 'good_command;rm -rf /'. - Be absolutely certain that you have sanitized your input prior to using - python_shell=True + The use of ``python_shell=True`` means that the shell will accept _any_ + input including potentially malicious commands such as 'good_command;rm + -rf /'. Be absolutely certain that you have sanitized your input prior + to using ``python_shell=True``. :param list success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -3968,6 +3899,7 @@ def run_bg(cmd, stdin=None, stderr=None, stdout=None, + output_encoding=output_encoding, output_loglevel=output_loglevel, use_vt=None, bg=True, @@ -3986,7 +3918,6 @@ def run_bg(cmd, log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, - ignore_retcode=ignore_retcode, saltenv=saltenv, password=password, success_retcodes=success_retcodes, diff --git a/salt/modules/cp.py b/salt/modules/cp.py index 4b3b4df0c5..f93985cdc0 100644 --- a/salt/modules/cp.py +++ b/salt/modules/cp.py @@ -240,7 +240,7 @@ def get_file(path, gzip=None, **kwargs): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 ``dest`` can now be a directory Used to get a single file from the salt master @@ -354,7 +354,7 @@ def get_dir(path, dest, saltenv='base', template=None, gzip=None, **kwargs): def get_url(path, dest='', saltenv='base', makedirs=False, source_hash=None): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 ``dest`` can now be a directory Used to get a single file from a URL. @@ -391,7 +391,7 @@ def get_url(path, dest='', saltenv='base', makedirs=False, source_hash=None): minion's file cache, this option can be passed to keep the minion from re-downloading the file if the cached copy matches the specified hash. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: @@ -445,7 +445,7 @@ def cache_file(path, saltenv='base', source_hash=None): minion's file cache, this option can be passed to keep the minion from re-downloading the file if the cached copy matches the specified hash. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: diff --git a/salt/modules/cryptdev.py b/salt/modules/cryptdev.py index 081d337e0f..1cd005d244 100644 --- a/salt/modules/cryptdev.py +++ b/salt/modules/cryptdev.py @@ -2,7 +2,7 @@ ''' Salt module to manage Unix cryptsetup jobs and the crypttab file -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' # Import python libraries diff --git a/salt/modules/debconfmod.py b/salt/modules/debconfmod.py index 2bbfccf466..a4e08870f0 100644 --- a/salt/modules/debconfmod.py +++ b/salt/modules/debconfmod.py @@ -12,6 +12,7 @@ import re # Import salt libs import salt.utils.path import salt.utils.files +import salt.utils.stringutils import salt.utils.versions log = logging.getLogger(__name__) @@ -128,7 +129,7 @@ def set_(package, question, type, value, *extra): fd_, fname = salt.utils.files.mkstemp(prefix="salt-", close_fd=False) line = "{0} {1} {2} {3}".format(package, question, type, value) - os.write(fd_, line) + os.write(fd_, salt.utils.stringutils.to_bytes(line)) os.close(fd_) _set_file(fname) diff --git a/salt/modules/debian_service.py b/salt/modules/debian_service.py index 6f38dd7eb1..03ee14827a 100644 --- a/salt/modules/debian_service.py +++ b/salt/modules/debian_service.py @@ -229,7 +229,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/dockermod.py b/salt/modules/dockermod.py index 105e902dfd..6bafb30a60 100644 --- a/salt/modules/dockermod.py +++ b/salt/modules/dockermod.py @@ -630,7 +630,6 @@ def _client_wrapper(attr, *args, **kwargs): ) ret = func(*args, **kwargs) except docker.errors.APIError as exc: - log.exception('Encountered error running API function %s', attr) if catch_api_errors: # Generic handling of Docker API errors raise CommandExecutionError( @@ -790,7 +789,7 @@ def get_client_args(limit=None): .. versionchanged:: 2017.7.0 Replaced the container config args with the ones from the API's ``create_container`` function. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Added ability to limit the input to specific client functions Many functions in Salt have been written to support the full list of @@ -885,7 +884,7 @@ def _get_create_kwargs(skip_translate=None, def compare_containers(first, second, ignore=None): ''' .. versionadded:: 2017.7.0 - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Renamed from ``docker.compare_container`` to ``docker.compare_containers`` (old function name remains as an alias) @@ -968,7 +967,7 @@ compare_container = salt.utils.functools.alias_function( def compare_container_networks(first, second): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Returns the differences between two containers' networks. When a network is only present one of the two containers, that network's diff will simply be @@ -1205,7 +1204,7 @@ def compare_container_networks(first, second): def compare_networks(first, second, ignore='Name,Id,Created,Containers'): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Compare two networks and return any differences between the two @@ -1278,7 +1277,7 @@ def compare_networks(first, second, ignore='Name,Id,Created,Containers'): def connected(name, verbose=False): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Return a list of running containers attached to the specified network @@ -1867,7 +1866,7 @@ def list_tags(): def resolve_image_id(name): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Given an image name (or partial image ID), return the full image ID. If no match is found among the locally-pulled images, then ``False`` will be @@ -1898,7 +1897,7 @@ def resolve_image_id(name): def resolve_tag(name, tags=None, **kwargs): ''' .. versionadded:: 2017.7.2 - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Instead of matching against pulled tags using :py:func:`docker.list_tags `, this function now simply inspects the passed image name using @@ -1921,10 +1920,10 @@ def resolve_tag(name, tags=None, **kwargs): is found but there are no tags, then a list will still be returned, but it will simply contain the image ID. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 tags - .. deprecated:: Oxygen + .. deprecated:: 2018.3.0 Ignored if passed, will be removed in the Neon release. CLI Examples: @@ -1973,7 +1972,7 @@ def resolve_tag(name, tags=None, **kwargs): def logs(name, **kwargs): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Support for all of docker-py's `logs()`_ function's arguments, with the exception of ``stream``. @@ -2394,7 +2393,7 @@ def create(image, start : False If ``True``, start container after creating it - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 skip_translate This function translates Salt CLI or SLS input into the format which @@ -2765,7 +2764,7 @@ def create(image, - ``labels=foo,bar=baz`` - ``labels="['foo', 'bar=baz']"`` - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Labels both with and without values can now be mixed. Earlier releases only permitted one method or the other. @@ -3159,7 +3158,7 @@ def run_container(image, networks=None, **kwargs): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Equivalent to ``docker run`` on the Docker CLI. Runs the container, waits for it to exit, and returns the container's logs when complete. @@ -3763,7 +3762,7 @@ def rm_(name, force=False, volumes=False, **kwargs): Optional timeout to be passed to :py:func:`docker.stop ` if stopping the container. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 volumes : False Also remove volumes associated with container @@ -3840,7 +3839,7 @@ def build(path=None, buildargs=None, image=None): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 If the built image should be tagged, then the repository and tag must now be passed separately using the ``repository`` and ``tag`` arguments, rather than together in the (now deprecated) ``image`` @@ -3854,15 +3853,15 @@ def build(path=None, repository Optional repository name for the image being built - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 tag : latest Tag name for the image (required if ``repository`` is passed) - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 image - .. deprecated:: Oxygen + .. deprecated:: 2018.3.0 Use both ``repository`` and ``tag`` instead cache : True @@ -4021,7 +4020,7 @@ def commit(name, author=None, image=None): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The repository and tag must now be passed separately using the ``repository`` and ``tag`` arguments, rather than together in the (now deprecated) ``image`` argument. @@ -4035,15 +4034,15 @@ def commit(name, repository Repository name for the image being committed - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 tag : latest Tag name for the image - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 image - .. deprecated:: Oxygen + .. deprecated:: 2018.3.0 Use both ``repository`` and ``tag`` instead message @@ -4169,7 +4168,7 @@ def import_(source, api_response=False, image=None): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The repository and tag must now be passed separately using the ``repository`` and ``tag`` arguments, rather than together in the (now deprecated) ``image`` argument. @@ -4186,15 +4185,15 @@ def import_(source, repository Repository name for the image being imported - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 tag : latest Tag name for the image - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 image - .. deprecated:: Oxygen + .. deprecated:: 2018.3.0 Use both ``repository`` and ``tag`` instead api_response : False @@ -4277,7 +4276,7 @@ def import_(source, def load(path, repository=None, tag=None, image=None): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 If the loaded image should be tagged, then the repository and tag must now be passed separately using the ``repository`` and ``tag`` arguments, rather than together in the (now deprecated) ``image`` @@ -4299,16 +4298,16 @@ def load(path, repository=None, tag=None, image=None): `. If a repository name is provided, then the ``tag`` argument is also required. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 tag Tag name to go along with the repository name, if the loaded image is to be tagged. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 image - .. deprecated:: Oxygen + .. deprecated:: 2018.3.0 Use both ``repository`` and ``tag`` instead @@ -4434,7 +4433,7 @@ def pull(image, api_response=False, client_timeout=salt.utils.docker.CLIENT_TIMEOUT): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 If no tag is specified in the ``image`` argument, all tags for the image will be pulled. For this reason is it recommended to pass ``image`` using the ``repo:tag`` notation. @@ -4901,7 +4900,7 @@ def save(name, def tag_(name, repository, tag='latest', force=False, image=None): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The repository and tag must now be passed separately using the ``repository`` and ``tag`` arguments, rather than together in the (now deprecated) ``image`` argument. @@ -4915,15 +4914,15 @@ def tag_(name, repository, tag='latest', force=False, image=None): repository Repository name for the image to be built - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 tag : latest Tag name for the image to be built - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 image - .. deprecated:: Oxygen + .. deprecated:: 2018.3.0 Use both ``repository`` and ``tag`` instead force : False @@ -4965,7 +4964,7 @@ def networks(names=None, ids=None): .. versionchanged:: 2017.7.0 The ``names`` and ``ids`` can be passed as a comma-separated list now, as well as a Python list. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The ``Containers`` key for each network is no longer always empty. List existing networks @@ -5009,7 +5008,7 @@ def create_network(name, client_timeout=salt.utils.docker.CLIENT_TIMEOUT, **kwargs): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Support added for network configuration options other than ``driver`` and ``driver_opts``, as well as IPAM configuration. @@ -5054,7 +5053,7 @@ def create_network(name, - docker-py `low-level API`_ - `Docker Engine API`_ - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 ignore_collisions : False Since many of docker-py's arguments differ in name from their CLI @@ -5065,7 +5064,7 @@ def create_network(name, will be raised. Set this argument to ``True`` to suppress these errors and keep the docker-py version of the argument. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 validate_ip_addrs : True For parameters which accept IP addresses as input, IP address @@ -5077,7 +5076,7 @@ def create_network(name, portion will be validated, and the subnet size will be checked to confirm it is a valid number (1-32 for IPv4, 1-128 for IPv6). - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. _salt-modules-dockermod-create-network-netconf: @@ -5313,7 +5312,7 @@ def connect_container_to_network(container, net_id, **kwargs): .. versionadded:: 2015.8.3 .. versionchanged:: 2017.7.0 Support for ``ipv4_address`` argument added - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 All arguments are now passed through to `connect_container_to_network()`_, allowing for any new arguments added to this function to be supported automagically. @@ -5397,7 +5396,7 @@ def disconnect_container_from_network(container, network_id): def disconnect_all_containers_from_network(network_id): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Runs :py:func:`docker.disconnect_container_from_network ` on all @@ -5861,6 +5860,106 @@ def wait(name, ignore_already_stopped=False, fail_on_exit_status=False): return result +def prune(containers=False, networks=False, images=False, + build=False, volumes=False, system=None, **filters): + ''' + .. versionadded:: Fluorine + + Prune Docker's various subsystems + + .. note:: + This requires docker-py version 2.1.0 or later. + + containers : False + If ``True``, prunes stopped containers (documentation__) + + .. __: https://docs.docker.com/engine/reference/commandline/container_prune/#filtering + + images : False + If ``True``, prunes unused images (documentation__) + + .. __: https://docs.docker.com/engine/reference/commandline/image_prune/#filtering + + networks : False + If ``False``, prunes unreferenced networks (documentation__) + + .. __: https://docs.docker.com/engine/reference/commandline/network_prune/#filtering) + + build : False + If ``True``, clears the builder cache + + .. note:: + Only supported in Docker 17.07.x and newer. Additionally, filters + do not apply to this argument. + + volumes : False + If ``True``, prunes unreferenced volumes (documentation__) + + .. __: https://docs.docker.com/engine/reference/commandline/volume_prune/ + + system + If ``True``, prunes containers, images, networks, and builder cache. + Assumed to be ``True`` if none of ``containers``, ``images``, + ``networks``, or ``build`` are set to ``True``. + + .. note:: + ``volumes=True`` must still be used to prune volumes + + filters + - ``dangling=True`` (images only) - remove only dangling images + + - ``until=`` - only remove objects created before given + timestamp. Not applicable to volumes. See the documentation links + above for examples of valid time expressions. + + - ``label`` - only remove objects matching the label expression. Valid + expressions include ``labelname`` or ``labelname=value``. + + CLI Examples: + + .. code-block:: bash + + salt myminion docker.prune system=True + salt myminion docker.prune system=True until=12h + salt myminion docker.prune images=True dangling=True + salt myminion docker.prune images=True label=foo,bar=baz + ''' + if system is None and not any((containers, images, networks, build)): + system = True + + filters = __utils__['args.clean_kwargs'](**filters) + for fname in list(filters): + if not isinstance(filters[fname], bool): + # support comma-separated values + filters[fname] = salt.utils.args.split_input(filters[fname]) + + ret = {} + if system or containers: + ret['containers'] = _client_wrapper('prune_containers', filters=filters) + if system or images: + ret['images'] = _client_wrapper('prune_images', filters=filters) + if system or networks: + ret['networks'] = _client_wrapper('prune_networks', filters=filters) + if system or build: + try: + # Doesn't exist currently in docker-py as of 3.0.1 + ret['build'] = _client_wrapper('prune_build', filters=filters) + except SaltInvocationError: + # It's not in docker-py yet, POST directly to the API endpoint + ret['build'] = _client_wrapper( + '_result', + _client_wrapper( + '_post', + _client_wrapper('_url', '/build/prune') + ), + True + ) + if volumes: + ret['volumes'] = _client_wrapper('prune_volumes', filters=filters) + + return ret + + # Functions to run commands inside containers @_refresh_mine_cache def _run(name, @@ -6583,7 +6682,7 @@ def sls(name, mods=None, **kwargs): :conf_minion:`pillarenv` minion config option nor this CLI argument is used, all Pillar environments will be merged together. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 pillar Custom Pillar values, passed as a dictionary of key-value pairs @@ -6592,7 +6691,7 @@ def sls(name, mods=None, **kwargs): Values passed this way will override Pillar values set via ``pillar_roots`` or an external Pillar source. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: @@ -6679,7 +6778,7 @@ def sls_build(repository, dryrun=False, **kwargs): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The repository and tag must now be passed separately using the ``repository`` and ``tag`` arguments, rather than together in the (now deprecated) ``image`` argument. @@ -6693,15 +6792,15 @@ def sls_build(repository, repository Repository name for the image to be built - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 tag : latest Tag name for the image to be built - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name - .. deprecated:: Oxygen + .. deprecated:: 2018.3.0 Use both ``repository`` and ``tag`` instead base : opensuse/python @@ -6722,7 +6821,7 @@ def sls_build(repository, :conf_minion:`pillarenv` minion config option nor this CLI argument is used, all Pillar environments will be merged together. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 pillar Custom Pillar values, passed as a dictionary of key-value pairs @@ -6731,7 +6830,7 @@ def sls_build(repository, Values passed this way will override Pillar values set via ``pillar_roots`` or an external Pillar source. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 dryrun: False when set to True the container will not be commited at the end of diff --git a/salt/modules/dracr.py b/salt/modules/dracr.py index c8122c7756..d5b278d201 100644 --- a/salt/modules/dracr.py +++ b/salt/modules/dracr.py @@ -29,7 +29,7 @@ try: except (NameError, KeyError): import salt.modules.cmdmod __salt__ = { - 'cmd.run_all': salt.modules.cmdmod._run_all_quiet + 'cmd.run_all': salt.modules.cmdmod.run_all } @@ -95,8 +95,7 @@ def __execute_cmd(command, host=None, output_loglevel='quiet') if cmd['retcode'] != 0: - log.warning('racadm return an exit code \'{0}\'.' - .format(cmd['retcode'])) + log.warning('racadm returned an exit code of %s', cmd['retcode']) return False return True @@ -129,8 +128,7 @@ def __execute_ret(command, host=None, output_loglevel='quiet') if cmd['retcode'] != 0: - log.warning('racadm return an exit code \'{0}\'.' - .format(cmd['retcode'])) + log.warning('racadm returned an exit code of %s', cmd['retcode']) else: fmtlines = [] for l in cmd['stdout'].splitlines(): @@ -193,8 +191,7 @@ def system_info(host=None, module=module) if cmd['retcode'] != 0: - log.warning('racadm return an exit code \'{0}\'.' - .format(cmd['retcode'])) + log.warning('racadm returned an exit code of %s', cmd['retcode']) return cmd return __parse_drac(cmd['stdout']) @@ -272,8 +269,7 @@ def network_info(host=None, module=module) if cmd['retcode'] != 0: - log.warning('racadm return an exit code \'{0}\'.' - .format(cmd['retcode'])) + log.warning('racadm returned an exit code of %s', cmd['retcode']) cmd['stdout'] = 'Network:\n' + 'Device = ' + module + '\n' + \ cmd['stdout'] @@ -395,8 +391,7 @@ def list_users(host=None, admin_password=admin_password) if cmd['retcode'] != 0: - log.warning('racadm return an exit code \'{0}\'.' - .format(cmd['retcode'])) + log.warning('racadm returned an exit code of %s', cmd['retcode']) for user in cmd['stdout'].splitlines(): if not user.startswith('cfg'): @@ -444,7 +439,7 @@ def delete_user(username, admin_password=admin_password) else: - log.warning('\'{0}\' does not exist'.format(username)) + log.warning('User \'%s\' does not exist', username) return False @@ -485,7 +480,7 @@ def change_password(username, password, uid=None, host=None, host=host, admin_username=admin_username, admin_password=admin_password, module=module) else: - log.warning('\'{0}\' does not exist'.format(username)) + log.warning('racadm: user \'%s\' does not exist', username) return False @@ -567,7 +562,7 @@ def create_user(username, password, permissions, users = list_users() if username in users: - log.warning('\'{0}\' already exists'.format(username)) + log.warning('racadm: user \'%s\' already exists', username) return False for idx in six.iterkeys(users): diff --git a/salt/modules/file.py b/salt/modules/file.py index 8199e3af65..3bea22ad39 100644 --- a/salt/modules/file.py +++ b/salt/modules/file.py @@ -505,7 +505,7 @@ def chgrp(path, group): def _cmp_attrs(path, attrs): ''' - .. versionadded: Oxygen + .. versionadded:: 2018.3.0 Compare attributes of a given file to given attributes. Returns a pair (list) where first item are attributes to @@ -534,7 +534,7 @@ def _cmp_attrs(path, attrs): def lsattr(path): ''' - .. versionadded: Oxygen + .. versionadded:: 2018.3.0 Obtain the modifiable attributes of the given file. If path is to a directory, an empty list is returned. @@ -565,7 +565,7 @@ def lsattr(path): def chattr(*args, **kwargs): ''' - .. versionadded: Oxygen + .. versionadded:: 2018.3.0 Change the attributes of files @@ -3974,7 +3974,7 @@ def get_managed( attrs Attributes of file - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 context Variables to add to the template context @@ -4729,7 +4729,7 @@ def check_file_meta( attrs Destination file attributes - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 saltenv Salt environment used to resolve source files @@ -4835,14 +4835,14 @@ def get_diff(file1, file1 The first file to feed into the diff utility - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Can now be either a local or remote file. In earlier releases, thuis had to be a file local to the minion. file2 The second file to feed into the diff utility - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Can now be either a local or remote file. In earlier releases, this had to be a file on the salt fileserver (i.e. ``salt://somefile.txt``) @@ -4861,7 +4861,7 @@ def get_diff(file1, except for within states, with the ``obfuscate_templates`` option set to ``True``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 source_hash_file1 If ``file1`` is an http(s)/ftp URL and the file exists in the minion's @@ -4869,7 +4869,7 @@ def get_diff(file1, re-downloading the archive if the cached copy matches the specified hash. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 source_hash_file2 If ``file2`` is an http(s)/ftp URL and the file exists in the minion's @@ -4877,7 +4877,7 @@ def get_diff(file1, re-downloading the archive if the cached copy matches the specified hash. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Examples: @@ -5015,7 +5015,7 @@ def manage_file(name, attrs attributes to be set on file: '' means remove all of them - .. versionadded: Oxygen + .. versionadded:: 2018.3.0 makedirs make directories if they do not exist diff --git a/salt/modules/freebsdservice.py b/salt/modules/freebsdservice.py index 018bc74fa3..ce7dad4dcd 100644 --- a/salt/modules/freebsdservice.py +++ b/salt/modules/freebsdservice.py @@ -484,7 +484,7 @@ def status(name, sig=None, jail=None): .. versionchanged:: 2016.3.4 - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/gcp_addon.py b/salt/modules/gcp_addon.py index 4f9d70ec0f..6a587de4b5 100644 --- a/salt/modules/gcp_addon.py +++ b/salt/modules/gcp_addon.py @@ -6,7 +6,7 @@ and the set of routes for a particular VM is called its routing table. For each packet leaving a virtual machine, the system searches that machine's routing table for a single best matching route. -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 This module will create a route to send traffic destined to the Internet through your gateway instance. diff --git a/salt/modules/gentoo_service.py b/salt/modules/gentoo_service.py index 23260c5a04..545d0772f5 100644 --- a/salt/modules/gentoo_service.py +++ b/salt/modules/gentoo_service.py @@ -242,7 +242,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/git.py b/salt/modules/git.py index 7ea4700d87..dda2868dbe 100644 --- a/salt/modules/git.py +++ b/salt/modules/git.py @@ -186,6 +186,28 @@ def _format_git_opts(opts): return _format_opts(opts) +def _find_ssh_exe(): + ''' + Windows only: search for Git's bundled ssh.exe in known locations + ''' + # Known locations for Git's ssh.exe in Windows + globmasks = [os.path.join(os.getenv('SystemDrive'), os.sep, + 'Program Files*', 'Git', 'usr', 'bin', + 'ssh.exe'), + os.path.join(os.getenv('SystemDrive'), os.sep, + 'Program Files*', 'Git', 'bin', + 'ssh.exe')] + for globmask in globmasks: + ssh_exe = glob.glob(globmask) + if ssh_exe and os.path.isfile(ssh_exe[0]): + ret = ssh_exe[0] + break + else: + ret = None + + return ret + + def _git_run(command, cwd=None, user=None, password=None, identity=None, ignore_retcode=False, failhard=True, redirect_stderr=False, saltenv='base', **kwargs): @@ -246,22 +268,12 @@ def _git_run(command, cwd=None, user=None, password=None, identity=None, ) tmp_ssh_wrapper = None if salt.utils.platform.is_windows(): - # Known locations for Git's ssh.exe in Windows - globmasks = [os.path.join(os.getenv('SystemDrive'), os.sep, - 'Program Files*', 'Git', 'usr', 'bin', - 'ssh.exe'), - os.path.join(os.getenv('SystemDrive'), os.sep, - 'Program Files*', 'Git', 'bin', - 'ssh.exe')] - for globmask in globmasks: - ssh_exe = glob.glob(globmask) - if ssh_exe and os.path.isfile(ssh_exe[0]): - env['GIT_SSH_EXE'] = ssh_exe[0] - break - else: + ssh_exe = _find_ssh_exe() + if ssh_exe is None: raise CommandExecutionError( 'Failed to find ssh.exe, unable to use identity file' ) + env['GIT_SSH_EXE'] = ssh_exe # Use the windows batch file instead of the bourne shell script ssh_id_wrapper += '.bat' env['GIT_SSH'] = ssh_id_wrapper @@ -275,7 +287,7 @@ def _git_run(command, cwd=None, user=None, password=None, identity=None, env['GIT_SSH'] = tmp_ssh_wrapper if 'salt-call' not in _salt_cli \ - and __salt__['ssh.key_is_encrypted'](id_file): + and __utils__['ssh.key_is_encrypted'](id_file): errors.append( 'Identity file {0} is passphrase-protected and cannot be ' 'used in a non-interactive command. Using salt-call from ' @@ -302,25 +314,33 @@ def _git_run(command, cwd=None, user=None, password=None, identity=None, redirect_stderr=redirect_stderr, **kwargs) finally: - # Cleanup the temporary ssh wrapper file - try: - __salt__['file.remove'](tmp_ssh_wrapper) - log.debug('Removed ssh wrapper file %s', tmp_ssh_wrapper) - except AttributeError: - # No wrapper was used - pass - except (SaltInvocationError, CommandExecutionError) as exc: - log.warning('Failed to remove ssh wrapper file %s: %s', tmp_ssh_wrapper, exc) + if tmp_ssh_wrapper: + # Cleanup the temporary ssh wrapper file + try: + __salt__['file.remove'](tmp_ssh_wrapper) + log.debug('Removed ssh wrapper file %s', tmp_ssh_wrapper) + except AttributeError: + # No wrapper was used + pass + except (SaltInvocationError, CommandExecutionError) as exc: + log.warning( + 'Failed to remove ssh wrapper file %s: %s', + tmp_ssh_wrapper, exc + ) - # Cleanup the temporary identity file - try: - __salt__['file.remove'](tmp_identity_file) - log.debug('Removed identity file %s', tmp_identity_file) - except AttributeError: - # No identify file was used - pass - except (SaltInvocationError, CommandExecutionError) as exc: - log.warning('Failed to remove identity file %s: %s', tmp_identity_file, exc) + if tmp_identity_file: + # Cleanup the temporary identity file + try: + __salt__['file.remove'](tmp_identity_file) + log.debug('Removed identity file %s', tmp_identity_file) + except AttributeError: + # No identify file was used + pass + except (SaltInvocationError, CommandExecutionError) as exc: + log.warning( + 'Failed to remove identity file %s: %s', + tmp_identity_file, exc + ) # If the command was successful, no need to try additional IDs if result['retcode'] == 0: diff --git a/salt/modules/glanceng.py b/salt/modules/glanceng.py index 6411a2d464..e47d022ab7 100644 --- a/salt/modules/glanceng.py +++ b/salt/modules/glanceng.py @@ -2,7 +2,7 @@ ''' Glance module for interacting with OpenStack Glance -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends:shade diff --git a/salt/modules/gpg.py b/salt/modules/gpg.py index 2a7c8409fd..5d57e4a192 100644 --- a/salt/modules/gpg.py +++ b/salt/modules/gpg.py @@ -1051,7 +1051,7 @@ def verify(text=None, signature Specify the filename of a detached signature. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: diff --git a/salt/modules/keystoneng.py b/salt/modules/keystoneng.py index c9faf697a5..97ae0f02ae 100644 --- a/salt/modules/keystoneng.py +++ b/salt/modules/keystoneng.py @@ -2,7 +2,7 @@ ''' Keystone module for interacting with OpenStack Keystone -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends:shade diff --git a/salt/modules/launchctl.py b/salt/modules/launchctl.py index e4600c43b8..6e705879c2 100644 --- a/salt/modules/launchctl.py +++ b/salt/modules/launchctl.py @@ -225,7 +225,7 @@ def status(name, runas=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/libcloud_compute.py b/salt/modules/libcloud_compute.py index 455efd5fc5..47725f5668 100644 --- a/salt/modules/libcloud_compute.py +++ b/salt/modules/libcloud_compute.py @@ -8,7 +8,7 @@ of supported clouds, see http://libcloud.readthedocs.io/en/latest/compute/suppor Clouds include Amazon EC2, Azure, Google GCE, VMware, OpenStack Nova -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :configuration: This module uses a configuration profile for one or multiple cloud providers diff --git a/salt/modules/libcloud_loadbalancer.py b/salt/modules/libcloud_loadbalancer.py index 68fd6abacd..65849be494 100644 --- a/salt/modules/libcloud_loadbalancer.py +++ b/salt/modules/libcloud_loadbalancer.py @@ -8,7 +8,7 @@ of supported clouds, see http://libcloud.readthedocs.io/en/latest/loadbalancer/s Clouds include Amazon ELB, ALB, Google, Aliyun, CloudStack, Softlayer -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :configuration: This module uses a configuration profile for one or multiple Storage providers diff --git a/salt/modules/libcloud_storage.py b/salt/modules/libcloud_storage.py index a9d4f76357..63ff8e6136 100644 --- a/salt/modules/libcloud_storage.py +++ b/salt/modules/libcloud_storage.py @@ -8,7 +8,7 @@ of supported clouds, see http://libcloud.readthedocs.io/en/latest/storage/suppor Clouds include Amazon S3, Google Storage, Aliyun, Azure Blobs, Ceph, OpenStack swift -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :configuration: This module uses a configuration profile for one or multiple Storage providers diff --git a/salt/modules/localemod.py b/salt/modules/localemod.py index 13abd74caf..e97af32647 100644 --- a/salt/modules/localemod.py +++ b/salt/modules/localemod.py @@ -67,7 +67,7 @@ def _localectl_status(): Parse localectl status into a dict. :return: dict ''' - if salt.utils.which('localectl') is None: + if salt.utils.path.which('localectl') is None: raise CommandExecutionError('Unable to find "localectl"') ret = {} diff --git a/salt/modules/logadm.py b/salt/modules/logadm.py index 3416c3a063..98ba62b5c4 100644 --- a/salt/modules/logadm.py +++ b/salt/modules/logadm.py @@ -183,7 +183,7 @@ def list_conf(conf_file=default_conf, log_file=None, include_unset=False): ''' Show parsed configuration - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 conf_file : string path to logadm.conf, defaults to /etc/logadm.conf @@ -222,7 +222,7 @@ def show_args(): ''' Show which arguments map to which flags and options. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: diff --git a/salt/modules/mac_assistive.py b/salt/modules/mac_assistive.py index 962c3350f1..484efcd718 100644 --- a/salt/modules/mac_assistive.py +++ b/salt/modules/mac_assistive.py @@ -30,7 +30,7 @@ def __virtual__(): Only work on Mac OS ''' if salt.utils.platform.is_darwin() \ - and _LooseVersion(__grains__['osrelease']) >= '10.9': + and _LooseVersion(__grains__['osrelease']) >= _LooseVersion('10.9'): return True return ( False, diff --git a/salt/modules/mac_sysctl.py b/salt/modules/mac_sysctl.py index 541799f665..030a0db9f5 100644 --- a/salt/modules/mac_sysctl.py +++ b/salt/modules/mac_sysctl.py @@ -164,7 +164,7 @@ def persist(name, value, config='/etc/sysctl.conf', apply_change=False): with salt.utils.files.fopen(config, 'r') as ifile: for line in ifile: - line = salt.utils.stringutils.to_unicode(line).rstrip('\n') + line = salt.utils.stringutils.to_unicode(line) if not line.startswith('{0}='.format(name)): nlines.append(line) continue diff --git a/salt/modules/mac_user.py b/salt/modules/mac_user.py index d68a42a019..a382b743a4 100644 --- a/salt/modules/mac_user.py +++ b/salt/modules/mac_user.py @@ -24,6 +24,7 @@ from salt.ext.six import string_types # Import salt libs import salt.utils.args +import salt.utils.data import salt.utils.decorators.path import salt.utils.files import salt.utils.stringutils @@ -571,7 +572,7 @@ def _kcpassword(password): # Convert each byte back to a character password = list(map(chr, password)) - return ''.join(password) + return b''.join(salt.utils.data.encode(password)) def enable_auto_login(name, password): @@ -609,7 +610,7 @@ def enable_auto_login(name, password): # Create/Update the kcpassword file with an obfuscated password o_password = _kcpassword(password=password) with salt.utils.files.set_umask(0o077): - with salt.utils.files.fopen('/etc/kcpassword', 'w') as fd: + with salt.utils.files.fopen('/etc/kcpassword', 'w' if six.PY2 else 'wb') as fd: fd.write(o_password) return current if isinstance(current, bool) else current.lower() == name.lower() diff --git a/salt/modules/mandrill.py b/salt/modules/mandrill.py index 50a41c8be6..248939d09c 100644 --- a/salt/modules/mandrill.py +++ b/salt/modules/mandrill.py @@ -15,7 +15,7 @@ In the minion configuration file, the following block is required: mandrill: key: -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' # Import Python libs diff --git a/salt/modules/mount.py b/salt/modules/mount.py index d724f2d332..3375943d95 100644 --- a/salt/modules/mount.py +++ b/salt/modules/mount.py @@ -1303,7 +1303,7 @@ def is_mounted(name): def read_mount_cache(name): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Provide information if the path is mounted @@ -1327,7 +1327,7 @@ def write_mount_cache(real_name, fstype, mount_opts): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Provide information if the path is mounted @@ -1367,7 +1367,7 @@ def write_mount_cache(real_name, def delete_mount_cache(real_name): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Provide information if the path is mounted diff --git a/salt/modules/napalm_network.py b/salt/modules/napalm_network.py index 68e97aeb5b..a5cc7df876 100644 --- a/salt/modules/napalm_network.py +++ b/salt/modules/napalm_network.py @@ -380,7 +380,7 @@ def cli(*commands, **kwargs): # pylint: disable=unused-argument textfsm_parse: ``False`` Try parsing the outputs using the TextFSM templates. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. note:: This option can be also specified in the minion configuration @@ -394,7 +394,7 @@ def cli(*commands, **kwargs): # pylint: disable=unused-argument ``salt://``, ``http://``, ``https://``, ``ftp://``, ``s3://``, ``swift://``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. note:: This needs to be a directory with a flat structure, having an @@ -416,14 +416,14 @@ def cli(*commands, **kwargs): # pylint: disable=unused-argument - ``s3://`` - ``swift://`` - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 textfsm_template_dict A dictionary with the mapping between a command and the corresponding TextFSM path to use to extract the data. The TextFSM paths can be specified as in ``textfsm_template``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. note:: This option can be also specified in the minion configuration @@ -433,7 +433,7 @@ def cli(*commands, **kwargs): # pylint: disable=unused-argument The name of the grain used to identify the platform name in the TextFSM index file. Default: ``os``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. note:: This option can be also specified in the minion configuration @@ -444,7 +444,7 @@ def cli(*commands, **kwargs): # pylint: disable=unused-argument exactly as specified in the TextFSM index file. Default: ``Platform``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. note:: This is field is case sensitive, make sure @@ -458,7 +458,7 @@ def cli(*commands, **kwargs): # pylint: disable=unused-argument index_file: ``index`` The name of the TextFSM index file, under the ``textfsm_path``. Default: ``index``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. note:: This option can be also specified in the minion configuration @@ -468,26 +468,26 @@ def cli(*commands, **kwargs): # pylint: disable=unused-argument Salt fileserver envrionment from which to retrieve the file. Ignored if ``textfsm_path`` is not a ``salt://`` URL. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 include_empty: ``False`` Include empty files under the ``textfsm_path``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 include_pat Glob or regex to narrow down the files cached from the given path. If matching with a regex, the regex must be prefixed with ``E@``, otherwise the expression will be interpreted as a glob. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 exclude_pat Glob or regex to exclude certain files from being cached from the given path. If matching with a regex, the regex must be prefixed with ``E@``, otherwise the expression will be interpreted as a glob. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. note:: If used with ``include_pat``, files matching this pattern will be @@ -1207,7 +1207,7 @@ def load_config(filename=None, - ``s3://`` - ``swift://`` - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 text String containing the desired configuration. @@ -1234,7 +1234,7 @@ def load_config(filename=None, saltenv: ``base`` Specifies the Salt environment name. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :return: a dictionary having the following keys: @@ -1422,7 +1422,7 @@ def load_template(template_name, template_attrs: "--------------e----" attributes of file. (see `man lsattr`) - .. versionadded:: oxygen + .. versionadded:: 2018.3.0 saltenv: base Specifies the template environment. diff --git a/salt/modules/netbox.py b/salt/modules/netbox.py index cf208c656a..d838c0c4e2 100644 --- a/salt/modules/netbox.py +++ b/salt/modules/netbox.py @@ -20,7 +20,7 @@ private key file: token: keyfile: -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' from __future__ import absolute_import, print_function, unicode_literals diff --git a/salt/modules/netbsdservice.py b/salt/modules/netbsdservice.py index cb2a2db514..2ccddc2043 100644 --- a/salt/modules/netbsdservice.py +++ b/salt/modules/netbsdservice.py @@ -109,7 +109,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/neutronng.py b/salt/modules/neutronng.py index 4d0a33ad5c..1379c5aad5 100644 --- a/salt/modules/neutronng.py +++ b/salt/modules/neutronng.py @@ -2,7 +2,7 @@ ''' Neutron module for interacting with OpenStack Neutron -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends:shade diff --git a/salt/modules/nexus.py b/salt/modules/nexus.py index b4184480d7..ef050ad03f 100644 --- a/salt/modules/nexus.py +++ b/salt/modules/nexus.py @@ -2,7 +2,7 @@ ''' Module for fetching artifacts from Nexus 3.x -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' # Import python libs diff --git a/salt/modules/nilrt_ip.py b/salt/modules/nilrt_ip.py index 313b847d84..a3d9d0ad24 100644 --- a/salt/modules/nilrt_ip.py +++ b/salt/modules/nilrt_ip.py @@ -147,16 +147,18 @@ def _get_service_info(service): ''' service_info = pyconnman.ConnService(_add_path(service)) data = { - 'name': service, + 'label': service, 'wireless': service_info.get_property('Type') == 'wifi', 'connectionid': six.text_type(service_info.get_property('Ethernet')['Interface']), - 'HWAddress': six.text_type(service_info.get_property('Ethernet')['Address']) + 'hwaddr': six.text_type(service_info.get_property('Ethernet')['Address']) } state = service_info.get_property('State') if state == 'ready' or state == 'online': data['up'] = True - data['ipv4'] = {} + data['ipv4'] = { + 'gateway': '0.0.0.0' + } ipv4 = 'IPv4' if service_info.get_property('IPv4')['Method'] == 'manual': ipv4 += '.Configuration' diff --git a/salt/modules/openbsdservice.py b/salt/modules/openbsdservice.py index 63f24bc8d5..3c88fcdb20 100644 --- a/salt/modules/openbsdservice.py +++ b/salt/modules/openbsdservice.py @@ -99,7 +99,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/opkg.py b/salt/modules/opkg.py index d641f5956d..bf21aefcfa 100644 --- a/salt/modules/opkg.py +++ b/salt/modules/opkg.py @@ -149,7 +149,7 @@ def refresh_db(failhard=False, **kwargs): # pylint: disable=unused-argument If True, raise an error with a list of the package databases that encountered errors. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: diff --git a/salt/modules/opsgenie.py b/salt/modules/opsgenie.py index 20dcf31202..0f84b3e9de 100644 --- a/salt/modules/opsgenie.py +++ b/salt/modules/opsgenie.py @@ -2,7 +2,7 @@ ''' Module for sending data to OpsGenie -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :configuration: This module can be used in Reactor System for posting data to OpsGenie as a remote-execution function. diff --git a/salt/modules/out.py b/salt/modules/out.py index 106d4c6401..3a95572881 100644 --- a/salt/modules/out.py +++ b/salt/modules/out.py @@ -3,7 +3,7 @@ Output Module ============= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Execution module that processes JSON serializable data and returns string having the format as processed by the outputters. diff --git a/salt/modules/panos.py b/salt/modules/panos.py index 42880a3576..bf71e7d47d 100644 --- a/salt/modules/panos.py +++ b/salt/modules/panos.py @@ -7,7 +7,7 @@ Module to provide Palo Alto compatibility to Salt. :depends: none :platform: unix -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Configuration ============= diff --git a/salt/modules/pip.py b/salt/modules/pip.py index 0224515d57..f9830056b9 100644 --- a/salt/modules/pip.py +++ b/salt/modules/pip.py @@ -139,11 +139,7 @@ def _get_pip_bin(bin_env): # try to get pip bin from virtualenv, bin_env if os.path.isdir(bin_env): if salt.utils.platform.is_windows(): - if six.PY2: - pip_bin = os.path.join( - bin_env, 'Scripts', 'pip.exe').encode('string-escape') - else: - pip_bin = os.path.join(bin_env, 'Scripts', 'pip.exe') + pip_bin = os.path.join(bin_env, 'Scripts', 'pip.exe') else: pip_bin = os.path.join(bin_env, 'bin', 'pip') if os.path.isfile(pip_bin): @@ -1198,7 +1194,7 @@ def is_installed(pkgname=None, salt '*' pip.is_installed salt - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 The packages wheel, setuptools, and distribute are included if the installed pip is new enough. diff --git a/salt/modules/pkgin.py b/salt/modules/pkgin.py index ff2e0e15d4..921143e88c 100644 --- a/salt/modules/pkgin.py +++ b/salt/modules/pkgin.py @@ -229,7 +229,7 @@ def refresh_db(force=False): force Pass -f so that the cache is always refreshed. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: @@ -312,7 +312,7 @@ def list_upgrades(refresh=True, **kwargs): ''' List all available package upgrades. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 refresh Whether or not to refresh the package database before installing. diff --git a/salt/modules/pkgng.py b/salt/modules/pkgng.py index 6ad704c3ae..65ba6d7f89 100644 --- a/salt/modules/pkgng.py +++ b/salt/modules/pkgng.py @@ -2316,84 +2316,110 @@ def _parse_upgrade(stdout): 'upgrade': pkgname: 'repo': repository + 'reason': reason 'version': 'current': n.n.n 'new': n.n.n 'install': pkgname: 'repo': repository + 'reason': reason 'version': 'current': n.n.n 'reinstall': pkgname: 'repo': repository + 'reason': reason + 'version': + 'current': n.n.n + 'downgrade': + pkgname: + 'repo': repository + 'reason': reason + 'version': + 'current': n.n.n + 'new': n.n.n + 'remove': + pkgname: + 'repo': repository + 'reason': reason 'version': 'current': n.n.n - ''' # Match strings like 'python36: 3.6.3 -> 3.6.4 [FreeBSD]' - upgrade_regex = re.compile(r'^\s+([^:]+):\s([0-9p_,.]+)\s+->\s+([0-9p_,.]+)\s+\[([^]]+)\]') + upgrade_regex = re.compile(r'^\s+([^:]+):\s([0-9a-z_,.]+)\s+->\s+([0-9a-z_,.]+)\s*(\[([^]]+)\])?\s*(\(([^)]+)\))?') # Match strings like 'rubygem-bcrypt_pbkdf: 1.0.0 [FreeBSD]' - install_regex = re.compile(r'^\s+([^:]+):\s+([0-9p_,.]+)\s+\[([^]]+)\]') + install_regex = re.compile(r'^\s+([^:]+):\s+([0-9a-z_,.]+)\s*(\[([^]]+)\])?\s*(\(([^)]+)\))?') # Match strings like 'py27-yaml-3.11_2 [FreeBSD] (direct dependency changed: py27-setuptools)' - reinstall_regex = re.compile(r'^\s+(\S+)-(?<=-)([0-9p_,.]+)\s+\[([^]]+)\]') + reinstall_regex = re.compile(r'^\s+(\S+)-(?<=-)([0-9a-z_,.]+)\s*(\[([^]]+)\])?\s*(\(([^)]+)\))?') - result = {'upgrade': {}, 'install': {}, 'reinstall': {}} - section = None + result = {'upgrade': {}, 'install': {}, 'reinstall': {}, 'remove': {}, 'downgrade': {}} + action = None for line in salt.utils.itertools.split(stdout, '\n'): if not line: - section = None + action = None continue if line == 'Installed packages to be UPGRADED:': - section = 'upgrade' + action = 'upgrade' continue if line == 'New packages to be INSTALLED:': - section = 'install' + action = 'install' continue if line == 'Installed packages to be REINSTALLED:': - section = 'reinstall' + action = 'reinstall' continue - if section == 'upgrade': + if line == 'Installed packages to be REMOVED:': + action = 'remove' + continue + + if line == 'Installed packages to be DOWNGRADED:': + action = 'downgrade' + continue + + if action == 'upgrade' or action == 'downgrade': match = upgrade_regex.match(line) if match: - result[section][match.group(1)] = { + result[action][match.group(1)] = { 'version': { 'current': match.group(2), 'new': match.group(3) }, - 'repo': match.group(4) + 'repo': match.group(5), + 'reason': match.group(7) } else: - log.error('Unable to parse upgrade: \'%s\'', line) + log.error('Unable to parse %s: \'%s\'', action, line) - if section == 'install': + if action == 'install': match = install_regex.match(line) if match: - result[section][match.group(1)] = { + result[action][match.group(1)] = { 'version': { 'current': match.group(2) }, - 'repo': match.group(3) + 'repo': match.group(4), + 'reason': match.group(6) } else: - log.error('Unable to parse install: \'%s\'', line) + log.error('Unable to parse %s: \'%s\'', action, line) - if section == 'reinstall': + if (action == 'reinstall') or (action == 'remove'): match = reinstall_regex.match(line) if match: - result[section][match.group(1)] = { + result[action][match.group(1)] = { 'version': { 'current': match.group(2) }, - 'repo': match.group(3) + 'repo': match.group(4), + 'reason': match.group(6) } else: - log.error('Unable to parse reinstall: \'%s\'', line) + log.error('Unable to parse %s: \'%s\'', action, line) return result diff --git a/salt/modules/purefa.py b/salt/modules/purefa.py index 2988008a25..6be9113a38 100644 --- a/salt/modules/purefa.py +++ b/salt/modules/purefa.py @@ -47,7 +47,7 @@ Installation Prerequisites :requires: purestorage :platform: all -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' @@ -211,7 +211,7 @@ def snap_create(name, suffix=None): Will return False is volume selected to snap does not exist. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume to snapshot @@ -247,7 +247,7 @@ def snap_delete(name, suffix=None, eradicate=False): Will return False if selected snapshot does not exist. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume @@ -289,7 +289,7 @@ def snap_eradicate(name, suffix=None): Will return False if snapshot is not in a deleted state. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume @@ -322,7 +322,7 @@ def volume_create(name, size=None): Will return False if volume already exists. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume (truncated to 63 characters) @@ -360,7 +360,7 @@ def volume_delete(name, eradicate=False): Will return False if volume doesn't exist is already in a deleted state. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume @@ -399,7 +399,7 @@ def volume_eradicate(name): Will return False is volume is not in a deleted state. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume @@ -429,7 +429,7 @@ def volume_extend(name, size): Will return False if new size is less than or equal to existing size. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume @@ -467,7 +467,7 @@ def snap_volume_create(name, target, overwrite=False): Will return False if target volume already exists and overwrite is not specified, or selected snapshot doesn't exist. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume snapshot @@ -513,7 +513,7 @@ def volume_clone(name, target, overwrite=False): Will return False if source volume doesn't exist, or target volume already exists and overwrite not specified. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume @@ -557,7 +557,7 @@ def volume_attach(name, host): Host and volume must exist or else will return False. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume @@ -590,7 +590,7 @@ def volume_detach(name, host): Will return False if either host or volume do not exist, or if selected volume isn't already connected to the host. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of volume @@ -624,7 +624,7 @@ def host_create(name, iqn=None, wwn=None): Fibre Channel parameters are not in a valid format. See Pure Storage FlashArray documentation. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of host (truncated to 63 characters) @@ -675,7 +675,7 @@ def host_update(name, iqn=None, wwn=None): by another host, or are not in a valid format. See Pure Storage FlashArray documentation. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of host @@ -715,7 +715,7 @@ def host_delete(name): Will return False if the host doesn't exist. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of host @@ -751,7 +751,7 @@ def hg_create(name, host=None, volume=None): Will return False if hostgroup already exists, or if named host or volume do not exist. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of hostgroup (truncated to 63 characters) @@ -807,7 +807,7 @@ def hg_update(name, host=None, volume=None): Will return False is hostgroup doesn't exist, or host or volume do not exist. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of hostgroup @@ -853,7 +853,7 @@ def hg_delete(name): Will return False is hostgroup is already in a deleted state. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of hostgroup @@ -891,7 +891,7 @@ def hg_remove(name, volume=None, host=None): Will return False is hostgroup does not exist, or named host or volume are not in the hostgroup. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of hostgroup @@ -952,7 +952,7 @@ def pg_create(name, hostgroup=None, host=None, volume=None, enabled=True): hostgroups, hosts or volumes * Named type for protection group does not exist - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of protection group @@ -1045,7 +1045,7 @@ def pg_update(name, hostgroup=None, host=None, volume=None): * Incorrect type selected for current protection group type * Specified type does not exist - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of protection group @@ -1135,7 +1135,7 @@ def pg_delete(name, eradicate=False): Will return False if protection group is already in a deleted state. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of protection group @@ -1172,7 +1172,7 @@ def pg_eradicate(name): Will return False if protection group is not in a deleted state. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of protection group @@ -1204,7 +1204,7 @@ def pg_remove(name, hostgroup=None, host=None, volume=None): * Protection group does not exist * Specified type is not currently associated with the protection group - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 name : string name of hostgroup diff --git a/salt/modules/reg.py b/salt/modules/reg.py index c33b91c37e..3e79bf9991 100644 --- a/salt/modules/reg.py +++ b/salt/modules/reg.py @@ -34,7 +34,6 @@ from salt.ext.six.moves import range # pylint: disable=W0622,import-error # Import third party libs try: - import win32gui import win32api import win32con import pywintypes @@ -45,6 +44,7 @@ except ImportError: # Import Salt libs import salt.utils.platform import salt.utils.stringutils +import salt.utils.win_functions from salt.exceptions import CommandExecutionError PY2 = sys.version_info[0] == 2 @@ -65,7 +65,7 @@ def __virtual__(): if not HAS_WINDOWS_MODULES: return (False, 'reg execution module failed to load: ' 'One of the following libraries did not load: ' - + 'win32gui, win32con, win32api') + 'win32con, win32api, pywintypes') return __virtualname__ @@ -190,11 +190,7 @@ def broadcast_change(): salt '*' reg.broadcast_change ''' - # https://msdn.microsoft.com/en-us/library/windows/desktop/ms644952(v=vs.85).aspx - _, res = win32gui.SendMessageTimeout( - win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 0, - win32con.SMTO_ABORTIFHUNG, 5000) - return not bool(res) + return salt.utils.win_functions.broadcast_setting_change('Environment') def list_keys(hive, key=None, use_32bit_registry=False): @@ -718,7 +714,7 @@ def import_file(source, use_32bit_registry=False): ''' Import registry settings from a Windows ``REG`` file by invoking ``REG.EXE``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Usage: diff --git a/salt/modules/rest_service.py b/salt/modules/rest_service.py index 1de7b43484..ad4adc1f03 100644 --- a/salt/modules/rest_service.py +++ b/salt/modules/rest_service.py @@ -133,7 +133,7 @@ def status(name, sig=None): .. versionadded:: 2015.8.0 - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/rh_service.py b/salt/modules/rh_service.py index f8df31c83d..558dfdadca 100644 --- a/salt/modules/rh_service.py +++ b/salt/modules/rh_service.py @@ -485,7 +485,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/saltcloudmod.py b/salt/modules/saltcloudmod.py index a1856abfc1..36b997377a 100644 --- a/salt/modules/saltcloudmod.py +++ b/salt/modules/saltcloudmod.py @@ -42,7 +42,7 @@ def create(name, profile): cmd = 'salt-cloud --out json -p {0} {1}'.format(profile, name) out = __salt__['cmd.run_stdout'](cmd, python_shell=False) try: - ret = salt.utils.json.loads(out, object_hook=salt.utils.data.encode_dict) + ret = salt.utils.json.loads(out) except ValueError: ret = {} return ret diff --git a/salt/modules/saltutil.py b/salt/modules/saltutil.py index aeddaf4f04..50d1f14ed9 100644 --- a/salt/modules/saltutil.py +++ b/salt/modules/saltutil.py @@ -588,7 +588,7 @@ def sync_engines(saltenv=None, refresh=False, extmod_whitelist=None, extmod_blac def sync_thorium(saltenv=None, refresh=False, extmod_whitelist=None, extmod_blacklist=None): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Sync Thorium modules from ``salt://_thorium`` to the minion @@ -1045,7 +1045,7 @@ def clear_job_cache(hours=24): ''' Forcibly removes job cache folders and files on a minion. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 WARNING: The safest way to clear a minion cache is by first stopping the minion and then deleting the cache files before restarting it. diff --git a/salt/modules/schedule.py b/salt/modules/schedule.py index b6dea4aeda..a77693e66f 100644 --- a/salt/modules/schedule.py +++ b/salt/modules/schedule.py @@ -9,6 +9,7 @@ Module for managing the Salt schedule on a minion # Import Python libs from __future__ import absolute_import, print_function, unicode_literals import copy as pycopy +import datetime import difflib import logging import os @@ -957,21 +958,28 @@ def copy(name, target, **kwargs): return ret -def postpone_job(name, current_time, new_time, **kwargs): +def postpone_job(name, + current_time, + new_time, + **kwargs): ''' Postpone a job in the minion's schedule - Current time and new time should be specified as Unix timestamps + Current time and new time should be in date string format, + default value is %Y-%m-%dT%H:%M:%S. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: .. code-block:: bash salt '*' schedule.postpone_job job current_time new_time + + salt '*' schedule.postpone_job job current_time new_time time_fmt='%Y-%m-%dT%H:%M:%S' ''' + time_fmt = kwargs.get('time_fmt') or '%Y-%m-%dT%H:%M:%S' ret = {'comment': [], 'result': True} @@ -985,8 +993,14 @@ def postpone_job(name, current_time, new_time, **kwargs): ret['result'] = False return ret else: - if not isinstance(current_time, six.integer_types): - ret['comment'] = 'Job current time must be an integer.' + try: + # Validate date string + datetime.datetime.strptime(current_time, time_fmt) + except (TypeError, ValueError): + log.error('Date string could not be parsed: %s, %s', + new_time, time_fmt) + + ret['comment'] = 'Date string could not be parsed.' ret['result'] = False return ret @@ -995,8 +1009,14 @@ def postpone_job(name, current_time, new_time, **kwargs): ret['result'] = False return ret else: - if not isinstance(new_time, six.integer_types): - ret['comment'] = 'Job new time must be an integer.' + try: + # Validate date string + datetime.datetime.strptime(new_time, time_fmt) + except (TypeError, ValueError): + log.error('Date string could not be parsed: %s, %s', + new_time, time_fmt) + + ret['comment'] = 'Date string could not be parsed.' ret['result'] = False return ret @@ -1008,11 +1028,13 @@ def postpone_job(name, current_time, new_time, **kwargs): event_data = {'name': name, 'time': current_time, 'new_time': new_time, + 'time_fmt': time_fmt, 'func': 'postpone_job'} elif name in list_(show_all=True, where='pillar', return_yaml=False): event_data = {'name': name, 'time': current_time, 'new_time': new_time, + 'time_fmt': time_fmt, 'where': 'pillar', 'func': 'postpone_job'} else: @@ -1041,13 +1063,14 @@ def postpone_job(name, current_time, new_time, **kwargs): return ret -def skip_job(name, time, **kwargs): +def skip_job(name, current_time, **kwargs): ''' Skip a job in the minion's schedule at specified time. - Time to skip should be specified as Unix timestamps + Time to skip should be specified as date string format, + default value is %Y-%m-%dT%H:%M:%S. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: @@ -1055,6 +1078,7 @@ def skip_job(name, time, **kwargs): salt '*' schedule.skip_job job time ''' + time_fmt = kwargs.get('time_fmt') or '%Y-%m-%dT%H:%M:%S' ret = {'comment': [], 'result': True} @@ -1063,9 +1087,20 @@ def skip_job(name, time, **kwargs): ret['comment'] = 'Job name is required.' ret['result'] = False - if not time: + if not current_time: ret['comment'] = 'Job time is required.' ret['result'] = False + else: + # Validate date string + try: + datetime.datetime.strptime(current_time, time_fmt) + except (TypeError, ValueError): + log.error('Date string could not be parsed: %s, %s', + current_time, time_fmt) + + ret['comment'] = 'Date string could not be parsed.' + ret['result'] = False + return ret if 'test' in __opts__ and __opts__['test']: ret['comment'] = 'Job: {0} would be skipped in schedule.'.format(name) @@ -1073,11 +1108,13 @@ def skip_job(name, time, **kwargs): if name in list_(show_all=True, where='opts', return_yaml=False): event_data = {'name': name, - 'time': time, + 'time': current_time, + 'time_fmt': time_fmt, 'func': 'skip_job'} elif name in list_(show_all=True, where='pillar', return_yaml=False): event_data = {'name': name, - 'time': time, + 'time': current_time, + 'time_fmt': time_fmt, 'where': 'pillar', 'func': 'skip_job'} else: @@ -1110,7 +1147,7 @@ def show_next_fire_time(name, **kwargs): ''' Show the next fire time for scheduled job - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: @@ -1120,8 +1157,7 @@ def show_next_fire_time(name, **kwargs): ''' - ret = {'comment': [], - 'result': True} + ret = {'result': True} if not name: ret['comment'] = 'Job name is required.' @@ -1139,7 +1175,10 @@ def show_next_fire_time(name, **kwargs): ret = {} ret['comment'] = 'Event module not available. Schedule show next fire time failed.' ret['result'] = True - log.debug(ret['comment']) return ret - return event_ret + if 'next_fire_time' in event_ret: + ret['next_fire_time'] = event_ret['next_fire_time'] + else: + ret['comment'] = 'next fire time not available.' + return ret diff --git a/salt/modules/service.py b/salt/modules/service.py index 9961a7de2e..a041fb1e0f 100644 --- a/salt/modules/service.py +++ b/salt/modules/service.py @@ -141,7 +141,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to PID or empty string is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/shadow.py b/salt/modules/shadow.py index 7cb3da36d3..8fc77b12a9 100644 --- a/salt/modules/shadow.py +++ b/salt/modules/shadow.py @@ -270,7 +270,7 @@ def set_password(name, password, use_usermod=False): ``SALTsalt`` is the 8-character crpytographic salt. Valid characters in the salt are ``.``, ``/``, and any alphanumeric character. - Keep in mind that the $7 represents a sha512 hash, if your OS is using a + Keep in mind that the $6 represents a sha512 hash, if your OS is using a different hashing algorithm this needs to be changed accordingly CLI Example: @@ -373,7 +373,7 @@ def set_expire(name, expire): def list_users(): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Return a list of all shadow users diff --git a/salt/modules/slsutil.py b/salt/modules/slsutil.py index 85b2542b47..77e33d4961 100644 --- a/salt/modules/slsutil.py +++ b/salt/modules/slsutil.py @@ -58,7 +58,7 @@ def renderer(path=None, string=None, default_renderer='jinja|yaml', **kwargs): ''' Parse a string or file through Salt's renderer system - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Add support for Salt fileserver URIs. This is an open-ended function and can be used for a variety of tasks. It diff --git a/salt/modules/smf.py b/salt/modules/smf.py index d0b9d9bf3f..837e1463e3 100644 --- a/salt/modules/smf.py +++ b/salt/modules/smf.py @@ -232,7 +232,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/ssh.py b/salt/modules/ssh.py index f21a6a726e..e271e6dbf7 100644 --- a/salt/modules/ssh.py +++ b/salt/modules/ssh.py @@ -843,11 +843,13 @@ def get_known_host(user, port=None, fingerprint_hash_type=None): ''' + .. deprecated:: 2018.3.0 + Use :py:func:`ssh.get_known_host_entries + ` instead. + Return information about known host from the configfile, if any. If there is no such key, return None. - .. deprecated:: Oxygen - CLI Example: .. code-block:: bash @@ -856,7 +858,7 @@ def get_known_host(user, ''' salt.utils.versions.warn_until( 'Neon', - '\'get_known_host\' has been deprecated in favour of ' + '\'get_known_host\' has been deprecated in favor of ' '\'get_known_host_entries\'. \'get_known_host\' will be ' 'removed in Salt Neon.' ) @@ -871,7 +873,7 @@ def get_known_host_entries(user, port=None, fingerprint_hash_type=None): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Return information about known host entries from the configfile, if any. If there are no entries for a matching hostname, return None. @@ -909,7 +911,9 @@ def recv_known_host(hostname, ''' Retrieve information about host public key from remote server - .. deprecated:: Oxygen + .. deprecated:: 2018.3.0 + Use :py:func:`ssh.recv_known_host_entries + ` instead. hostname The name of the remote host (e.g. "github.com") @@ -948,7 +952,7 @@ def recv_known_host(hostname, ''' salt.utils.versions.warn_until( 'Neon', - '\'recv_known_host\' has been deprecated in favour of ' + '\'recv_known_host\' has been deprecated in favor of ' '\'recv_known_host_entries\'. \'recv_known_host\' will be ' 'removed in Salt Neon.' ) @@ -964,7 +968,7 @@ def recv_known_host_entries(hostname, timeout=5, fingerprint_hash_type=None): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Retrieve information about host public keys from remote server @@ -1472,18 +1476,4 @@ def key_is_encrypted(key): salt '*' ssh.key_is_encrypted /root/id_rsa ''' - try: - with salt.utils.files.fopen(key, 'r') as fp_: - key_data = salt.utils.stringutils.to_unicode(fp_.read()) - except (IOError, OSError) as exc: - # Raise a CommandExecutionError - salt.utils.files.process_read_exception(exc, key) - - is_private_key = re.search(r'BEGIN (?:\w+\s)*PRIVATE KEY', key_data) - is_encrypted = 'ENCRYPTED' in key_data - del key_data - - if not is_private_key: - raise CommandExecutionError('{0} is not a private key'.format(key)) - - return is_encrypted + return __utils__['ssh.key_is_encrypted'](key) diff --git a/salt/modules/ssh_service.py b/salt/modules/ssh_service.py index 2712791227..9095311471 100644 --- a/salt/modules/ssh_service.py +++ b/salt/modules/ssh_service.py @@ -120,7 +120,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/state.py b/salt/modules/state.py index 88d9c70fce..71ad72e164 100644 --- a/salt/modules/state.py +++ b/salt/modules/state.py @@ -927,8 +927,8 @@ def highstate(test=None, queue=False, **kwargs): .. code-block:: bash - salt '*' state.higstate exclude=bar,baz - salt '*' state.higstate exclude=foo* + salt '*' state.highstate exclude=bar,baz + salt '*' state.highstate exclude=foo* salt '*' state.highstate exclude="[{'id': 'id_to_exclude'}, {'sls': 'sls_to_exclude'}]" saltenv @@ -1616,7 +1616,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs): ``pillar_roots`` or an external Pillar source. Pillar values that are not included in the kwarg will not be overwritten. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: @@ -2066,7 +2066,7 @@ def pkg(pkg_path, roster_grains_json = os.path.join(root, 'roster_grains.json') if os.path.isfile(roster_grains_json): with salt.utils.files.fopen(roster_grains_json, 'r') as fp_: - roster_grains = salt.utils.json.load(fp_, object_hook=salt.utils.data.encode_dict) + roster_grains = salt.utils.json.load(fp_) if os.path.isfile(roster_grains_json): popts['grains'] = roster_grains diff --git a/salt/modules/status.py b/salt/modules/status.py index 34ea40c44d..e7dfd5f7a9 100644 --- a/salt/modules/status.py +++ b/salt/modules/status.py @@ -300,7 +300,7 @@ def cpustats(): .. versionchanged:: 2016.11.4 Added support for AIX - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Added support for OpenBSD CLI Example: @@ -448,7 +448,7 @@ def meminfo(): .. versionchanged:: 2016.11.4 Added support for AIX - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Added support for OpenBSD CLI Example: @@ -612,7 +612,7 @@ def cpuinfo(): .. versionchanged:: 2016.11.4 Added support for AIX - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Added support for NetBSD and OpenBSD CLI Example: @@ -1081,7 +1081,7 @@ def nproc(): .. versionchanged:: 2016.11.4 Added support for AIX - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Added support for Darwin, FreeBSD and OpenBSD CLI Example: @@ -1130,7 +1130,7 @@ def netstats(): .. versionchanged:: 2016.11.4 Added support for AIX - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Added support for OpenBSD CLI Example: @@ -1555,7 +1555,7 @@ def version(): .. versionchanged:: 2016.11.4 Added support for AIX - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Added support for OpenBSD CLI Example: diff --git a/salt/modules/swarm.py b/salt/modules/swarm.py index ed4cbf1661..81bc5431b8 100644 --- a/salt/modules/swarm.py +++ b/salt/modules/swarm.py @@ -6,7 +6,7 @@ Docker Swarm Module using Docker's Python SDK :codeauthor: Tyler Jones -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 The Docker Swarm Module is used to manage and create Docker Swarms. diff --git a/salt/modules/systemd.py b/salt/modules/systemd.py index c3d7b1bd7e..fb349d30e6 100644 --- a/salt/modules/systemd.py +++ b/salt/modules/systemd.py @@ -1030,7 +1030,7 @@ def status(name, sig=None): # pylint: disable=unused-argument If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/test.py b/salt/modules/test.py index 138cf25f0f..9020d7107f 100644 --- a/salt/modules/test.py +++ b/salt/modules/test.py @@ -505,7 +505,7 @@ def rand_str(size=9999999999, hash_type=None): def random_hash(size=9999999999, hash_type=None): ''' .. versionadded:: 2015.5.2 - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Function has been renamed from ``test.rand_str`` to ``test.random_hash`` diff --git a/salt/modules/textfsm_mod.py b/salt/modules/textfsm_mod.py index 760f27d3a0..f0c5c777b9 100644 --- a/salt/modules/textfsm_mod.py +++ b/salt/modules/textfsm_mod.py @@ -3,7 +3,7 @@ TextFSM ======= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Execution module that processes plain text and extracts data using TextFSM templates. The output is presented in JSON serializable diff --git a/salt/modules/upstart.py b/salt/modules/upstart.py index d438bdf7e8..54007734ec 100644 --- a/salt/modules/upstart.py +++ b/salt/modules/upstart.py @@ -441,7 +441,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/vagrant.py b/salt/modules/vagrant.py index 38cffdf40b..0592dede55 100644 --- a/salt/modules/vagrant.py +++ b/salt/modules/vagrant.py @@ -2,7 +2,7 @@ ''' Work with virtual machines managed by Vagrant. -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Mapping between a Salt node id and the Vagrant machine name (and the path to the Vagrantfile where it is defined) diff --git a/salt/modules/vault.py b/salt/modules/vault.py index eb824c940e..cb1277b2e9 100644 --- a/salt/modules/vault.py +++ b/salt/modules/vault.py @@ -40,7 +40,7 @@ Functions to interact with Hashicorp Vault. For details please see http://docs.python-requests.org/en/master/user/advanced/#ssl-cert-verification - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 auth Currently only token auth is supported. The token must be able to create diff --git a/salt/modules/win_file.py b/salt/modules/win_file.py index 0ea60ca02e..8eb8ddd60c 100644 --- a/salt/modules/win_file.py +++ b/salt/modules/win_file.py @@ -1270,7 +1270,7 @@ def mkdir(path, settings defined in this function. If ``False``, new entries will be appended to the existing DACL. Default is ``False``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Returns: bool: True if successful @@ -1383,7 +1383,7 @@ def makedirs_(path, settings defined in this function. If ``False``, new entries will be appended to the existing DACL. Default is ``False``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Returns: bool: True if successful @@ -1505,7 +1505,7 @@ def makedirs_perms(path, settings defined in this function. If ``False``, new entries will be appended to the existing DACL. Default is ``False``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Returns: bool: True if successful, otherwise raises an error @@ -2028,7 +2028,7 @@ def set_perms(path, settings defined in this function. If ``False``, new entries will be appended to the existing DACL. Default is ``False``. - .. versionadded: Oxygen + .. versionadded:: 2018.3.0 Returns: bool: True if successful diff --git a/salt/modules/win_lgpo.py b/salt/modules/win_lgpo.py index 2c82515282..cbf4cc079b 100644 --- a/salt/modules/win_lgpo.py +++ b/salt/modules/win_lgpo.py @@ -2442,7 +2442,7 @@ class _policy_info(object): elif ord(val) == 1: return 'Enabled' else: - return 'Invalid Value' + return 'Invalid Value: {0!r}'.format(val) # pylint: disable=repr-flag-used-in-string else: return 'Not Defined' except TypeError: @@ -5066,7 +5066,10 @@ def get(policy_class=None, return_full_policy_names=True, class_vals[policy_name] = __salt__['reg.read_value'](_pol['Registry']['Hive'], _pol['Registry']['Path'], _pol['Registry']['Value'])['vdata'] - log.debug('Value %s found for reg policy %s', class_vals[policy_name], policy_name) + log.debug( + 'Value %r found for reg policy %s', + class_vals[policy_name], policy_name + ) elif 'Secedit' in _pol: # get value from secedit _ret, _val = _findOptionValueInSeceditFile(_pol['Secedit']['Option']) diff --git a/salt/modules/win_path.py b/salt/modules/win_path.py index 6d44493a04..ce54f97ebc 100644 --- a/salt/modules/win_path.py +++ b/salt/modules/win_path.py @@ -18,12 +18,11 @@ import salt.utils.args import salt.utils.data import salt.utils.platform import salt.utils.stringutils +import salt.utils.win_functions # Import 3rd-party libs from salt.ext.six.moves import map try: - from win32con import HWND_BROADCAST, WM_SETTINGCHANGE - from win32api import SendMessage HAS_WIN32 = True except ImportError: HAS_WIN32 = False @@ -57,7 +56,14 @@ def _normalize_dir(string_): def rehash(): ''' Send a WM_SETTINGCHANGE Broadcast to Windows to refresh the Environment - variables + variables for new processes. + + .. note:: + This will only affect new processes that aren't launched by services. To + apply changes to the path to services, the host must be restarted. The + ``salt-minion``, if running as a service, will not see changes to the + environment until the system is restarted. See + `MSDN Documentation `_ CLI Example: @@ -65,7 +71,7 @@ def rehash(): salt '*' win_path.rehash ''' - return bool(SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 'Environment')) + return salt.utils.win_functions.broadcast_setting_change('Environment') def get_path(): diff --git a/salt/modules/win_pkg.py b/salt/modules/win_pkg.py index f37eea8ccd..5dad3b061d 100644 --- a/salt/modules/win_pkg.py +++ b/salt/modules/win_pkg.py @@ -581,28 +581,77 @@ def _refresh_db_conditional(saltenv, **kwargs): def refresh_db(**kwargs): - ''' - Fetches metadata files and calls :py:func:`pkg.genrepo - ` to compile updated repository metadata. + r''' + Generates the local software metadata database (`winrepo.p`) on the minion. + The database is stored in a serialized format located by default at the + following location: + + `C:\salt\var\cache\salt\minion\files\base\win\repo-ng\winrepo.p` + + This module performs the following steps to generate the software metadata + database: + + - Fetch the package definition files (.sls) from `winrepo_source_dir` + (default `salt://win/repo-ng`) and cache them in + `\files\\` + (default: `C:\salt\var\cache\salt\minion\files\base\win\repo-ng`) + - Call :py:func:`pkg.genrepo ` to parse the + package definition files and generate the repository metadata database + file (`winrepo.p`) + - Return the report received from + :py:func:`pkg.genrepo ` + + The default winrepo directory on the master is `/srv/salt/win/repo-ng`. All + files that end with `.sls` in this and all subdirectories will be used to + generate the repository metadata database (`winrepo.p`). + + .. note:: + - Hidden directories (directories beginning with '`.`', such as + '`.git`') will be ignored. + + .. note:: + There is no need to call `pkg.refresh_db` every time you work with the + pkg module. Automatic refresh will occur based on the following minion + configuration settings: + - `winrepo_cache_expire_min` + - `winrepo_cache_expire_max` + However, if the package definition files have changed, as would be the + case if you are developing a new package definition, this function + should be called to ensure the minion has the latest information about + packages available to it. + + .. warning:: + Directories and files fetched from + (`/srv/salt/win/repo-ng`) will be processed in alphabetical order. If + two or more software definition files contain the same name, the last + one processed replaces all data from the files processed before it. + + For more information see + :ref:`Windows Software Repository ` Kwargs: saltenv (str): Salt environment. Default: ``base`` verbose (bool): - Return verbose data structure which includes 'success_list', a list - of all sls files and the package names contained within. Default - 'False' + Return a verbose data structure which includes 'success_list', a + list of all sls files and the package names contained within. + Default is 'False' failhard (bool): - If ``True``, an error will be raised if any repo SLS files failed to + If ``True``, an error will be raised if any repo SLS files fails to process. If ``False``, no error will be raised, and a dictionary containing the full results will be returned. Returns: dict: A dictionary containing the results of the database refresh. - .. Warning:: + .. note:: + A result with a `total: 0` generally means that the files are in the + wrong location on the master. Try running the following command on the + minion: `salt-call -l debug pkg.refresh saltenv=base` + + .. warning:: When calling this command from a state using `module.run` be sure to pass `failhard: False`. Otherwise the state will report failure if it encounters a bad software definition file. @@ -648,10 +697,12 @@ def refresh_db(**kwargs): ) # Cache repo-ng locally + log.info('Fetching *.sls files from {0}'.format(repo_details.winrepo_source_dir)) __salt__['cp.cache_dir']( - repo_details.winrepo_source_dir, - saltenv, - include_pat='*.sls' + path=repo_details.winrepo_source_dir, + saltenv=saltenv, + include_pat='*.sls', + exclude_pat=r'E@\/\..*?\/' # Exclude all hidden directories (.git) ) return genrepo(saltenv=saltenv, verbose=verbose, failhard=failhard) @@ -754,6 +805,10 @@ def genrepo(**kwargs): to process. If ``False``, no error will be raised, and a dictionary containing the full results will be returned. + .. note:: + - Hidden directories (directories beginning with '`.`', such as + '`.git`') will be ignored. + Returns: dict: A dictionary of the results of the command @@ -777,9 +832,16 @@ def genrepo(**kwargs): repo_details = _get_repo_details(saltenv) for root, _, files in salt.utils.path.os_walk(repo_details.local_dest, followlinks=False): + + # Skip hidden directories (.git) + if re.search(r'[\\/]\..*', root): + log.debug('Skipping files in directory: {0}'.format(root)) + continue + short_path = os.path.relpath(root, repo_details.local_dest) if short_path == '.': short_path = '' + for name in files: if name.endswith('.sls'): total_files_processed += 1 @@ -1209,11 +1271,11 @@ def install(name=None, refresh=False, pkgs=None, **kwargs): # single files if cache_dir and installer.startswith('salt:'): path, _ = os.path.split(installer) - __salt__['cp.cache_dir'](path, - saltenv, - False, - None, - 'E@init.sls$') + __salt__['cp.cache_dir'](path=path, + saltenv=saltenv, + include_empty=False, + include_pat=None, + exclude_pat='E@init.sls$') # Check to see if the cache_file is cached... if passed if cache_file and cache_file.startswith('salt:'): @@ -1820,7 +1882,7 @@ def get_repo_data(saltenv='base'): serial = salt.payload.Serial(__opts__) with salt.utils.files.fopen(repo_details.winrepo_file, 'rb') as repofile: try: - repodata = salt.utils.data.decode(serial.loads(repofile.read()) or {}) + repodata = salt.utils.data.decode(serial.loads(repofile.read(), encoding='utf-8') or {}) __context__['winrepo.data'] = repodata return repodata except Exception as exc: @@ -1843,7 +1905,7 @@ def _get_name_map(saltenv='base'): return name_map for k in name_map: - u_name_map[k.decode('utf-8')] = name_map[k] + u_name_map[k] = name_map[k] return u_name_map diff --git a/salt/modules/win_servermanager.py b/salt/modules/win_servermanager.py index a8db48576a..47267dbb7d 100644 --- a/salt/modules/win_servermanager.py +++ b/salt/modules/win_servermanager.py @@ -133,7 +133,7 @@ def install(feature, recurse=False, restart=False, source=None, exclude=None): a string of features in a comma delimited list (no spaces), or a list of features. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Added the ability to pass a list of features to be installed. recurse (Options[bool]): @@ -297,7 +297,7 @@ def remove(feature, remove_payload=False, restart=False): a string of features in a comma delimited list (no spaces), or a list of features. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Added the ability to pass a list of features to be removed. remove_payload (Optional[bool]): diff --git a/salt/modules/win_service.py b/salt/modules/win_service.py index f0fdccf519..c8d0fb3d15 100644 --- a/salt/modules/win_service.py +++ b/salt/modules/win_service.py @@ -537,7 +537,7 @@ def status(name, sig=None): If the name contains globbing, a dict mapping service name to True/False values is returned. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The service name can now be a glob (e.g. ``salt*``) Args: diff --git a/salt/modules/x509.py b/salt/modules/x509.py index ff2c645f3e..108379635e 100644 --- a/salt/modules/x509.py +++ b/salt/modules/x509.py @@ -335,9 +335,8 @@ def _parse_subject(subject): if val: ret[nid_name] = val nids.append(nid_num) - except TypeError as e: - if e.args and e.args[0] == 'No string argument provided': - pass + except TypeError as err: + log.trace("Missing attribute '%s'. Error: %s", nid_name, err) return ret diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py index e419039c87..8408eb93ac 100644 --- a/salt/modules/yumpkg.py +++ b/salt/modules/yumpkg.py @@ -211,25 +211,29 @@ def _check_versionlock(): ) -def _get_repo_options(**kwargs): +def _get_options(**kwargs): ''' - Returns a list of '--enablerepo' and '--disablerepo' options to be used - in the yum command, based on the kwargs. + Returns a list of options to be used in the yum/dnf command, based on the + kwargs passed. ''' # Get repo options from the kwargs fromrepo = kwargs.pop('fromrepo', '') repo = kwargs.pop('repo', '') disablerepo = kwargs.pop('disablerepo', '') enablerepo = kwargs.pop('enablerepo', '') + disableexcludes = kwargs.pop('disableexcludes', '') + branch = kwargs.pop('branch', '') + get_extra_options = kwargs.pop('get_extra_options', False) # Support old 'repo' argument if repo and not fromrepo: fromrepo = repo ret = [] + if fromrepo: log.info('Restricting to repo \'%s\'', fromrepo) - ret.extend(['--disablerepo=*', '--enablerepo=' + fromrepo]) + ret.extend(['--disablerepo=*', '--enablerepo={0}'.format(fromrepo)]) else: if disablerepo: targets = [disablerepo] \ @@ -245,58 +249,30 @@ def _get_repo_options(**kwargs): else enablerepo log.info('Enabling repo(s): %s', ', '.join(targets)) ret.extend(['--enablerepo={0}'.format(x) for x in targets]) - return ret + if disableexcludes: + log.info('Disabling excludes for \'%s\'', disableexcludes) + ret.append('--disableexcludes={0}'.format(disableexcludes)) -def _get_excludes_option(**kwargs): - ''' - Returns a list of '--disableexcludes' option to be used in the yum command, - based on the kwargs. - ''' - disable_excludes = kwargs.pop('disableexcludes', '') - ret = [] - if disable_excludes: - log.info('Disabling excludes for \'%s\'', disable_excludes) - ret.append('--disableexcludes={0}'.format(disable_excludes)) - return ret - - -def _get_branch_option(**kwargs): - ''' - Returns a list of '--branch' option to be used in the yum command, - based on the kwargs. This feature requires 'branch' plugin for YUM. - ''' - branch = kwargs.pop('branch', '') - ret = [] if branch: log.info('Adding branch \'%s\'', branch) - ret.append('--branch=\'{0}\''.format(branch)) - return ret + ret.append('--branch={0}'.format(branch)) + if get_extra_options: + # sorting here to make order uniform, makes unit testing more reliable + for key in sorted(kwargs): + if key.startswith('__'): + continue + value = kwargs[key] + if isinstance(value, six.string_types): + log.info('Found extra option --%s=%s', key, value) + ret.append('--{0}={1}'.format(key, value)) + elif value is True: + log.info('Found extra option --%s', key) + ret.append('--{0}'.format(key)) + if ret: + log.info('Adding extra options: %s', ret) -def _get_extra_options(**kwargs): - ''' - Returns list of extra options for yum - ''' - ret = [] - kwargs = salt.utils.args.clean_kwargs(**kwargs) - - # Remove already handled options from kwargs - fromrepo = kwargs.pop('fromrepo', '') - repo = kwargs.pop('repo', '') - disablerepo = kwargs.pop('disablerepo', '') - enablerepo = kwargs.pop('enablerepo', '') - disable_excludes = kwargs.pop('disableexcludes', '') - branch = kwargs.pop('branch', '') - - for key, value in six.iteritems(kwargs): - if isinstance(value, six.string_types): - log.info('Adding extra option --%s=\'%s\'', key, value) - ret.append('--{0}=\'{1}\''.format(key, value)) - elif value is True: - log.info('Adding extra option --%s', key) - ret.append('--{0}'.format(key)) - log.info('Adding extra options %s', ret) return ret @@ -460,8 +436,7 @@ def latest_version(*names, **kwargs): if len(names) == 0: return '' - repo_arg = _get_repo_options(**kwargs) - exclude_arg = _get_excludes_option(**kwargs) + options = _get_options(**kwargs) # Refresh before looking for the latest version available if refresh: @@ -471,8 +446,7 @@ def latest_version(*names, **kwargs): # Get available versions for specified package(s) cmd = [_yum(), '--quiet'] - cmd.extend(repo_arg) - cmd.extend(exclude_arg) + cmd.extend(options) cmd.extend(['list', 'available']) cmd.extend(names) out = __salt__['cmd.run_all'](cmd, @@ -635,7 +609,7 @@ def list_pkgs(versions_as_list=False, **kwargs): If ``all`` is specified, all valid attributes will be returned. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: @@ -818,7 +792,7 @@ def list_repo_pkgs(*args, **kwargs): disablerepo = kwargs.pop('disablerepo', '') or '' enablerepo = kwargs.pop('enablerepo', '') or '' - repo_arg = _get_repo_options(fromrepo=fromrepo, **kwargs) + repo_arg = _get_options(fromrepo=fromrepo, **kwargs) if fromrepo and not isinstance(fromrepo, list): try: @@ -970,15 +944,13 @@ def list_upgrades(refresh=True, **kwargs): salt '*' pkg.list_upgrades ''' - repo_arg = _get_repo_options(**kwargs) - exclude_arg = _get_excludes_option(**kwargs) + options = _get_options(**kwargs) if salt.utils.data.is_true(refresh): refresh_db(check_update=False, **kwargs) cmd = [_yum(), '--quiet'] - cmd.extend(repo_arg) - cmd.extend(exclude_arg) + cmd.extend(options) cmd.extend(['list', 'upgrades' if _yum() == 'dnf' else 'updates']) out = __salt__['cmd.run_all'](cmd, output_loglevel='trace', @@ -1096,21 +1068,19 @@ def refresh_db(**kwargs): check_update_ = kwargs.pop('check_update', True) - repo_arg = _get_repo_options(**kwargs) - exclude_arg = _get_excludes_option(**kwargs) - branch_arg = _get_branch_option(**kwargs) + options = _get_options(**kwargs) - clean_cmd = [_yum(), '--quiet', 'clean', 'expire-cache'] - update_cmd = [_yum(), '--quiet', 'check-update'] + clean_cmd = [_yum(), '--quiet', '--assumeyes', 'clean', 'expire-cache'] + update_cmd = [_yum(), '--quiet', '--assumeyes', 'check-update'] - if __grains__.get('os_family') == 'RedHat' and __grains__.get('osmajorrelease') == '7': - # This feature is disable because it is not used by Salt and lasts a lot with using large repo like EPEL + if __grains__.get('os_family') == 'RedHat' \ + and __grains__.get('osmajorrelease') == 7: + # This feature is disabled because it is not used by Salt and adds a + # lot of extra time to the command with large repos like EPEL update_cmd.append('--setopt=autocheck_running_kernel=false') - for args in (repo_arg, exclude_arg, branch_arg): - if args: - clean_cmd.extend(args) - update_cmd.extend(args) + clean_cmd.extend(options) + update_cmd.extend(options) __salt__['cmd.run'](clean_cmd, python_shell=False) if check_update_: @@ -1162,6 +1132,7 @@ def install(name=None, reinstall=False, normalize=True, update_holds=False, + saltenv='base', ignore_epoch=False, **kwargs): ''' @@ -1225,7 +1196,7 @@ def install(name=None, Install a specific version of the package, e.g. 1.2.3-4.el5. Ignored if "pkgs" or "sources" is passed. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 version can now contain comparison operators (e.g. ``>1.2.3``, ``<=2.0``, etc.) @@ -1265,7 +1236,7 @@ def install(name=None, ignored when comparing the currently-installed version to the desired version. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Multiple Package Installation Options: @@ -1324,7 +1295,7 @@ def install(name=None, If ``all`` is specified, all valid attributes will be returned. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Returns a dict containing the new package names and versions:: @@ -1343,9 +1314,7 @@ def install(name=None, 'version': '', 'arch': ''}}} ''' - repo_arg = _get_repo_options(**kwargs) - exclude_arg = _get_excludes_option(**kwargs) - branch_arg = _get_branch_option(**kwargs) + options = _get_options(**kwargs) if salt.utils.data.is_true(refresh): refresh_db(**kwargs) @@ -1353,7 +1322,7 @@ def install(name=None, try: pkg_params, pkg_type = __salt__['pkg_resource.parse_targets']( - name, pkgs, sources, normalize=normalize, **kwargs + name, pkgs, sources, saltenv=saltenv, normalize=normalize ) except MinionError as exc: raise CommandExecutionError(exc) @@ -1580,9 +1549,7 @@ def install(name=None, ''' DRY function to add args common to all yum/dnf commands ''' - for arg in (repo_arg, exclude_arg, branch_arg): - if arg: - cmd.extend(arg) + cmd.extend(options) if skip_verify: cmd.append('--nogpgcheck') if downloadonly: @@ -1847,17 +1814,14 @@ def upgrade(name=None, .. note:: To add extra arguments to the ``yum upgrade`` command, pass them as key - word arguments. For arguments without assignments, pass ``True`` + word arguments. For arguments without assignments, pass ``True`` .. code-block:: bash salt '*' pkg.upgrade security=True exclude='kernel*' ''' - repo_arg = _get_repo_options(**kwargs) - exclude_arg = _get_excludes_option(**kwargs) - branch_arg = _get_branch_option(**kwargs) - extra_args = _get_extra_options(**kwargs) + options = _get_options(get_extra_options=True, **kwargs) if salt.utils.data.is_true(refresh): refresh_db(**kwargs) @@ -1886,9 +1850,7 @@ def upgrade(name=None, and __salt__['config.get']('systemd.scope', True): cmd.extend(['systemd-run', '--scope']) cmd.extend([_yum(), '--quiet', '-y']) - for args in (repo_arg, exclude_arg, branch_arg, extra_args): - if args: - cmd.extend(args) + cmd.extend(options) if skip_verify: cmd.append('--nogpgcheck') cmd.append('upgrade') diff --git a/salt/modules/zookeeper.py b/salt/modules/zookeeper.py index 4e68b49ecc..7f9014d10f 100644 --- a/salt/modules/zookeeper.py +++ b/salt/modules/zookeeper.py @@ -7,7 +7,7 @@ Zookeeper Module :platform: all :depends: kazoo -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Configuration ============= diff --git a/salt/modules/zpool.py b/salt/modules/zpool.py index fa616f9f71..faa92645d8 100644 --- a/salt/modules/zpool.py +++ b/salt/modules/zpool.py @@ -239,6 +239,7 @@ def iostat(zpool=None, sample_time=5, parsable=True): zpool : string optional name of storage pool + sample_time : int seconds to capture data before output default a sample of 5 seconds is used @@ -346,11 +347,18 @@ def iostat(zpool=None, sample_time=5, parsable=True): def list_(properties='size,alloc,free,cap,frag,health', zpool=None, parsable=True): ''' +<<<<<<< HEAD +======= + .. versionadded:: 2015.5.0 + +>>>>>>> 2018.3 Return information about (all) storage pools zpool : string optional name of storage pool + properties : string +<<<<<<< HEAD comma-separated list of properties to display parsable : boolean display data in pythonc values (True, False, Bytes,...) @@ -359,15 +367,26 @@ def list_(properties='size,alloc,free,cap,frag,health', zpool=None, parsable=Tru .. versionchanged:: Fluorine Added ```parsable``` parameter that defaults to True +======= + comma-separated list of properties to list + + parsable : boolean + display numbers in parsable (exact) values + + .. versionadded:: 2018.3.0 +>>>>>>> 2018.3 .. note:: - the 'name' property will always be included, the 'frag' property will get removed if not available + + The ``name`` property will always be included, while the ``frag`` + property will get removed if not available zpool : string optional zpool .. note:: - multiple storage pool can be provded as a space separated list + + Multiple storage pool can be provded as a space separated list CLI Example: @@ -439,21 +458,35 @@ def list_(properties='size,alloc,free,cap,frag,health', zpool=None, parsable=Tru def get(zpool, prop=None, show_source=False, parsable=True): ''' +<<<<<<< HEAD +======= + .. versionadded:: 2016.3.0 + +>>>>>>> 2018.3 Retrieves the given list of properties zpool : string - name of storage pool + Name of storage pool + prop : string - optional name of property to retrieve + Optional name of property to retrieve + show_source : boolean - show source of property + Show source of property + parsable : boolean +<<<<<<< HEAD display data in pythonc values (True, False, Bytes,...) .. versionadded:: 2016.3.0 .. versionchanged:: Fluorine Added ```parsable``` parameter that defaults to True +======= + Display numbers in parsable (exact) values + + .. versionadded:: 2018.3.0 +>>>>>>> 2018.3 CLI Example: @@ -519,11 +552,13 @@ def set(zpool, prop, value): Sets the given property on the specified pool zpool : string - name of storage pool + Name of storage pool + prop : string - name of property + Name of property to set + value : string - value to set property to + Value to set for the specified property .. versionadded:: 2016.3.0 @@ -555,7 +590,7 @@ def exists(zpool): Check if a ZFS storage pool is active zpool : string - name of storage pool + Name of storage pool CLI Example: @@ -583,9 +618,10 @@ def destroy(zpool, force=False): Destroys a storage pool zpool : string - name of storage pool + Name of storage pool + force : boolean - force destroy of pool + Force destroy of pool CLI Example: @@ -612,18 +648,30 @@ def scrub(zpool, stop=False, pause=False): Scrub a storage pool zpool : string - name of storage pool + Name of storage pool + stop : boolean - if true, cancel ongoing scrub + If ``True``, cancel ongoing scrub + pause : boolean +<<<<<<< HEAD if true, pause ongoing scrub +======= + If ``True``, pause ongoing scrub + +>>>>>>> 2018.3 .. versionadded:: 2018.3.0 .. note:: +<<<<<<< HEAD If both pause and stop are true, stop will win. Pause support was added in this PR: https://github.com/openzfs/openzfs/pull/407 +======= + If both ``pause`` and ``stop`` are ``True``, then ``stop`` will + win. +>>>>>>> 2018.3 CLI Example: @@ -663,39 +711,74 @@ def scrub(zpool, stop=False, pause=False): def create(zpool, *vdevs, **kwargs): ''' +<<<<<<< HEAD +======= + .. versionadded:: 2015.5.0 + +>>>>>>> 2018.3 Create a simple zpool, a mirrored zpool, a zpool having nested VDEVs, a hybrid zpool with cache, spare and log drives or a zpool with RAIDZ-1, RAIDZ-2 or RAIDZ-3 zpool : string - name of storage pool - *vdevs : string - one or move devices + Name of storage pool + + vdevs : string + One or move devices + force : boolean - forces use of vdevs, even if they appear in use or specify a conflicting replication level. + Forces use of vdevs, even if they appear in use or specify a + conflicting replication level. + mountpoint : string - sets the mount point for the root dataset + Sets the mount point for the root dataset + altroot : string - equivalent to "-o cachefile=none,altroot=root" + Equivalent to "-o cachefile=none,altroot=root" + properties : dict - additional pool properties + Additional pool properties + filesystem_properties : dict - additional filesystem properties + Additional filesystem properties + createboot : boolean +<<<<<<< HEAD ..versionadded:: 2018.3.0 create a boot partition .. versionadded:: 2015.5.0 +======= + create a boot partition + + .. versionadded:: 2018.3.0 + + CLI Examples: + + .. code-block:: bash + + salt '*' zpool.create myzpool /path/to/vdev1 [...] [force=True|False] + salt '*' zpool.create myzpool mirror /path/to/vdev1 /path/to/vdev2 [...] [force=True|False] + salt '*' zpool.create myzpool raidz1 /path/to/vdev1 /path/to/vdev2 raidz2 /path/to/vdev3 /path/to/vdev4 /path/to/vdev5 [...] [force=True|False] + salt '*' zpool.create myzpool mirror /path/to/vdev1 [...] mirror /path/to/vdev2 /path/to/vdev3 [...] [force=True|False] + salt '*' zpool.create myhybridzpool mirror /tmp/file1 [...] log mirror /path/to/vdev1 [...] cache /path/to/vdev2 [...] spare /path/to/vdev3 [...] [force=True|False] +>>>>>>> 2018.3 .. note:: - Zpool properties can be specified at the time of creation of the pool by - passing an additional argument called "properties" and specifying the properties - with their respective values in the form of a python dictionary:: + Zpool properties can be specified at the time of creation of the pool + by passing an additional argument called "properties" and specifying + the properties with their respective values in the form of a python + dictionary: + + .. code-block:: text properties="{'property1': 'value1', 'property2': 'value2'}" - Filesystem properties can be specified at the time of creation of the pool by - passing an additional argument called "filesystem_properties" and specifying the properties - with their respective values in the form of a python dictionary:: + Filesystem properties can be specified at the time of creation of the + pool by passing an additional argument called "filesystem_properties" + and specifying the properties with their respective values in the form + of a python dictionary: + + .. code-block:: text filesystem_properties="{'property1': 'value1', 'property2': 'value2'}" @@ -768,11 +851,13 @@ def add(zpool, *vdevs, **kwargs): Add the specified vdev\'s to the given storage pool zpool : string - name of storage pool - *vdevs : string - one or more devices + Name of storage pool + + vdevs : string + One or more devices + force : boolean - forces use of device + Forces use of device CLI Example: @@ -819,13 +904,16 @@ def attach(zpool, device, new_device, force=False): Attach specified device to zpool zpool : string - name of storage pool + Name of storage pool + device : string - device to attach too + Existing device name too + new_device : string - device to attach + New device name (to be attached to ``device``) + force : boolean - forces use of device + Forces use of device CLI Example: @@ -873,9 +961,10 @@ def detach(zpool, device): Detach specified device to zpool zpool : string - name of storage pool + Name of storage pool + device : string - device to detach + Device to detach CLI Example: @@ -905,33 +994,54 @@ def detach(zpool, device): def split(zpool, newzpool, **kwargs): ''' +<<<<<<< HEAD +======= + .. versionadded:: 2018.3.0 + +>>>>>>> 2018.3 Splits devices off pool creating newpool. .. note:: All vdevs in pool must be mirrors. At the time of the split, - newpool will be a replica of pool. + ``newzpool`` will be a replica of ``zpool``. After splitting, do not forget to import the new pool! zpool : string - name of storage pool - newzpool : string - name of new storage pool - mountpoint : string - sets the mount point for the root dataset - altroot : string - sets altroot for newzpool - properties : dict - additional pool properties for newzpool + Name of storage pool + newzpool : string + Name of new storage pool + + mountpoint : string + Sets the mount point for the root dataset + + altroot : string + Sets altroot for newzpool + + properties : dict + Additional pool properties for newzpool + +<<<<<<< HEAD .. versionadded:: 2018.3.0 +======= + CLI Examples: + + .. code-block:: bash + + salt '*' zpool.split datamirror databackup + salt '*' zpool.split datamirror databackup altroot=/backup +>>>>>>> 2018.3 .. note:: - Zpool properties can be specified at the time of creation of the pool by - passing an additional argument called "properties" and specifying the properties - with their respective values in the form of a python dictionary:: + Zpool properties can be specified at the time of creation of the pool + by passing an additional argument called "properties" and specifying + the properties with their respective values in the form of a python + dictionary: + + .. code-block:: text properties="{'property1': 'value1', 'property2': 'value2'}" @@ -976,21 +1086,29 @@ def split(zpool, newzpool, **kwargs): def replace(zpool, old_device, new_device=None, force=False): ''' +<<<<<<< HEAD Replaces old_device with new_device. +======= + Replaces ``old_device`` with ``new_device`` +>>>>>>> 2018.3 .. note:: - This is equivalent to attaching new_device, - waiting for it to resilver, and then detaching old_device. - The size of new_device must be greater than or equal to the minimum + This is equivalent to attaching ``new_device``, + waiting for it to resilver, and then detaching ``old_device``. + + The size of ``new_device`` must be greater than or equal to the minimum size of all the devices in a mirror or raidz configuration. zpool : string - name of storage pool + Name of storage pool + old_device : string - old device to replace + Old device to replace + new_device : string - optional new device + Optional new device + force : boolean Forces use of new_device, even if its appears to be in use. @@ -1039,9 +1157,13 @@ def replace(zpool, old_device, new_device=None, force=False): @salt.utils.decorators.path.which('mkfile') def create_file_vdev(size, *vdevs): ''' +<<<<<<< HEAD Creates file based ``virtual devices`` for a zpool ``*vdevs`` is a list of full paths for mkfile to create +======= + Creates file based virtual devices for a zpool +>>>>>>> 2018.3 CLI Example: @@ -1084,12 +1206,18 @@ def create_file_vdev(size, *vdevs): def export(*pools, **kwargs): ''' +<<<<<<< HEAD +======= + .. versionadded:: 2015.5.0 + +>>>>>>> 2018.3 Export storage pools - *pools : string - one or more storage pools to export + pools : string + One or more storage pools to export + force : boolean - force export of storage pools + Force export of storage pools .. versionadded:: 2015.5.0 @@ -1128,23 +1256,38 @@ def export(*pools, **kwargs): def import_(zpool=None, new_name=None, **kwargs): ''' +<<<<<<< HEAD +======= + .. versionadded:: 2015.5.0 + +>>>>>>> 2018.3 Import storage pools or list pools available for import zpool : string - optional name of storage pool + Optional name of storage pool + new_name : string - optional new name for the storage pool + Optional new name for the storage pool + mntopts : string - comma-separated list of mount options to use when mounting datasets within the pool. + Comma-separated list of mount options to use when mounting datasets + within the pool. + force : boolean - forces import, even if the pool appears to be potentially active. + Forces import, even if the pool appears to be potentially active. + altroot : string - equivalent to "-o cachefile=none,altroot=root" + Equivalent to "-o cachefile=none,altroot=root" + dir : string - searches for devices or files in dir, multiple dirs can be specified as follows:: dir="dir1,dir2" + Searches for devices or files in dir, multiple dirs can be specified as + follows: ``dir="dir1,dir2"`` + no_mount : boolean - import the pool without mounting any file systems. + Import the pool without mounting any file systems. + only_destroyed : boolean +<<<<<<< HEAD imports destroyed pools only. this also sets force=True. recovery : bool|str false: do not try to recovery broken pools @@ -1158,15 +1301,21 @@ def import_(zpool=None, new_name=None, **kwargs): .. warning:: When recovery is set to 'test' the result will be have imported set to True if the pool can be imported. The pool might also be imported if the pool was not broken to begin with. +======= + Imports destroyed pools only. this also sets force=True. +>>>>>>> 2018.3 properties : dict - additional pool properties + Additional pool properties .. note:: - Zpool properties can be specified at the time of creation of the pool by - passing an additional argument called "properties" and specifying the properties - with their respective values in the form of a python dictionary:: + Zpool properties can be specified at the time of creation of the pool + by passing an additional argument called "properties" and specifying + the properties with their respective values in the form of a python + dictionary: + + .. code-block:: text properties="{'property1': 'value1', 'property2': 'value2'}" @@ -1238,16 +1387,24 @@ def import_(zpool=None, new_name=None, **kwargs): def online(zpool, *vdevs, **kwargs): ''' +<<<<<<< HEAD +======= + .. versionadded:: 2015.5.0 + +>>>>>>> 2018.3 Ensure that the specified devices are online zpool : string name of storage pool - *vdevs : string + + vdevs : string one or more devices + expand : boolean Expand the device to use all available space. .. note:: + If the device is part of a mirror or raidz then all devices must be expanded before the new space will become available to the pool. @@ -1300,19 +1457,27 @@ def online(zpool, *vdevs, **kwargs): def offline(zpool, *vdevs, **kwargs): ''' +<<<<<<< HEAD +======= + .. versionadded:: 2015.5.0 + +>>>>>>> 2018.3 Ensure that the specified devices are offline .. warning:: - By default, the OFFLINE state is persistent. The device remains offline when - the system is rebooted. To temporarily take a device offline, use ``temporary=True``. + By default, the ``OFFLINE`` state is persistent. The device remains + offline when the system is rebooted. To temporarily take a device + offline, use ``temporary=True``. zpool : string name of storage pool - *vdevs : string - one or more devices + + vdevs : string + One or more devices + temporary : boolean - enable temporarily offline + Enable temporarily offline .. versionadded:: 2015.5.0 @@ -1351,12 +1516,22 @@ def offline(zpool, *vdevs, **kwargs): def labelclear(device, force=False): ''' +<<<<<<< HEAD +======= + .. versionadded:: 2018.3.0 + +>>>>>>> 2018.3 Removes ZFS label information from the specified device device : string +<<<<<<< HEAD device, must not be part of an active pool configuration. +======= + Device name + +>>>>>>> 2018.3 force : boolean - treat exported or foreign devices as inactive + Treat exported or foreign devices as inactive .. versionadded:: 2018.3.0 @@ -1428,8 +1603,8 @@ def reguid(zpool): Generates a new unique identifier for the pool .. warning:: - You must ensure that all devices in this pool are online - and healthy before performing this action. + You must ensure that all devices in this pool are online and healthy + before performing this action. zpool : string name of storage pool @@ -1486,10 +1661,20 @@ def upgrade(zpool=None, version=None): ''' Enables all supported features on the given pool +<<<<<<< HEAD +======= + .. warning:: + Once this is done, the pool will no longer be accessible on systems + that do not support feature flags. See ``zpool-features(5)`` for + details on compatibility with systems that support feature flags, but + do not support all features enabled on the pool. + +>>>>>>> 2018.3 zpool : string - optional storage pool, applies to all otherwize + Optional storage pool, applies to all otherwize + version : int - version to upgrade to, if unspecified upgrade to the highest possible + Version to upgrade to, if unspecified upgrade to the highest possible .. versionadded:: 2016.3.0 @@ -1532,14 +1717,24 @@ def upgrade(zpool=None, version=None): def history(zpool=None, internal=False, verbose=False): ''' +<<<<<<< HEAD Displays the command history of the specified pools or all pools if no pool is specified +======= + .. versionadded:: 2016.3.0 + + Displays the command history of the specified pools, or all pools if no + pool is specified +>>>>>>> 2018.3 zpool : string - optional storage pool + Optional storage pool + internal : boolean - toggle display of internally logged ZFS events + Toggle display of internally logged ZFS events + verbose : boolean - toggle display of the user name, the hostname, and the zone in which the operation was performed + Toggle display of the user name, the hostname, and the zone in which + the operation was performed .. versionadded:: 2016.3.0 @@ -1588,5 +1783,3 @@ def history(zpool=None, internal=False, verbose=False): ret[pool][log_timestamp] = log_command return ret - -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py index a937106473..b84d8abcc9 100644 --- a/salt/modules/zypper.py +++ b/salt/modules/zypper.py @@ -482,15 +482,6 @@ def info_installed(*names, **kwargs): t_nfo = dict() # Translate dpkg-specific keys to a common structure for key, value in six.iteritems(pkg_nfo): - if isinstance(value, six.string_types): - # Check, if string is encoded in a proper UTF-8 - if six.PY3: - value_ = value.encode('UTF-8', 'ignore').decode('UTF-8', 'ignore') - else: - value_ = value.decode('UTF-8', 'ignore').encode('UTF-8', 'ignore') - if value != value_: - value = kwargs.get('errors', 'ignore') == 'ignore' and value_ or 'N/A (invalid UTF-8)' - log.error('Package %s has bad UTF-8 code in %s: %s', pkg_name, key, value) if key == 'source_rpm': t_nfo['source'] = value else: @@ -681,7 +672,7 @@ def list_pkgs(versions_as_list=False, **kwargs): If ``all`` is specified, all valid attributes will be returned. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 removed: not supported @@ -1121,7 +1112,7 @@ def install(name=None, If ``all`` is specified, all valid attributes will be returned. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Returns a dict containing the new package names and versions:: @@ -2130,7 +2121,7 @@ def list_installed_patches(): def list_provides(**kwargs): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 List package provides of installed packages as a dict. {'': ['', '', ...]} @@ -2161,7 +2152,7 @@ def list_provides(**kwargs): def resolve_capabilities(pkgs, refresh, **kwargs): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Convert name provides in ``pkgs`` into real package names if ``resolve_capabilities`` parameter is set to True. In case of diff --git a/salt/netapi/rest_cherrypy/app.py b/salt/netapi/rest_cherrypy/app.py index 79292f5b0c..d4b6c93f28 100644 --- a/salt/netapi/rest_cherrypy/app.py +++ b/salt/netapi/rest_cherrypy/app.py @@ -103,7 +103,7 @@ A REST API for Salt Whether to check for and kill HTTP responses that have exceeded the default timeout. - .. deprecated:: 2016.11.9, 2017.7.3, Oxygen + .. deprecated:: 2016.11.9,2017.7.3,2018.3.0 The "expire_responses" configuration setting, which corresponds to the ``timeout_monitor`` setting in CherryPy, is no longer @@ -118,7 +118,7 @@ A REST API for Salt stats_disable_auth : False Do not require authentication to access the ``/stats`` endpoint. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 static A filesystem path to static HTML/JavaScript/CSS/image assets. static_path : ``/static`` diff --git a/salt/netapi/rest_tornado/saltnado.py b/salt/netapi/rest_tornado/saltnado.py index 042b82dbe0..7f927e9473 100644 --- a/salt/netapi/rest_tornado/saltnado.py +++ b/salt/netapi/rest_tornado/saltnado.py @@ -248,28 +248,6 @@ def _json_dumps(obj, **kwargs): # - "wheel" (need async api...) -class SaltClientsMixIn(object): - ''' - MixIn class to container all of the salt clients that the API needs - ''' - # TODO: load this proactively, instead of waiting for a request - __saltclients = None - - @property - def saltclients(self): - if SaltClientsMixIn.__saltclients is None: - local_client = salt.client.get_local_client(mopts=self.application.opts) - # TODO: refreshing clients using cachedict - SaltClientsMixIn.__saltclients = { - 'local': local_client.run_job_async, - # not the actual client we'll use.. but its what we'll use to get args - 'local_async': local_client.run_job_async, - 'runner': salt.runner.RunnerClient(opts=self.application.opts).cmd_async, - 'runner_async': None, # empty, since we use the same client as `runner` - } - return SaltClientsMixIn.__saltclients - - AUTH_TOKEN_HEADER = 'X-Auth-Token' AUTH_COOKIE_NAME = 'session_id' @@ -400,7 +378,7 @@ class EventListener(object): del self.timeout_map[future] -class BaseSaltAPIHandler(tornado.web.RequestHandler, SaltClientsMixIn): # pylint: disable=W0223 +class BaseSaltAPIHandler(tornado.web.RequestHandler): # pylint: disable=W0223 ct_out_map = ( ('application/json', _json_dumps), ('application/x-yaml', salt.utils.yaml.safe_dump), @@ -428,6 +406,16 @@ class BaseSaltAPIHandler(tornado.web.RequestHandler, SaltClientsMixIn): # pylin self.application.opts, ) + if not hasattr(self, 'saltclients'): + local_client = salt.client.get_local_client(mopts=self.application.opts) + self.saltclients = { + 'local': local_client.run_job_async, + # not the actual client we'll use.. but its what we'll use to get args + 'local_async': local_client.run_job_async, + 'runner': salt.runner.RunnerClient(opts=self.application.opts).cmd_async, + 'runner_async': None, # empty, since we use the same client as `runner` + } + @property def token(self): ''' @@ -759,7 +747,7 @@ class SaltAuthHandler(BaseSaltAPIHandler): # pylint: disable=W0223 self.write(self.serialize(ret)) -class SaltAPIHandler(BaseSaltAPIHandler, SaltClientsMixIn): # pylint: disable=W0223 +class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223 ''' Main API handler for base "/" ''' diff --git a/salt/output/__init__.py b/salt/output/__init__.py index 30d849e350..bca1573d44 100644 --- a/salt/output/__init__.py +++ b/salt/output/__init__.py @@ -226,6 +226,9 @@ def strip_esc_sequence(txt): from writing their own terminal manipulation commands ''' if isinstance(txt, six.string_types): - return txt.replace('\033', '?') + try: + return txt.replace('\033', '?') + except UnicodeDecodeError: + return txt.replace(str('\033'), str('?')) # future lint: disable=blacklisted-function else: return txt diff --git a/salt/output/nested.py b/salt/output/nested.py index 9ece388c82..19666780c0 100644 --- a/salt/output/nested.py +++ b/salt/output/nested.py @@ -71,20 +71,34 @@ class NestDisplay(object): endc, suffix) except UnicodeDecodeError: - return fmt.format( - indent, - color, - prefix, - salt.utils.stringutils.to_unicode(msg), - endc, - suffix) + try: + return fmt.format( + indent, + color, + prefix, + salt.utils.stringutils.to_unicode(msg), + endc, + suffix) + except UnicodeDecodeError: + # msg contains binary data that can't be decoded + return str(fmt).format( # future lint: disable=blacklisted-function + indent, + color, + prefix, + msg, + endc, + suffix) def display(self, ret, indent, prefix, out): ''' Recursively iterate down through data structures to determine output ''' if isinstance(ret, bytes): - ret = salt.utils.stringutils.to_unicode(ret) + try: + ret = salt.utils.stringutils.to_unicode(ret) + except UnicodeDecodeError: + # ret contains binary data that can't be decoded + pass if ret is None or ret is True or ret is False: out.append( @@ -183,4 +197,11 @@ def output(ret, **kwargs): base_indent = kwargs.get('nested_indent', 0) \ or __opts__.get('nested_indent', 0) nest = NestDisplay(retcode=retcode) - return '\n'.join(nest.display(ret, base_indent, '', [])) + lines = nest.display(ret, base_indent, '', []) + try: + return '\n'.join(lines) + except UnicodeDecodeError: + # output contains binary data that can't be decoded + return str('\n').join( # future lint: disable=blacklisted-function + [salt.utils.stringutils.to_str(x) for x in lines] + ) diff --git a/salt/pillar/ec2_pillar.py b/salt/pillar/ec2_pillar.py index 3ce05fd0b8..8ccbd30b2d 100644 --- a/salt/pillar/ec2_pillar.py +++ b/salt/pillar/ec2_pillar.py @@ -1,19 +1,37 @@ # -*- coding: utf-8 -*- ''' -Retrieve EC2 instance data for minions. +Retrieve EC2 instance data for minions for ec2_tags and ec2_tags_list -The minion id must be the instance-id retrieved from AWS. As an -option, use_grain can be set to True. This allows the use of an +The minion id must be the AWS instance-id or value in 'tag_match_key'. +For example set 'tag_match_key' to 'Name', to have the minion-id matched against the +tag 'Name'. The tag contents must be unique. The value of tag_match_value can +be 'uqdn' or 'asis'. if 'uqdn' strips any domain before comparison. + +The option use_grain can be set to True. This allows the use of an instance-id grain instead of the minion-id. Since this is a potential security risk, the configuration can be further expanded to include a list of minions that are trusted to only allow the alternate id of the instances to specific hosts. There is no glob matching at this time. +The optional 'tag_list_key' indicates which keys should be added to +'ec2_tags_list' and be split by tag_list_sep (default `;`). If a tag key is +included in 'tag_list_key' it is removed from ec2_tags. If a tag does not +exist it is still included as an empty list. + + + Note: restart the salt-master for changes to take effect. + + .. code-block:: yaml ext_pillar: - ec2_pillar: + tag_match_key: 'Name' + tag_match_value: 'asis' + tag_list_key: + - Role + tag_list_sep: ';' use_grain: True minion_ids: - trusted-minion-1 @@ -31,6 +49,8 @@ the instance. from __future__ import absolute_import, print_function, unicode_literals import re import logging +import salt.ext.six as six +from salt.ext.six.moves import range # Import salt libs from salt.utils.versions import StrictVersion as _StrictVersion @@ -47,6 +67,9 @@ except ImportError: # Set up logging log = logging.getLogger(__name__) +# DEBUG boto is far too verbose +logging.getLogger('boto').setLevel(logging.WARNING) + def __virtual__(): ''' @@ -59,7 +82,7 @@ def __virtual__(): required_boto_version = _StrictVersion('2.8.0') if boto_version < required_boto_version: log.error("%s: installed boto version %s < %s, can't retrieve instance data", - __name__, boto_version, required_boto_version) + __name__, boto_version, required_boto_version) return False return True @@ -76,64 +99,145 @@ def _get_instance_info(): def ext_pillar(minion_id, pillar, # pylint: disable=W0613 use_grain=False, - minion_ids=None): + minion_ids=None, + tag_match_key=None, + tag_match_value='asis', + tag_list_key=None, + tag_list_sep=';'): ''' Execute a command and read the output as YAML ''' + valid_tag_match_value = ['uqdn', 'asis'] - log.debug("Querying EC2 tags for minion id %s", minion_id) + # meta-data:instance-id + grain_instance_id = __grains__.get('meta-data', {}).get('instance-id', None) + if not grain_instance_id: + # dynamic:instance-identity:document:instanceId + grain_instance_id = \ + __grains__.get('dynamic', {}).get('instance-identity', {}).get('document', {}).get('instance-id', None) + if grain_instance_id and re.search(r'^i-([0-9a-z]{17}|[0-9a-z]{8})$', grain_instance_id) is None: + log.error('External pillar %s, instance-id \'%s\' is not valid for ' + '\'%s\'', __name__, grain_instance_id, minion_id) + grain_instance_id = None # invalid instance id found, remove it from use. - # If minion_id is not in the format of an AWS EC2 instance, check to see - # if there is a grain named 'instance-id' use that. Because this is a - # security risk, the master config must contain a use_grain: True option - # for this external pillar, which defaults to no - if re.search(r'^i-([0-9a-z]{17}|[0-9a-z]{8})$', minion_id) is None: - if 'instance-id' not in __grains__: - log.debug("Minion-id is not in AWS instance-id formation, and there " - "is no instance-id grain for minion %s", minion_id) - return {} - if not use_grain: - log.debug("Minion-id is not in AWS instance-id formation, and option " - "not set to use instance-id grain, for minion %s, use_grain " - "is %s", minion_id, use_grain) - return {} - log.debug("use_grain set to %s", use_grain) - if minion_ids is not None and minion_id not in minion_ids: - log.debug("Minion-id is not in AWS instance ID format, and minion_ids " - "is set in the ec2_pillar configuration, but minion %s is " - "not in the list of allowed minions %s", minion_id, minion_ids) - return {} - if re.search(r'^i-([0-9a-z]{17}|[0-9a-z]{8})$', __grains__['instance-id']) is not None: - minion_id = __grains__['instance-id'] - log.debug("Minion-id is not in AWS instance ID format, but a grain" - " is, so using %s as the minion ID", minion_id) + # Check AWS Tag restrictions .i.e. letters, spaces, and numbers and + - = . _ : / @ + if tag_match_key and re.match(r'[\w=.:/@-]+$', tag_match_key) is None: + log.error('External pillar %s, tag_match_key \'%s\' is not valid ', + __name__, tag_match_key if isinstance(tag_match_key, six.text_type) else 'non-string') + return {} + + if tag_match_key and tag_match_value not in valid_tag_match_value: + log.error('External pillar %s, tag_value \'%s\' is not valid must be one ' + 'of %s', __name__, tag_match_value, ' '.join(valid_tag_match_value)) + return {} + + if not tag_match_key: + base_msg = ('External pillar %s, querying EC2 tags for minion id \'%s\' ' + 'against instance-id', __name__, minion_id) + else: + base_msg = ('External pillar %s, querying EC2 tags for minion id \'%s\' ' + 'against instance-id or \'%s\' against \'%s\'', __name__, minion_id, tag_match_key, tag_match_value) + + log.debug(base_msg) + find_filter = None + find_id = None + + if re.search(r'^i-([0-9a-z]{17}|[0-9a-z]{8})$', minion_id) is not None: + find_filter = None + find_id = minion_id + elif tag_match_key: + if tag_match_value == 'uqdn': + find_filter = {'tag:{0}'.format(tag_match_key): minion_id.split('.', 1)[0]} else: - log.debug("Nether minion id nor a grain named instance-id is in " - "AWS format, can't query EC2 tags for minion %s", minion_id) - return {} + find_filter = {'tag:{0}'.format(tag_match_key): minion_id} + if grain_instance_id: + # we have an untrusted grain_instance_id, use it to narrow the search + # even more. Combination will be unique even if uqdn is set. + find_filter.update({'instance-id': grain_instance_id}) + # Add this if running state is not dependant on EC2Config + # find_filter.update('instance-state-name': 'running') - m = boto.utils.get_instance_metadata(timeout=0.1, num_retries=1) - if len(m.keys()) < 1: - log.info("%s: not an EC2 instance, skipping", __name__) - return None + # no minion-id is instance-id and no suitable filter, try use_grain if enabled + if not find_filter and not find_id and use_grain: + if not grain_instance_id: + log.debug('Minion-id is not in AWS instance-id formation, and there ' + 'is no instance-id grain for minion %s', minion_id) + return {} + if minion_ids is not None and minion_id not in minion_ids: + log.debug('Minion-id is not in AWS instance ID format, and minion_ids ' + 'is set in the ec2_pillar configuration, but minion %s is ' + 'not in the list of allowed minions %s', minion_id, minion_ids) + return {} + find_id = grain_instance_id + + if not (find_filter or find_id): + log.debug('External pillar %s, querying EC2 tags for minion id \'%s\' against ' + 'instance-id or \'%s\' against \'%s\' noughthing to match against', + __name__, minion_id, tag_match_key, tag_match_value) + return {} + + myself = boto.utils.get_instance_metadata(timeout=0.1, num_retries=1) + if len(myself.keys()) < 1: + log.info("%s: salt master not an EC2 instance, skipping", __name__) + return {} # Get the Master's instance info, primarily the region - (instance_id, region) = _get_instance_info() + (_, region) = _get_instance_info() try: conn = boto.ec2.connect_to_region(region) - except boto.exception as e: # pylint: disable=E0712 - log.error("%s: invalid AWS credentials.", __name__) - return None + except boto.exception.AWSConnectionError as exc: + log.error('%s: invalid AWS credentials, %s', __name__, exc) + return {} + except: + raise + + if conn is None: + log.error('%s: Could not connect to region %s', __name__, region) + return {} - tags = {} try: - _tags = conn.get_all_tags(filters={'resource-type': 'instance', - 'resource-id': minion_id}) - for tag in _tags: - tags[tag.name] = tag.value - except IndexError as e: - log.error("Couldn't retrieve instance information: %s", e) - return None + if find_id: + instance_data = conn.get_only_instances(instance_ids=[find_id], dry_run=False) + else: + # filters and max_results can not be used togther. + instance_data = conn.get_only_instances(filters=find_filter, dry_run=False) - return {'ec2_tags': tags} + except boto.exception.EC2ResponseError as exc: + log.error('%s failed with \'%s\'', base_msg, exc) + return {} + + if not instance_data: + log.debug('%s no match using \'%s\'', base_msg, find_id if find_id else find_filter) + return {} + + # Find a active instance, i.e. ignore terminated and stopped instances + active_inst = [] + for inst in range(0, len(instance_data)): + if instance_data[inst].state not in ['terminated', 'stopped']: + active_inst.append(inst) + + valid_inst = len(active_inst) + if not valid_inst: + log.debug('%s match found but not active \'%s\'', base_msg, find_id if find_id else find_filter) + return {} + + if valid_inst > 1: + log.error('%s multiple matches, ignored, using \'%s\'', base_msg, find_id if find_id else find_filter) + return {} + + instance = instance_data[active_inst[0]] + if instance.tags: + ec2_tags = instance.tags + ec2_tags_list = {} + log.debug('External pillar %s, for minion id \'%s\', tags: %s', __name__, minion_id, instance.tags) + if tag_list_key and isinstance(tag_list_key, list): + for item in tag_list_key: + if item in ec2_tags: + ec2_tags_list[item] = ec2_tags[item].split(tag_list_sep) + del ec2_tags[item] # make sure its only in ec2_tags_list + else: + ec2_tags_list[item] = [] # always return a result + + return {'ec2_tags': ec2_tags, 'ec2_tags_list': ec2_tags_list} + return {} diff --git a/salt/pillar/file_tree.py b/salt/pillar/file_tree.py index 85ac743b4e..cc3728e8fb 100644 --- a/salt/pillar/file_tree.py +++ b/salt/pillar/file_tree.py @@ -1,22 +1,32 @@ # -*- coding: utf-8 -*- ''' +The ``file_tree`` external pillar allows values from all files in a directory +tree to be imported as Pillar data. -``File_tree`` is an external pillar that allows -values from all files in a directory tree to be imported as Pillar data. +.. note:: -Note this is an external pillar, and is subject to the rules and constraints -governing external pillars detailed here: :ref:`external-pillars`. + This is an external pillar and is subject to the :ref:`rules and + constraints ` governing external pillars. .. versionadded:: 2015.5.0 -Example Configuration ---------------------- +In this pillar, data is organized by either Minion ID or Nodegroup name. To +setup pillar data for a specific Minion, place it in +``/hosts/``. To setup pillar data for an entire +Nodegroup, place it in ``/nodegroups/`` where +```` is the Nodegroup's name. + +Example ``file_tree`` Pillar +============================ + +Master Configuration +-------------------- .. code-block:: yaml ext_pillar: - file_tree: - root_dir: /path/to/root/directory + root_dir: /srv/ext_pillar follow_dir_links: False keep_newline: True @@ -29,7 +39,7 @@ will follow symbolic links to other directories. Be careful when using ``follow_dir_links``, as a recursive symlink chain will result in unexpected results. -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 If ``root_dir`` is a relative path, it will be treated as relative to the :conf_master:`pillar_roots` of the environment specified by :conf_minion:`pillarenv`. If an environment specifies multiple @@ -109,74 +119,28 @@ will result in the following pillar tree for minion with ID ``test-host``: test-host: ---------- - files: + apache: ---------- - another-testdir: + config.d: ---------- - symlink-to-file1.txt: - Contents of file #1. - - testdir: + 00_important.conf: + + 20_bob_extra.conf: + + corporate_app: + ---------- + settings: ---------- - file1.txt: - Contents of file #1. - - file2.txt: - Contents of file #2. + common_settings: + // This is the main settings file for the corporate + // internal web app + main_setting: probably + bob_settings: + role: bob .. note:: - Subdirectories underneath ``root_dir``/hosts/``id`` become nested - dictionaries, as shown above. - -Assigning Pillar Data to Entire Nodegroups ------------------------------------------- - -To assign Pillar data to all minions in a given nodegroup, this external pillar -recursively iterates over ``root_dir``/nodegroups/``nodegroup`` (where -``nodegroup`` is the name of a nodegroup), and like for individual hosts, -compiles pillar data with each subdirectory as a dictionary key and each file -as a value. - -.. important:: - If the same Pillar key is set for a minion both by nodegroup and by - individual host, then the value set for the individual host will take - precedence. - -For example, the following ``root_dir`` tree: - -.. code-block:: text - - ./nodegroups/ - ./nodegroups/test-group/ - ./nodegroups/test-group/files/ - ./nodegroups/test-group/files/testdir/ - ./nodegroups/test-group/files/testdir/file1.txt - ./nodegroups/test-group/files/testdir/file2.txt - ./nodegroups/test-group/files/another-testdir/ - ./nodegroups/test-group/files/another-testdir/symlink-to-file1.txt - -will result in the following pillar data for minions in the node group -``test-group``: - -.. code-block:: text - - test-host: - ---------- - files: - ---------- - another-testdir: - ---------- - symlink-to-file1.txt: - Contents of file #1. - - testdir: - ---------- - file1.txt: - Contents of file #1. - - file2.txt: - Contents of file #2. + The leaf data in the example shown is the contents of the pillar files. ''' from __future__ import absolute_import, print_function, unicode_literals @@ -311,7 +275,130 @@ def ext_pillar(minion_id, renderer_whitelist=None, template=False): ''' - Compile pillar data for the specified minion ID + Compile pillar data from the given ``root_dir`` specific to Nodegroup names + and Minion IDs. + + If a Minion's ID is not found at ``/host/`` or if it + is not included in any Nodegroups named at + ``/nodegroups/``, no pillar data provided by this + pillar module will be available for that Minion. + + .. versionchanged:: 2017.7.0 + Templating/rendering has been added. You can now specify a default + render pipeline and a black- and whitelist of (dis)allowed renderers. + + :param:`template` must be set to ``True`` for templating to happen. + + .. code-block:: yaml + + ext_pillar: + - file_tree: + root_dir: /path/to/root/directory + render_default: jinja|yaml + renderer_blacklist: + - gpg + renderer_whitelist: + - jinja + - yaml + template: True + + :param minion_id: + The ID of the Minion whose pillar data is to be collected + + :param pillar: + Unused by the ``file_tree`` pillar module + + :param root_dir: + Filesystem directory used as the root for pillar data (e.g. + ``/srv/ext_pillar``) + + .. versionchanged:: 2018.3.0 + If ``root_dir`` is a relative path, it will be treated as relative to the + :conf_master:`pillar_roots` of the environment specified by + :conf_minion:`pillarenv`. If an environment specifies multiple + roots, this module will search for files relative to all of them, in order, + merging the results. + + :param follow_dir_links: + Follow symbolic links to directories while collecting pillar files. + Defaults to ``False``. + + .. warning:: + + Care should be exercised when enabling this option as it will + follow links that point outside of :param:`root_dir`. + + .. warning:: + + Symbolic links that lead to infinite recursion are not filtered. + + :param debug: + Enable debug information at log level ``debug``. Defaults to + ``False``. This option may be useful to help debug errors when setting + up the ``file_tree`` pillar module. + + :param keep_newline: + Preserve the end-of-file newline in files. Defaults to ``False``. + This option may either be a boolean or a list of file globs (as defined + by the `Python fnmatch package + `_) for which end-of-file + newlines are to be kept. + + ``keep_newline`` should be turned on if the pillar data is intended to + be used to deploy a file using ``contents_pillar`` with a + :py:func:`file.managed ` state. + + .. versionchanged:: 2015.8.4 + The ``raw_data`` parameter has been renamed to ``keep_newline``. In + earlier releases, ``raw_data`` must be used. Also, this parameter + can now be a list of globs, allowing for more granular control over + which pillar values keep their end-of-file newline. The globs match + paths relative to the directories named for Minion IDs and + Nodegroup namess underneath the :param:`root_dir`. + + .. code-block:: yaml + + ext_pillar: + - file_tree: + root_dir: /srv/ext_pillar + keep_newline: + - apache/config.d/* + - corporate_app/settings/* + + .. note:: + In earlier releases, this documentation incorrectly stated that + binary files would not affected by the ``keep_newline``. However, + this module does not actually distinguish between binary and text + files. + + + :param render_default: + Override Salt's :conf_master:`default global renderer ` for + the ``file_tree`` pillar. + + .. code-block:: yaml + + render_default: jinja + + :param renderer_blacklist: + Disallow renderers for pillar files. + + .. code-block:: yaml + + renderer_blacklist: + - json + + :param renderer_whitelist: + Allow renderers for pillar files. + + .. code-block:: yaml + + renderer_whitelist: + - yaml + - jinja + + :param template: + Enable templating of pillar files. Defaults to ``False``. ''' # Not used del pillar @@ -391,7 +478,7 @@ def _ext_pillar(minion_id, ngroup_pillar = {} nodegroups_dir = os.path.join(root_dir, 'nodegroups') - if os.path.exists(nodegroups_dir) and len(__opts__['nodegroups']) > 0: + if os.path.exists(nodegroups_dir) and len(__opts__.get('nodegroups', ())) > 0: master_ngroups = __opts__['nodegroups'] ext_pillar_dirs = os.listdir(nodegroups_dir) if len(ext_pillar_dirs) > 0: @@ -419,8 +506,8 @@ def _ext_pillar(minion_id, else: if debug is True: log.debug( - 'file_tree: no nodegroups found in file tree directory ' - 'ext_pillar_dirs, skipping...' + 'file_tree: no nodegroups found in file tree directory %s, skipping...', + ext_pillar_dirs ) else: if debug is True: @@ -428,7 +515,12 @@ def _ext_pillar(minion_id, host_dir = os.path.join(root_dir, 'hosts', minion_id) if not os.path.exists(host_dir): - # No data for host with this ID + if debug is True: + log.debug( + 'file_tree: no pillar data for minion %s found in file tree directory %s', + minion_id, + host_dir + ) return ngroup_pillar if not os.path.isdir(host_dir): diff --git a/salt/pillar/http_json.py b/salt/pillar/http_json.py index c57b489004..e24b80a2f4 100644 --- a/salt/pillar/http_json.py +++ b/salt/pillar/http_json.py @@ -27,7 +27,7 @@ in <> brackets) in the url in order to populate pillar data based on the grain v url: http://example.com/api/ with_grains: True -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 If %s is present in the url, it will be automaticaly replaced by the minion_id: diff --git a/salt/pillar/http_yaml.py b/salt/pillar/http_yaml.py index 2a037b7398..e3523ad044 100644 --- a/salt/pillar/http_yaml.py +++ b/salt/pillar/http_yaml.py @@ -27,7 +27,7 @@ in <> brackets) in the url in order to populate pillar data based on the grain v url: http://example.com/api/ with_grains: True -.. versionchanged:: Oxygen +.. versionchanged:: 2018.3.0 If %s is present in the url, it will be automaticaly replaced by the minion_id: diff --git a/salt/pillar/rethinkdb_pillar.py b/salt/pillar/rethinkdb_pillar.py index 16edb6fc2f..85d35af4ce 100644 --- a/salt/pillar/rethinkdb_pillar.py +++ b/salt/pillar/rethinkdb_pillar.py @@ -2,7 +2,7 @@ ''' Provide external pillar data from RethinkDB -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: rethinkdb (on the salt-master) diff --git a/salt/proxy/junos.py b/salt/proxy/junos.py index 8346bca349..80f671e1e3 100644 --- a/salt/proxy/junos.py +++ b/salt/proxy/junos.py @@ -124,7 +124,7 @@ def alive(opts): ''' Validate and return the connection status with the remote device. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 ''' dev = conn() diff --git a/salt/returners/local_cache.py b/salt/returners/local_cache.py index 8df04aa1f2..70c641af19 100644 --- a/salt/returners/local_cache.py +++ b/salt/returners/local_cache.py @@ -26,7 +26,7 @@ import salt.exceptions # Import 3rd-party libs import msgpack from salt.ext import six - +from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin log = logging.getLogger(__name__) @@ -296,8 +296,19 @@ def get_load(jid): return {} serial = salt.payload.Serial(__opts__) ret = {} - with salt.utils.files.fopen(os.path.join(jid_dir, LOAD_P), 'rb') as rfh: - ret = serial.load(rfh) + load_p = os.path.join(jid_dir, LOAD_P) + num_tries = 5 + for index in range(1, num_tries + 1): + with salt.utils.files.fopen(load_p, 'rb') as rfh: + try: + ret = serial.load(rfh) + break + except Exception as exc: + if index == num_tries: + time.sleep(0.25) + else: + log.critical('Failed to unpack %s', load_p) + raise exc if ret is None: ret = {} minions_cache = [os.path.join(jid_dir, MINIONS_P)] diff --git a/salt/roster/clustershell.py b/salt/roster/clustershell.py index d192208d3a..77d5b118a8 100644 --- a/salt/roster/clustershell.py +++ b/salt/roster/clustershell.py @@ -45,7 +45,7 @@ def targets(tgt, tgt_type='glob', **kwargs): for host, addr in host_addrs.items(): addr = six.text_type(addr) - ret[addr] = copy.deepcopy(__opts__.get('roster_defaults', {})) + ret[host] = copy.deepcopy(__opts__.get('roster_defaults', {})) for port in ports: try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/salt/runner.py b/salt/runner.py index e7bd4cd2c3..d96a8af38c 100644 --- a/salt/runner.py +++ b/salt/runner.py @@ -205,7 +205,7 @@ class Runner(RunnerClient): if self.opts.get('eauth'): if 'token' in self.opts: try: - with salt.utils.files.fopen(os.path.join(self.opts['key_dir'], '.root_key'), 'r') as fp_: + with salt.utils.files.fopen(os.path.join(self.opts['cachedir'], '.root_key'), 'r') as fp_: low['key'] = salt.utils.stringutils.to_unicode(fp_.readline()) except IOError: low['token'] = self.opts['token'] @@ -232,7 +232,7 @@ class Runner(RunnerClient): else: user = salt.utils.user.get_specific_user() - if low['fun'] == 'state.orchestrate': + if low['fun'] in ('state.orchestrate', 'state.orch'): low['kwarg']['orchestration_jid'] = async_pub['jid'] # Run the runner! diff --git a/salt/runners/cache.py b/salt/runners/cache.py index 514847160a..0e4da67431 100644 --- a/salt/runners/cache.py +++ b/salt/runners/cache.py @@ -316,7 +316,7 @@ def clear_git_lock(role, remote=None, **kwargs): comma-separated or Python list. .. versionadded:: 2015.8.8 - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 ``mountpoint`` lock type added CLI Examples: diff --git a/salt/runners/git_pillar.py b/salt/runners/git_pillar.py index b90f98977d..b567891bac 100644 --- a/salt/runners/git_pillar.py +++ b/salt/runners/git_pillar.py @@ -28,7 +28,7 @@ def update(branch=None, repo=None): fetched, and ``False`` if there were errors or no new commits were fetched. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The return for a given git_pillar remote will now be ``None`` when no changes were fetched. ``False`` now is reserved only for instances in which there were errors. diff --git a/salt/runners/pillar.py b/salt/runners/pillar.py index adbcf4361c..7331fcb41b 100644 --- a/salt/runners/pillar.py +++ b/salt/runners/pillar.py @@ -82,19 +82,17 @@ def show_pillar(minion='*', **kwargs): pillar = runner.cmd('pillar.show_pillar', []) print(pillar) ''' - + pillarenv = None saltenv = 'base' - pillarenv = __opts__['pillarenv'] if 'pillarenv' in __opts__ else None id_, grains, _ = salt.utils.minions.get_minion_data(minion, __opts__) if grains is None: grains = {'fqdn': minion} for key in kwargs: - if key == 'pillarenv': - __opts__['pillarenv'] = kwargs[key] if key == 'saltenv': saltenv = kwargs[key] elif key == 'pillarenv': + # pillarenv overridden on CLI pillarenv = kwargs[key] else: grains[key] = kwargs[key] diff --git a/salt/runners/salt.py b/salt/runners/salt.py index a8f60bb0fc..9ba670c301 100644 --- a/salt/runners/salt.py +++ b/salt/runners/salt.py @@ -46,7 +46,7 @@ log = logging.getLogger(__name__) # pylint: disable=invalid-name def cmd(fun, *args, **kwargs): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Added ``with_pillar`` argument Execute ``fun`` with the given ``args`` and ``kwargs``. Parameter ``fun`` diff --git a/salt/runners/saltutil.py b/salt/runners/saltutil.py index 883cc4d1e5..4a6e7b3ed2 100644 --- a/salt/runners/saltutil.py +++ b/salt/runners/saltutil.py @@ -308,7 +308,7 @@ def sync_engines(saltenv='base', extmod_whitelist=None, extmod_blacklist=None): def sync_thorium(saltenv='base', extmod_whitelist=None, extmod_blacklist=None): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Sync Thorium from ``salt://_thorium`` to the master @@ -480,7 +480,7 @@ def sync_cache(saltenv='base', extmod_whitelist=None, extmod_blacklist=None): def sync_fileserver(saltenv='base', extmod_whitelist=None, extmod_blacklist=None): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Sync fileserver modules from ``salt://_fileserver`` to the master @@ -558,7 +558,7 @@ def sync_roster(saltenv='base', extmod_whitelist=None, extmod_blacklist=None): def sync_eauth_tokens(saltenv='base', extmod_whitelist=None, extmod_blacklist=None): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Sync eauth token modules from ``salt://_tokens`` to the master diff --git a/salt/runners/test.py b/salt/runners/test.py index 229c28e82c..8f3b05cdff 100644 --- a/salt/runners/test.py +++ b/salt/runners/test.py @@ -78,7 +78,7 @@ def stream(): def get_opts(): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Return the configuration options of the master. diff --git a/salt/scripts.py b/salt/scripts.py index df8e9b6f30..e677368a0f 100644 --- a/salt/scripts.py +++ b/salt/scripts.py @@ -43,7 +43,12 @@ def _handle_interrupt(exc, original_exc, hardfail=False, trace=''): def _handle_signals(client, signum, sigframe): - trace = traceback.format_exc() + try: + # This raises AttributeError on Python 3.4 and 3.5 if there is no current exception. + # Ref: https://bugs.python.org/issue23003 + trace = traceback.format_exc() + except AttributeError: + trace = '' try: hardcrash = client.options.hard_crash except (AttributeError, KeyError): diff --git a/salt/state.py b/salt/state.py index b04a007628..45511d6039 100644 --- a/salt/state.py +++ b/salt/state.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- ''' -The module used to execute states in salt. A state is unlike a module -execution in that instead of just executing a command it ensure that a -certain state is present on the system. +The State Compiler is used to execute states in Salt. A state is unlike +an execution module in that instead of just executing a command, it +ensures that a certain state is present on the system. The data sent to the state calls is as follows: { 'state': '', @@ -167,6 +167,23 @@ def _l_tag(name, id_): return _gen_tag(low) +def _calculate_fake_duration(): + ''' + Generate a NULL duration for when states do not run + but we want the results to be consistent. + ''' + utc_start_time = datetime.datetime.utcnow() + local_start_time = utc_start_time - \ + (datetime.datetime.utcnow() - datetime.datetime.now()) + utc_finish_time = datetime.datetime.utcnow() + start_time = local_start_time.time().isoformat() + delta = (utc_finish_time - utc_start_time) + # duration in milliseconds.microseconds + duration = (delta.seconds * 1000000 + delta.microseconds)/1000.0 + + return start_time, duration + + def get_accumulator_dir(cachedir): ''' Return the directory that accumulator data is stored in, creating it if it @@ -1274,7 +1291,7 @@ class State(object): ''' err = [] for chunk in chunks: - err += self.verify_data(chunk) + err.extend(self.verify_data(chunk)) return err def order_chunks(self, chunks): @@ -2504,8 +2521,11 @@ class State(object): run_dict = self.pre else: run_dict = running + start_time, duration = _calculate_fake_duration() run_dict[tag] = {'changes': {}, 'result': False, + 'duration': duration, + 'start_time': start_time, 'comment': comment, '__run_num__': self.__run_num, '__sls__': low['__sls__']} @@ -2588,9 +2608,12 @@ class State(object): _cmt = 'One or more requisite failed: {0}'.format( ', '.join(six.text_type(i) for i in failed_requisites) ) + start_time, duration = _calculate_fake_duration() running[tag] = { 'changes': {}, 'result': False, + 'duration': duration, + 'start_time': start_time, 'comment': _cmt, '__run_num__': self.__run_num, '__sls__': low['__sls__'] @@ -2606,8 +2629,11 @@ class State(object): ret = self.call(low, chunks, running) running[tag] = ret elif status == 'pre': + start_time, duration = _calculate_fake_duration() pre_ret = {'changes': {}, 'result': True, + 'duration': duration, + 'start_time': start_time, 'comment': 'No changes detected', '__run_num__': self.__run_num, '__sls__': low['__sls__']} @@ -2615,15 +2641,21 @@ class State(object): self.pre[tag] = pre_ret self.__run_num += 1 elif status == 'onfail': + start_time, duration = _calculate_fake_duration() running[tag] = {'changes': {}, 'result': True, + 'duration': duration, + 'start_time': start_time, 'comment': 'State was not run because onfail req did not change', '__run_num__': self.__run_num, '__sls__': low['__sls__']} self.__run_num += 1 elif status == 'onchanges': + start_time, duration = _calculate_fake_duration() running[tag] = {'changes': {}, 'result': True, + 'duration': duration, + 'start_time': start_time, 'comment': 'State was not run because none of the onchanges reqs changed', '__run_num__': self.__run_num, '__sls__': low['__sls__']} @@ -2713,12 +2745,12 @@ class State(object): errors = [] # If there is extension data reconcile it high, ext_errors = self.reconcile_extend(high) - errors += ext_errors - errors += self.verify_high(high) + errors.extend(ext_errors) + errors.extend(self.verify_high(high)) if errors: return errors high, req_in_errors = self.requisite_in(high) - errors += req_in_errors + errors.extend(req_in_errors) high = self.apply_exclude(high) # Verify that the high data is structurally sound if errors: diff --git a/salt/states/archive.py b/salt/states/archive.py index e49465cdef..c4ea3019b1 100644 --- a/salt/states/archive.py +++ b/salt/states/archive.py @@ -966,7 +966,7 @@ def extracted(name, if result['result']: # Get the path of the file in the minion cache - cached = __salt__['cp.is_cached'](source_match) + cached = __salt__['cp.is_cached'](source_match, saltenv=__env__) else: log.debug( 'failed to download %s', diff --git a/salt/states/azurearm_compute.py b/salt/states/azurearm_compute.py new file mode 100644 index 0000000000..29596cd469 --- /dev/null +++ b/salt/states/azurearm_compute.py @@ -0,0 +1,326 @@ +# -*- coding: utf-8 -*- +''' +Azure (ARM) Compute State Module + +.. versionadded:: Fluorine + +:maintainer: +:maturity: new +:depends: + * `azure `_ >= 2.0.0 + * `azure-common `_ >= 1.1.8 + * `azure-mgmt `_ >= 1.0.0 + * `azure-mgmt-compute `_ >= 1.0.0 + * `azure-mgmt-network `_ >= 1.7.1 + * `azure-mgmt-resource `_ >= 1.1.0 + * `azure-mgmt-storage `_ >= 1.0.0 + * `azure-mgmt-web `_ >= 0.32.0 + * `azure-storage `_ >= 0.34.3 + * `msrestazure `_ >= 0.4.21 +:platform: linux + +:configuration: This module requires Azure Resource Manager credentials to be passed as a dictionary of +keyword arguments to the ``connection_auth`` parameter in order to work properly. Since the authentication +parameters are sensitive, it's recommended to pass them to the states via pillar. + + Required provider parameters: + + if using username and password: + * ``subscription_id`` + * ``username`` + * ``password`` + + if using a service principal: + * ``subscription_id`` + * ``tenant`` + * ``client_id`` + * ``secret`` + + Optional provider parameters: + + **cloud_environment**: Used to point the cloud driver to different API endpoints, such as Azure GovCloud. Possible values: + * ``AZURE_PUBLIC_CLOUD`` (default) + * ``AZURE_CHINA_CLOUD`` + * ``AZURE_US_GOV_CLOUD`` + * ``AZURE_GERMAN_CLOUD`` + + Example Pillar for Azure Resource Manager authentication: + + .. code-block:: yaml + + azurearm: + user_pass_auth: + subscription_id: 3287abc8-f98a-c678-3bde-326766fd3617 + username: fletch + password: 123pass + mysubscription: + subscription_id: 3287abc8-f98a-c678-3bde-326766fd3617 + tenant: ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF + client_id: ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF + secret: XXXXXXXXXXXXXXXXXXXXXXXX + cloud_environment: AZURE_PUBLIC_CLOUD + + Example states using Azure Resource Manager authentication: + + .. code-block:: yaml + + {% set profile = salt['pillar.get']('azurearm:mysubscription') %} + Ensure availability set exists: + azurearm_compute.availability_set_present: + - name: my_avail_set + - resource_group: my_rg + - virtual_machines: + - my_vm1 + - my_vm2 + - tags: + how_awesome: very + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + + Ensure availability set is absent: + azurearm_compute.availability_set_absent: + - name: other_avail_set + - resource_group: my_rg + - connection_auth: {{ profile }} + +''' + +# Python libs +from __future__ import absolute_import +import logging + +__virtualname__ = 'azurearm_compute' + +log = logging.getLogger(__name__) + + +def __virtual__(): + ''' + Only make this state available if the azurearm_compute module is available. + ''' + return __virtualname__ if 'azurearm_compute.availability_set_create_or_update' in __salt__ else False + + +def availability_set_present(name, resource_group, tags=None, platform_update_domain_count=None, + platform_fault_domain_count=None, virtual_machines=None, sku=None, connection_auth=None, + **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure an availability set exists. + + :param name: + Name of the availability set. + + :param resource_group: + The resource group assigned to the availability set. + + :param tags: + A dictionary of strings can be passed as tag metadata to the availability set object. + + :param platform_update_domain_count: + An optional parameter which indicates groups of virtual machines and underlying physical hardware that can be + rebooted at the same time. + + :param platform_fault_domain_count: + An optional parameter which defines the group of virtual machines that share a common power source and network + switch. + + :param virtual_machines: + A list of names of existing virtual machines to be included in the availability set. + + :param sku: + The availability set SKU, which specifies whether the availability set is managed or not. Possible values are + 'Aligned' or 'Classic'. An 'Aligned' availability set is managed, 'Classic' is not. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure availability set exists: + azurearm_compute.availability_set_present: + - name: aset1 + - resource_group: group1 + - platform_update_domain_count: 5 + - platform_fault_domain_count: 3 + - sku: aligned + - tags: + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + - require: + - azurearm_resource: Ensure resource group exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + if sku: + sku = {'name': sku.capitalize()} + + aset = __salt__['azurearm_compute.availability_set_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in aset: + tag_changes = __utils__['dictdiffer.deep_diff'](aset.get('tags', {}), tags or {}) + if tag_changes: + ret['changes']['tags'] = tag_changes + + if platform_update_domain_count and (int(platform_update_domain_count) != aset.get('platform_update_domain_count')): + ret['changes']['platform_update_domain_count'] = { + 'old': aset.get('platform_update_domain_count'), + 'new': platform_update_domain_count + } + + if platform_fault_domain_count and (int(platform_fault_domain_count) != aset.get('platform_fault_domain_count')): + ret['changes']['platform_fault_domain_count'] = { + 'old': aset.get('platform_fault_domain_count'), + 'new': platform_fault_domain_count + } + + if sku and (sku['name'] != aset.get('sku', {}).get('name')): + ret['changes']['sku'] = { + 'old': aset.get('sku'), + 'new': sku + } + + if virtual_machines: + if not isinstance(virtual_machines, list): + ret['comment'] = 'Virtual machines must be supplied as a list!' + return ret + aset_vms = aset.get('virtual_machines', []) + remote_vms = sorted([vm['id'].split('/')[-1].lower() for vm in aset_vms if 'id' in aset_vms]) + local_vms = sorted([vm.lower() for vm in virtual_machines or []]) + if local_vms != remote_vms: + ret['changes']['virtual_machines'] = { + 'old': aset_vms, + 'new': virtual_machines + } + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Availability set {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Availability set {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'virtual_machines': virtual_machines, + 'platform_update_domain_count': platform_update_domain_count, + 'platform_fault_domain_count': platform_fault_domain_count, + 'sku': sku, + 'tags': tags + } + } + + if __opts__['test']: + ret['comment'] = 'Availability set {0} would be created.'.format(name) + ret['result'] = None + return ret + + aset_kwargs = kwargs.copy() + aset_kwargs.update(connection_auth) + + aset = __salt__['azurearm_compute.availability_set_create_or_update']( + name=name, + resource_group=resource_group, + virtual_machines=virtual_machines, + platform_update_domain_count=platform_update_domain_count, + platform_fault_domain_count=platform_fault_domain_count, + sku=sku, + tags=tags, + **aset_kwargs + ) + + if 'error' not in aset: + ret['result'] = True + ret['comment'] = 'Availability set {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create availability set {0}! ({1})'.format(name, aset.get('error')) + return ret + + +def availability_set_absent(name, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure an availability set does not exist in a resource group. + + :param name: + Name of the availability set. + + :param resource_group: + Name of the resource group containing the availability set. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + aset = __salt__['azurearm_compute.availability_set_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in aset: + ret['result'] = True + ret['comment'] = 'Availability set {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Availability set {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': aset, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_compute.availability_set_delete'](name, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Availability set {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': aset, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete availability set {0}!'.format(name) + return ret diff --git a/salt/states/azurearm_network.py b/salt/states/azurearm_network.py new file mode 100644 index 0000000000..e7f3ef48dc --- /dev/null +++ b/salt/states/azurearm_network.py @@ -0,0 +1,2514 @@ +# -*- coding: utf-8 -*- +''' +Azure (ARM) Network State Module + +.. versionadded:: Fluorine + +:maintainer: +:maturity: new +:depends: + * `azure `_ >= 2.0.0 + * `azure-common `_ >= 1.1.8 + * `azure-mgmt `_ >= 1.0.0 + * `azure-mgmt-compute `_ >= 1.0.0 + * `azure-mgmt-network `_ >= 1.7.1 + * `azure-mgmt-resource `_ >= 1.1.0 + * `azure-mgmt-storage `_ >= 1.0.0 + * `azure-mgmt-web `_ >= 0.32.0 + * `azure-storage `_ >= 0.34.3 + * `msrestazure `_ >= 0.4.21 +:platform: linux + +:configuration: This module requires Azure Resource Manager credentials to be passed as a dictionary of +keyword arguments to the ``connection_auth`` parameter in order to work properly. Since the authentication +parameters are sensitive, it's recommended to pass them to the states via pillar. + + Required provider parameters: + + if using username and password: + * ``subscription_id`` + * ``username`` + * ``password`` + + if using a service principal: + * ``subscription_id`` + * ``tenant`` + * ``client_id`` + * ``secret`` + + Optional provider parameters: + + **cloud_environment**: Used to point the cloud driver to different API endpoints, such as Azure GovCloud. Possible values: + * ``AZURE_PUBLIC_CLOUD`` (default) + * ``AZURE_CHINA_CLOUD`` + * ``AZURE_US_GOV_CLOUD`` + * ``AZURE_GERMAN_CLOUD`` + + Example Pillar for Azure Resource Manager authentication: + + .. code-block:: yaml + + azurearm: + user_pass_auth: + subscription_id: 3287abc8-f98a-c678-3bde-326766fd3617 + username: fletch + password: 123pass + mysubscription: + subscription_id: 3287abc8-f98a-c678-3bde-326766fd3617 + tenant: ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF + client_id: ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF + secret: XXXXXXXXXXXXXXXXXXXXXXXX + cloud_environment: AZURE_PUBLIC_CLOUD + + Example states using Azure Resource Manager authentication: + + .. code-block:: yaml + + {% set profile = salt['pillar.get']('azurearm:mysubscription') %} + Ensure virtual network exists: + azurearm_network.virtual_network_present: + - name: my_vnet + - resource_group: my_rg + - address_prefixes: + - '10.0.0.0/8' + - '192.168.0.0/16' + - dns_servers: + - '8.8.8.8' + - tags: + how_awesome: very + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + + Ensure virtual network is absent: + azurearm_network.virtual_network_absent: + - name: other_vnet + - resource_group: my_rg + - connection_auth: {{ profile }} + +''' + +# Python libs +from __future__ import absolute_import +import logging + +# Salt libs +try: + from salt.ext.six.moves import range as six_range +except ImportError: + six_range = range + +__virtualname__ = 'azurearm_network' + +log = logging.getLogger(__name__) + + +def __virtual__(): + ''' + Only make this state available if the azurearm_network module is available. + ''' + return __virtualname__ if 'azurearm_network.check_ip_address_availability' in __salt__ else False + + +def virtual_network_present(name, address_prefixes, resource_group, dns_servers=None, + tags=None, connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a virtual network exists. + + :param name: + Name of the virtual network. + + :param resource_group: + The resource group assigned to the virtual network. + + :param address_prefixes: + A list of CIDR blocks which can be used by subnets within the virtual network. + + :param dns_servers: + A list of DNS server addresses. + + :param tags: + A dictionary of strings can be passed as tag metadata to the virtual network object. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure virtual network exists: + azurearm_network.virtual_network_present: + - name: vnet1 + - resource_group: group1 + - address_prefixes: + - '10.0.0.0/8' + - '192.168.0.0/16' + - dns_servers: + - '8.8.8.8' + - tags: + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + - require: + - azurearm_resource: Ensure resource group exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + vnet = __salt__['azurearm_network.virtual_network_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in vnet: + tag_changes = __utils__['dictdiffer.deep_diff'](vnet.get('tags', {}), tags or {}) + if tag_changes: + ret['changes']['tags'] = tag_changes + + dns_changes = set(dns_servers or []).symmetric_difference( + set(vnet.get('dhcp_options', {}).get('dns_servers', []))) + if dns_changes: + ret['changes']['dns_servers'] = { + 'old': vnet.get('dhcp_options', {}).get('dns_servers', []), + 'new': dns_servers, + } + + addr_changes = set(address_prefixes or []).symmetric_difference( + set(vnet.get('address_space', {}).get('address_prefixes', []))) + if addr_changes: + ret['changes']['address_space'] = { + 'address_prefixes': { + 'old': vnet.get('address_space', {}).get('address_prefixes', []), + 'new': address_prefixes, + } + } + + if kwargs.get('enable_ddos_protection', False) != vnet.get('enable_ddos_protection'): + ret['changes']['enable_ddos_protection'] = { + 'old': vnet.get('enable_ddos_protection'), + 'new': kwargs.get('enable_ddos_protection') + } + + if kwargs.get('enable_vm_protection', False) != vnet.get('enable_vm_protection'): + ret['changes']['enable_vm_protection'] = { + 'old': vnet.get('enable_vm_protection'), + 'new': kwargs.get('enable_vm_protection') + } + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Virtual network {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Virtual network {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'resource_group': resource_group, + 'address_space': {'address_prefixes': address_prefixes}, + 'dhcp_options': {'dns_servers': dns_servers}, + 'enable_ddos_protection': kwargs.get('enable_ddos_protection', False), + 'enable_vm_protection': kwargs.get('enable_vm_protection', False), + 'tags': tags, + } + } + + if __opts__['test']: + ret['comment'] = 'Virtual network {0} would be created.'.format(name) + ret['result'] = None + return ret + + vnet_kwargs = kwargs.copy() + vnet_kwargs.update(connection_auth) + + vnet = __salt__['azurearm_network.virtual_network_create_or_update']( + name=name, + resource_group=resource_group, + address_prefixes=address_prefixes, + dns_servers=dns_servers, + tags=tags, + **vnet_kwargs + ) + + if 'error' not in vnet: + ret['result'] = True + ret['comment'] = 'Virtual network {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create virtual network {0}! ({1})'.format(name, vnet.get('error')) + return ret + + +def virtual_network_absent(name, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a virtual network does not exist in the resource group. + + :param name: + Name of the virtual network. + + :param resource_group: + The resource group assigned to the virtual network. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + vnet = __salt__['azurearm_network.virtual_network_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in vnet: + ret['result'] = True + ret['comment'] = 'Virtual network {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Virtual network {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': vnet, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_network.virtual_network_delete'](name, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Virtual network {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': vnet, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete virtual network {0}!'.format(name) + return ret + + +def subnet_present(name, address_prefix, virtual_network, resource_group, + security_group=None, route_table=None, connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a subnet exists. + + :param name: + Name of the subnet. + + :param address_prefix: + A CIDR block used by the subnet within the virtual network. + + :param virtual_network: + Name of the existing virtual network to contain the subnet. + + :param resource_group: + The resource group assigned to the virtual network. + + :param security_group: + The name of the existing network security group to assign to the subnet. + + :param route_table: + The name of the existing route table to assign to the subnet. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure subnet exists: + azurearm_network.subnet_present: + - name: vnet1_sn1 + - virtual_network: vnet1 + - resource_group: group1 + - address_prefix: '192.168.1.0/24' + - security_group: nsg1 + - route_table: rt1 + - connection_auth: {{ profile }} + - require: + - azurearm_network: Ensure virtual network exists + - azurearm_network: Ensure network security group exists + - azurearm_network: Ensure route table exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + snet = __salt__['azurearm_network.subnet_get']( + name, + virtual_network, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in snet: + if address_prefix != snet.get('address_prefix'): + ret['changes']['address_prefix'] = { + 'old': snet.get('address_prefix'), + 'new': address_prefix + } + + nsg_name = None + if snet.get('network_security_group'): + nsg_name = snet['network_security_group']['id'].split('/')[-1] + + if security_group and (security_group != nsg_name): + ret['changes']['network_security_group'] = { + 'old': nsg_name, + 'new': security_group + } + + rttbl_name = None + if snet.get('route_table'): + rttbl_name = snet['route_table']['id'].split('/')[-1] + + if route_table and (route_table != rttbl_name): + ret['changes']['route_table'] = { + 'old': rttbl_name, + 'new': route_table + } + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Subnet {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Subnet {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'address_prefix': address_prefix, + 'network_security_group': security_group, + 'route_table': route_table + } + } + + if __opts__['test']: + ret['comment'] = 'Subnet {0} would be created.'.format(name) + ret['result'] = None + return ret + + snet_kwargs = kwargs.copy() + snet_kwargs.update(connection_auth) + + snet = __salt__['azurearm_network.subnet_create_or_update']( + name=name, + virtual_network=virtual_network, + resource_group=resource_group, + address_prefix=address_prefix, + network_security_group=security_group, + route_table=route_table, + **snet_kwargs + ) + + if 'error' not in snet: + ret['result'] = True + ret['comment'] = 'Subnet {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create subnet {0}! ({1})'.format(name, snet.get('error')) + return ret + + +def subnet_absent(name, virtual_network, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a virtual network does not exist in the virtual network. + + :param name: + Name of the subnet. + + :param virtual_network: + Name of the existing virtual network containing the subnet. + + :param resource_group: + The resource group assigned to the virtual network. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + snet = __salt__['azurearm_network.subnet_get']( + name, + virtual_network, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in snet: + ret['result'] = True + ret['comment'] = 'Subnet {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Subnet {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': snet, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_network.subnet_delete'](name, virtual_network, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Subnet {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': snet, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete subnet {0}!'.format(name) + return ret + + +def network_security_group_present(name, resource_group, tags=None, security_rules=None, connection_auth=None, + **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a network security group exists. + + :param name: + Name of the network security group. + + :param resource_group: + The resource group assigned to the network security group. + + :param tags: + A dictionary of strings can be passed as tag metadata to the network security group object. + + :param security_rules: An optional list of dictionaries representing valid SecurityRule objects. See the + documentation for the security_rule_present state or security_rule_create_or_update execution module + for more information on required and optional parameters for security rules. The rules are only + managed if this parameter is present. When this parameter is absent, implemented rules will not be removed, + and will merely become unmanaged. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure network security group exists: + azurearm_network.network_security_group_present: + - name: nsg1 + - resource_group: group1 + - security_rules: + - name: nsg1_rule1 + priority: 100 + protocol: tcp + access: allow + direction: outbound + source_address_prefix: virtualnetwork + destination_address_prefix: internet + source_port_range: '*' + destination_port_range: '*' + - name: nsg1_rule2 + priority: 101 + protocol: tcp + access: allow + direction: inbound + source_address_prefix: internet + destination_address_prefix: virtualnetwork + source_port_range: '*' + destination_port_ranges: + - '80' + - '443' + - tags: + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + - require: + - azurearm_resource: Ensure resource group exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + nsg = __salt__['azurearm_network.network_security_group_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in nsg: + tag_changes = __utils__['dictdiffer.deep_diff'](nsg.get('tags', {}), tags or {}) + if tag_changes: + ret['changes']['tags'] = tag_changes + + if security_rules: + comp_ret = __utils__['azurearm.compare_list_of_dicts'](nsg.get('security_rules', []), security_rules) + + if comp_ret.get('comment'): + ret['comment'] = '"security_rules" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['security_rules'] = comp_ret['changes'] + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Network security group {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Network security group {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'resource_group': resource_group, + 'tags': tags, + 'security_rules': security_rules, + } + } + + if __opts__['test']: + ret['comment'] = 'Network security group {0} would be created.'.format(name) + ret['result'] = None + return ret + + nsg_kwargs = kwargs.copy() + nsg_kwargs.update(connection_auth) + + nsg = __salt__['azurearm_network.network_security_group_create_or_update']( + name=name, + resource_group=resource_group, + tags=tags, + security_rules=security_rules, + **nsg_kwargs + ) + + if 'error' not in nsg: + ret['result'] = True + ret['comment'] = 'Network security group {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create network security group {0}! ({1})'.format(name, nsg.get('error')) + return ret + + +def network_security_group_absent(name, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a network security group does not exist in the resource group. + + :param name: + Name of the network security group. + + :param resource_group: + The resource group assigned to the network security group. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + nsg = __salt__['azurearm_network.network_security_group_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in nsg: + ret['result'] = True + ret['comment'] = 'Network security group {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Network security group {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': nsg, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_network.network_security_group_delete'](name, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Network security group {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': nsg, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete network security group {0}!'.format(name) + return ret + + +def security_rule_present(name, access, direction, priority, protocol, security_group, resource_group, + destination_address_prefix=None, destination_port_range=None, source_address_prefix=None, + source_port_range=None, description=None, destination_address_prefixes=None, + destination_port_ranges=None, source_address_prefixes=None, source_port_ranges=None, + connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a security rule exists. + + :param name: + Name of the security rule. + + :param access: + 'allow' or 'deny' + + :param direction: + 'inbound' or 'outbound' + + :param priority: + Integer between 100 and 4096 used for ordering rule application. + + :param protocol: + 'tcp', 'udp', or '*' + + :param security_group: + The name of the existing network security group to contain the security rule. + + :param resource_group: + The resource group assigned to the network security group. + + :param description: + Optional description of the security rule. + + :param destination_address_prefix: + The CIDR or destination IP range. Asterix '*' can also be used to match all destination IPs. + Default tags such as 'VirtualNetwork', 'AzureLoadBalancer' and 'Internet' can also be used. + If this is an ingress rule, specifies where network traffic originates from. + + :param destination_port_range: + The destination port or range. Integer or range between 0 and 65535. Asterix '*' + can also be used to match all ports. + + :param source_address_prefix: + The CIDR or source IP range. Asterix '*' can also be used to match all source IPs. + Default tags such as 'VirtualNetwork', 'AzureLoadBalancer' and 'Internet' can also be used. + If this is an ingress rule, specifies where network traffic originates from. + + :param source_port_range: + The source port or range. Integer or range between 0 and 65535. Asterix '*' + can also be used to match all ports. + + :param destination_address_prefixes: + A list of destination_address_prefix values. This parameter overrides destination_address_prefix + and will cause any value entered there to be ignored. + + :param destination_port_ranges: + A list of destination_port_range values. This parameter overrides destination_port_range + and will cause any value entered there to be ignored. + + :param source_address_prefixes: + A list of source_address_prefix values. This parameter overrides source_address_prefix + and will cause any value entered there to be ignored. + + :param source_port_ranges: + A list of source_port_range values. This parameter overrides source_port_range + and will cause any value entered there to be ignored. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure security rule exists: + azurearm_network.security_rule_present: + - name: nsg1_rule2 + - security_group: nsg1 + - resource_group: group1 + - priority: 101 + - protocol: tcp + - access: allow + - direction: inbound + - source_address_prefix: internet + - destination_address_prefix: virtualnetwork + - source_port_range: '*' + - destination_port_ranges: + - '80' + - '443' + - connection_auth: {{ profile }} + - require: + - azurearm_network: Ensure network security group exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + exclusive_params = [ + ('source_port_ranges', 'source_port_range'), + ('source_address_prefixes', 'source_address_prefix'), + ('destination_port_ranges', 'destination_port_range'), + ('destination_address_prefixes', 'destination_address_prefix'), + ] + + for params in exclusive_params: + # pylint: disable=eval-used + if not eval(params[0]) and not eval(params[1]): + ret['comment'] = 'Either the {0} or {1} parameter must be provided!'.format(params[0], params[1]) + return ret + # pylint: disable=eval-used + if eval(params[0]): + # pylint: disable=eval-used + if not isinstance(eval(params[0]), list): + ret['comment'] = 'The {0} parameter must be a list!'.format(params[0]) + return ret + # pylint: disable=exec-used + exec('{0} = None'.format(params[1])) + + rule = __salt__['azurearm_network.security_rule_get']( + name, + security_group, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in rule: + # access changes + if access.capitalize() != rule.get('access'): + ret['changes']['access'] = { + 'old': rule.get('access'), + 'new': access + } + + # description changes + if description != rule.get('description'): + ret['changes']['description'] = { + 'old': rule.get('description'), + 'new': description + } + + # direction changes + if direction.capitalize() != rule.get('direction'): + ret['changes']['direction'] = { + 'old': rule.get('direction'), + 'new': direction + } + + # priority changes + if int(priority) != rule.get('priority'): + ret['changes']['priority'] = { + 'old': rule.get('priority'), + 'new': priority + } + + # protocol changes + if protocol.lower() != rule.get('protocol', '').lower(): + ret['changes']['protocol'] = { + 'old': rule.get('protocol'), + 'new': protocol + } + + # destination_port_range changes + if destination_port_range != rule.get('destination_port_range'): + ret['changes']['destination_port_range'] = { + 'old': rule.get('destination_port_range'), + 'new': destination_port_range + } + + # source_port_range changes + if source_port_range != rule.get('source_port_range'): + ret['changes']['source_port_range'] = { + 'old': rule.get('source_port_range'), + 'new': source_port_range + } + + # destination_port_ranges changes + if sorted(destination_port_ranges or []) != sorted(rule.get('destination_port_ranges', [])): + ret['changes']['destination_port_ranges'] = { + 'old': rule.get('destination_port_ranges'), + 'new': destination_port_ranges + } + + # source_port_ranges changes + if sorted(source_port_ranges or []) != sorted(rule.get('source_port_ranges', [])): + ret['changes']['source_port_ranges'] = { + 'old': rule.get('source_port_ranges'), + 'new': source_port_ranges + } + + # destination_address_prefix changes + if (destination_address_prefix or '').lower() != rule.get('destination_address_prefix', '').lower(): + ret['changes']['destination_address_prefix'] = { + 'old': rule.get('destination_address_prefix'), + 'new': destination_address_prefix + } + + # source_address_prefix changes + if (source_address_prefix or '').lower() != rule.get('source_address_prefix', '').lower(): + ret['changes']['source_address_prefix'] = { + 'old': rule.get('source_address_prefix'), + 'new': source_address_prefix + } + + # destination_address_prefixes changes + if sorted(destination_address_prefixes or []) != sorted(rule.get('destination_address_prefixes', [])): + if len(destination_address_prefixes or []) != len(rule.get('destination_address_prefixes', [])): + ret['changes']['destination_address_prefixes'] = { + 'old': rule.get('destination_address_prefixes'), + 'new': destination_address_prefixes + } + else: + local_dst_addrs, remote_dst_addrs = (sorted(destination_address_prefixes), + sorted(rule.get('destination_address_prefixes'))) + for idx in six_range(0, len(local_dst_addrs)): + if local_dst_addrs[idx].lower() != remote_dst_addrs[idx].lower(): + ret['changes']['destination_address_prefixes'] = { + 'old': rule.get('destination_address_prefixes'), + 'new': destination_address_prefixes + } + break + + # source_address_prefixes changes + if sorted(source_address_prefixes or []) != sorted(rule.get('source_address_prefixes', [])): + if len(source_address_prefixes or []) != len(rule.get('source_address_prefixes', [])): + ret['changes']['source_address_prefixes'] = { + 'old': rule.get('source_address_prefixes'), + 'new': source_address_prefixes + } + else: + local_src_addrs, remote_src_addrs = (sorted(source_address_prefixes), + sorted(rule.get('source_address_prefixes'))) + for idx in six_range(0, len(local_src_addrs)): + if local_src_addrs[idx].lower() != remote_src_addrs[idx].lower(): + ret['changes']['source_address_prefixes'] = { + 'old': rule.get('source_address_prefixes'), + 'new': source_address_prefixes + } + break + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Security rule {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Security rule {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'access': access, + 'description': description, + 'direction': direction, + 'priority': priority, + 'protocol': protocol, + 'destination_address_prefix': destination_address_prefix, + 'destination_address_prefixes': destination_address_prefixes, + 'destination_port_range': destination_port_range, + 'destination_port_ranges': destination_port_ranges, + 'source_address_prefix': source_address_prefix, + 'source_address_prefixes': source_address_prefixes, + 'source_port_range': source_port_range, + 'source_port_ranges': source_port_ranges, + } + } + + if __opts__['test']: + ret['comment'] = 'Security rule {0} would be created.'.format(name) + ret['result'] = None + return ret + + rule_kwargs = kwargs.copy() + rule_kwargs.update(connection_auth) + + rule = __salt__['azurearm_network.security_rule_create_or_update']( + name=name, + access=access, + description=description, + direction=direction, + priority=priority, + protocol=protocol, + security_group=security_group, + resource_group=resource_group, + destination_address_prefix=destination_address_prefix, + destination_address_prefixes=destination_address_prefixes, + destination_port_range=destination_port_range, + destination_port_ranges=destination_port_ranges, + source_address_prefix=source_address_prefix, + source_address_prefixes=source_address_prefixes, + source_port_range=source_port_range, + source_port_ranges=source_port_ranges, + **rule_kwargs + ) + + if 'error' not in rule: + ret['result'] = True + ret['comment'] = 'Security rule {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create security rule {0}! ({1})'.format(name, rule.get('error')) + return ret + + +def security_rule_absent(name, security_group, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a security rule does not exist in the network security group. + + :param name: + Name of the security rule. + + :param security_group: + The network security group containing the security rule. + + :param resource_group: + The resource group assigned to the network security group. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + rule = __salt__['azurearm_network.security_rule_get']( + name, + security_group, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in rule: + ret['result'] = True + ret['comment'] = 'Security rule {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Security rule {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': rule, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_network.security_rule_delete'](name, security_group, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Security rule {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': rule, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete security rule {0}!'.format(name) + return ret + + +def load_balancer_present(name, resource_group, sku=None, frontend_ip_configurations=None, backend_address_pools=None, + load_balancing_rules=None, probes=None, inbound_nat_rules=None, inbound_nat_pools=None, + outbound_nat_rules=None, tags=None, connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a load balancer exists. + + :param name: + Name of the load balancer. + + :param resource_group: + The resource group assigned to the load balancer. + + :param sku: + The load balancer SKU, which can be 'Basic' or 'Standard'. + + :param tags: + A dictionary of strings can be passed as tag metadata to the load balancer object. + + :param frontend_ip_configurations: + An optional list of dictionaries representing valid FrontendIPConfiguration objects. A frontend IP + configuration can be either private (using private IP address and subnet parameters) or public (using a + reference to a public IP address object). Valid parameters are: + + - ``name``: The name of the resource that is unique within a resource group. + - ``private_ip_address``: The private IP address of the IP configuration. Required if + 'private_ip_allocation_method' is 'Static'. + - ``private_ip_allocation_method``: The Private IP allocation method. Possible values are: 'Static' and + 'Dynamic'. + - ``subnet``: Name of an existing subnet inside of which the frontend IP will reside. + - ``public_ip_address``: Name of an existing public IP address which will be assigned to the frontend IP object. + + :param backend_address_pools: + An optional list of dictionaries representing valid BackendAddressPool objects. Only the 'name' parameter is + valid for a BackendAddressPool dictionary. All other parameters are read-only references from other objects + linking to the backend address pool. Inbound traffic is randomly load balanced across IPs in the backend IPs. + + :param probes: + An optional list of dictionaries representing valid Probe objects. Valid parameters are: + + - ``name``: The name of the resource that is unique within a resource group. + - ``protocol``: The protocol of the endpoint. Possible values are 'Http' or 'Tcp'. If 'Tcp' is specified, a + received ACK is required for the probe to be successful. If 'Http' is specified, a 200 OK response from the + specified URI is required for the probe to be successful. + - ``port``: The port for communicating the probe. Possible values range from 1 to 65535, inclusive. + - ``interval_in_seconds``: The interval, in seconds, for how frequently to probe the endpoint for health status. + Typically, the interval is slightly less than half the allocated timeout period (in seconds) which allows two + full probes before taking the instance out of rotation. The default value is 15, the minimum value is 5. + - ``number_of_probes``: The number of probes where if no response, will result in stopping further traffic from + being delivered to the endpoint. This values allows endpoints to be taken out of rotation faster or slower + than the typical times used in Azure. + - ``request_path``: The URI used for requesting health status from the VM. Path is required if a protocol is + set to 'Http'. Otherwise, it is not allowed. There is no default value. + + :param load_balancing_rules: + An optional list of dictionaries representing valid LoadBalancingRule objects. Valid parameters are: + + - ``name``: The name of the resource that is unique within a resource group. + - ``load_distribution``: The load distribution policy for this rule. Possible values are 'Default', 'SourceIP', + and 'SourceIPProtocol'. + - ``frontend_port``: The port for the external endpoint. Port numbers for each rule must be unique within the + Load Balancer. Acceptable values are between 0 and 65534. Note that value 0 enables 'Any Port'. + - ``backend_port``: The port used for internal connections on the endpoint. Acceptable values are between 0 and + 65535. Note that value 0 enables 'Any Port'. + - ``idle_timeout_in_minutes``: The timeout for the TCP idle connection. The value can be set between 4 and 30 + minutes. The default value is 4 minutes. This element is only used when the protocol is set to TCP. + - ``enable_floating_ip``: Configures a virtual machine's endpoint for the floating IP capability required + to configure a SQL AlwaysOn Availability Group. This setting is required when using the SQL AlwaysOn + Availability Groups in SQL server. This setting can't be changed after you create the endpoint. + - ``disable_outbound_snat``: Configures SNAT for the VMs in the backend pool to use the public IP address + specified in the frontend of the load balancing rule. + - ``frontend_ip_configuration``: Name of the frontend IP configuration object used by the load balancing rule + object. + - ``backend_address_pool``: Name of the backend address pool object used by the load balancing rule object. + Inbound traffic is randomly load balanced across IPs in the backend IPs. + - ``probe``: Name of the probe object used by the load balancing rule object. + + :param inbound_nat_rules: + An optional list of dictionaries representing valid InboundNatRule objects. Defining inbound NAT rules on your + load balancer is mutually exclusive with defining an inbound NAT pool. Inbound NAT pools are referenced from + virtual machine scale sets. NICs that are associated with individual virtual machines cannot reference an + Inbound NAT pool. They have to reference individual inbound NAT rules. Valid parameters are: + + - ``name``: The name of the resource that is unique within a resource group. + - ``frontend_ip_configuration``: Name of the frontend IP configuration object used by the inbound NAT rule + object. + - ``protocol``: Possible values include 'Udp', 'Tcp', or 'All'. + - ``frontend_port``: The port for the external endpoint. Port numbers for each rule must be unique within the + Load Balancer. Acceptable values range from 1 to 65534. + - ``backend_port``: The port used for the internal endpoint. Acceptable values range from 1 to 65535. + - ``idle_timeout_in_minutes``: The timeout for the TCP idle connection. The value can be set between 4 and 30 + minutes. The default value is 4 minutes. This element is only used when the protocol is set to TCP. + - ``enable_floating_ip``: Configures a virtual machine's endpoint for the floating IP capability required + to configure a SQL AlwaysOn Availability Group. This setting is required when using the SQL AlwaysOn + Availability Groups in SQL server. This setting can't be changed after you create the endpoint. + + :param inbound_nat_pools: + An optional list of dictionaries representing valid InboundNatPool objects. They define an external port range + for inbound NAT to a single backend port on NICs associated with a load balancer. Inbound NAT rules are created + automatically for each NIC associated with the Load Balancer using an external port from this range. Defining an + Inbound NAT pool on your Load Balancer is mutually exclusive with defining inbound NAT rules. Inbound NAT pools + are referenced from virtual machine scale sets. NICs that are associated with individual virtual machines cannot + reference an inbound NAT pool. They have to reference individual inbound NAT rules. Valid parameters are: + + - ``name``: The name of the resource that is unique within a resource group. + - ``frontend_ip_configuration``: Name of the frontend IP configuration object used by the inbound NAT pool + object. + - ``protocol``: Possible values include 'Udp', 'Tcp', or 'All'. + - ``frontend_port_range_start``: The first port number in the range of external ports that will be used to + provide Inbound NAT to NICs associated with a load balancer. Acceptable values range between 1 and 65534. + - ``frontend_port_range_end``: The last port number in the range of external ports that will be used to + provide Inbound NAT to NICs associated with a load balancer. Acceptable values range between 1 and 65535. + - ``backend_port``: The port used for internal connections to the endpoint. Acceptable values are between 1 and + 65535. + + :param outbound_nat_rules: + An optional list of dictionaries representing valid OutboundNatRule objects. Valid parameters are: + + - ``name``: The name of the resource that is unique within a resource group. + - ``frontend_ip_configuration``: Name of the frontend IP configuration object used by the outbound NAT rule + object. + - ``backend_address_pool``: Name of the backend address pool object used by the outbound NAT rule object. + Outbound traffic is randomly load balanced across IPs in the backend IPs. + - ``allocated_outbound_ports``: The number of outbound ports to be used for NAT. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure load balancer exists: + azurearm_network.load_balancer_present: + - name: lb1 + - resource_group: group1 + - location: eastus + - frontend_ip_configurations: + - name: lb1_feip1 + public_ip_address: pub_ip1 + - backend_address_pools: + - name: lb1_bepool1 + - probes: + - name: lb1_webprobe1 + protocol: tcp + port: 80 + interval_in_seconds: 5 + number_of_probes: 2 + - load_balancing_rules: + - name: lb1_webprobe1 + protocol: tcp + frontend_port: 80 + backend_port: 80 + idle_timeout_in_minutes: 4 + frontend_ip_configuration: lb1_feip1 + backend_address_pool: lb1_bepool1 + probe: lb1_webprobe1 + - tags: + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + - require: + - azurearm_resource: Ensure resource group exists + - azurearm_network: Ensure public IP exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + if sku: + sku = {'name': sku.capitalize()} + + load_bal = __salt__['azurearm_network.load_balancer_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in load_bal: + # tag changes + tag_changes = __utils__['dictdiffer.deep_diff'](load_bal.get('tags', {}), tags or {}) + if tag_changes: + ret['changes']['tags'] = tag_changes + + # sku changes + if sku: + sku_changes = __utils__['dictdiffer.deep_diff'](load_bal.get('sku', {}), sku) + if sku_changes: + ret['changes']['sku'] = sku_changes + + # frontend_ip_configurations changes + if frontend_ip_configurations: + comp_ret = __utils__['azurearm.compare_list_of_dicts']( + load_bal.get('frontend_ip_configurations', []), + frontend_ip_configurations, + ['public_ip_address', 'subnet'] + ) + + if comp_ret.get('comment'): + ret['comment'] = '"frontend_ip_configurations" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['frontend_ip_configurations'] = comp_ret['changes'] + + # backend_address_pools changes + if backend_address_pools: + comp_ret = __utils__['azurearm.compare_list_of_dicts']( + load_bal.get('backend_address_pools', []), + backend_address_pools + ) + + if comp_ret.get('comment'): + ret['comment'] = '"backend_address_pools" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['backend_address_pools'] = comp_ret['changes'] + + # probes changes + if probes: + comp_ret = __utils__['azurearm.compare_list_of_dicts'](load_bal.get('probes', []), probes) + + if comp_ret.get('comment'): + ret['comment'] = '"probes" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['probes'] = comp_ret['changes'] + + # load_balancing_rules changes + if load_balancing_rules: + comp_ret = __utils__['azurearm.compare_list_of_dicts']( + load_bal.get('load_balancing_rules', []), + load_balancing_rules, + ['frontend_ip_configuration', 'backend_address_pool', 'probe'] + ) + + if comp_ret.get('comment'): + ret['comment'] = '"load_balancing_rules" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['load_balancing_rules'] = comp_ret['changes'] + + # inbound_nat_rules changes + if inbound_nat_rules: + comp_ret = __utils__['azurearm.compare_list_of_dicts']( + load_bal.get('inbound_nat_rules', []), + inbound_nat_rules, + ['frontend_ip_configuration'] + ) + + if comp_ret.get('comment'): + ret['comment'] = '"inbound_nat_rules" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['inbound_nat_rules'] = comp_ret['changes'] + + # inbound_nat_pools changes + if inbound_nat_pools: + comp_ret = __utils__['azurearm.compare_list_of_dicts']( + load_bal.get('inbound_nat_pools', []), + inbound_nat_pools, + ['frontend_ip_configuration'] + ) + + if comp_ret.get('comment'): + ret['comment'] = '"inbound_nat_pools" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['inbound_nat_pools'] = comp_ret['changes'] + + # outbound_nat_rules changes + if outbound_nat_rules: + comp_ret = __utils__['azurearm.compare_list_of_dicts']( + load_bal.get('outbound_nat_rules', []), + outbound_nat_rules, + ['frontend_ip_configuration'] + ) + + if comp_ret.get('comment'): + ret['comment'] = '"outbound_nat_rules" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['outbound_nat_rules'] = comp_ret['changes'] + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Load balancer {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Load balancer {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'sku': sku, + 'tags': tags, + 'frontend_ip_configurations': frontend_ip_configurations, + 'backend_address_pools': backend_address_pools, + 'load_balancing_rules': load_balancing_rules, + 'probes': probes, + 'inbound_nat_rules': inbound_nat_rules, + 'inbound_nat_pools': inbound_nat_pools, + 'outbound_nat_rules': outbound_nat_rules, + } + } + + if __opts__['test']: + ret['comment'] = 'Load balancer {0} would be created.'.format(name) + ret['result'] = None + return ret + + lb_kwargs = kwargs.copy() + lb_kwargs.update(connection_auth) + + load_bal = __salt__['azurearm_network.load_balancer_create_or_update']( + name=name, + resource_group=resource_group, + sku=sku, + tags=tags, + frontend_ip_configurations=frontend_ip_configurations, + backend_address_pools=backend_address_pools, + load_balancing_rules=load_balancing_rules, + probes=probes, + inbound_nat_rules=inbound_nat_rules, + inbound_nat_pools=inbound_nat_pools, + outbound_nat_rules=outbound_nat_rules, + **lb_kwargs + ) + + if 'error' not in load_bal: + ret['result'] = True + ret['comment'] = 'Load balancer {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create load balancer {0}! ({1})'.format(name, load_bal.get('error')) + return ret + + +def load_balancer_absent(name, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a load balancer does not exist in the resource group. + + :param name: + Name of the load balancer. + + :param resource_group: + The resource group assigned to the load balancer. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + load_bal = __salt__['azurearm_network.load_balancer_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in load_bal: + ret['result'] = True + ret['comment'] = 'Load balancer {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Load balancer {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': load_bal, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_network.load_balancer_delete'](name, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Load balancer {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': load_bal, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete load balancer {0}!'.format(name) + return ret + + +def public_ip_address_present(name, resource_group, tags=None, sku=None, public_ip_allocation_method=None, + public_ip_address_version=None, dns_settings=None, idle_timeout_in_minutes=None, + connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a public IP address exists. + + :param name: + Name of the public IP address. + + :param resource_group: + The resource group assigned to the public IP address. + + :param dns_settings: + An optional dictionary representing a valid PublicIPAddressDnsSettings object. Parameters include + 'domain_name_label' and 'reverse_fqdn', which accept strings. The 'domain_name_label' parameter is concatenated + with the regionalized DNS zone make up the fully qualified domain name associated with the public IP address. + If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS + system. The 'reverse_fqdn' parameter is a user-visible, fully qualified domain name that resolves to this public + IP address. If the reverse FQDN is specified, then a PTR DNS record is created pointing from the IP address in + the in-addr.arpa domain to the reverse FQDN. + + :param sku: + The public IP address SKU, which can be 'Basic' or 'Standard'. + + :param public_ip_allocation_method: + The public IP allocation method. Possible values are: 'Static' and 'Dynamic'. + + :param public_ip_address_version: + The public IP address version. Possible values are: 'IPv4' and 'IPv6'. + + :param idle_timeout_in_minutes: + An integer representing the idle timeout of the public IP address. + + :param tags: + A dictionary of strings can be passed as tag metadata to the public IP address object. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure public IP exists: + azurearm_network.public_ip_address_present: + - name: pub_ip1 + - resource_group: group1 + - dns_settings: + domain_name_label: decisionlab-ext-test-label + - sku: basic + - public_ip_allocation_method: static + - public_ip_address_version: ipv4 + - idle_timeout_in_minutes: 4 + - tags: + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + - require: + - azurearm_resource: Ensure resource group exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + if sku: + sku = {'name': sku.capitalize()} + + pub_ip = __salt__['azurearm_network.public_ip_address_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in pub_ip: + # tag changes + tag_changes = __utils__['dictdiffer.deep_diff'](pub_ip.get('tags', {}), tags or {}) + if tag_changes: + ret['changes']['tags'] = tag_changes + + # dns_settings changes + if dns_settings: + if not isinstance(dns_settings, dict): + ret['comment'] = 'DNS settings must be provided as a dictionary!' + return ret + + for key in dns_settings: + if dns_settings[key] != pub_ip.get('dns_settings', {}).get(key): + ret['changes']['dns_settings'] = { + 'old': pub_ip.get('dns_settings'), + 'new': dns_settings + } + break + + # sku changes + if sku: + sku_changes = __utils__['dictdiffer.deep_diff'](pub_ip.get('sku', {}), sku) + if sku_changes: + ret['changes']['sku'] = sku_changes + + # public_ip_allocation_method changes + if public_ip_allocation_method: + if public_ip_allocation_method.capitalize() != pub_ip.get('public_ip_allocation_method'): + ret['changes']['public_ip_allocation_method'] = { + 'old': pub_ip.get('public_ip_allocation_method'), + 'new': public_ip_allocation_method + } + + # public_ip_address_version changes + if public_ip_address_version: + if public_ip_address_version.lower() != pub_ip.get('public_ip_address_version', '').lower(): + ret['changes']['public_ip_address_version'] = { + 'old': pub_ip.get('public_ip_address_version'), + 'new': public_ip_address_version + } + + # idle_timeout_in_minutes changes + if idle_timeout_in_minutes and (int(idle_timeout_in_minutes) != pub_ip.get('idle_timeout_in_minutes')): + ret['changes']['idle_timeout_in_minutes'] = { + 'old': pub_ip.get('idle_timeout_in_minutes'), + 'new': idle_timeout_in_minutes + } + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Public IP address {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Public IP address {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'tags': tags, + 'dns_settings': dns_settings, + 'sku': sku, + 'public_ip_allocation_method': public_ip_allocation_method, + 'public_ip_address_version': public_ip_address_version, + 'idle_timeout_in_minutes': idle_timeout_in_minutes, + } + } + + if __opts__['test']: + ret['comment'] = 'Public IP address {0} would be created.'.format(name) + ret['result'] = None + return ret + + pub_ip_kwargs = kwargs.copy() + pub_ip_kwargs.update(connection_auth) + + pub_ip = __salt__['azurearm_network.public_ip_address_create_or_update']( + name=name, + resource_group=resource_group, + sku=sku, + tags=tags, + dns_settings=dns_settings, + public_ip_allocation_method=public_ip_allocation_method, + public_ip_address_version=public_ip_address_version, + idle_timeout_in_minutes=idle_timeout_in_minutes, + **pub_ip_kwargs + ) + + if 'error' not in pub_ip: + ret['result'] = True + ret['comment'] = 'Public IP address {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create public IP address {0}! ({1})'.format(name, pub_ip.get('error')) + return ret + + +def public_ip_address_absent(name, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a public IP address does not exist in the resource group. + + :param name: + Name of the public IP address. + + :param resource_group: + The resource group assigned to the public IP address. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + pub_ip = __salt__['azurearm_network.public_ip_address_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in pub_ip: + ret['result'] = True + ret['comment'] = 'Public IP address {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Public IP address {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': pub_ip, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_network.public_ip_address_delete'](name, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Public IP address {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': pub_ip, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete public IP address {0}!'.format(name) + return ret + + +def network_interface_present(name, ip_configurations, subnet, virtual_network, resource_group, tags=None, + virtual_machine=None, network_security_group=None, dns_settings=None, mac_address=None, + primary=None, enable_accelerated_networking=None, enable_ip_forwarding=None, + connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a network interface exists. + + :param name: + Name of the network interface. + + :param ip_configurations: + A list of dictionaries representing valid NetworkInterfaceIPConfiguration objects. The 'name' key is required at + minimum. At least one IP Configuration must be present. + + :param subnet: + Name of the existing subnet assigned to the network interface. + + :param virtual_network: + Name of the existing virtual network containing the subnet. + + :param resource_group: + The resource group assigned to the virtual network. + + :param tags: + A dictionary of strings can be passed as tag metadata to the network interface object. + + :param network_security_group: + The name of the existing network security group to assign to the network interface. + + :param virtual_machine: + The name of the existing virtual machine to assign to the network interface. + + :param dns_settings: + An optional dictionary representing a valid NetworkInterfaceDnsSettings object. Valid parameters are: + + - ``dns_servers``: List of DNS server IP addresses. Use 'AzureProvidedDNS' to switch to Azure provided DNS + resolution. 'AzureProvidedDNS' value cannot be combined with other IPs, it must be the only value in + dns_servers collection. + - ``internal_dns_name_label``: Relative DNS name for this NIC used for internal communications between VMs in + the same virtual network. + - ``internal_fqdn``: Fully qualified DNS name supporting internal communications between VMs in the same virtual + network. + - ``internal_domain_name_suffix``: Even if internal_dns_name_label is not specified, a DNS entry is created for + the primary NIC of the VM. This DNS name can be constructed by concatenating the VM name with the value of + internal_domain_name_suffix. + + :param mac_address: + Optional string containing the MAC address of the network interface. + + :param primary: + Optional boolean allowing the interface to be set as the primary network interface on a virtual machine + with multiple interfaces attached. + + :param enable_accelerated_networking: + Optional boolean indicating whether accelerated networking should be enabled for the interface. + + :param enable_ip_forwarding: + Optional boolean indicating whether IP forwarding should be enabled for the interface. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure network interface exists: + azurearm_network.network_interface_present: + - name: iface1 + - subnet: vnet1_sn1 + - virtual_network: vnet1 + - resource_group: group1 + - ip_configurations: + - name: iface1_ipc1 + public_ip_address: pub_ip2 + - dns_settings: + internal_dns_name_label: decisionlab-int-test-label + - primary: True + - enable_accelerated_networking: True + - enable_ip_forwarding: False + - network_security_group: nsg1 + - connection_auth: {{ profile }} + - require: + - azurearm_network: Ensure subnet exists + - azurearm_network: Ensure network security group exists + - azurearm_network: Ensure another public IP exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + iface = __salt__['azurearm_network.network_interface_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in iface: + # tag changes + tag_changes = __utils__['dictdiffer.deep_diff'](iface.get('tags', {}), tags or {}) + if tag_changes: + ret['changes']['tags'] = tag_changes + + # mac_address changes + if mac_address and (mac_address != iface.get('mac_address')): + ret['changes']['mac_address'] = { + 'old': iface.get('mac_address'), + 'new': mac_address + } + + # primary changes + if primary is not None: + if primary != iface.get('primary', True): + ret['changes']['primary'] = { + 'old': iface.get('primary'), + 'new': primary + } + + # enable_accelerated_networking changes + if enable_accelerated_networking is not None: + if enable_accelerated_networking != iface.get('enable_accelerated_networking'): + ret['changes']['enable_accelerated_networking'] = { + 'old': iface.get('enable_accelerated_networking'), + 'new': enable_accelerated_networking + } + + # enable_ip_forwarding changes + if enable_ip_forwarding is not None: + if enable_ip_forwarding != iface.get('enable_ip_forwarding'): + ret['changes']['enable_ip_forwarding'] = { + 'old': iface.get('enable_ip_forwarding'), + 'new': enable_ip_forwarding + } + + # network_security_group changes + nsg_name = None + if iface.get('network_security_group'): + nsg_name = iface['network_security_group']['id'].split('/')[-1] + + if network_security_group and (network_security_group != nsg_name): + ret['changes']['network_security_group'] = { + 'old': nsg_name, + 'new': network_security_group + } + + # virtual_machine changes + vm_name = None + if iface.get('virtual_machine'): + vm_name = iface['virtual_machine']['id'].split('/')[-1] + + if virtual_machine and (virtual_machine != vm_name): + ret['changes']['virtual_machine'] = { + 'old': vm_name, + 'new': virtual_machine + } + + # dns_settings changes + if dns_settings: + if not isinstance(dns_settings, dict): + ret['comment'] = 'DNS settings must be provided as a dictionary!' + return ret + + for key in dns_settings: + if dns_settings[key].lower() != iface.get('dns_settings', {}).get(key, '').lower(): + ret['changes']['dns_settings'] = { + 'old': iface.get('dns_settings'), + 'new': dns_settings + } + break + + # ip_configurations changes + comp_ret = __utils__['azurearm.compare_list_of_dicts']( + iface.get('ip_configurations', []), + ip_configurations, + ['public_ip_address', 'subnet'] + ) + + if comp_ret.get('comment'): + ret['comment'] = '"ip_configurations" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['ip_configurations'] = comp_ret['changes'] + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Network interface {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Network interface {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'ip_configurations': ip_configurations, + 'dns_settings': dns_settings, + 'network_security_group': network_security_group, + 'virtual_machine': virtual_machine, + 'enable_accelerated_networking': enable_accelerated_networking, + 'enable_ip_forwarding': enable_ip_forwarding, + 'mac_address': mac_address, + 'primary': primary, + 'tags': tags, + } + } + + if __opts__['test']: + ret['comment'] = 'Network interface {0} would be created.'.format(name) + ret['result'] = None + return ret + + iface_kwargs = kwargs.copy() + iface_kwargs.update(connection_auth) + + iface = __salt__['azurearm_network.network_interface_create_or_update']( + name=name, + subnet=subnet, + virtual_network=virtual_network, + resource_group=resource_group, + ip_configurations=ip_configurations, + dns_settings=dns_settings, + enable_accelerated_networking=enable_accelerated_networking, + enable_ip_forwarding=enable_ip_forwarding, + mac_address=mac_address, + primary=primary, + network_security_group=network_security_group, + virtual_machine=virtual_machine, + tags=tags, + **iface_kwargs + ) + + if 'error' not in iface: + ret['result'] = True + ret['comment'] = 'Network interface {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create network interface {0}! ({1})'.format(name, iface.get('error')) + return ret + + +def network_interface_absent(name, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a network interface does not exist in the resource group. + + :param name: + Name of the network interface. + + :param resource_group: + The resource group assigned to the network interface. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + iface = __salt__['azurearm_network.network_interface_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in iface: + ret['result'] = True + ret['comment'] = 'Network interface {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Network interface {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': iface, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_network.network_interface_delete'](name, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Network interface {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': iface, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete network interface {0}!)'.format(name) + return ret + + +def route_table_present(name, resource_group, tags=None, routes=None, disable_bgp_route_propagation=None, + connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a route table exists. + + :param name: + Name of the route table. + + :param resource_group: + The resource group assigned to the route table. + + :param routes: + An optional list of dictionaries representing valid Route objects contained within a route table. See the + documentation for the route_present state or route_create_or_update execution module for more information on + required and optional parameters for routes. The routes are only managed if this parameter is present. When this + parameter is absent, implemented routes will not be removed, and will merely become unmanaged. + + :param disable_bgp_route_propagation: + An optional boolean parameter setting whether to disable the routes learned by BGP on the route table. + + :param tags: + A dictionary of strings can be passed as tag metadata to the route table object. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure route table exists: + azurearm_network.route_table_present: + - name: rt1 + - resource_group: group1 + - routes: + - name: rt1_route1 + address_prefix: '0.0.0.0/0' + next_hop_type: internet + - name: rt1_route2 + address_prefix: '192.168.0.0/16' + next_hop_type: vnetlocal + - tags: + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + - require: + - azurearm_resource: Ensure resource group exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + rt_tbl = __salt__['azurearm_network.route_table_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in rt_tbl: + # tag changes + tag_changes = __utils__['dictdiffer.deep_diff'](rt_tbl.get('tags', {}), tags or {}) + if tag_changes: + ret['changes']['tags'] = tag_changes + + # disable_bgp_route_propagation changes + # pylint: disable=line-too-long + if disable_bgp_route_propagation and (disable_bgp_route_propagation != rt_tbl.get('disable_bgp_route_propagation')): + ret['changes']['disable_bgp_route_propagation'] = { + 'old': rt_tbl.get('disable_bgp_route_propagation'), + 'new': disable_bgp_route_propagation + } + + # routes changes + if routes: + comp_ret = __utils__['azurearm.compare_list_of_dicts'](rt_tbl.get('routes', []), routes) + + if comp_ret.get('comment'): + ret['comment'] = '"routes" {0}'.format(comp_ret['comment']) + return ret + + if comp_ret.get('changes'): + ret['changes']['routes'] = comp_ret['changes'] + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Route table {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Route table {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'tags': tags, + 'routes': routes, + 'disable_bgp_route_propagation': disable_bgp_route_propagation, + } + } + + if __opts__['test']: + ret['comment'] = 'Route table {0} would be created.'.format(name) + ret['result'] = None + return ret + + rt_tbl_kwargs = kwargs.copy() + rt_tbl_kwargs.update(connection_auth) + + rt_tbl = __salt__['azurearm_network.route_table_create_or_update']( + name=name, + resource_group=resource_group, + disable_bgp_route_propagation=disable_bgp_route_propagation, + routes=routes, + tags=tags, + **rt_tbl_kwargs + ) + + if 'error' not in rt_tbl: + ret['result'] = True + ret['comment'] = 'Route table {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create route table {0}! ({1})'.format(name, rt_tbl.get('error')) + return ret + + +def route_table_absent(name, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a route table does not exist in the resource group. + + :param name: + Name of the route table. + + :param resource_group: + The resource group assigned to the route table. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + rt_tbl = __salt__['azurearm_network.route_table_get']( + name, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in rt_tbl: + ret['result'] = True + ret['comment'] = 'Route table {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Route table {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': rt_tbl, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_network.route_table_delete'](name, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Route table {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': rt_tbl, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete route table {0}!'.format(name) + return ret + + +def route_present(name, address_prefix, next_hop_type, route_table, resource_group, next_hop_ip_address=None, + connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a route exists within a route table. + + :param name: + Name of the route. + + :param address_prefix: + The destination CIDR to which the route applies. + + :param next_hop_type: + The type of Azure hop the packet should be sent to. Possible values are: 'VirtualNetworkGateway', 'VnetLocal', + 'Internet', 'VirtualAppliance', and 'None'. + + :param next_hop_ip_address: + The IP address packets should be forwarded to. Next hop values are only allowed in routes where the next hop + type is 'VirtualAppliance'. + + :param route_table: + The name of the existing route table which will contain the route. + + :param resource_group: + The resource group assigned to the route table. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure route exists: + azurearm_network.route_present: + - name: rt1_route2 + - route_table: rt1 + - resource_group: group1 + - address_prefix: '192.168.0.0/16' + - next_hop_type: vnetlocal + - connection_auth: {{ profile }} + - require: + - azurearm_network: Ensure route table exists + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + route = __salt__['azurearm_network.route_get']( + name, + route_table, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in route: + if address_prefix != route.get('address_prefix'): + ret['changes']['address_prefix'] = { + 'old': route.get('address_prefix'), + 'new': address_prefix + } + + if next_hop_type.lower() != route.get('next_hop_type', '').lower(): + ret['changes']['next_hop_type'] = { + 'old': route.get('next_hop_type'), + 'new': next_hop_type + } + + if next_hop_type.lower() == 'virtualappliance' and next_hop_ip_address != route.get('next_hop_ip_address'): + ret['changes']['next_hop_ip_address'] = { + 'old': route.get('next_hop_ip_address'), + 'new': next_hop_ip_address + } + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Route {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Route {0} would be updated.'.format(name) + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'address_prefix': address_prefix, + 'next_hop_type': next_hop_type, + 'next_hop_ip_address': next_hop_ip_address + } + } + + if __opts__['test']: + ret['comment'] = 'Route {0} would be created.'.format(name) + ret['result'] = None + return ret + + route_kwargs = kwargs.copy() + route_kwargs.update(connection_auth) + + route = __salt__['azurearm_network.route_create_or_update']( + name=name, + route_table=route_table, + resource_group=resource_group, + address_prefix=address_prefix, + next_hop_type=next_hop_type, + next_hop_ip_address=next_hop_ip_address, + **route_kwargs + ) + + if 'error' not in route: + ret['result'] = True + ret['comment'] = 'Route {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create route {0}! ({1})'.format(name, route.get('error')) + return ret + + +def route_absent(name, route_table, resource_group, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a route table does not exist in the resource group. + + :param name: + Name of the route table. + + :param route_table: + The name of the existing route table containing the route. + + :param resource_group: + The resource group assigned to the route table. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + route = __salt__['azurearm_network.route_get']( + name, + route_table, + resource_group, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in route: + ret['result'] = True + ret['comment'] = 'Route {0} was not found.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Route {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': route, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_network.route_delete'](name, route_table, resource_group, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Route {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': route, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete route {0}!'.format(name) + return ret diff --git a/salt/states/azurearm_resource.py b/salt/states/azurearm_resource.py new file mode 100644 index 0000000000..d0c555c90d --- /dev/null +++ b/salt/states/azurearm_resource.py @@ -0,0 +1,816 @@ +# -*- coding: utf-8 -*- +''' +Azure (ARM) Resource State Module + +.. versionadded:: Fluorine + +:maintainer: +:maturity: new +:depends: + * `azure `_ >= 2.0.0 + * `azure-common `_ >= 1.1.8 + * `azure-mgmt `_ >= 1.0.0 + * `azure-mgmt-compute `_ >= 1.0.0 + * `azure-mgmt-network `_ >= 1.7.1 + * `azure-mgmt-resource `_ >= 1.1.0 + * `azure-mgmt-storage `_ >= 1.0.0 + * `azure-mgmt-web `_ >= 0.32.0 + * `azure-storage `_ >= 0.34.3 + * `msrestazure `_ >= 0.4.21 +:platform: linux + +:configuration: This module requires Azure Resource Manager credentials to be passed as a dictionary of +keyword arguments to the ``connection_auth`` parameter in order to work properly. Since the authentication +parameters are sensitive, it's recommended to pass them to the states via pillar. + + Required provider parameters: + + if using username and password: + * ``subscription_id`` + * ``username`` + * ``password`` + + if using a service principal: + * ``subscription_id`` + * ``tenant`` + * ``client_id`` + * ``secret`` + + Optional provider parameters: + + **cloud_environment**: Used to point the cloud driver to different API endpoints, such as Azure GovCloud. Possible values: + * ``AZURE_PUBLIC_CLOUD`` (default) + * ``AZURE_CHINA_CLOUD`` + * ``AZURE_US_GOV_CLOUD`` + * ``AZURE_GERMAN_CLOUD`` + + Example Pillar for Azure Resource Manager authentication: + + .. code-block:: yaml + + azurearm: + user_pass_auth: + subscription_id: 3287abc8-f98a-c678-3bde-326766fd3617 + username: fletch + password: 123pass + mysubscription: + subscription_id: 3287abc8-f98a-c678-3bde-326766fd3617 + tenant: ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF + client_id: ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF + secret: XXXXXXXXXXXXXXXXXXXXXXXX + cloud_environment: AZURE_PUBLIC_CLOUD + + Example states using Azure Resource Manager authentication: + + .. code-block:: yaml + + {% set profile = salt['pillar.get']('azurearm:mysubscription') %} + Ensure resource group exists: + azurearm_resource.resource_group_present: + - name: my_rg + - location: westus + - tags: + how_awesome: very + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + + Ensure resource group is absent: + azurearm_resource.resource_group_absent: + - name: other_rg + - connection_auth: {{ profile }} + +''' + +# Python libs +from __future__ import absolute_import +import json +import logging + +# Salt libs +import salt.utils + +__virtualname__ = 'azurearm_resource' + +log = logging.getLogger(__name__) + + +def __virtual__(): + ''' + Only make this state available if the azurearm_resource module is available. + ''' + return __virtualname__ if 'azurearm_resource.resource_group_check_existence' in __salt__ else False + + +def resource_group_present(name, location, managed_by=None, tags=None, connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a resource group exists. + + :param name: + Name of the resource group. + + :param location: + The Azure location in which to create the resource group. This value cannot be updated once + the resource group is created. + + :param managed_by: + The ID of the resource that manages this resource group. This value cannot be updated once + the resource group is created. + + :param tags: + A dictionary of strings can be passed as tag metadata to the resource group object. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure resource group exists: + azurearm_resource.resource_group_present: + - name: group1 + - location: eastus + - tags: + contact_name: Elmer Fudd Gantry + - connection_auth: {{ profile }} + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + group = {} + + present = __salt__['azurearm_resource.resource_group_check_existence'](name, **connection_auth) + + if present: + group = __salt__['azurearm_resource.resource_group_get'](name, **connection_auth) + ret['changes'] = __utils__['dictdiffer.deep_diff'](group.get('tags', {}), tags or {}) + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Resource group {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['comment'] = 'Resource group {0} tags would be updated.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': group.get('tags', {}), + 'new': tags + } + return ret + + elif __opts__['test']: + ret['comment'] = 'Resource group {0} would be created.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'location': location, + 'managed_by': managed_by, + 'tags': tags, + } + } + return ret + + group_kwargs = kwargs.copy() + group_kwargs.update(connection_auth) + + group = __salt__['azurearm_resource.resource_group_create_or_update']( + name, + location, + managed_by=managed_by, + tags=tags, + **group_kwargs + ) + present = __salt__['azurearm_resource.resource_group_check_existence'](name, **connection_auth) + + if present: + ret['result'] = True + ret['comment'] = 'Resource group {0} has been created.'.format(name) + ret['changes'] = { + 'old': {}, + 'new': group + } + return ret + + ret['comment'] = 'Failed to create resource group {0}! ({1})'.format(name, group.get('error')) + return ret + + +def resource_group_absent(name, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a resource group does not exist in the current subscription. + + :param name: + Name of the resource group. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + group = {} + + present = __salt__['azurearm_resource.resource_group_check_existence'](name, **connection_auth) + + if not present: + ret['result'] = True + ret['comment'] = 'Resource group {0} is already absent.'.format(name) + return ret + + elif __opts__['test']: + group = __salt__['azurearm_resource.resource_group_get'](name, **connection_auth) + + ret['comment'] = 'Resource group {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': group, + 'new': {}, + } + return ret + + group = __salt__['azurearm_resource.resource_group_get'](name, **connection_auth) + deleted = __salt__['azurearm_resource.resource_group_delete'](name, **connection_auth) + + if deleted: + present = False + else: + present = __salt__['azurearm_resource.resource_group_check_existence'](name, **connection_auth) + + if not present: + ret['result'] = True + ret['comment'] = 'Resource group {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': group, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete resource group {0}!'.format(name) + return ret + + +def policy_definition_present(name, policy_rule=None, policy_type=None, mode=None, display_name=None, description=None, + metadata=None, parameters=None, policy_rule_json=None, policy_rule_file=None, + template='jinja', source_hash=None, source_hash_name=None, skip_verify=False, + connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a security policy definition exists. + + :param name: + Name of the policy definition. + + :param policy_rule: + A YAML dictionary defining the policy rule. See `Azure Policy Definition documentation + `_ for details on the + structure. One of ``policy_rule``, ``policy_rule_json``, or ``policy_rule_file`` is required, in that order of + precedence for use if multiple parameters are used. + + :param policy_rule_json: + A text field defining the entirety of a policy definition in JSON. See `Azure Policy Definition documentation + `_ for details on the + structure. One of ``policy_rule``, ``policy_rule_json``, or ``policy_rule_file`` is required, in that order of + precedence for use if multiple parameters are used. Note that the `name` field in the JSON will override the + ``name`` parameter in the state. + + :param policy_rule_file: + The source of a JSON file defining the entirety of a policy definition. See `Azure Policy Definition + documentation `_ for + details on the structure. One of ``policy_rule``, ``policy_rule_json``, or ``policy_rule_file`` is required, + in that order of precedence for use if multiple parameters are used. Note that the `name` field in the JSON + will override the ``name`` parameter in the state. + + :param skip_verify: + Used for the ``policy_rule_file`` parameter. If ``True``, hash verification of remote file sources + (``http://``, ``https://``, ``ftp://``) will be skipped, and the ``source_hash`` argument will be ignored. + + :param source_hash: + This can be a source hash string or the URI of a file that contains source hash strings. + + :param source_hash_name: + When ``source_hash`` refers to a hash file, Salt will try to find the correct hash by matching the + filename/URI associated with that hash. + + :param policy_type: + The type of policy definition. Possible values are NotSpecified, BuiltIn, and Custom. Only used with the + ``policy_rule`` parameter. + + :param mode: + The policy definition mode. Possible values are NotSpecified, Indexed, and All. Only used with the + ``policy_rule`` parameter. + + :param display_name: + The display name of the policy definition. Only used with the ``policy_rule`` parameter. + + :param description: + The policy definition description. Only used with the ``policy_rule`` parameter. + + :param metadata: + The policy definition metadata defined as a dictionary. Only used with the ``policy_rule`` parameter. + + :param parameters: + Required dictionary if a parameter is used in the policy rule. Only used with the ``policy_rule`` parameter. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure policy definition exists: + azurearm_resource.policy_definition_present: + - name: testpolicy + - display_name: Test Policy + - description: Test policy for testing policies. + - policy_rule: + if: + allOf: + - equals: Microsoft.Compute/virtualMachines/write + source: action + - field: location + in: + - eastus + - eastus2 + - centralus + then: + effect: deny + - connection_auth: {{ profile }} + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + if not policy_rule and not policy_rule_json and not policy_rule_file: + ret['comment'] = 'One of "policy_rule", "policy_rule_json", or "policy_rule_file" is required!' + return ret + + if sum(x is not None for x in [policy_rule, policy_rule_json, policy_rule_file]) > 1: + ret['comment'] = 'Only one of "policy_rule", "policy_rule_json", or "policy_rule_file" is allowed!' + return ret + + if ((policy_rule_json or policy_rule_file) and + (policy_type or mode or display_name or description or metadata or parameters)): + ret['comment'] = 'Policy definitions cannot be passed when "policy_rule_json" or "policy_rule_file" is defined!' + return ret + + temp_rule = {} + if policy_rule_json: + try: + temp_rule = json.loads(policy_rule_json) + except Exception as exc: + ret['comment'] = 'Unable to load policy rule json! ({0})'.format(exc) + return ret + elif policy_rule_file: + try: + # pylint: disable=unused-variable + sfn, source_sum, comment_ = __salt__['file.get_managed']( + None, + template, + policy_rule_file, + source_hash, + source_hash_name, + None, + None, + None, + __env__, + None, + None, + skip_verify=skip_verify, + **kwargs + ) + except Exception as exc: + ret['comment'] = 'Unable to locate policy rule file "{0}"! ({1})'.format(policy_rule_file, exc) + return ret + + if not sfn: + ret['comment'] = 'Unable to locate policy rule file "{0}"!)'.format(policy_rule_file) + return ret + + try: + with salt.utils.fopen(sfn, 'r') as prf: + temp_rule = json.load(prf) + except Exception as exc: + ret['comment'] = 'Unable to load policy rule file "{0}"! ({1})'.format(policy_rule_file, exc) + return ret + + if sfn: + salt.utils.files.remove(sfn) + + policy_name = name + if policy_rule_json or policy_rule_file: + if temp_rule.get('name'): + policy_name = temp_rule.get('name') + policy_rule = temp_rule.get('properties', {}).get('policyRule') + policy_type = temp_rule.get('properties', {}).get('policyType') + mode = temp_rule.get('properties', {}).get('mode') + display_name = temp_rule.get('properties', {}).get('displayName') + description = temp_rule.get('properties', {}).get('description') + metadata = temp_rule.get('properties', {}).get('metadata') + parameters = temp_rule.get('properties', {}).get('parameters') + + policy = __salt__['azurearm_resource.policy_definition_get'](name, azurearm_log_level='info', **connection_auth) + + if 'error' not in policy: + if policy_type and policy_type.lower() != policy.get('policy_type', '').lower(): + ret['changes']['policy_type'] = { + 'old': policy.get('policy_type'), + 'new': policy_type + } + + if (mode or '').lower() != policy.get('mode', '').lower(): + ret['changes']['mode'] = { + 'old': policy.get('mode'), + 'new': mode + } + + if (display_name or '').lower() != policy.get('display_name', '').lower(): + ret['changes']['display_name'] = { + 'old': policy.get('display_name'), + 'new': display_name + } + + if (description or '').lower() != policy.get('description', '').lower(): + ret['changes']['description'] = { + 'old': policy.get('description'), + 'new': description + } + + rule_changes = __utils__['dictdiffer.deep_diff'](policy.get('policy_rule', {}), policy_rule or {}) + if rule_changes: + ret['changes']['policy_rule'] = rule_changes + + meta_changes = __utils__['dictdiffer.deep_diff'](policy.get('metadata', {}), metadata or {}) + if meta_changes: + ret['changes']['metadata'] = meta_changes + + param_changes = __utils__['dictdiffer.deep_diff'](policy.get('parameters', {}), parameters or {}) + if param_changes: + ret['changes']['parameters'] = param_changes + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Policy definition {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['comment'] = 'Policy definition {0} would be updated.'.format(name) + ret['result'] = None + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': policy_name, + 'policy_type': policy_type, + 'mode': mode, + 'display_name': display_name, + 'description': description, + 'metadata': metadata, + 'parameters': parameters, + 'policy_rule': policy_rule, + } + } + + if __opts__['test']: + ret['comment'] = 'Policy definition {0} would be created.'.format(name) + ret['result'] = None + return ret + + # Convert OrderedDict to dict + if isinstance(metadata, dict): + metadata = json.loads(json.dumps(metadata)) + if isinstance(parameters, dict): + parameters = json.loads(json.dumps(parameters)) + + policy_kwargs = kwargs.copy() + policy_kwargs.update(connection_auth) + + policy = __salt__['azurearm_resource.policy_definition_create_or_update']( + name=policy_name, + policy_rule=policy_rule, + policy_type=policy_type, + mode=mode, + display_name=display_name, + description=description, + metadata=metadata, + parameters=parameters, + **policy_kwargs + ) + + if 'error' not in policy: + ret['result'] = True + ret['comment'] = 'Policy definition {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create policy definition {0}! ({1})'.format(name, policy.get('error')) + return ret + + +def policy_definition_absent(name, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a policy definition does not exist in the current subscription. + + :param name: + Name of the policy definition. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + policy = __salt__['azurearm_resource.policy_definition_get'](name, azurearm_log_level='info', **connection_auth) + + if 'error' in policy: + ret['result'] = True + ret['comment'] = 'Policy definition {0} is already absent.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Policy definition {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': policy, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_resource.policy_definition_delete'](name, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Policy definition {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': policy, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete policy definition {0}!'.format(name) + return ret + + +def policy_assignment_present(name, scope, definition_name, display_name=None, description=None, assignment_type=None, + parameters=None, connection_auth=None, **kwargs): + ''' + .. versionadded:: Fluorine + + Ensure a security policy assignment exists. + + :param name: + Name of the policy assignment. + + :param scope: + The scope of the policy assignment. + + :param definition_name: + The name of the policy definition to assign. + + :param display_name: + The display name of the policy assignment. + + :param description: + The policy assignment description. + + :param assignment_type: + The type of policy assignment. + + :param parameters: + Required dictionary if a parameter is used in the policy rule. + + :param connection_auth: + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + + Example usage: + + .. code-block:: yaml + + Ensure policy assignment exists: + azurearm_resource.policy_assignment_present: + - name: testassign + - scope: /subscriptions/bc75htn-a0fhsi-349b-56gh-4fghti-f84852 + - definition_name: testpolicy + - display_name: Test Assignment + - description: Test assignment for testing assignments. + - connection_auth: {{ profile }} + + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + policy = __salt__['azurearm_resource.policy_assignment_get']( + name, + scope, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' not in policy: + if assignment_type and assignment_type.lower() != policy.get('type', '').lower(): + ret['changes']['type'] = { + 'old': policy.get('type'), + 'new': assignment_type + } + + if scope.lower() != policy['scope'].lower(): + ret['changes']['scope'] = { + 'old': policy['scope'], + 'new': scope + } + + pa_name = policy['policy_definition_id'].split('/')[-1] + if definition_name.lower() != pa_name.lower(): + ret['changes']['definition_name'] = { + 'old': pa_name, + 'new': definition_name + } + + if (display_name or '').lower() != policy.get('display_name', '').lower(): + ret['changes']['display_name'] = { + 'old': policy.get('display_name'), + 'new': display_name + } + + if (description or '').lower() != policy.get('description', '').lower(): + ret['changes']['description'] = { + 'old': policy.get('description'), + 'new': description + } + + param_changes = __utils__['dictdiffer.deep_diff'](policy.get('parameters', {}), parameters or {}) + if param_changes: + ret['changes']['parameters'] = param_changes + + if not ret['changes']: + ret['result'] = True + ret['comment'] = 'Policy assignment {0} is already present.'.format(name) + return ret + + if __opts__['test']: + ret['comment'] = 'Policy assignment {0} would be updated.'.format(name) + ret['result'] = None + return ret + + else: + ret['changes'] = { + 'old': {}, + 'new': { + 'name': name, + 'scope': scope, + 'definition_name': definition_name, + 'type': assignment_type, + 'display_name': display_name, + 'description': description, + 'parameters': parameters, + } + } + + if __opts__['test']: + ret['comment'] = 'Policy assignment {0} would be created.'.format(name) + ret['result'] = None + return ret + + if isinstance(parameters, dict): + parameters = json.loads(json.dumps(parameters)) + + policy_kwargs = kwargs.copy() + policy_kwargs.update(connection_auth) + policy = __salt__['azurearm_resource.policy_assignment_create']( + name=name, + scope=scope, + definition_name=definition_name, + type=assignment_type, + display_name=display_name, + description=description, + parameters=parameters, + **policy_kwargs + ) + + if 'error' not in policy: + ret['result'] = True + ret['comment'] = 'Policy assignment {0} has been created.'.format(name) + return ret + + ret['comment'] = 'Failed to create policy assignment {0}! ({1})'.format(name, policy.get('error')) + return ret + + +def policy_assignment_absent(name, scope, connection_auth=None): + ''' + .. versionadded:: Fluorine + + Ensure a policy assignment does not exist in the provided scope. + + :param name: + Name of the policy assignment. + + :param scope: + The scope of the policy assignment. + + connection_auth + A dict with subscription and authentication parameters to be used in connecting to the + Azure Resource Manager API. + ''' + ret = { + 'name': name, + 'result': False, + 'comment': '', + 'changes': {} + } + + if not isinstance(connection_auth, dict): + ret['comment'] = 'Connection information must be specified via connection_auth dictionary!' + return ret + + policy = __salt__['azurearm_resource.policy_assignment_get']( + name, + scope, + azurearm_log_level='info', + **connection_auth + ) + + if 'error' in policy: + ret['result'] = True + ret['comment'] = 'Policy assignment {0} is already absent.'.format(name) + return ret + + elif __opts__['test']: + ret['comment'] = 'Policy assignment {0} would be deleted.'.format(name) + ret['result'] = None + ret['changes'] = { + 'old': policy, + 'new': {}, + } + return ret + + deleted = __salt__['azurearm_resource.policy_assignment_delete'](name, scope, **connection_auth) + + if deleted: + ret['result'] = True + ret['comment'] = 'Policy assignment {0} has been deleted.'.format(name) + ret['changes'] = { + 'old': policy, + 'new': {} + } + return ret + + ret['comment'] = 'Failed to delete policy assignment {0}!'.format(name) + return ret diff --git a/salt/states/boto_cloudfront.py b/salt/states/boto_cloudfront.py index bc54d1aec0..27c6260e9d 100644 --- a/salt/states/boto_cloudfront.py +++ b/salt/states/boto_cloudfront.py @@ -2,7 +2,7 @@ ''' Manage CloudFront distributions -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Create, update and destroy CloudFront distributions. diff --git a/salt/states/boto_s3.py b/salt/states/boto_s3.py index 116e78fe8f..a75fe71afa 100644 --- a/salt/states/boto_s3.py +++ b/salt/states/boto_s3.py @@ -3,7 +3,7 @@ Manage S3 Resources ================= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 Manage S3 resources. Be aware that this interacts with Amazon's services, and so may incur charges. diff --git a/salt/states/chocolatey.py b/salt/states/chocolatey.py index 275dc69e2f..5f2e6e9842 100644 --- a/salt/states/chocolatey.py +++ b/salt/states/chocolatey.py @@ -285,7 +285,7 @@ def upgraded(name, ''' Upgrades a package. Will install the package if not installed. - .. versionadded: Oxygen + .. versionadded:: 2018.3.0 Args: diff --git a/salt/states/cmd.py b/salt/states/cmd.py index 6442279e38..2ae3bbaf7c 100644 --- a/salt/states/cmd.py +++ b/salt/states/cmd.py @@ -510,7 +510,7 @@ def wait(name, This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 use_vt Use VT utils (saltstack) to stream the command output more @@ -654,7 +654,7 @@ def wait_script(name, This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the @@ -758,7 +758,7 @@ def run(name, $PATH segment to prepend (trailing ':' not necessary) to $PATH. This is an easier alternative to the Jinja workaround. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 stateful The command being executed is expected to return data about executing @@ -782,7 +782,7 @@ def run(name, This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 quiet This option no longer has any functionality and will be removed, please @@ -1088,7 +1088,7 @@ def script(name, This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 success_retcodes: This parameter will be allow a list of non-zero return codes that should be considered a success. If the diff --git a/salt/states/cryptdev.py b/salt/states/cryptdev.py index cf6422164a..8178376784 100644 --- a/salt/states/cryptdev.py +++ b/salt/states/cryptdev.py @@ -26,7 +26,7 @@ Ensure that an encrypted device is mapped with the `mapped` function: - keyfile: /etc/keyfile.key - config: /etc/alternate-crypttab -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' from __future__ import absolute_import, print_function, unicode_literals diff --git a/salt/states/docker_container.py b/salt/states/docker_container.py index 6f21862f1e..ecee5077b8 100644 --- a/salt/states/docker_container.py +++ b/salt/states/docker_container.py @@ -248,7 +248,7 @@ def running(name, ` state should be used to manage the image. - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 If no tag is specified in the image name, and nothing matching the specified image is pulled on the minion, the ``docker pull`` that retrieves the image will pull *all tags* for the image. A tag of @@ -383,7 +383,7 @@ def running(name, **NETWORK MANAGEMENT** - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 The ``networks`` argument can be used to ensure that a container is attached to one or more networks. Optionally, arguments can be passed to @@ -1043,7 +1043,7 @@ def running(name, bar: baz hello: world - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Methods for specifying labels can now be mixed. Earlier releases required either labels with or without values. @@ -2067,7 +2067,7 @@ def run(name, client_timeout=salt.utils.docker.CLIENT_TIMEOUT, **kwargs): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. note:: If no tag is specified in the image name, and nothing matching the diff --git a/salt/states/docker_image.py b/salt/states/docker_image.py index 4e63f0fce1..2c83d4e72c 100644 --- a/salt/states/docker_image.py +++ b/salt/states/docker_image.py @@ -77,7 +77,7 @@ def present(name, pillar=None, **kwargs): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The ``tag`` argument has been added. It is now required unless pulling from a registry. @@ -101,7 +101,7 @@ def present(name, Tag name for the image. Required when using ``build``, ``load``, or ``sls`` to create the image, but optional if pulling from a repository. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 build Path to directory on the Minion containing a Dockerfile @@ -124,7 +124,7 @@ def present(name, will be applied to it. .. versionadded:: 2016.11.0 - .. versionchanged: Oxygen + .. versionchanged:: 2018.3.0 The ``tag`` must be manually specified using the ``tag`` argument. load @@ -139,7 +139,7 @@ def present(name, - load: salt://path/to/image.tar - tag: mytag - .. versionchanged: Oxygen + .. versionchanged:: 2018.3.0 The ``tag`` must be manually specified using the ``tag`` argument. force : False @@ -173,7 +173,7 @@ def present(name, - saltenv: base .. versionadded: 2017.7.0 - .. versionchanged: Oxygen + .. versionchanged:: 2018.3.0 The ``tag`` must be manually specified using the ``tag`` argument. base @@ -187,7 +187,7 @@ def present(name, `mods` parameter. .. versionadded:: 2017.7.0 - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Now uses the effective saltenv if not explicitly passed. In earlier versions, ``base`` was assumed as a default. @@ -198,7 +198,7 @@ def present(name, :conf_minion:`pillarenv` minion config option nor this CLI argument is used, all Pillar environments will be merged together. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 pillar Custom Pillar values, passed as a dictionary of key-value pairs @@ -207,7 +207,7 @@ def present(name, Values passed this way will override Pillar values set via ``pillar_roots`` or an external Pillar source. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 ''' ret = {'name': name, 'changes': {}, diff --git a/salt/states/docker_network.py b/salt/states/docker_network.py index 84af7a6cd2..4457e6d0e6 100644 --- a/salt/states/docker_network.py +++ b/salt/states/docker_network.py @@ -100,7 +100,7 @@ def present(name, reconnect=True, **kwargs): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Support added for network configuration options other than ``driver`` and ``driver_opts``, as well as IPAM configuration. @@ -145,7 +145,7 @@ def present(name, - `docker-py Low-level API`_ - `Docker Engine API`_ - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. _`docker-py Low-level API`: http://docker-py.readthedocs.io/en/stable/api.html#docker.api.container.ContainerApiMixin.create_container .. _`Docker Engine API`: https://docs.docker.com/engine/api/v1.33/#operation/ContainerCreate @@ -159,19 +159,19 @@ def present(name, will be raised. Set this argument to ``True`` to suppress these errors and keep the docker-py version of the argument. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 validate_ip_addrs : True For parameters which accept IP addresses/subnets as input, validation will be performed. To disable, set this to ``False``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 containers A list of containers which should be connected to this network. .. note:: - As of the Oxygen release, this is not the recommended way of + As of the 2018.3.0 release, this is not the recommended way of managing a container's membership in a network, for a couple reasons: @@ -214,7 +214,7 @@ def present(name, IP. Disabling the reconnect behavior in these cases would prevent the unnecessary extra reconnection. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. _salt-states-docker-network-present-netconf: @@ -325,7 +325,7 @@ def present(name, bar: baz hello: world - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Methods for specifying labels can now be mixed. Earlier releases required either labels with or without values. diff --git a/salt/states/file.py b/salt/states/file.py index f158ef515b..5ab8b4ca7c 100644 --- a/salt/states/file.py +++ b/salt/states/file.py @@ -1812,7 +1812,7 @@ def managed(name, .. note:: This option is **not** supported on Windows. - .. versionadded: Oxygen + .. versionadded:: 2018.3.0 template If this setting is applied, the named templating engine will be used to @@ -2117,7 +2117,7 @@ def managed(name, settings defined in this function. If ``False``, new entries will be appended to the existing DACL. Default is ``False``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Here's an example using the above ``win_*`` parameters: @@ -2821,7 +2821,7 @@ def directory(name, settings defined in this function. If ``False``, new entries will be appended to the existing DACL. Default is ``False``. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Here's an example using the above ``win_*`` parameters: @@ -6645,7 +6645,7 @@ def cached(name, .. code-block:: python - cached = __salt__['cp.is_cached'](source_match) + cached = __salt__['cp.is_cached'](source_match, saltenv=__env__) This function will return the cached path of the file, or an empty string if the file is not present in the minion cache. diff --git a/salt/states/glance_image.py b/salt/states/glance_image.py index e0e3808bfa..aff285a48d 100644 --- a/salt/states/glance_image.py +++ b/salt/states/glance_image.py @@ -3,7 +3,7 @@ Management of OpenStack Glance Images ======================================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.glanceng` for setup instructions diff --git a/salt/states/keystone_domain.py b/salt/states/keystone_domain.py index 4c18285590..27d98657e7 100644 --- a/salt/states/keystone_domain.py +++ b/salt/states/keystone_domain.py @@ -3,7 +3,7 @@ Management of OpenStack Keystone Domains ======================================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.keystoneng` for setup instructions diff --git a/salt/states/keystone_endpoint.py b/salt/states/keystone_endpoint.py index 40c93c4cde..fb6151519d 100644 --- a/salt/states/keystone_endpoint.py +++ b/salt/states/keystone_endpoint.py @@ -3,7 +3,7 @@ Management of OpenStack Keystone Endpoints ========================================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.keystoneng` for setup instructions diff --git a/salt/states/keystone_group.py b/salt/states/keystone_group.py index a1e252fe78..ac00b6a553 100644 --- a/salt/states/keystone_group.py +++ b/salt/states/keystone_group.py @@ -3,7 +3,7 @@ Management of OpenStack Keystone Groups ======================================= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.keystoneng` for setup instructions diff --git a/salt/states/keystone_project.py b/salt/states/keystone_project.py index 66c5040a44..94a6cc52ac 100644 --- a/salt/states/keystone_project.py +++ b/salt/states/keystone_project.py @@ -3,7 +3,7 @@ Management of OpenStack Keystone Projects ========================================= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.keystoneng` for setup instructions diff --git a/salt/states/keystone_role.py b/salt/states/keystone_role.py index 58f2565e73..394a51cfb7 100644 --- a/salt/states/keystone_role.py +++ b/salt/states/keystone_role.py @@ -3,7 +3,7 @@ Management of OpenStack Keystone Roles ====================================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.keystoneng` for setup instructions diff --git a/salt/states/keystone_role_grant.py b/salt/states/keystone_role_grant.py index 36a2f422b3..bf2f23f558 100644 --- a/salt/states/keystone_role_grant.py +++ b/salt/states/keystone_role_grant.py @@ -3,7 +3,7 @@ Management of OpenStack Keystone Role Grants ============================================ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.keystoneng` for setup instructions diff --git a/salt/states/keystone_service.py b/salt/states/keystone_service.py index 75a1b7c4d1..ac62b59584 100644 --- a/salt/states/keystone_service.py +++ b/salt/states/keystone_service.py @@ -3,7 +3,7 @@ Management of OpenStack Keystone Services ========================================= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.keystoneng` for setup instructions diff --git a/salt/states/keystone_user.py b/salt/states/keystone_user.py index 6005825e0d..23f95fd260 100644 --- a/salt/states/keystone_user.py +++ b/salt/states/keystone_user.py @@ -3,7 +3,7 @@ Management of OpenStack Keystone Users ====================================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.keystoneng` for setup instructions diff --git a/salt/states/libcloud_loadbalancer.py b/salt/states/libcloud_loadbalancer.py index 9f254b6c1a..a3e2162f40 100644 --- a/salt/states/libcloud_loadbalancer.py +++ b/salt/states/libcloud_loadbalancer.py @@ -12,7 +12,7 @@ of supported clouds, see http://libcloud.readthedocs.io/en/latest/loadbalancer/s Clouds include Amazon ELB, ALB, Google, Aliyun, CloudStack, Softlayer -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :configuration: This module uses a configuration profile for one or multiple Cloud providers diff --git a/salt/states/libcloud_storage.py b/salt/states/libcloud_storage.py index e3f62e4179..1f43ab2a63 100644 --- a/salt/states/libcloud_storage.py +++ b/salt/states/libcloud_storage.py @@ -12,7 +12,7 @@ of supported clouds, see http://libcloud.readthedocs.io/en/latest/storage/suppor Clouds include Amazon S3, Google Storage, Aliyun, Azure Blobs, Ceph, OpenStack swift -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :configuration: This module uses a configuration profile for one or multiple Storage providers diff --git a/salt/states/lvm.py b/salt/states/lvm.py index 594bb5f2c6..04cd61796f 100644 --- a/salt/states/lvm.py +++ b/salt/states/lvm.py @@ -246,7 +246,7 @@ def lv_present(name, thinpool Logical volume is a thin pool - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 force Assume yes to all prompts diff --git a/salt/states/netconfig.py b/salt/states/netconfig.py index 96bf334278..3529467052 100644 --- a/salt/states/netconfig.py +++ b/salt/states/netconfig.py @@ -192,7 +192,7 @@ def managed(name, template_attrs: "--------------e----" Attributes of file (see `man lsattr`) - .. versionadded:: oxygen + .. versionadded:: 2018.3.0 saltenv: base Specifies the template environment. This will influence the relative imports inside the templates. diff --git a/salt/states/neutron_network.py b/salt/states/neutron_network.py index 40ec891110..05015f55a7 100644 --- a/salt/states/neutron_network.py +++ b/salt/states/neutron_network.py @@ -3,7 +3,7 @@ Management of OpenStack Neutron Networks ========================================= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.neutronng` for setup instructions diff --git a/salt/states/neutron_secgroup.py b/salt/states/neutron_secgroup.py index 3cc46091bd..0442e09e49 100644 --- a/salt/states/neutron_secgroup.py +++ b/salt/states/neutron_secgroup.py @@ -3,7 +3,7 @@ Management of OpenStack Neutron Security Groups ========================================= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.neutronng` for setup instructions diff --git a/salt/states/neutron_secgroup_rule.py b/salt/states/neutron_secgroup_rule.py index 3f8ad4d8bc..608cab657c 100644 --- a/salt/states/neutron_secgroup_rule.py +++ b/salt/states/neutron_secgroup_rule.py @@ -3,7 +3,7 @@ Management of OpenStack Neutron Security Group Rules ========================================= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.neutronng` for setup instructions diff --git a/salt/states/neutron_subnet.py b/salt/states/neutron_subnet.py index edfc755d43..43e4ab3ccf 100644 --- a/salt/states/neutron_subnet.py +++ b/salt/states/neutron_subnet.py @@ -3,7 +3,7 @@ Management of OpenStack Neutron Subnets ========================================= -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 :depends: shade :configuration: see :py:mod:`salt.modules.neutronng` for setup instructions diff --git a/salt/states/nexus.py b/salt/states/nexus.py index cf938cf590..c87b58352d 100644 --- a/salt/states/nexus.py +++ b/salt/states/nexus.py @@ -2,7 +2,7 @@ ''' This state downloads artifacts from Nexus 3.x. -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' # Import python libs diff --git a/salt/states/nfs_export.py b/salt/states/nfs_export.py index 5bebe19be2..170da99fd1 100644 --- a/salt/states/nfs_export.py +++ b/salt/states/nfs_export.py @@ -3,7 +3,7 @@ Management of NFS exports =============================================== -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 To ensure an NFS export exists: diff --git a/salt/states/opsgenie.py b/salt/states/opsgenie.py index 9ccbf6810e..09e0e37167 100644 --- a/salt/states/opsgenie.py +++ b/salt/states/opsgenie.py @@ -3,7 +3,7 @@ Create/Close an alert in OpsGenie ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 This state is useful for creating or closing alerts in OpsGenie during state runs. diff --git a/salt/states/pkg.py b/salt/states/pkg.py index 61ad4ff581..4c406aa04e 100644 --- a/salt/states/pkg.py +++ b/salt/states/pkg.py @@ -1135,7 +1135,7 @@ def installed( :param bool resolve_capabilities: Turn on resolving capabilities. This allow to name "provides" or alias names for packages. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 :param bool allow_updates: Allow the package to be updated outside Salt's control (e.g. auto @@ -1969,7 +1969,7 @@ def downloaded(name, :param bool resolve_capabilities: Turn on resolving capabilities. This allow to name "provides" or alias names for packages. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 CLI Example: @@ -2261,7 +2261,7 @@ def latest( :param bool resolve_capabilities: Turn on resolving capabilities. This allow to name "provides" or alias names for packages. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Multiple Package Installation Options: @@ -2856,7 +2856,7 @@ def purged(name, def uptodate(name, refresh=False, pkgs=None, **kwargs): ''' .. versionadded:: 2014.7.0 - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 Added support for the ``pkgin`` provider. @@ -2888,7 +2888,7 @@ def uptodate(name, refresh=False, pkgs=None, **kwargs): :param bool resolve_capabilities: Turn on resolving capabilities. This allow to name "provides" or alias names for packages. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 kwargs Any keyword arguments to pass through to ``pkg.upgrade``. diff --git a/salt/states/pkgrepo.py b/salt/states/pkgrepo.py index df7ab35a86..0edba482a3 100644 --- a/salt/states/pkgrepo.py +++ b/salt/states/pkgrepo.py @@ -270,7 +270,7 @@ def managed(name, ppa=None, **kwargs): key_text The string representation of the GPG key to install. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 .. note:: @@ -299,7 +299,7 @@ def managed(name, ppa=None, **kwargs): on debian based systems. refresh_db : True - .. deprecated:: Oxygen + .. deprecated:: 2018.3.0 Use ``refresh`` instead. require_in diff --git a/salt/states/reg.py b/salt/states/reg.py index 4f3ecb44d8..d4ff1e74d3 100644 --- a/salt/states/reg.py +++ b/salt/states/reg.py @@ -192,9 +192,14 @@ def present(name, salt.utils.stringutils.to_unicode(name, 'utf-8')) return ret + try: + vdata_decoded = salt.utils.stringutils.to_unicode(vdata, 'utf-8') + except UnicodeDecodeError: + # vdata contains binary data that can't be decoded + vdata_decoded = vdata add_change = {'Key': r'{0}\{1}'.format(hive, key), 'Entry': '{0}'.format(salt.utils.stringutils.to_unicode(vname, 'utf-8') if vname else '(Default)'), - 'Value': salt.utils.stringutils.to_unicode(vdata, 'utf-8')} + 'Value': vdata_decoded} # Check for test option if __opts__['test']: diff --git a/salt/states/rsync.py b/salt/states/rsync.py index 896c6fdcd3..d2babf5541 100644 --- a/salt/states/rsync.py +++ b/salt/states/rsync.py @@ -123,7 +123,7 @@ def synchronized(name, source, additional_opts Pass additional options to rsync, should be included as a list. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 ''' ret = {'name': name, 'changes': {}, 'result': True, 'comment': ''} diff --git a/salt/states/svn.py b/salt/states/svn.py index ce571d96a5..3f14a42172 100644 --- a/salt/states/svn.py +++ b/salt/states/svn.py @@ -48,7 +48,8 @@ def latest(name, password=None, force=False, externals=True, - trust=False): + trust=False, + trust_failures=None): ''' Checkout or update the working directory to the latest revision from the remote repository. @@ -84,6 +85,14 @@ def latest(name, trust : False Automatically trust the remote server. SVN's --trust-server-cert + + trust_failures : None + Comma-separated list of certificate trust failures, that shall be + ignored. This can be used if trust=True is not sufficient. The + specified string is passed to SVN's --trust-server-cert-failures + option as-is. + + .. versionadded:: Fluorine ''' ret = {'name': name, 'result': True, 'comment': '', 'changes': {}} if not target: @@ -147,6 +156,9 @@ def latest(name, if trust: opts += ('--trust-server-cert',) + if trust_failures: + opts += ('--trust-server-cert-failures', trust_failures) + if svn_cmd == 'svn.update': out = __salt__[svn_cmd](cwd, basename, user, username, password, *opts) @@ -184,7 +196,8 @@ def export(name, force=False, overwrite=False, externals=True, - trust=False): + trust=False, + trust_failures=None): ''' Export a file or directory from an SVN repository @@ -222,6 +235,14 @@ def export(name, trust : False Automatically trust the remote server. SVN's --trust-server-cert + + trust_failures : None + Comma-separated list of certificate trust failures, that shall be + ignored. This can be used if trust=True is not sufficient. The + specified string is passed to SVN's --trust-server-cert-failures + option as-is. + + .. versionadded:: Fluorine ''' ret = {'name': name, 'result': True, 'comment': '', 'changes': {}} if not target: @@ -260,6 +281,9 @@ def export(name, if trust: opts += ('--trust-server-cert',) + if trust_failures: + opts += ('--trust-server-cert-failures', trust_failures) + out = __salt__[svn_cmd](cwd, name, basename, user, username, password, rev, *opts) ret['changes'] = name + ' was Exported to ' + target diff --git a/salt/states/vagrant.py b/salt/states/vagrant.py index 012bbf7170..86e2f13797 100644 --- a/salt/states/vagrant.py +++ b/salt/states/vagrant.py @@ -19,7 +19,7 @@ developers who use Vagrant to quickly define their virtual environments. .. _Docker: https://www.docker.io/ .. _VMWare: https://www.vmware.com/ - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 The configuration of each virtual machine is defined in a file named ``Vagrantfile`` which must exist on the VM host machine. diff --git a/salt/states/virt.py b/salt/states/virt.py index c296c95e54..96b1c77d5c 100644 --- a/salt/states/virt.py +++ b/salt/states/virt.py @@ -63,30 +63,30 @@ def keys(name, basepath='/etc/pki', **kwargs): country The country that the certificate should use. Defaults to US. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 state The state that the certificate should use. Defaults to Utah. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 locality The locality that the certificate should use. Defaults to Salt Lake City. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 organization The organization that the certificate should use. Defaults to Salted. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 expiration_days The number of days that the certificate should be valid for. Defaults to 365 days (1 year) - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 ''' ret = {'name': name, 'changes': {}, 'result': True, 'comment': ''} diff --git a/salt/states/win_servermanager.py b/salt/states/win_servermanager.py index 49deda54d6..ce8b746f4d 100644 --- a/salt/states/win_servermanager.py +++ b/salt/states/win_servermanager.py @@ -53,7 +53,7 @@ def installed(name, A list of features to install. If this is passed it will be used instead of the ``name`` parameter. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 recurse (Optional[bool]): Install all sub-features as well. If the feature is installed but @@ -118,7 +118,7 @@ def installed(name, 'Flourine', 'Parameter \'force\' has been detected in the argument list. This' 'parameter is no longer used and has been replaced by \'recurse\'' - 'as of Salt Oxygen. This warning will be removed in Salt Flourine.' + 'as of Salt 2018.3.0. This warning will be removed in Salt Flourine.' ) kwargs.pop('force') @@ -219,7 +219,7 @@ def removed(name, features=None, remove_payload=False, restart=False): A list of features to remove. If this is passed it will be used instead of the ``name`` parameter. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 remove_payload (Optional[bool]): True will cause the feature to be removed from the side-by-side diff --git a/salt/transport/ipc.py b/salt/transport/ipc.py index 1cf2b18f78..7ea9bf8c87 100644 --- a/salt/transport/ipc.py +++ b/salt/transport/ipc.py @@ -558,6 +558,11 @@ class IPCMessagePublisher(object): io_loop=self.io_loop ) self.streams.add(stream) + + def discard_after_closed(): + self.streams.discard(stream) + + stream.set_close_callback(discard_after_closed) except Exception as exc: log.error('IPC streaming error: %s', exc) diff --git a/salt/transport/mixins/auth.py b/salt/transport/mixins/auth.py index df4c3b57d4..16a9be63fa 100644 --- a/salt/transport/mixins/auth.py +++ b/salt/transport/mixins/auth.py @@ -128,14 +128,13 @@ class AESReqServerMixin(object): return {'error': 'AES key not found'} pret = {} + if not six.PY2: + key = salt.utils.stringutils.to_bytes(key) if HAS_M2: - pret['key'] = pub.public_encrypt(six.b(key), RSA.pkcs1_oaep_padding) + pret['key'] = pub.public_encrypt(key, RSA.pkcs1_oaep_padding) else: cipher = PKCS1_OAEP.new(pub) - if six.PY2: - pret['key'] = cipher.encrypt(key) - else: - pret['key'] = cipher.encrypt(salt.utils.stringutils.to_bytes(key)) + pret['key'] = cipher.encrypt(key) pret[dictkey] = pcrypt.dumps( ret if ret is not False else {} ) @@ -420,6 +419,10 @@ class AESReqServerMixin(object): log.debug('Host key change detected in open mode.') with salt.utils.files.fopen(pubfn, 'w+') as fp_: fp_.write(load['pub']) + elif not load['pub']: + log.error('Public key is empty: {0}'.format(load['id'])) + return {'enc': 'clear', + 'load': {'ret': False}} pub = None @@ -468,7 +471,7 @@ class AESReqServerMixin(object): if 'token' in load: try: if HAS_M2: - mtoken = self.master_key.key.private_decrypt(six.b(load['token']), + mtoken = self.master_key.key.private_decrypt(load['token'], RSA.pkcs1_oaep_padding) else: mtoken = mcipher.decrypt(load['token']) @@ -481,16 +484,16 @@ class AESReqServerMixin(object): aes = salt.master.SMaster.secrets['aes']['secret'].value if HAS_M2: - ret['aes'] = pub.public_encrypt(six.b(aes), RSA.pkcs1_oaep_padding) + ret['aes'] = pub.public_encrypt(aes, RSA.pkcs1_oaep_padding) else: ret['aes'] = cipher.encrypt(aes) else: if 'token' in load: try: if HAS_M2: - mtoken = self.master_key.key.private_decrypt(six.b(load['token']), + mtoken = self.master_key.key.private_decrypt(load['token'], RSA.pkcs1_oaep_padding) - ret['token'] = pub.public_encrypt(six.b(mtoken), RSA.pkcs1_oaep_padding) + ret['token'] = pub.public_encrypt(mtoken, RSA.pkcs1_oaep_padding) else: mtoken = mcipher.decrypt(load['token']) ret['token'] = cipher.encrypt(mtoken) @@ -501,11 +504,12 @@ class AESReqServerMixin(object): aes = salt.master.SMaster.secrets['aes']['secret'].value if HAS_M2: - ret['aes'] = pub.public_encrypt(six.b(aes), RSA.pkcs1_oaep_padding) + ret['aes'] = pub.public_encrypt(aes, + RSA.pkcs1_oaep_padding) else: ret['aes'] = cipher.encrypt(aes) # Be aggressive about the signature - digest = hashlib.sha256(aes).hexdigest() + digest = salt.utils.stringutils.to_bytes(hashlib.sha256(aes).hexdigest()) ret['sig'] = salt.crypt.private_encrypt(self.master_key.key, digest) eload = {'result': True, 'act': 'accept', diff --git a/salt/transport/tcp.py b/salt/transport/tcp.py index 22f39a8d4e..334ed0a3ad 100644 --- a/salt/transport/tcp.py +++ b/salt/transport/tcp.py @@ -302,7 +302,7 @@ class AsyncTCPReqChannel(salt.transport.client.ReqChannel): ret = yield self.message_client.send(self._package_load(self.auth.crypticle.dumps(load)), timeout=timeout) key = self.auth.get_keys() if HAS_M2: - aes = key.private_decrypt(six.b(ret['key']), RSA.pkcs1_oaep_padding) + aes = key.private_decrypt(ret['key'], RSA.pkcs1_oaep_padding) else: cipher = PKCS1_OAEP.new(key) aes = cipher.decrypt(ret['key']) diff --git a/salt/transport/zeromq.py b/salt/transport/zeromq.py index adbea625a1..ad3dbc27e9 100644 --- a/salt/transport/zeromq.py +++ b/salt/transport/zeromq.py @@ -16,8 +16,6 @@ import weakref from random import randint # Import Salt Libs -from salt.ext import six -from salt.ext.six.moves import map import salt.auth import salt.crypt import salt.utils.event @@ -31,25 +29,19 @@ import salt.transport.client import salt.transport.server import salt.transport.mixins.auth from salt.ext import six -from salt.ext.six.moves import map from salt.exceptions import SaltReqTimeoutError -import zmq +from salt.utils.zeromq import zmq, ZMQDefaultLoop, install_zmq, ZMQ_VERSION_INFO, LIBZMQ_VERSION_INFO import zmq.error import zmq.eventloop.ioloop -# support pyzmq 13.0.x, TODO: remove once we force people to 14.0.x -if not hasattr(zmq.eventloop.ioloop, 'ZMQIOLoop'): - zmq.eventloop.ioloop.ZMQIOLoop = zmq.eventloop.ioloop.IOLoop import zmq.eventloop.zmqstream + try: import zmq.utils.monitor HAS_ZMQ_MONITOR = True except ImportError: HAS_ZMQ_MONITOR = False -LIBZMQ_VERSION = tuple(map(int, zmq.zmq_version().split('.'))) -PYZMQ_VERSION = tuple(map(int, zmq.pyzmq_version().split('.'))) - # Import Tornado Libs import tornado import tornado.gen @@ -82,7 +74,7 @@ def _get_master_uri(master_ip, Source: http://api.zeromq.org/4-1:zmq-tcp ''' - if LIBZMQ_VERSION >= (4, 1, 6) and PYZMQ_VERSION >= (16, 0, 1): + if LIBZMQ_VERSION_INFO >= (4, 1, 6) and ZMQ_VERSION_INFO >= (16, 0, 1): # The source:port syntax for ZeroMQ has been added in libzmq 4.1.6 # which is included in the pyzmq wheels starting with 16.0.1. if source_ip or source_port: @@ -123,8 +115,8 @@ class AsyncZeroMQReqChannel(salt.transport.client.ReqChannel): # do we have any mapping for this io_loop io_loop = kwargs.get('io_loop') if io_loop is None: - zmq.eventloop.ioloop.install() - io_loop = tornado.ioloop.IOLoop.current() + install_zmq() + io_loop = ZMQDefaultLoop.current() if io_loop not in cls.instance_map: cls.instance_map[io_loop] = weakref.WeakValueDictionary() loop_instance_map = cls.instance_map[io_loop] @@ -139,7 +131,8 @@ class AsyncZeroMQReqChannel(salt.transport.client.ReqChannel): obj = object.__new__(cls) obj.__singleton_init__(opts, **kwargs) loop_instance_map[key] = obj - log.trace('Inserted key into loop_instance_map id %s for key %s and process %s', id(loop_instance_map), key, os.getpid()) + log.trace('Inserted key into loop_instance_map id %s for key %s and process %s', + id(loop_instance_map), key, os.getpid()) else: log.debug('Re-using AsyncZeroMQReqChannel for %s', key) return obj @@ -191,8 +184,8 @@ class AsyncZeroMQReqChannel(salt.transport.client.ReqChannel): self._io_loop = kwargs.get('io_loop') if self._io_loop is None: - zmq.eventloop.ioloop.install() - self._io_loop = tornado.ioloop.IOLoop.current() + install_zmq() + self._io_loop = ZMQDefaultLoop.current() if self.crypt != 'clear': # we don't need to worry about auth as a kwarg, since its a singleton @@ -248,7 +241,8 @@ class AsyncZeroMQReqChannel(salt.transport.client.ReqChannel): tries=tries, ) if HAS_M2: - aes = key.private_decrypt(six.b(ret['key']), RSA.pkcs1_oaep_padding) + aes = key.private_decrypt(ret['key'], + RSA.pkcs1_oaep_padding) else: cipher = PKCS1_OAEP.new(key) aes = cipher.decrypt(ret['key']) @@ -341,18 +335,15 @@ class AsyncZeroMQPubChannel(salt.transport.mixins.auth.AESPubClientMixin, salt.t **kwargs): self.opts = opts self.ttype = 'zeromq' - self.io_loop = kwargs.get('io_loop') + if self.io_loop is None: - zmq.eventloop.ioloop.install() - self.io_loop = tornado.ioloop.IOLoop.current() + install_zmq() + self.io_loop = ZMQDefaultLoop.current() self.hexid = hashlib.sha1(salt.utils.stringutils.to_bytes(self.opts['id'])).hexdigest() - self.auth = salt.crypt.AsyncAuth(self.opts, io_loop=self.io_loop) - self.serial = salt.payload.Serial(self.opts) - self.context = zmq.Context() self._socket = self.context.socket(zmq.SUB) @@ -384,8 +375,7 @@ class AsyncZeroMQPubChannel(salt.transport.mixins.auth.AESPubClientMixin, salt.t if self.opts['recon_randomize']: recon_delay = randint(self.opts['recon_default'], - self.opts['recon_default'] + self.opts['recon_max'] - ) + self.opts['recon_default'] + self.opts['recon_max']) log.debug( "Generated random reconnect delay between '%sms' and '%sms' (%s)", @@ -420,7 +410,7 @@ class AsyncZeroMQPubChannel(salt.transport.mixins.auth.AESPubClientMixin, salt.t self._monitor.stop() self._monitor = None if hasattr(self, '_stream'): - if PYZMQ_VERSION < (14, 3, 0): + if ZMQ_VERSION_INFO < (14, 3, 0): # stream.close() doesn't work properly on pyzmq < 14.3.0 self._stream.io_loop.remove_handler(self._stream.socket) self._stream.socket.close(0) @@ -504,7 +494,8 @@ class AsyncZeroMQPubChannel(salt.transport.mixins.auth.AESPubClientMixin, salt.t return self.stream.on_recv(wrap_callback) -class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt.transport.server.ReqServerChannel): +class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, + salt.transport.server.ReqServerChannel): def __init__(self, opts): salt.transport.server.ReqServerChannel.__init__(self, opts) @@ -524,13 +515,7 @@ class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt. # IPv6 sockets work for both IPv6 and IPv4 addresses self.clients.setsockopt(zmq.IPV4ONLY, 0) self.clients.setsockopt(zmq.BACKLOG, self.opts.get('zmq_backlog', 1000)) - if HAS_ZMQ_MONITOR and self.opts['zmq_monitor']: - # Socket monitor shall be used the only for debug purposes so using threading doesn't look too bad here - import threading - self._monitor = ZeroMQSocketMonitor(self.clients) - t = threading.Thread(target=self._monitor.start_poll) - t.start() - + self._start_zmq_monitor() self.workers = self.context.socket(zmq.DEALER) if self.opts.get('ipc_mode', '') == 'tcp': @@ -544,7 +529,6 @@ class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt. log.info('Setting up the master communication server') self.clients.bind(self.uri) - self.workers.bind(self.w_uri) while True: @@ -567,10 +551,11 @@ class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt. return log.info('MWorkerQueue under PID %s is closing', os.getpid()) self._closing = True - if hasattr(self, '_monitor') and self._monitor is not None: + # pylint: disable=E0203 + if getattr(self, '_monitor', None) is not None: self._monitor.stop() self._monitor = None - if hasattr(self, '_w_monitor') and self._w_monitor is not None: + if getattr(self, '_w_monitor', None) is not None: self._w_monitor.stop() self._w_monitor = None if hasattr(self, 'clients') and self.clients.closed is False: @@ -583,6 +568,7 @@ class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt. self._socket.close() if hasattr(self, 'context') and self.context.closed is False: self.context.term() + # pylint: enable=E0203 def pre_fork(self, process_manager): ''' @@ -593,6 +579,21 @@ class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt. salt.transport.mixins.auth.AESReqServerMixin.pre_fork(self, process_manager) process_manager.add_process(self.zmq_device) + def _start_zmq_monitor(self): + ''' + Starts ZMQ monitor for debugging purposes. + :return: + ''' + # Socket monitor shall be used the only for debug + # purposes so using threading doesn't look too bad here + + if HAS_ZMQ_MONITOR and self.opts['zmq_monitor']: + log.debug('Starting ZMQ monitor') + import threading + self._w_monitor = ZeroMQSocketMonitor(self._socket) + threading.Thread(target=self._w_monitor.start_poll).start() + log.debug('ZMQ monitor has been started started') + def post_fork(self, payload_handler, io_loop): ''' After forking we need to create all of the local sockets to listen to the @@ -607,12 +608,7 @@ class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt. self.context = zmq.Context(1) self._socket = self.context.socket(zmq.REP) - if HAS_ZMQ_MONITOR and self.opts['zmq_monitor']: - # Socket monitor shall be used the only for debug purposes so using threading doesn't look too bad here - import threading - self._w_monitor = ZeroMQSocketMonitor(self._socket) - t = threading.Thread(target=self._w_monitor.start_poll) - t.start() + self._start_zmq_monitor() if self.opts.get('ipc_mode', '') == 'tcp': self.w_uri = 'tcp://127.0.0.1:{0}'.format( @@ -821,27 +817,35 @@ class ZeroMQPubServerChannel(salt.transport.server.PubServerChannel): # Catch and handle EINTR from when this process is sent # SIGUSR1 gracefully so we don't choke and die horribly try: + log.trace('Getting data from puller %s', pull_uri) package = pull_sock.recv() unpacked_package = salt.payload.unpackage(package) if six.PY3: unpacked_package = salt.transport.frame.decode_embedded_strs(unpacked_package) payload = unpacked_package['payload'] + log.trace('Accepted unpacked package from puller') if self.opts['zmq_filtering']: # if you have a specific topic list, use that if 'topic_lst' in unpacked_package: for topic in unpacked_package['topic_lst']: + log.trace('Sending filtered data over publisher %s', pub_uri) # zmq filters are substring match, hash the topic # to avoid collisions htopic = hashlib.sha1(topic).hexdigest() pub_sock.send(htopic, flags=zmq.SNDMORE) pub_sock.send(payload) + log.trace('Filtered data has been sent') # otherwise its a broadcast else: # TODO: constants file for "broadcast" + log.trace('Sending broadcasted data over publisher %s', pub_uri) pub_sock.send('broadcast', flags=zmq.SNDMORE) pub_sock.send(payload) + log.trace('Broadcasted data has been sent') else: + log.trace('Sending ZMQ-unfiltered data over publisher %s', pub_uri) pub_sock.send(payload) + log.trace('Unfiltered data has been sent') except zmq.ZMQError as exc: if exc.errno == errno.EINTR: continue @@ -960,13 +964,12 @@ class AsyncReqMessageClient(object): self.addr = addr self.linger = linger if io_loop is None: - zmq.eventloop.ioloop.install() - tornado.ioloop.IOLoop.current() + install_zmq() + ZMQDefaultLoop.current() else: self.io_loop = io_loop self.serial = salt.payload.Serial(self.opts) - self.context = zmq.Context() # wire up sockets @@ -981,7 +984,7 @@ class AsyncReqMessageClient(object): # TODO: timeout all in-flight sessions, or error def destroy(self): if hasattr(self, 'stream') and self.stream is not None: - if PYZMQ_VERSION < (14, 3, 0): + if ZMQ_VERSION_INFO < (14, 3, 0): # stream.close() doesn't work properly on pyzmq < 14.3.0 if self.stream.socket: self.stream.socket.close() @@ -1046,7 +1049,8 @@ class AsyncReqMessageClient(object): try: ret = yield future - except: # pylint: disable=W0702 + except Exception as err: # pylint: disable=W0702 + log.debug('Re-init ZMQ socket: %s', err) self._init_socket() # re-init the zmq socket (no other way in zmq) del self.send_queue[0] continue diff --git a/salt/utils/__init__.py b/salt/utils/__init__.py index d9bd472d7e..b169749b55 100644 --- a/salt/utils/__init__.py +++ b/salt/utils/__init__.py @@ -126,7 +126,7 @@ def get_accumulator_dir(cachedir): 'Neon', 'Use of \'salt.utils.get_accumulator_dir\' detected. This function ' 'has been moved to \'salt.state.get_accumulator_dir\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.state.get_accumulator_dir(cachedir) @@ -139,7 +139,7 @@ def fnmatch_multiple(candidates, pattern): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.fnmatch_multiple\' detected. This function has been ' - 'moved to \'salt.utils.itertools.fnmatch_multiple\' as of Salt Oxygen. ' + 'moved to \'salt.utils.itertools.fnmatch_multiple\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -153,7 +153,7 @@ def appendproctitle(name): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.appendproctitle\' detected. This function has been ' - 'moved to \'salt.utils.process.appendproctitle\' as of Salt Oxygen. ' + 'moved to \'salt.utils.process.appendproctitle\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -167,7 +167,7 @@ def daemonize(redirect_out=True): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.daemonize\' detected. This function has been ' - 'moved to \'salt.utils.process.daemonize\' as of Salt Oxygen. ' + 'moved to \'salt.utils.process.daemonize\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -181,7 +181,7 @@ def daemonize_if(opts): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.daemonize_if\' detected. This function has been ' - 'moved to \'salt.utils.process.daemonize_if\' as of Salt Oxygen. ' + 'moved to \'salt.utils.process.daemonize_if\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -195,7 +195,7 @@ def reinit_crypto(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.reinit_crypto\' detected. This function has been ' - 'moved to \'salt.utils.crypt.reinit_crypto\' as of Salt Oxygen. ' + 'moved to \'salt.utils.crypt.reinit_crypto\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -209,7 +209,7 @@ def pem_finger(path=None, key=None, sum_type='sha256'): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.pem_finger\' detected. This function has been ' - 'moved to \'salt.utils.crypt.pem_finger\' as of Salt Oxygen. ' + 'moved to \'salt.utils.crypt.pem_finger\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -223,7 +223,7 @@ def to_bytes(s, encoding=None): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.to_bytes\' detected. This function has been ' - 'moved to \'salt.utils.stringutils.to_bytes\' as of Salt Oxygen. ' + 'moved to \'salt.utils.stringutils.to_bytes\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -237,7 +237,7 @@ def to_str(s, encoding=None): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.to_str\' detected. This function has been moved ' - 'to \'salt.utils.stringutils.to_str\' as of Salt Oxygen. This ' + 'to \'salt.utils.stringutils.to_str\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -251,7 +251,7 @@ def to_unicode(s, encoding=None): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.to_unicode\' detected. This function has been ' - 'moved to \'salt.utils.stringutils.to_unicode\' as of Salt Oxygen. ' + 'moved to \'salt.utils.stringutils.to_unicode\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -265,7 +265,7 @@ def str_to_num(text): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.str_to_num\' detected. This function has been ' - 'moved to \'salt.utils.stringutils.to_num\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.stringutils.to_num\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -279,7 +279,7 @@ def is_quoted(value): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_quoted\' detected. This function has been ' - 'moved to \'salt.utils.stringutils.is_quoted\' as of Salt Oxygen. ' + 'moved to \'salt.utils.stringutils.is_quoted\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -293,7 +293,7 @@ def dequote(value): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.dequote\' detected. This function has been moved ' - 'to \'salt.utils.stringutils.dequote\' as of Salt Oxygen. This ' + 'to \'salt.utils.stringutils.dequote\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -307,7 +307,7 @@ def is_hex(value): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_hex\' detected. This function has been moved ' - 'to \'salt.utils.stringutils.is_hex\' as of Salt Oxygen. This warning ' + 'to \'salt.utils.stringutils.is_hex\' as of Salt 2018.3.0. This warning ' 'will be removed in Salt Neon.', stacklevel=3 ) @@ -321,7 +321,7 @@ def is_bin_str(data): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_bin_str\' detected. This function has been ' - 'moved to \'salt.utils.stringutils.is_binary\' as of Salt Oxygen. ' + 'moved to \'salt.utils.stringutils.is_binary\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -335,7 +335,7 @@ def rand_string(size=32): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.rand_string\' detected. This function has been ' - 'moved to \'salt.utils.stringutils.random\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.stringutils.random\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -350,7 +350,7 @@ def contains_whitespace(text): 'Neon', 'Use of \'salt.utils.contains_whitespace\' detected. This function ' 'has been moved to \'salt.utils.stringutils.contains_whitespace\' as ' - 'of Salt Oxygen. This warning will be removed in Salt Neon.', + 'of Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.stringutils.contains_whitespace(text) @@ -365,7 +365,7 @@ def build_whitespace_split_regex(text): 'Use of \'salt.utils.build_whitespace_split_regex\' detected. This ' 'function has been moved to ' '\'salt.utils.stringutils.build_whitespace_split_regex\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.stringutils.build_whitespace_split_regex(text) @@ -379,7 +379,7 @@ def expr_match(line, expr): 'Neon', 'Use of \'salt.utils.expr_match\' detected. This function ' 'has been moved to \'salt.utils.stringutils.expr_match\' as ' - 'of Salt Oxygen. This warning will be removed in Salt Neon.', + 'of Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.stringutils.expr_match(line, expr) @@ -394,7 +394,7 @@ def check_whitelist_blacklist(value, whitelist=None, blacklist=None): 'Use of \'salt.utils.check_whitelist_blacklist\' detected. This ' 'function has been moved to ' '\'salt.utils.stringutils.check_whitelist_blacklist\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.stringutils.check_whitelist_blacklist( @@ -410,7 +410,7 @@ def check_include_exclude(path_str, include_pat=None, exclude_pat=None): 'Use of \'salt.utils.check_include_exclude\' detected. This ' 'function has been moved to ' '\'salt.utils.stringutils.check_include_exclude\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.stringutils.check_include_exclude( @@ -425,7 +425,7 @@ def print_cli(msg, retries=10, step=0.01): 'Neon', 'Use of \'salt.utils.print_cli\' detected. This function ' 'has been moved to \'salt.utils.stringutils.print_cli\' as ' - 'of Salt Oxygen. This warning will be removed in Salt Neon.', + 'of Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.stringutils.print_cli(msg, retries, step) @@ -438,7 +438,7 @@ def clean_kwargs(**kwargs): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.clean_kwargs\' detected. This function has been ' - 'moved to \'salt.utils.args.clean_kwargs\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.args.clean_kwargs\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -452,7 +452,7 @@ def invalid_kwargs(invalid_kwargs, raise_exc=True): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.invalid_kwargs\' detected. This function has ' - 'been moved to \'salt.utils.args.invalid_kwargs\' as of Salt Oxygen. ' + 'been moved to \'salt.utils.args.invalid_kwargs\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -466,7 +466,7 @@ def shlex_split(s, **kwargs): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.shlex_split\' detected. This function has been ' - 'moved to \'salt.utils.args.shlex_split\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.args.shlex_split\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -480,7 +480,7 @@ def arg_lookup(fun, aspec=None): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.arg_lookup\' detected. This function has been ' - 'moved to \'salt.utils.args.arg_lookup\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.args.arg_lookup\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -494,7 +494,7 @@ def argspec_report(functions, module=''): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.argspec_report\' detected. This function has been ' - 'moved to \'salt.utils.args.argspec_report\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.args.argspec_report\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -508,7 +508,7 @@ def split_input(val): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.split_input\' detected. This function has been ' - 'moved to \'salt.utils.args.split_input\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.args.split_input\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -522,7 +522,7 @@ def test_mode(**kwargs): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.test_mode\' detected. This function has been ' - 'moved to \'salt.utils.args.test_mode\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.args.test_mode\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -537,7 +537,7 @@ def format_call(fun, data, initial_ret=None, expected_extra_kws=(), salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.format_call\' detected. This function has been ' - 'moved to \'salt.utils.args.format_call\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.args.format_call\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -552,7 +552,7 @@ def which(exe=None): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.which\' detected. This function has been moved to ' - '\'salt.utils.path.which\' as of Salt Oxygen. This warning will be ' + '\'salt.utils.path.which\' as of Salt 2018.3.0. This warning will be ' 'removed in Salt Neon.', stacklevel=3 ) @@ -566,7 +566,7 @@ def which_bin(exes): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.which_bin\' detected. This function has been ' - 'moved to \'salt.utils.path.which_bin\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.path.which_bin\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -580,7 +580,7 @@ def path_join(*parts, **kwargs): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.path_join\' detected. This function has been ' - 'moved to \'salt.utils.path.join\' as of Salt Oxygen. This warning ' + 'moved to \'salt.utils.path.join\' as of Salt 2018.3.0. This warning ' 'will be removed in Salt Neon.', stacklevel=3 ) @@ -594,7 +594,7 @@ def check_or_die(command): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.check_or_die\' detected. This function has been ' - 'moved to \'salt.utils.path.check_or_die\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.path.check_or_die\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -609,7 +609,7 @@ def sanitize_win_path_string(winpath): 'Neon', 'Use of \'salt.utils.sanitize_win_path_string\' detected. This ' 'function has been moved to \'salt.utils.path.sanitize_win_path\' as ' - 'of Salt Oxygen. This warning will be removed in Salt Neon.', + 'of Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.path.sanitize_win_path(winpath) @@ -622,7 +622,7 @@ def rand_str(size=9999999999, hash_type=None): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.rand_str\' detected. This function has been ' - 'moved to \'salt.utils.hashutils.random_hash\' as of Salt Oxygen. ' + 'moved to \'salt.utils.hashutils.random_hash\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -636,7 +636,7 @@ def get_hash(path, form='sha256', chunk_size=65536): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.get_hash\' detected. This function has been ' - 'moved to \'salt.utils.hashutils.get_hash\' as of Salt Oxygen. ' + 'moved to \'salt.utils.hashutils.get_hash\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -650,7 +650,7 @@ def is_windows(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_windows\' detected. This function has been ' - 'moved to \'salt.utils.platform.is_windows\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.platform.is_windows\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -664,7 +664,7 @@ def is_proxy(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_proxy\' detected. This function has been ' - 'moved to \'salt.utils.platform.is_proxy\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.platform.is_proxy\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -678,7 +678,7 @@ def is_linux(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_linux\' detected. This function has been ' - 'moved to \'salt.utils.platform.is_linux\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.platform.is_linux\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -692,7 +692,7 @@ def is_darwin(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_darwin\' detected. This function has been ' - 'moved to \'salt.utils.platform.is_darwin\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.platform.is_darwin\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -706,7 +706,7 @@ def is_sunos(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_sunos\' detected. This function has been ' - 'moved to \'salt.utils.platform.is_sunos\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.platform.is_sunos\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -720,7 +720,7 @@ def is_smartos(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_smartos\' detected. This function has been ' - 'moved to \'salt.utils.platform.is_smartos\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.platform.is_smartos\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -735,7 +735,7 @@ def is_smartos_globalzone(): 'Neon', 'Use of \'salt.utils.is_smartos_globalzone\' detected. This function ' 'has been moved to \'salt.utils.platform.is_smartos_globalzone\' as ' - 'of Salt Oxygen. This warning will be removed in Salt Neon.', + 'of Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.platform.is_smartos_globalzone() @@ -749,7 +749,7 @@ def is_smartos_zone(): 'Neon', 'Use of \'salt.utils.is_smartos_zone\' detected. This function has ' 'been moved to \'salt.utils.platform.is_smartos_zone\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.platform.is_smartos_zone() @@ -762,7 +762,7 @@ def is_freebsd(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_freebsd\' detected. This function has been ' - 'moved to \'salt.utils.platform.is_freebsd\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.platform.is_freebsd\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -776,7 +776,7 @@ def is_netbsd(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_netbsd\' detected. This function has been ' - 'moved to \'salt.utils.platform.is_netbsd\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.platform.is_netbsd\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -790,7 +790,7 @@ def is_openbsd(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_openbsd\' detected. This function has been ' - 'moved to \'salt.utils.platform.is_openbsd\' as of Salt Oxygen. This ' + 'moved to \'salt.utils.platform.is_openbsd\' as of Salt 2018.3.0. This ' 'warning will be removed in Salt Neon.', stacklevel=3 ) @@ -804,7 +804,7 @@ def is_aix(): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_aix\' detected. This function has been moved to ' - '\'salt.utils.platform.is_aix\' as of Salt Oxygen. This warning will be ' + '\'salt.utils.platform.is_aix\' as of Salt 2018.3.0. This warning will be ' 'removed in Salt Neon.', stacklevel=3 ) @@ -818,7 +818,7 @@ def safe_rm(tgt): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.safe_rm\' detected. This function has been moved to ' - '\'salt.utils.files.safe_rm\' as of Salt Oxygen. This warning will be ' + '\'salt.utils.files.safe_rm\' as of Salt 2018.3.0. This warning will be ' 'removed in Salt Neon.', stacklevel=3 ) @@ -832,7 +832,7 @@ def is_empty(filename): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_empty\' detected. This function has been moved to ' - '\'salt.utils.files.is_empty\' as of Salt Oxygen. This warning will be ' + '\'salt.utils.files.is_empty\' as of Salt 2018.3.0. This warning will be ' 'removed in Salt Neon.', stacklevel=3 ) @@ -846,7 +846,7 @@ def fopen(*args, **kwargs): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.fopen\' detected. This function has been moved to ' - '\'salt.utils.files.fopen\' as of Salt Oxygen. This warning will be ' + '\'salt.utils.files.fopen\' as of Salt 2018.3.0. This warning will be ' 'removed in Salt Neon.', stacklevel=3 ) @@ -860,7 +860,7 @@ def flopen(*args, **kwargs): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.flopen\' detected. This function has been moved to ' - '\'salt.utils.files.flopen\' as of Salt Oxygen. This warning will be ' + '\'salt.utils.files.flopen\' as of Salt 2018.3.0. This warning will be ' 'removed in Salt Neon.', stacklevel=3 ) @@ -874,7 +874,7 @@ def fpopen(*args, **kwargs): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.fpopen\' detected. This function has been moved to ' - '\'salt.utils.files.fpopen\' as of Salt Oxygen. This warning will be ' + '\'salt.utils.files.fpopen\' as of Salt 2018.3.0. This warning will be ' 'removed in Salt Neon.', stacklevel=3 ) @@ -888,7 +888,7 @@ def rm_rf(path): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.rm_rf\' detected. This function has been moved to ' - '\'salt.utils.files.rm_rf\' as of Salt Oxygen. This warning will be ' + '\'salt.utils.files.rm_rf\' as of Salt 2018.3.0. This warning will be ' 'removed in Salt Neon.', stacklevel=3 ) @@ -902,7 +902,7 @@ def mkstemp(*args, **kwargs): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.mkstemp\' detected. This function has been moved to ' - '\'salt.utils.files.mkstemp\' as of Salt Oxygen. This warning will be ' + '\'salt.utils.files.mkstemp\' as of Salt 2018.3.0. This warning will be ' 'removed in Salt Neon.', stacklevel=3 ) @@ -917,7 +917,7 @@ def istextfile(fp_, blocksize=512): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.istextfile\' detected. This function has been moved ' - 'to \'salt.utils.files.is_text_file\' as of Salt Oxygen. This warning will ' + 'to \'salt.utils.files.is_text_file\' as of Salt 2018.3.0. This warning will ' 'be removed in Salt Neon.', stacklevel=3 ) @@ -932,7 +932,7 @@ def is_bin_file(path): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.is_bin_file\' detected. This function has been moved ' - 'to \'salt.utils.files.is_binary\' as of Salt Oxygen. This warning will ' + 'to \'salt.utils.files.is_binary\' as of Salt 2018.3.0. This warning will ' 'be removed in Salt Neon.', stacklevel=3 ) @@ -947,7 +947,7 @@ def list_files(directory): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.list_files\' detected. This function has been moved ' - 'to \'salt.utils.files.list_files\' as of Salt Oxygen. This warning will ' + 'to \'salt.utils.files.list_files\' as of Salt 2018.3.0. This warning will ' 'be removed in Salt Neon.', stacklevel=3 ) @@ -962,7 +962,7 @@ def safe_walk(top, topdown=True, onerror=None, followlinks=True, _seen=None): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.safe_walk\' detected. This function has been moved ' - 'to \'salt.utils.files.safe_walk\' as of Salt Oxygen. This warning will ' + 'to \'salt.utils.files.safe_walk\' as of Salt 2018.3.0. This warning will ' 'be removed in Salt Neon.', stacklevel=3 ) @@ -978,7 +978,7 @@ def st_mode_to_octal(mode): 'Neon', 'Use of \'salt.utils.st_mode_to_octal\' detected. This function has ' 'been moved to \'salt.utils.files.st_mode_to_octal\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.files.st_mode_to_octal(mode) @@ -992,7 +992,7 @@ def normalize_mode(mode): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.normalize_mode\' detected. This function has ' - 'been moved to \'salt.utils.files.normalize_mode\' as of Salt Oxygen. ' + 'been moved to \'salt.utils.files.normalize_mode\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -1008,7 +1008,7 @@ def human_size_to_bytes(human_size): 'Neon', 'Use of \'salt.utils.human_size_to_bytes\' detected. This function has ' 'been moved to \'salt.utils.files.human_size_to_bytes\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.files.human_size_to_bytes(human_size) @@ -1023,7 +1023,7 @@ def backup_minion(path, bkroot): 'Neon', 'Use of \'salt.utils.backup_minion\' detected. This function has ' 'been moved to \'salt.utils.files.backup_minion\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.files.backup_minion(path, bkroot) @@ -1037,7 +1037,7 @@ def str_version_to_evr(verstring): 'Neon', 'Use of \'salt.utils.str_version_to_evr\' detected. This function has ' 'been moved to \'salt.utils.pkg.rpm.version_to_evr\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.pkg.rpm.version_to_evr(verstring) @@ -1050,7 +1050,7 @@ def parse_docstring(docstring): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.parse_docstring\' detected. This function has ' - 'been moved to \'salt.utils.doc.parse_docstring\' as of Salt Oxygen. ' + 'been moved to \'salt.utils.doc.parse_docstring\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -1063,7 +1063,7 @@ def compare_versions(ver1='', oper='==', ver2='', cmp_func=None, ignore_epoch=Fa salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.compare_versions\' detected. This function has ' - 'been moved to \'salt.utils.versions.compare\' as of Salt Oxygen. ' + 'been moved to \'salt.utils.versions.compare\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -1080,7 +1080,7 @@ def version_cmp(pkg1, pkg2, ignore_epoch=False): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.version_cmp\' detected. This function has ' - 'been moved to \'salt.utils.versions.version_cmp\' as of Salt Oxygen. ' + 'been moved to \'salt.utils.versions.version_cmp\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -1101,7 +1101,7 @@ def warn_until(version, 'Neon', 'Use of \'salt.utils.warn_until\' detected. This function has ' 'been moved to \'salt.utils.versions.warn_until\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.versions.warn_until(version, @@ -1124,7 +1124,7 @@ def kwargs_warn_until(kwargs, 'Neon', 'Use of \'salt.utils.kwargs_warn_until\' detected. This function has ' 'been moved to \'salt.utils.versions.kwargs_warn_until\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.versions.kwargs_warn_until( @@ -1145,7 +1145,7 @@ def get_color_theme(theme): 'Neon', 'Use of \'salt.utils.get_color_theme\' detected. This function has ' 'been moved to \'salt.utils.color.get_color_theme\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.color.get_color_theme(theme) @@ -1160,7 +1160,7 @@ def get_colors(use=True, theme=None): 'Neon', 'Use of \'salt.utils.get_colors\' detected. This function has ' 'been moved to \'salt.utils.color.get_colors\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.color.get_colors(use=use, theme=theme) @@ -1173,7 +1173,7 @@ def gen_state_tag(low): salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.gen_state_tag\' detected. This function has been ' - 'moved to \'salt.utils.state.gen_tag\' as of Salt Oxygen. This warning ' + 'moved to \'salt.utils.state.gen_tag\' as of Salt 2018.3.0. This warning ' 'will be removed in Salt Neon.', stacklevel=3 ) @@ -1188,7 +1188,7 @@ def search_onfail_requisites(sid, highstate): 'Neon', 'Use of \'salt.utils.search_onfail_requisites\' detected. This function ' 'has been moved to \'salt.utils.state.search_onfail_requisites\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.state.search_onfail_requisites(sid, highstate) @@ -1202,7 +1202,7 @@ def check_onfail_requisites(state_id, state_result, running, highstate): 'Neon', 'Use of \'salt.utils.check_onfail_requisites\' detected. This function ' 'has been moved to \'salt.utils.state.check_onfail_requisites\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.state.check_onfail_requisites( @@ -1218,7 +1218,7 @@ def check_state_result(running, recurse=False, highstate=None): 'Neon', 'Use of \'salt.utils.check_state_result\' detected. This function ' 'has been moved to \'salt.utils.state.check_result\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.state.check_result( @@ -1234,7 +1234,7 @@ def get_user(): 'Neon', 'Use of \'salt.utils.get_user\' detected. This function ' 'has been moved to \'salt.utils.user.get_user\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.get_user() @@ -1248,7 +1248,7 @@ def get_uid(user=None): 'Neon', 'Use of \'salt.utils.get_uid\' detected. This function ' 'has been moved to \'salt.utils.user.get_uid\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.get_uid(user) @@ -1262,7 +1262,7 @@ def get_specific_user(): 'Neon', 'Use of \'salt.utils.get_specific_user\' detected. This function ' 'has been moved to \'salt.utils.user.get_specific_user\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.get_specific_user() @@ -1276,7 +1276,7 @@ def chugid(runas): 'Neon', 'Use of \'salt.utils.chugid\' detected. This function ' 'has been moved to \'salt.utils.user.chugid\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.chugid(runas) @@ -1290,7 +1290,7 @@ def chugid_and_umask(runas, umask): 'Neon', 'Use of \'salt.utils.chugid_and_umask\' detected. This function ' 'has been moved to \'salt.utils.user.chugid_and_umask\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.chugid_and_umask(runas, umask) @@ -1304,7 +1304,7 @@ def get_default_group(user): 'Neon', 'Use of \'salt.utils.get_default_group\' detected. This function ' 'has been moved to \'salt.utils.user.get_default_group\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.get_default_group(user) @@ -1318,7 +1318,7 @@ def get_group_list(user, include_default=True): 'Neon', 'Use of \'salt.utils.get_group_list\' detected. This function ' 'has been moved to \'salt.utils.user.get_group_list\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.get_group_list(user, include_default) @@ -1332,7 +1332,7 @@ def get_group_dict(user=None, include_default=True): 'Neon', 'Use of \'salt.utils.get_group_dict\' detected. This function ' 'has been moved to \'salt.utils.user.get_group_dict\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.get_group_dict(user, include_default) @@ -1346,7 +1346,7 @@ def get_gid_list(user, include_default=True): 'Neon', 'Use of \'salt.utils.get_gid_list\' detected. This function ' 'has been moved to \'salt.utils.user.get_gid_list\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.get_gid_list(user, include_default) @@ -1360,7 +1360,7 @@ def get_gid(group=None): 'Neon', 'Use of \'salt.utils.get_gid\' detected. This function ' 'has been moved to \'salt.utils.user.get_gid\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.user.get_gid(group) @@ -1375,7 +1375,7 @@ def enable_ctrl_logoff_handler(): 'Use of \'salt.utils.enable_ctrl_logoff_handler\' detected. This ' 'function has been moved to ' '\'salt.utils.win_functions.enable_ctrl_logoff_handler\' as of Salt ' - 'Oxygen. This warning will be removed in Salt Neon.', + '2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.win_functions.enable_ctrl_logoff_handler() @@ -1389,7 +1389,7 @@ def traverse_dict(data, key, default=None, delimiter=DEFAULT_TARGET_DELIM): 'Neon', 'Use of \'salt.utils.traverse_dict\' detected. This function ' 'has been moved to \'salt.utils.data.traverse_dict\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.traverse_dict(data, key, default, delimiter) @@ -1403,7 +1403,7 @@ def traverse_dict_and_list(data, key, default=None, delimiter=DEFAULT_TARGET_DEL 'Neon', 'Use of \'salt.utils.traverse_dict_and_list\' detected. This function ' 'has been moved to \'salt.utils.data.traverse_dict_and_list\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.traverse_dict_and_list(data, key, default, delimiter) @@ -1422,7 +1422,7 @@ def filter_by(lookup_dict, 'Neon', 'Use of \'salt.utils.filter_by\' detected. This function ' 'has been moved to \'salt.utils.data.filter_by\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.filter_by( @@ -1441,7 +1441,7 @@ def subdict_match(data, 'Neon', 'Use of \'salt.utils.subdict_match\' detected. This function ' 'has been moved to \'salt.utils.data.subdict_match\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.subdict_match( @@ -1456,7 +1456,7 @@ def substr_in_list(string_to_search_for, list_to_search): 'Neon', 'Use of \'salt.utils.substr_in_list\' detected. This function ' 'has been moved to \'salt.utils.data.substr_in_list\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.substr_in_list(string_to_search_for, list_to_search) @@ -1470,7 +1470,7 @@ def is_dictlist(data): 'Neon', 'Use of \'salt.utils.is_dictlist\' detected. This function ' 'has been moved to \'salt.utils.data.is_dictlist\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.is_dictlist(data) @@ -1488,7 +1488,7 @@ def repack_dictlist(data, 'Neon', 'Use of \'salt.utils.is_dictlist\' detected. This function ' 'has been moved to \'salt.utils.data.is_dictlist\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.repack_dictlist(data, strict, recurse, key_cb, val_cb) @@ -1502,7 +1502,7 @@ def compare_dicts(old=None, new=None): 'Neon', 'Use of \'salt.utils.compare_dicts\' detected. This function ' 'has been moved to \'salt.utils.data.compare_dicts\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.compare_dicts(old, new) @@ -1516,7 +1516,7 @@ def compare_lists(old=None, new=None): 'Neon', 'Use of \'salt.utils.compare_lists\' detected. This function ' 'has been moved to \'salt.utils.data.compare_lists\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.compare_lists(old, new) @@ -1531,7 +1531,7 @@ def decode_dict(data): 'Neon', 'Use of \'salt.utils.decode_dict\' detected. This function ' 'has been moved to \'salt.utils.data.encode_dict\' as of ' - 'Salt Oxygen. Note that the new name is "encode_dict", as this ' + 'Salt 2018.3.0. Note that the new name is "encode_dict", as this ' 'function was erroneously named when initially added. This ' 'warning will be removed in Salt Neon.', stacklevel=3 @@ -1547,7 +1547,7 @@ def decode_list(data): 'Neon', 'Use of \'salt.utils.decode_list\' detected. This function ' 'has been moved to \'salt.utils.data.encode_list\' as of ' - 'Salt Oxygen. Note that the new name is "encode_list", as this ' + 'Salt 2018.3.0. Note that the new name is "encode_list", as this ' 'function was erroneously named when initially added. This ' 'warning will be removed in Salt Neon.', stacklevel=3 @@ -1563,7 +1563,7 @@ def exactly_n(l, n=1): 'Neon', 'Use of \'salt.utils.exactly_n\' detected. This function ' 'has been moved to \'salt.utils.data.exactly_n\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.exactly_n(l, n) @@ -1577,7 +1577,7 @@ def exactly_one(l): 'Neon', 'Use of \'salt.utils.exactly_one\' detected. This function ' 'has been moved to \'salt.utils.data.exactly_one\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.exactly_one(l) @@ -1591,7 +1591,7 @@ def is_list(value): 'Neon', 'Use of \'salt.utils.is_list\' detected. This function ' 'has been moved to \'salt.utils.data.is_list\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.is_list(value) @@ -1605,7 +1605,7 @@ def is_iter(y, ignore=six.string_types): 'Neon', 'Use of \'salt.utils.is_iter\' detected. This function ' 'has been moved to \'salt.utils.data.is_iter\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.is_iter(y, ignore) @@ -1619,7 +1619,7 @@ def isorted(to_sort): 'Neon', 'Use of \'salt.utils.isorted\' detected. This function ' 'has been moved to \'salt.utils.data.sorted_ignorecase\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.sorted_ignorecase(to_sort) @@ -1633,7 +1633,7 @@ def is_true(value=None): 'Neon', 'Use of \'salt.utils.is_true\' detected. This function ' 'has been moved to \'salt.utils.data.is_true\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.is_true(value) @@ -1647,7 +1647,7 @@ def mysql_to_dict(data, key): 'Neon', 'Use of \'salt.utils.mysql_to_dict\' detected. This function ' 'has been moved to \'salt.utils.data.mysql_to_dict\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.mysql_to_dict(data, key) @@ -1661,7 +1661,7 @@ def simple_types_filter(data): 'Neon', 'Use of \'salt.utils.simple_types_filter\' detected. This function ' 'has been moved to \'salt.utils.data.simple_types_filter\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.data.simple_types_filter(data) @@ -1675,7 +1675,7 @@ def ip_bracket(addr): 'Neon', 'Use of \'salt.utils.ip_bracket\' detected. This function ' 'has been moved to \'salt.utils.zeromq.ip_bracket\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.zeromq.ip_bracket(addr) @@ -1689,7 +1689,7 @@ def gen_mac(prefix='AC:DE:48'): 'Neon', 'Use of \'salt.utils.gen_mac\' detected. This function ' 'has been moved to \'salt.utils.network.gen_mac\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.network.gen_mac(prefix) @@ -1703,7 +1703,7 @@ def mac_str_to_bytes(mac_str): 'Neon', 'Use of \'salt.utils.mac_str_to_bytes\' detected. This function ' 'has been moved to \'salt.utils.network.mac_str_to_bytes\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.network.mac_str_to_bytes(mac_str) @@ -1717,7 +1717,7 @@ def refresh_dns(): 'Neon', 'Use of \'salt.utils.refresh_dns\' detected. This function ' 'has been moved to \'salt.utils.network.refresh_dns\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.network.refresh_dns() @@ -1731,7 +1731,7 @@ def dns_check(addr, port, safe=False, ipv6=None): 'Neon', 'Use of \'salt.utils.dns_check\' detected. This function ' 'has been moved to \'salt.utils.network.dns_check\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.network.dns_check(addr, port, safe, ipv6) @@ -1740,15 +1740,15 @@ def dns_check(addr, port, safe=False, ipv6=None): def get_context(template, line, num_lines=5, marker=None): # Late import to avoid circular import. import salt.utils.versions - import salt.utils.templates + import salt.utils.stringutils salt.utils.versions.warn_until( 'Neon', 'Use of \'salt.utils.get_context\' detected. This function ' - 'has been moved to \'salt.utils.templates.get_context\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'has been moved to \'salt.utils.stringutils.get_context\' as of ' + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) - return salt.utils.templates.get_context(template, line, num_lines, marker) + return salt.utils.stringutils.get_context(template, line, num_lines, marker) def get_master_key(key_user, opts, skip_perm_errors=False): @@ -1759,7 +1759,7 @@ def get_master_key(key_user, opts, skip_perm_errors=False): 'Neon', 'Use of \'salt.utils.get_master_key\' detected. This function ' 'has been moved to \'salt.utils.master.get_master_key\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.master.get_master_key(key_user, opts, skip_perm_errors) @@ -1773,7 +1773,7 @@ def get_values_of_matching_keys(pattern_dict, user_name): 'Neon', 'Use of \'salt.utils.get_values_of_matching_keys\' detected. ' 'This function has been moved to ' - '\'salt.utils.master.get_values_of_matching_keys\' as of Salt Oxygen. ' + '\'salt.utils.master.get_values_of_matching_keys\' as of Salt 2018.3.0. ' 'This warning will be removed in Salt Neon.', stacklevel=3 ) @@ -1788,7 +1788,7 @@ def date_cast(date): 'Neon', 'Use of \'salt.utils.date_cast\' detected. This function ' 'has been moved to \'salt.utils.dateutils.date_cast\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.dateutils.date_cast(date) @@ -1802,7 +1802,7 @@ def date_format(date=None, format="%Y-%m-%d"): 'Neon', 'Use of \'salt.utils.date_format\' detected. This function ' 'has been moved to \'salt.utils.dateutils.strftime\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.dateutils.strftime(date, format) @@ -1816,7 +1816,7 @@ def total_seconds(td): 'Neon', 'Use of \'salt.utils.total_seconds\' detected. This function ' 'has been moved to \'salt.utils.dateutils.total_seconds\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.dateutils.total_seconds(td) @@ -1830,7 +1830,7 @@ def find_json(raw): 'Neon', 'Use of \'salt.utils.find_json\' detected. This function ' 'has been moved to \'salt.utils.json.find_json\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.json.find_json(raw) @@ -1844,7 +1844,7 @@ def import_json(): 'Neon', 'Use of \'salt.utils.import_json\' detected. This function ' 'has been moved to \'salt.utils.json.import_json\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.json.import_json() @@ -1859,7 +1859,7 @@ def namespaced_function(function, global_dict, defaults=None, 'Neon', 'Use of \'salt.utils.namespaced_function\' detected. This function ' 'has been moved to \'salt.utils.functools.namespaced_function\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.functools.namespaced_function( @@ -1874,7 +1874,7 @@ def alias_function(fun, name, doc=None): 'Neon', 'Use of \'salt.utils.alias_function\' detected. This function ' 'has been moved to \'salt.utils.functools.alias_function\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.functools.alias_function(fun, name, doc) @@ -1888,7 +1888,7 @@ def profile_func(filename=None): 'Neon', 'Use of \'salt.utils.profile_func\' detected. This function ' 'has been moved to \'salt.utils.profile.profile_func\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.profile.profile_func(filename) @@ -1902,7 +1902,7 @@ def activate_profile(test=True): 'Neon', 'Use of \'salt.utils.activate_profile\' detected. This function ' 'has been moved to \'salt.utils.profile.activate_profile\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.profile.activate_profile(test) @@ -1916,7 +1916,7 @@ def output_profile(pr, stats_path='/tmp/stats', stop=False, id_=None): 'Neon', 'Use of \'salt.utils.output_profile\' detected. This function ' 'has been moved to \'salt.utils.profile.output_profile\' as of ' - 'Salt Oxygen. This warning will be removed in Salt Neon.', + 'Salt 2018.3.0. This warning will be removed in Salt Neon.', stacklevel=3 ) return salt.utils.profile.output_profile(pr, stats_path, stop, id_) diff --git a/salt/utils/args.py b/salt/utils/args.py index 29ba3d8211..f2c9a10d51 100644 --- a/salt/utils/args.py +++ b/salt/utils/args.py @@ -14,7 +14,7 @@ import shlex # Import salt libs from salt.exceptions import SaltInvocationError from salt.ext import six -from salt.ext.six.moves import zip # pylint: disable=import-error,redefined-builtin +from salt.ext.six.moves import map, zip # pylint: disable=import-error,redefined-builtin import salt.utils.data import salt.utils.jid import salt.utils.versions @@ -269,7 +269,13 @@ def shlex_split(s, **kwargs): Only split if variable is a string ''' if isinstance(s, six.string_types): - return shlex.split(s, **kwargs) + # On PY2, shlex.split will fail with unicode types if there are + # non-ascii characters in the string. So, we need to make sure we + # invoke it with a str type, and then decode the resulting string back + # to unicode to return it. + return salt.utils.data.decode( + shlex.split(salt.utils.stringutils.to_str(s), **kwargs) + ) else: return s @@ -333,16 +339,18 @@ def argspec_report(functions, module=''): return ret -def split_input(val): +def split_input(val, mapper=None): ''' Take an input value and split it into a list, returning the resulting list ''' + if mapper is None: + mapper = lambda x: x if isinstance(val, list): - return val + return list(map(mapper, val)) try: - return [x.strip() for x in val.split(',')] + return list(map(mapper, [x.strip() for x in val.split(',')])) except AttributeError: - return [x.strip() for x in six.text_type(val).split(',')] + return list(map(mapper, [x.strip() for x in six.text_type(val).split(',')])) def test_mode(**kwargs): diff --git a/salt/utils/async.py b/salt/utils/async.py index 0b5f33bf13..55d21d0ccc 100644 --- a/salt/utils/async.py +++ b/salt/utils/async.py @@ -7,19 +7,8 @@ from __future__ import absolute_import, print_function, unicode_literals import tornado.ioloop import tornado.concurrent -# attempt to use zmq-- if we have it otherwise fallback to tornado loop -try: - import zmq.eventloop.ioloop - # support pyzmq 13.0.x, TODO: remove once we force people to 14.0.x - if not hasattr(zmq.eventloop.ioloop, 'ZMQIOLoop'): - zmq.eventloop.ioloop.ZMQIOLoop = zmq.eventloop.ioloop.IOLoop - LOOP_CLASS = zmq.eventloop.ioloop.ZMQIOLoop - HAS_ZMQ = True -except ImportError: - LOOP_CLASS = tornado.ioloop.IOLoop - HAS_ZMQ = False - import contextlib +from salt.utils import zeromq @contextlib.contextmanager @@ -53,7 +42,7 @@ class SyncWrapper(object): if kwargs is None: kwargs = {} - self.io_loop = LOOP_CLASS() + self.io_loop = zeromq.ZMQDefaultLoop() kwargs['io_loop'] = self.io_loop with current_ioloop(self.io_loop): diff --git a/salt/utils/azurearm.py b/salt/utils/azurearm.py index 5985dc3efb..a40f660fae 100644 --- a/salt/utils/azurearm.py +++ b/salt/utils/azurearm.py @@ -7,24 +7,38 @@ Azure (ARM) Utilities :maintainer: :maturity: new :depends: - * `Microsoft Azure SDK for Python `_ >= 2.0rc6 - * `AutoRest swagger generator Python client runtime (Azure-specific module) `_ >= 0.4 + * `azure `_ >= 2.0.0rc6 + * `azure-common `_ >= 1.1.4 + * `azure-mgmt `_ >= 0.30.0rc6 + * `azure-mgmt-compute `_ >= 0.33.0 + * `azure-mgmt-network `_ >= 0.30.0rc6 + * `azure-mgmt-resource `_ >= 0.30.0 + * `azure-mgmt-storage `_ >= 0.30.0rc6 + * `azure-mgmt-web `_ >= 0.30.0rc6 + * `azure-storage `_ >= 0.32.0 + * `msrestazure `_ >= 0.4.21 :platform: linux ''' # Import Python libs from __future__ import absolute_import, print_function, unicode_literals +from operator import itemgetter import importlib import logging import sys # Import Salt libs import salt.config +import salt.ext.six as six import salt.loader import salt.version from salt.exceptions import ( SaltInvocationError, SaltSystemExit ) +try: + from salt.ext.six.moves import range as six_range +except ImportError: + six_range = range # Import third party libs try: @@ -58,7 +72,7 @@ def _determine_auth(**kwargs): ''' Acquire Azure ARM Credentials ''' - if 'profile' in kwargs.keys(): + if 'profile' in kwargs: azure_credentials = __salt__['config.option'](kwargs['profile']) kwargs.update(azure_credentials) @@ -75,23 +89,35 @@ def _determine_auth(**kwargs): raise sys.exit('The Azure cloud environment {0} is not available.'.format(kwargs['cloud_environment'])) if set(service_principal_creds_kwargs).issubset(kwargs): - credentials = ServicePrincipalCredentials(kwargs['client_id'], - kwargs['secret'], - tenant=kwargs['tenant'], - cloud_environment=cloud_env) + if not (kwargs['client_id'] and kwargs['secret'] and kwargs['tenant']): + raise SaltInvocationError( + 'The client_id, secret, and tenant parameters must all be ' + 'populated if using service principals.' + ) + else: + credentials = ServicePrincipalCredentials(kwargs['client_id'], + kwargs['secret'], + tenant=kwargs['tenant'], + cloud_environment=cloud_env) elif set(user_pass_creds_kwargs).issubset(kwargs): - credentials = UserPassCredentials(kwargs['username'], - kwargs['password'], - cloud_environment=cloud_env) + if not (kwargs['username'] and kwargs['password']): + raise SaltInvocationError( + 'The username and password parameters must both be ' + 'populated if using username/password authentication.' + ) + else: + credentials = UserPassCredentials(kwargs['username'], + kwargs['password'], + cloud_environment=cloud_env) else: raise SaltInvocationError( - 'Unable to do determine credentials. ' + 'Unable to determine credentials. ' 'A subscription_id with username and password, ' 'or client_id, secret, and tenant or a profile with the ' 'required parameters populated' ) - if 'subscription_id' not in kwargs.keys(): + if 'subscription_id' not in kwargs: raise SaltInvocationError( 'A subscription_id must be specified' ) @@ -108,11 +134,12 @@ def get_client(client_type, **kwargs): client_map = {'compute': 'ComputeManagement', 'storage': 'StorageManagement', 'network': 'NetworkManagement', + 'policy': 'Policy', 'resource': 'ResourceManagement', 'subscription': 'Subscription', 'web': 'WebSiteManagement'} - if client_type not in client_map.keys(): + if client_type not in client_map: raise SaltSystemExit( 'The Azure ARM client_type {0} specified can not be found.'.format( client_type) @@ -120,7 +147,7 @@ def get_client(client_type, **kwargs): map_value = client_map[client_type] - if client_type == 'subscription': + if client_type == 'subscription' or client_type == 'policy': module_name = 'resource' else: module_name = client_type @@ -154,11 +181,16 @@ def get_client(client_type, **kwargs): return client -def log_cloud_error(client, message): +def log_cloud_error(client, message, **kwargs): ''' Log an azurearm cloud error exception ''' - log.error( + try: + cloud_logger = getattr(log, kwargs.get('azurearm_log_level')) + except (AttributeError, TypeError): + cloud_logger = getattr(log, 'error') + + cloud_logger( 'An AzureARM %s CloudError has occurred: %s', client.capitalize(), message @@ -182,3 +214,103 @@ def paged_object_to_list(paged_object): break return paged_return + + +def create_object_model(module_name, object_name, **kwargs): + ''' + Assemble an object from incoming parameters. + ''' + object_kwargs = {} + + try: + model_module = importlib.import_module('azure.mgmt.{0}.models'.format(module_name)) + # pylint: disable=invalid-name + Model = getattr(model_module, object_name) + except ImportError: + raise sys.exit( + 'The {0} model in the {1} Azure module is not available.'.format(object_name, module_name) + ) + + if '_attribute_map' in dir(Model): + for attr, items in Model._attribute_map.items(): + param = kwargs.get(attr) + if param: + if items['type'][0].isupper() and isinstance(param, dict): + object_kwargs[attr] = create_object_model(module_name, items['type'], **param) + elif items['type'][0] == '{' and isinstance(param, dict): + object_kwargs[attr] = param + elif items['type'][0] == '[' and isinstance(param, list): + obj_list = [] + for list_item in param: + if items['type'][1].isupper() and isinstance(list_item, dict): + obj_list.append( + create_object_model( + module_name, + items['type'][items['type'].index('[')+1:items['type'].rindex(']')], + **list_item + ) + ) + elif items['type'][1] == '{' and isinstance(list_item, dict): + obj_list.append(list_item) + elif not items['type'][1].isupper() and items['type'][1] != '{': + obj_list.append(list_item) + object_kwargs[attr] = obj_list + else: + object_kwargs[attr] = param + + # wrap calls to this function to catch TypeError exceptions + return Model(**object_kwargs) + + +def compare_list_of_dicts(old, new, convert_id_to_name=None): + ''' + Compare lists of dictionaries representing Azure objects. Only keys found in the "new" dictionaries are compared to + the "old" dictionaries, since getting Azure objects from the API returns some read-only data which should not be + used in the comparison. A list of parameter names can be passed in order to compare a bare object name to a full + Azure ID path for brevity. If string types are found in values, comparison is case insensitive. Return comment + should be used to trigger exit from the calling function. + ''' + ret = {} + + if not convert_id_to_name: + convert_id_to_name = [] + + if not isinstance(new, list): + ret['comment'] = 'must be provided as a list of dictionaries!' + return ret + + if len(new) != len(old): + ret['changes'] = { + 'old': old, + 'new': new + } + return ret + + try: + local_configs, remote_configs = [sorted(config, key=itemgetter('name')) for config in (new, old)] + except TypeError: + ret['comment'] = 'configurations must be provided as a list of dictionaries!' + return ret + except KeyError: + ret['comment'] = 'configuration dictionaries must contain the "name" key!' + return ret + + for idx in six_range(0, len(local_configs)): + for key in local_configs[idx]: + local_val = local_configs[idx][key] + if key in convert_id_to_name: + remote_val = remote_configs[idx].get(key, {}).get('id', '').split('/')[-1] + else: + remote_val = remote_configs[idx].get(key) + if isinstance(local_val, six.string_types): + local_val = local_val.lower() + if isinstance(remote_val, six.string_types): + remote_val = remote_val.lower() + if local_val != remote_val: + ret['changes'] = { + 'old': remote_configs, + 'new': local_configs + } + return ret + + return ret diff --git a/salt/utils/cache.py b/salt/utils/cache.py index 6350b37fe2..6581af9f87 100644 --- a/salt/utils/cache.py +++ b/salt/utils/cache.py @@ -23,11 +23,7 @@ import salt.utils.files # Import third party libs from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin -try: - import zmq - HAS_ZMQ = True -except ImportError: - HAS_ZMQ = False +from salt.utils.zeromq import zmq log = logging.getLogger(__name__) diff --git a/salt/utils/data.py b/salt/utils/data.py index fff01964f8..2dcca51be8 100644 --- a/salt/utils/data.py +++ b/salt/utils/data.py @@ -68,7 +68,7 @@ def compare_lists(old=None, new=None): def decode(data, encoding=None, errors='strict', keep=False, - preserve_dict_class=False, preserve_tuples=False): + normalize=False, preserve_dict_class=False, preserve_tuples=False): ''' Generic function which will decode whichever type is passed, if necessary @@ -77,22 +77,43 @@ def decode(data, encoding=None, errors='strict', keep=False, original value to silently be returned in cases where decoding fails. This can be useful for cases where the data passed to this function is likely to contain binary blobs, such as in the case of cp.recv. + + If `normalize` is True, then unicodedata.normalize() will be used to + normalize unicode strings down to a single code point per glyph. It is + recommended not to normalize unless you know what you're doing. For + instance, if `data` contains a dictionary, it is possible that normalizing + will lead to data loss because the following two strings will normalize to + the same value: + + - u'\\u044f\\u0438\\u0306\\u0446\\u0430.txt' + - u'\\u044f\\u0439\\u0446\\u0430.txt' + + One good use case for normalization is in the test suite. For example, on + some platforms such as Mac OS, os.listdir() will produce the first of the + two strings above, in which "й" is represented as two code points (i.e. one + for the base character, and one for the breve mark). Normalizing allows for + a more reliable test case. ''' if isinstance(data, collections.Mapping): - return decode_dict(data, encoding, errors, keep, + return decode_dict(data, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) elif isinstance(data, list): - return decode_list(data, encoding, errors, keep, + return decode_list(data, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) elif isinstance(data, tuple): - return decode_tuple(data, encoding, errors, keep, preserve_dict_class) \ + return decode_tuple(data, encoding, errors, keep, normalize, + preserve_dict_class) \ if preserve_tuples \ - else decode_list(data, encoding, errors, keep, + else decode_list(data, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) else: try: - return salt.utils.stringutils.to_unicode(data, encoding, errors) + data = salt.utils.stringutils.to_unicode( + data, encoding, errors, normalize) except TypeError: + # to_unicode raises a TypeError when input is not a + # string/bytestring/bytearray. This is expected and simply means we + # are going to leave the value as-is. pass except UnicodeDecodeError: if not keep: @@ -101,7 +122,8 @@ def decode(data, encoding=None, errors='strict', keep=False, def decode_dict(data, encoding=None, errors='strict', keep=False, - preserve_dict_class=False, preserve_tuples=False): + normalize=False, preserve_dict_class=False, + preserve_tuples=False): ''' Decode all string values to Unicode ''' @@ -109,34 +131,44 @@ def decode_dict(data, encoding=None, errors='strict', keep=False, rv = data.__class__() if preserve_dict_class else {} for key, value in six.iteritems(data): if isinstance(key, tuple): - key = decode_tuple(key, encoding, errors, keep, preserve_dict_class) \ + key = decode_tuple(key, encoding, errors, keep, normalize, + preserve_dict_class) \ if preserve_tuples \ - else decode_list(key, encoding, errors, keep, + else decode_list(key, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) else: try: - key = salt.utils.stringutils.to_unicode(key, encoding, errors) + key = salt.utils.stringutils.to_unicode( + key, encoding, errors, normalize) except TypeError: + # to_unicode raises a TypeError when input is not a + # string/bytestring/bytearray. This is expected and simply + # means we are going to leave the value as-is. pass except UnicodeDecodeError: if not keep: raise if isinstance(value, list): - value = decode_list(value, encoding, errors, keep, + value = decode_list(value, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) elif isinstance(value, tuple): - value = decode_tuple(value, encoding, errors, keep, preserve_dict_class) \ + value = decode_tuple(value, encoding, errors, keep, normalize, + preserve_dict_class) \ if preserve_tuples \ - else decode_list(value, encoding, errors, keep, + else decode_list(value, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) elif isinstance(value, collections.Mapping): - value = decode_dict(value, encoding, errors, keep, + value = decode_dict(value, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) else: try: - value = salt.utils.stringutils.to_unicode(value, encoding, errors) + value = salt.utils.stringutils.to_unicode( + value, encoding, errors, normalize) except TypeError: + # to_unicode raises a TypeError when input is not a + # string/bytestring/bytearray. This is expected and simply + # means we are going to leave the value as-is. pass except UnicodeDecodeError: if not keep: @@ -147,27 +179,33 @@ def decode_dict(data, encoding=None, errors='strict', keep=False, def decode_list(data, encoding=None, errors='strict', keep=False, - preserve_dict_class=False, preserve_tuples=False): + normalize=False, preserve_dict_class=False, + preserve_tuples=False): ''' Decode all string values to Unicode ''' rv = [] for item in data: if isinstance(item, list): - item = decode_list(item, encoding, errors, keep, + item = decode_list(item, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) elif isinstance(item, tuple): - item = decode_tuple(item, encoding, errors, keep, preserve_dict_class) \ + item = decode_tuple(item, encoding, errors, keep, normalize, + preserve_dict_class) \ if preserve_tuples \ - else decode_list(item, encoding, errors, keep, + else decode_list(item, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) elif isinstance(item, collections.Mapping): - item = decode_dict(item, encoding, errors, keep, + item = decode_dict(item, encoding, errors, keep, normalize, preserve_dict_class, preserve_tuples) else: try: - item = salt.utils.stringutils.to_unicode(item, encoding, errors) + item = salt.utils.stringutils.to_unicode( + item, encoding, errors, normalize) except TypeError: + # to_unicode raises a TypeError when input is not a + # string/bytestring/bytearray. This is expected and simply + # means we are going to leave the value as-is. pass except UnicodeDecodeError: if not keep: @@ -178,12 +216,14 @@ def decode_list(data, encoding=None, errors='strict', keep=False, def decode_tuple(data, encoding=None, errors='strict', keep=False, - preserve_dict_class=False): + normalize=False, preserve_dict_class=False): ''' Decode all string values to Unicode ''' return tuple( - decode_list(data, encoding, errors, keep, preserve_dict_class, True)) + decode_list(data, encoding, errors, keep, normalize, + preserve_dict_class, True) + ) def encode(data, encoding=None, errors='strict', keep=False, @@ -212,6 +252,9 @@ def encode(data, encoding=None, errors='strict', keep=False, try: return salt.utils.stringutils.to_bytes(data, encoding, errors) except TypeError: + # to_bytes raises a TypeError when input is not a + # string/bytestring/bytearray. This is expected and simply + # means we are going to leave the value as-is. pass except UnicodeEncodeError: if not keep: @@ -237,6 +280,9 @@ def encode_dict(data, encoding=None, errors='strict', keep=False, try: key = salt.utils.stringutils.to_bytes(key, encoding, errors) except TypeError: + # to_bytes raises a TypeError when input is not a + # string/bytestring/bytearray. This is expected and simply + # means we are going to leave the value as-is. pass except UnicodeEncodeError: if not keep: @@ -257,6 +303,9 @@ def encode_dict(data, encoding=None, errors='strict', keep=False, try: value = salt.utils.stringutils.to_bytes(value, encoding, errors) except TypeError: + # to_bytes raises a TypeError when input is not a + # string/bytestring/bytearray. This is expected and simply + # means we are going to leave the value as-is. pass except UnicodeEncodeError: if not keep: @@ -290,6 +339,9 @@ def encode_list(data, encoding=None, errors='strict', keep=False, try: item = salt.utils.stringutils.to_bytes(item, encoding, errors) except TypeError: + # to_bytes raises a TypeError when input is not a + # string/bytestring/bytearray. This is expected and simply + # means we are going to leave the value as-is. pass except UnicodeEncodeError: if not keep: diff --git a/salt/utils/docker/translate/container.py b/salt/utils/docker/translate/container.py index 1a167369ac..265cde74ba 100644 --- a/salt/utils/docker/translate/container.py +++ b/salt/utils/docker/translate/container.py @@ -114,28 +114,27 @@ def _post_processing(kwargs, skip_translate, invalid): actual_volumes.sort() if kwargs.get('port_bindings') is not None \ - and (skip_translate is True or - all(x not in skip_translate - for x in ('port_bindings', 'expose', 'ports'))): + and all(x not in skip_translate + for x in ('port_bindings', 'expose', 'ports')): # Make sure that all ports defined in "port_bindings" are included in # the "ports" param. - auto_ports = list(kwargs['port_bindings']) - if auto_ports: - actual_ports = [] - # Sort list to make unit tests more reliable - for port in auto_ports: - if port in actual_ports: - continue - if isinstance(port, six.integer_types): - actual_ports.append((port, 'tcp')) - else: - port, proto = port.split('/') - actual_ports.append((int(port), proto)) - actual_ports.sort() - actual_ports = [ - port if proto == 'tcp' else '{}/{}'.format(port, proto) for (port, proto) in actual_ports - ] - kwargs.setdefault('ports', actual_ports) + ports_to_bind = list(kwargs['port_bindings']) + if ports_to_bind: + ports_to_open = set(kwargs.get('ports', [])) + ports_to_open.update([helpers.get_port_def(x) for x in ports_to_bind]) + kwargs['ports'] = list(ports_to_open) + + if 'ports' in kwargs \ + and all(x not in skip_translate for x in ('expose', 'ports')): + # TCP ports should only be passed as the port number. Normalize the + # input so a port definition of 80/tcp becomes just 80 instead of + # (80, 'tcp'). + for index, _ in enumerate(kwargs['ports']): + try: + if kwargs['ports'][index][1] == 'tcp': + kwargs['ports'][index] = ports_to_open[index][0] + except TypeError: + continue # Functions below must match names of docker-py arguments @@ -552,13 +551,7 @@ def ports(val, **kwargs): # pylint: disable=unused-argument raise SaltInvocationError(exc.__str__()) new_ports.update([helpers.get_port_def(x, proto) for x in range(range_start, range_end + 1)]) - ordered_new_ports = [ - port if proto == 'tcp' else (port, proto) for (port, proto) in sorted( - [(new_port, 'tcp') if isinstance(new_port, six.integer_types) else new_port - for new_port in new_ports] - ) - ] - return ordered_new_ports + return list(new_ports) def privileged(val, **kwargs): # pylint: disable=unused-argument diff --git a/salt/utils/files.py b/salt/utils/files.py index 3ca73b9db8..397b2206fb 100644 --- a/salt/utils/files.py +++ b/salt/utils/files.py @@ -328,6 +328,17 @@ def fopen(*args, **kwargs): NB! We still have small race condition between open and fcntl. ''' + if six.PY3: + try: + # Don't permit stdin/stdout/stderr to be opened. The boolean False + # and True are treated by Python 3's open() as file descriptors 0 + # and 1, respectively. + if args[0] in (0, 1, 2): + raise TypeError( + '{0} is not a permitted file descriptor'.format(args[0]) + ) + except IndexError: + pass binary = None # ensure 'binary' mode is always used on Windows in Python 2 if ((six.PY2 and salt.utils.platform.is_windows() and 'binary' not in kwargs) or diff --git a/salt/utils/gitfs.py b/salt/utils/gitfs.py index 55413ecb0b..275fad4c83 100644 --- a/salt/utils/gitfs.py +++ b/salt/utils/gitfs.py @@ -7,7 +7,6 @@ Classes which provide the shared base for GitFS, git_pillar, and winrepo from __future__ import absolute_import, print_function, unicode_literals import copy import contextlib -import distutils import errno import fnmatch import glob @@ -90,9 +89,9 @@ log = logging.getLogger(__name__) try: import git import gitdb - HAS_GITPYTHON = True + GITPYTHON_VERSION = _LooseVersion(git.__version__) except ImportError: - HAS_GITPYTHON = False + GITPYTHON_VERSION = None try: # Squelch warning on cent7 due to them upgrading cffi @@ -100,7 +99,31 @@ try: with warnings.catch_warnings(): warnings.simplefilter('ignore') import pygit2 - HAS_PYGIT2 = True + PYGIT2_VERSION = _LooseVersion(pygit2.__version__) + LIBGIT2_VERSION = _LooseVersion(pygit2.LIBGIT2_VERSION) + + # Work around upstream bug where bytestrings were being decoded using the + # default encoding (which is usually ascii on Python 2). This was fixed + # on 2 Feb 2018, so releases prior to 0.26.3 will need a workaround. + if PYGIT2_VERSION <= _LooseVersion('0.26.3'): + try: + import pygit2.ffi + import pygit2.remote + except ImportError: + # If we couldn't import these, then we're using an old enough + # version where ffi isn't in use and this workaround would be + # useless. + pass + else: + def __maybe_string(ptr): + if not ptr: + return None + return pygit2.ffi.string(ptr).decode('utf-8') + + pygit2.remote.maybe_string = __maybe_string + + # Older pygit2 releases did not raise a specific exception class, this + # try/except makes Salt's exception catching work on any supported release. try: GitError = pygit2.errors.GitError except AttributeError: @@ -111,16 +134,17 @@ except Exception as exc: # to rebuild itself against the newer cffi). Therefore, we simply will # catch a generic exception, and log the exception if it is anything other # than an ImportError. - HAS_PYGIT2 = False + PYGIT2_VERSION = None + LIBGIT2_VERSION = None if not isinstance(exc, ImportError): log.exception('Failed to import pygit2') # pylint: enable=import-error # Minimum versions for backend providers -GITPYTHON_MINVER = '0.3' -PYGIT2_MINVER = '0.20.3' -LIBGIT2_MINVER = '0.20.0' +GITPYTHON_MINVER = _LooseVersion('0.3') +PYGIT2_MINVER = _LooseVersion('0.20.3') +LIBGIT2_MINVER = _LooseVersion('0.20.0') def enforce_types(key, val): @@ -1658,7 +1682,7 @@ class Pygit2(GitProvider): origin = self.repo.remotes[0] refs_pre = self.repo.listall_references() fetch_kwargs = {} - # pygit2 0.23.2 brought + # pygit2 radically changed fetchiing in 0.23.2 if self.remotecallbacks is not None: fetch_kwargs['callbacks'] = self.remotecallbacks else: @@ -1841,10 +1865,7 @@ class Pygit2(GitProvider): ''' Assign attributes for pygit2 callbacks ''' - # pygit2 radically changed fetching in 0.23.2 - pygit2_version = pygit2.__version__ - if distutils.version.LooseVersion(pygit2_version) >= \ - distutils.version.LooseVersion('0.23.2'): + if PYGIT2_VERSION >= _LooseVersion('0.23.2'): self.remotecallbacks = pygit2.RemoteCallbacks( credentials=self.credentials) if not self.ssl_verify: @@ -1859,7 +1880,7 @@ class Pygit2(GitProvider): 'pygit2 does not support disabling the SSL certificate ' 'check in versions prior to 0.23.2 (installed: {0}). ' 'Fetches for self-signed certificates will fail.'.format( - pygit2_version + PYGIT2_VERSION ) ) @@ -2013,7 +2034,7 @@ class GitBase(object): really designed right now for winrepo, as its repos need to be checked out into the winrepo locations and not within the cachedir. - As of the Oxygen release cycle, the classes used to interface with + As of the 2018.3 release cycle, the classes used to interface with Pygit2 and GitPython can be overridden by passing the git_providers argument when spawning a class instance. This allows for one to write classes which inherit from salt.utils.gitfs.Pygit2 or @@ -2136,6 +2157,9 @@ class GitBase(object): for saltenv, saltenv_conf in six.iteritems(repo_obj.saltenv): if 'ref' in saltenv_conf: ref = saltenv_conf['ref'] + repo_obj.saltenv_revmap.setdefault( + ref, []).append(saltenv) + if saltenv == 'base': # Remove redundant 'ref' config for base saltenv repo_obj.saltenv[saltenv].pop('ref') @@ -2150,9 +2174,6 @@ class GitBase(object): ) # Rewrite 'base' config param repo_obj.base = ref - else: - repo_obj.saltenv_revmap.setdefault( - ref, []).append(saltenv) # Build list of all envs defined by ref mappings in the # per-remote 'saltenv' param. We won't add any matching envs @@ -2325,7 +2346,7 @@ class GitBase(object): def update(self, remotes=None): ''' - .. versionchanged:: Oxygen + .. versionchanged:: 2018.3.0 The remotes argument was added. This being a list of remote URLs, it will only update matching remotes. This actually matches on repo.id @@ -2435,10 +2456,10 @@ class GitBase(object): Check if GitPython is available and at a compatible version (>= 0.3.0) ''' def _recommend(): - if HAS_PYGIT2 and 'pygit2' in self.git_providers: + if PYGIT2_VERSION and 'pygit2' in self.git_providers: log.error(_RECOMMEND_PYGIT2, self.role, self.role) - if not HAS_GITPYTHON: + if not GITPYTHON_VERSION: if not quiet: log.error( '%s is configured but could not be loaded, is GitPython ' @@ -2449,18 +2470,14 @@ class GitBase(object): elif 'gitpython' not in self.git_providers: return False - # pylint: disable=no-member - gitver = _LooseVersion(git.__version__) - minver = _LooseVersion(GITPYTHON_MINVER) - # pylint: enable=no-member errors = [] - if gitver < minver: + if GITPYTHON_VERSION < GITPYTHON_MINVER: errors.append( '{0} is configured, but the GitPython version is earlier than ' '{1}. Version {2} detected.'.format( self.role, GITPYTHON_MINVER, - git.__version__ + GITPYTHON_VERSION ) ) if not salt.utils.path.which('git'): @@ -2486,10 +2503,10 @@ class GitBase(object): Pygit2 must be at least 0.20.3 and libgit2 must be at least 0.20.0. ''' def _recommend(): - if HAS_GITPYTHON and 'gitpython' in self.git_providers: + if GITPYTHON_VERSION and 'gitpython' in self.git_providers: log.error(_RECOMMEND_GITPYTHON, self.role, self.role) - if not HAS_PYGIT2: + if not PYGIT2_VERSION: if not quiet: log.error( '%s is configured but could not be loaded, are pygit2 ' @@ -2500,31 +2517,23 @@ class GitBase(object): elif 'pygit2' not in self.git_providers: return False - # pylint: disable=no-member - pygit2ver = _LooseVersion(pygit2.__version__) - pygit2_minver = _LooseVersion(PYGIT2_MINVER) - - libgit2ver = _LooseVersion(pygit2.LIBGIT2_VERSION) - libgit2_minver = _LooseVersion(LIBGIT2_MINVER) - # pylint: enable=no-member - errors = [] - if pygit2ver < pygit2_minver: + if PYGIT2_VERSION < PYGIT2_MINVER: errors.append( '{0} is configured, but the pygit2 version is earlier than ' '{1}. Version {2} detected.'.format( self.role, PYGIT2_MINVER, - pygit2.__version__ + PYGIT2_VERSION ) ) - if libgit2ver < libgit2_minver: + if LIBGIT2_VERSION < LIBGIT2_MINVER: errors.append( '{0} is configured, but the libgit2 version is earlier than ' '{1}. Version {2} detected.'.format( self.role, LIBGIT2_MINVER, - pygit2.LIBGIT2_VERSION + LIBGIT2_VERSION ) ) if not salt.utils.path.which('git'): @@ -2749,15 +2758,20 @@ class GitFS(GitBase): return fnd salt.fileserver.wait_lock(lk_fn, dest) - if os.path.isfile(blobshadest) and os.path.isfile(dest): + try: with salt.utils.files.fopen(blobshadest, 'r') as fp_: sha = salt.utils.stringutils.to_unicode(fp_.read()) if sha == blob_hexsha: fnd['rel'] = path fnd['path'] = dest return _add_file_stat(fnd, blob_mode) + except IOError as exc: + if exc.errno != errno.ENOENT: + raise exc + with salt.utils.files.fopen(lk_fn, 'w'): pass + for filename in glob.glob(hashes_glob): try: os.remove(filename) @@ -2829,17 +2843,24 @@ class GitFS(GitBase): load['saltenv'], '{0}.hash.{1}'.format(relpath, self.opts['hash_type'])) - if not os.path.isfile(hashdest): - if not os.path.exists(os.path.dirname(hashdest)): - os.makedirs(os.path.dirname(hashdest)) - ret['hsum'] = salt.utils.hashutils.get_hash(path, self.opts['hash_type']) - with salt.utils.files.fopen(hashdest, 'w+') as fp_: - fp_.write(ret['hsum']) - return ret - else: + try: with salt.utils.files.fopen(hashdest, 'rb') as fp_: ret['hsum'] = fp_.read() return ret + except IOError as exc: + if exc.errno != errno.ENOENT: + raise exc + + try: + os.makedirs(os.path.dirname(hashdest)) + except OSError as exc: + if exc.errno != errno.EEXIST: + raise exc + + ret['hsum'] = salt.utils.hashutils.get_hash(path, self.opts['hash_type']) + with salt.utils.files.fopen(hashdest, 'w+') as fp_: + fp_.write(ret['hsum']) + return ret def _file_lists(self, load, form): ''' diff --git a/salt/utils/http.py b/salt/utils/http.py index 918c5643cb..49a6a9613e 100644 --- a/salt/utils/http.py +++ b/salt/utils/http.py @@ -569,7 +569,7 @@ def query(url, not isinstance(result_text, six.text_type): result_text = result_text.decode(res_params['charset']) ret['body'] = result_text - if 'Set-Cookie' in result_headers.keys() and cookies is not None: + if 'Set-Cookie' in result_headers and cookies is not None: result_cookies = parse_cookie_header(result_headers['Set-Cookie']) for item in result_cookies: sess_cookies.set_cookie(item) @@ -899,12 +899,10 @@ def parse_cookie_header(header): for cookie in cookies: name = None value = None - for item in cookie: + for item in list(cookie): if item in attribs: continue - name = item - value = cookie[item] - del cookie[name] + value = cookie.pop(item) # cookielib.Cookie() requires an epoch if 'expires' in cookie: @@ -912,7 +910,7 @@ def parse_cookie_header(header): # Fill in missing required fields for req in reqd: - if req not in cookie.keys(): + if req not in cookie: cookie[req] = '' if cookie['version'] == '': cookie['version'] = 0 diff --git a/salt/utils/jinja.py b/salt/utils/jinja.py index 5a0bacfcc5..6c772ddcdb 100644 --- a/salt/utils/jinja.py +++ b/salt/utils/jinja.py @@ -67,9 +67,11 @@ class SaltCacheLoader(BaseLoader): else: self.searchpath = [os.path.join(opts['cachedir'], 'files', saltenv)] log.debug('Jinja search path: %s', self.searchpath) - self._file_client = None self.cached = [] self.pillar_rend = pillar_rend + self._file_client = None + # Instantiate the fileclient + self.file_client() def file_client(self): ''' @@ -850,6 +852,24 @@ class SerializerExtension(Extension, object): value = six.text_type(value) try: return salt.utils.data.decode(salt.utils.yaml.safe_load(value)) + except salt.utils.yaml.YAMLError as exc: + msg = 'Encountered error loading yaml: ' + try: + # Reported line is off by one, add 1 to correct it + line = exc.problem_mark.line + 1 + buf = exc.problem_mark.buffer + problem = exc.problem + except AttributeError: + # No context information available in the exception, fall back + # to the stringified version of the exception. + msg += six.text_type(exc) + else: + msg += '{0}\n'.format(problem) + msg += salt.utils.stringutils.get_context( + buf, + line, + marker=' <======================') + raise TemplateRuntimeError(msg) except AttributeError: raise TemplateRuntimeError( 'Unable to load yaml from {0}'.format(value)) diff --git a/salt/utils/json.py b/salt/utils/json.py index 7d562a5fad..788505cb25 100644 --- a/salt/utils/json.py +++ b/salt/utils/json.py @@ -28,7 +28,7 @@ def find_json(raw): for ind, _ in enumerate(raw): working = '\n'.join(raw.splitlines()[ind:]) try: - ret = json.loads(working, object_hook=salt.utils.data.decode_dict) # future lint: blacklisted-function + ret = json.loads(working) # future lint: blacklisted-function except ValueError: continue if ret: @@ -53,7 +53,7 @@ def import_json(): def load(fp, **kwargs): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Wraps json.load @@ -65,7 +65,7 @@ def load(fp, **kwargs): def loads(s, **kwargs): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Wraps json.loads and prevents a traceback in the event that a bytestring is passed to the function. (Python < 3.6 cannot load bytestrings) @@ -86,7 +86,7 @@ def loads(s, **kwargs): def dump(obj, fp, **kwargs): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Wraps json.dump, and assumes that ensure_ascii is False (unless explicitly passed as True) for unicode compatibility. Note that setting it to True @@ -109,7 +109,7 @@ def dump(obj, fp, **kwargs): def dumps(obj, **kwargs): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Wraps json.dumps, and assumes that ensure_ascii is False (unless explicitly passed as True) for unicode compatibility. Note that setting it to True diff --git a/salt/utils/master.py b/salt/utils/master.py index 1c339f7711..9fd3cd369d 100644 --- a/salt/utils/master.py +++ b/salt/utils/master.py @@ -34,11 +34,7 @@ from salt.utils.process import MultiprocessingProcess # Import third party libs from salt.ext import six -try: - import zmq - HAS_ZMQ = True -except ImportError: - HAS_ZMQ = False +from salt.utils.zeromq import zmq log = logging.getLogger(__name__) diff --git a/salt/utils/minions.py b/salt/utils/minions.py index 1285f11744..c3acc6ba90 100644 --- a/salt/utils/minions.py +++ b/salt/utils/minions.py @@ -13,6 +13,7 @@ import logging # Import salt libs import salt.payload +import salt.roster import salt.utils.data import salt.utils.files import salt.utils.network @@ -682,6 +683,13 @@ class CkMinions(object): _res = check_func(expr, delimiter, greedy) else: _res = check_func(expr, greedy) + _res['ssh_minions'] = False + if self.opts.get('enable_ssh_minions', False) is True and isinstance('tgt', six.string_types): + roster = salt.roster.Roster(self.opts, self.opts.get('roster', 'flat')) + ssh_minions = roster.targets(expr, tgt_type) + if ssh_minions: + _res['minions'].extend(ssh_minions) + _res['ssh_minions'] = True except Exception: log.exception( 'Failed matching available minions with %s pattern: %s', diff --git a/salt/utils/parsers.py b/salt/utils/parsers.py index 09fe7d880e..88ce272fa9 100644 --- a/salt/utils/parsers.py +++ b/salt/utils/parsers.py @@ -47,6 +47,8 @@ import salt.exceptions from salt.ext import six from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin +logger = logging.getLogger(__name__) + def _sorted(mixins_or_funcs): return sorted( @@ -64,8 +66,8 @@ class MixInMeta(type): instance = super(MixInMeta, mcs).__new__(mcs, name, bases, attrs) if not hasattr(instance, '_mixin_setup'): raise RuntimeError( - 'Don\'t subclass {0} in {1} if you\'re not going to use it ' - 'as a salt parser mix-in.'.format(mcs.__name__, name) + "Don't subclass {0} in {1} if you're not going " + "to use it as a salt parser mix-in.".format(mcs.__name__, name) ) return instance @@ -206,7 +208,7 @@ class OptionParser(optparse.OptionParser, object): try: process_option_func() except Exception as err: # pylint: disable=broad-except - logging.getLogger(__name__).exception(err) + logger.exception(err) self.error( 'Error while processing {0}: {1}'.format( process_option_func, traceback.format_exc(err) @@ -218,7 +220,7 @@ class OptionParser(optparse.OptionParser, object): try: mixin_after_parsed_func(self) except Exception as err: # pylint: disable=broad-except - logging.getLogger(__name__).exception(err) + logger.exception(err) self.error( 'Error while processing {0}: {1}'.format( mixin_after_parsed_func, traceback.format_exc(err) @@ -226,7 +228,7 @@ class OptionParser(optparse.OptionParser, object): ) if self.config.get('conf_file', None) is not None: # pylint: disable=no-member - logging.getLogger(__name__).debug( + logger.debug( 'Configuration file path: %s', self.config['conf_file'] # pylint: disable=no-member ) @@ -259,12 +261,10 @@ class OptionParser(optparse.OptionParser, object): try: mixin_before_exit_func(self) except Exception as err: # pylint: disable=broad-except - logger = logging.getLogger(__name__) logger.exception(err) - logger.error( - 'Error while processing %s: %s', - mixin_before_exit_func, traceback.format_exc(err) - ) + logger.error('Error while processing %s: %s', + six.text_type(mixin_before_exit_func), + traceback.format_exc(err)) if self._setup_mp_logging_listener_ is True: # Stop logging through the queue log.shutdown_multiprocessing_logging() @@ -399,17 +399,13 @@ class SaltfileMixIn(six.with_metaclass(MixInMeta, object)): return if not os.path.isfile(self.options.saltfile): - self.error( - '\'{0}\' file does not exist.\n'.format(self.options.saltfile) - ) + self.error("'{0}' file does not exist.\n".format(self.options.saltfile)) # Make sure we have an absolute path self.options.saltfile = os.path.abspath(self.options.saltfile) # Make sure we let the user know that we will be loading a Saltfile - logging.getLogger(__name__).info( - 'Loading Saltfile from \'%s\'', self.options.saltfile - ) + logger.info("Loading Saltfile from '%s'", six.text_type(self.options.saltfile)) try: saltfile_config = config._read_conf_file(saltfile) @@ -488,8 +484,7 @@ class HardCrashMixin(six.with_metaclass(MixInMeta, object)): hard_crash = os.environ.get('SALT_HARD_CRASH', False) self.add_option( '--hard-crash', action='store_true', default=hard_crash, - help=('Raise any original exception rather than exiting gracefully. ' - 'Default: %default.') + help='Raise any original exception rather than exiting gracefully. Default: %default.' ) @@ -500,9 +495,8 @@ class NoParseMixin(six.with_metaclass(MixInMeta, object)): no_parse = os.environ.get('SALT_NO_PARSE', '') self.add_option( '--no-parse', default=no_parse, - help=('Comma-separated list of named CLI arguments (i.e. ' - 'argname=value) which should not be parsed as Python ' - 'data types'), + help='Comma-separated list of named CLI arguments (i.e. argname=value) ' + 'which should not be parsed as Python data types', metavar='argname1,argname2,...', ) @@ -527,11 +521,10 @@ class ConfigDirMixIn(six.with_metaclass(MixInMeta, object)): config_dir = os.environ.get(self._default_config_dir_env_var_, None) if not config_dir: config_dir = self._default_config_dir_ - logging.getLogger(__name__).debug('SYSPATHS setup as: %s', syspaths.CONFIG_DIR) + logger.debug('SYSPATHS setup as: %s', six.text_type(syspaths.CONFIG_DIR)) self.add_option( '-c', '--config-dir', default=config_dir, - help=('Pass in an alternative configuration directory. Default: ' - '\'%default\'.') + help="Pass in an alternative configuration directory. Default: '%default'." ) def process_config_dir(self): @@ -539,7 +532,7 @@ class ConfigDirMixIn(six.with_metaclass(MixInMeta, object)): if not os.path.isdir(self.options.config_dir): # No logging is configured yet sys.stderr.write( - 'WARNING: CONFIG \'{0}\' directory does not exist.\n'.format( + "WARNING: CONFIG '{0}' directory does not exist.\n".format( self.options.config_dir ) ) @@ -717,7 +710,7 @@ class LogLevelMixIn(six.with_metaclass(MixInMeta, object)): # Remove it from config so it inherits from log_file self.config.pop(self._logfile_config_setting_name_) - if self.config['verify_env']: + if self.config['verify_env'] and self.config['log_level'] not in ('quiet', ): # Verify the logfile if it was explicitly set but do not try to # verify the default if logfile is not None and not logfile.startswith(('tcp://', 'udp://', 'file://')): @@ -794,12 +787,11 @@ class LogLevelMixIn(six.with_metaclass(MixInMeta, object)): logfile_basename = os.path.basename( self._default_logging_logfile_ ) - logging.getLogger(__name__).debug( - 'The user \'%s\' is not allowed to write to \'%s\'. ' - 'The log file will be stored in ' - '\'~/.salt/\'%s\'.log\'', - current_user, logfile, logfile_basename - ) + logger.debug("The user '%s' is not allowed to write to '%s'. " + "The log file will be stored in '~/.salt/'%s'.log'", + six.text_type(current_user), + six.text_type(logfile), + six.text_type(logfile_basename)) logfile = os.path.join( user_salt_dir, '{0}.log'.format(logfile_basename) ) @@ -814,10 +806,10 @@ class LogLevelMixIn(six.with_metaclass(MixInMeta, object)): # Not supported on platforms other than Windows. # Other platforms may use an external tool such as 'logrotate' if log_rotate_max_bytes != 0: - logging.getLogger(__name__).warning('\'log_rotate_max_bytes\' is only supported on Windows') + logger.warning("'log_rotate_max_bytes' is only supported on Windows") log_rotate_max_bytes = 0 if log_rotate_backup_count != 0: - logging.getLogger(__name__).warning('\'log_rotate_backup_count\' is only supported on Windows') + logger.warning("'log_rotate_backup_count' is only supported on Windows") log_rotate_backup_count = 0 # Save the settings back to the configuration @@ -962,22 +954,23 @@ class DaemonMixIn(six.with_metaclass(MixInMeta, object)): default=os.path.join( syspaths.PIDFILE_DIR, '{0}.pid'.format(self.get_prog_name()) ), - help=('Specify the location of the pidfile. Default: \'%default\'.') + help="Specify the location of the pidfile. Default: '%default'." ) def _mixin_before_exit(self): - if hasattr(self, 'config') and self.config.get('pidfile', ''): + if hasattr(self, 'config') and self.config.get('pidfile'): # We've loaded and merged options into the configuration, it's safe # to query about the pidfile if self.check_pidfile(): try: os.unlink(self.config['pidfile']) except OSError as err: - logging.getLogger(__name__).info( - 'PIDfile could not be deleted: {0}'.format( - self.config['pidfile'] - ) - ) + # Log error only when running salt-master as a root user. + # Otherwise this can be ignored, since salt-master is able to + # overwrite the PIDfile on the next start. + if not os.getuid(): + logger.info('PIDfile could not be deleted: %s', six.text_type(self.config['pidfile'])) + logger.debug(six.text_type(err)) def set_pidfile(self): from salt.utils.process import set_pidfile @@ -2739,31 +2732,31 @@ class SaltCallOptionParser(six.with_metaclass(OptionParserMeta, role = opts.get('id') if not role: - emsg = ("Missing role required to setup RAET SaltCaller.") - logging.getLogger(__name__).error(emsg + "\n") + emsg = "Missing role required to setup RAET SaltCaller." + logger.error(emsg) raise ValueError(emsg) kind = opts.get('__role') # application kind 'master', 'minion', etc if kind not in kinds.APPL_KINDS: - emsg = ("Invalid application kind = '{0}' for RAET SaltCaller.".format(kind)) - logging.getLogger(__name__).error(emsg + "\n") + emsg = "Invalid application kind = '{0}' for RAET SaltCaller.".format(six.text_type(kind)) + logger.error(emsg) raise ValueError(emsg) - if kind in [kinds.APPL_KIND_NAMES[kinds.applKinds.minion], - kinds.APPL_KIND_NAMES[kinds.applKinds.caller], ]: + if kind in [kinds.APPL_KIND_NAMES[kinds.applKinds.minion], kinds.APPL_KIND_NAMES[kinds.applKinds.caller]]: lanename = "{0}_{1}".format(role, kind) else: - emsg = ("Unsupported application kind '{0}' for RAET SaltCaller.".format(kind)) - logging.getLogger(__name__).error(emsg + '\n') + emsg = "Unsupported application kind '{0}' for RAET SaltCaller.".format(six.text_type(kind)) + logger.error(emsg) raise ValueError(emsg) if kind == kinds.APPL_KIND_NAMES[kinds.applKinds.minion]: # minion check - from raet.lane.yarding import Yard # pylint: disable=3rd-party-module-not-gated - ha, dirpath = Yard.computeHa(dirpath, lanename, yardname) # pylint: disable=invalid-name - if (os.path.exists(ha) and - not os.path.isfile(ha) and - not os.path.isdir(ha)): # minion manor yard - return True + try: + from raet.lane.yarding import Yard # pylint: disable=3rd-party-module-not-gated + ha, dirpath = Yard.computeHa(dirpath, lanename, yardname) # pylint: disable=invalid-name + if os.path.exists(ha) and not os.path.isfile(ha) and not os.path.isdir(ha): # minion manor yard + return True + except ImportError as ex: + logger.error("Error while importing Yard: %s", ex) return False def process_module_dirs(self): @@ -2822,13 +2815,13 @@ class SaltRunOptionParser(six.with_metaclass(OptionParserMeta, '--async', default=False, action='store_true', - help=('Start the runner operation and immediately return control.') + help='Start the runner operation and immediately return control.' ) self.add_option( '--skip-grains', default=False, action='store_true', - help=('Do not load grains.') + help='Do not load grains.' ) group = self.output_options_group = optparse.OptionGroup( self, 'Output Options', 'Configure your preferred output format.' @@ -2946,14 +2939,13 @@ class SaltSSHOptionParser(six.with_metaclass(OptionParserMeta, '-v', '--verbose', default=False, action='store_true', - help=('Turn on command verbosity, display jid.') + help='Turn on command verbosity, display jid.' ) self.add_option( '-s', '--static', default=False, action='store_true', - help=('Return the data from minions as a group after they ' - 'all return.') + help='Return the data from minions as a group after they all return.' ) self.add_option( '-w', '--wipe', diff --git a/salt/utils/rsax931.py b/salt/utils/rsax931.py index 55be7dc804..168c02734b 100644 --- a/salt/utils/rsax931.py +++ b/salt/utils/rsax931.py @@ -28,7 +28,8 @@ def _load_libcrypto(): Load OpenSSL libcrypto ''' if sys.platform.startswith('win'): - return cdll.LoadLibrary('libeay32') + # cdll.LoadLibrary on windows requires an 'str' argument + return cdll.LoadLibrary(str('libeay32')) # future lint: disable=blacklisted-function elif getattr(sys, 'frozen', False) and salt.utils.platform.is_smartos(): return cdll.LoadLibrary(glob.glob(os.path.join( os.path.dirname(sys.executable), diff --git a/salt/utils/schedule.py b/salt/utils/schedule.py index 98e9e5cc30..d6eb78225b 100644 --- a/salt/utils/schedule.py +++ b/salt/utils/schedule.py @@ -66,13 +66,6 @@ except ImportError: _CRON_SUPPORTED = False # pylint: enable=import-error -try: - import pytz - _PYTZ_SUPPORTED = True -except ImportError: - _PYTZ_SUPPORTED = False -# pylint: enable=import-error - log = logging.getLogger(__name__) @@ -109,6 +102,7 @@ class Schedule(object): self.standalone = standalone self.skip_function = None self.skip_during_range = None + self.enabled = True if isinstance(intervals, dict): self.intervals = intervals else: @@ -141,7 +135,8 @@ class Schedule(object): def _get_schedule(self, include_opts=True, - include_pillar=True): + include_pillar=True, + remove_hidden=False): ''' Return the schedule data structure ''' @@ -156,6 +151,13 @@ class Schedule(object): if not isinstance(opts_schedule, dict): raise ValueError('Schedule must be of type dict.') schedule.update(opts_schedule) + + if remove_hidden: + _schedule = copy.deepcopy(schedule) + for job in _schedule: + for item in _schedule[job]: + if item.startswith('_'): + del schedule[job][item] return schedule def _check_max_running(self, func, data, opts, now): @@ -221,12 +223,14 @@ class Schedule(object): schedule_conf = os.path.join(minion_d_dir, '_schedule.conf') log.debug('Persisting schedule') + schedule_data = self._get_schedule(include_pillar=False, + remove_hidden=True) try: with salt.utils.files.fopen(schedule_conf, 'wb+') as fp_: fp_.write( salt.utils.stringutils.to_bytes( salt.utils.yaml.safe_dump( - {'schedule': self._get_schedule(include_pillar=False)} + {'schedule': schedule_data} ) ) ) @@ -246,7 +250,8 @@ class Schedule(object): # Fire the complete event back along with updated list of schedule evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False) - evt.fire_event({'complete': True, 'schedule': self._get_schedule()}, + evt.fire_event({'complete': True, + 'schedule': self._get_schedule()}, tag='/salt/minion/minion_schedule_delete_complete') # remove from self.intervals @@ -256,6 +261,15 @@ class Schedule(object): if persist: self.persist() + def reset(self): + ''' + Reset the scheduler to defaults + ''' + self.skip_function = None + self.skip_during_range = None + self.enabled = True + self.opts['schedule'] = {} + def delete_job_prefix(self, name, persist=True): ''' Deletes a job from the scheduler. Ignores jobs from pillar @@ -270,7 +284,8 @@ class Schedule(object): # Fire the complete event back along with updated list of schedule evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False) - evt.fire_event({'complete': True, 'schedule': self._get_schedule()}, + evt.fire_event({'complete': True, + 'schedule': self._get_schedule()}, tag='/salt/minion/minion_schedule_delete_complete') # remove from self.intervals @@ -316,7 +331,8 @@ class Schedule(object): # Fire the complete event back along with updated list of schedule evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False) - evt.fire_event({'complete': True, 'schedule': self._get_schedule()}, + evt.fire_event({'complete': True, + 'schedule': self._get_schedule()}, tag='/salt/minion/minion_schedule_add_complete') if persist: @@ -335,7 +351,8 @@ class Schedule(object): # Fire the complete event back along with updated list of schedule evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False) - evt.fire_event({'complete': True, 'schedule': self._get_schedule()}, + evt.fire_event({'complete': True, + 'schedule': self._get_schedule()}, tag='/salt/minion/minion_schedule_enabled_job_complete') if persist: @@ -354,7 +371,8 @@ class Schedule(object): # Fire the complete event back along with updated list of schedule evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False) - evt.fire_event({'complete': True, 'schedule': self._get_schedule()}, + evt.fire_event({'complete': True, + 'schedule': self._get_schedule()}, tag='/salt/minion/minion_schedule_disabled_job_complete') if persist: @@ -404,7 +422,7 @@ class Schedule(object): data = self._check_max_running(func, data, self.opts, - int(time.time())) + datetime.datetime.now()) # Grab run, assume True run = data.get('run', True) @@ -493,23 +511,27 @@ class Schedule(object): ''' time = data['time'] new_time = data['new_time'] + time_fmt = data.get('time_fmt', '%Y-%m-%dT%H:%M:%S') # ensure job exists, then disable it if name in self.opts['schedule']: if 'skip_explicit' not in self.opts['schedule'][name]: self.opts['schedule'][name]['skip_explicit'] = [] - self.opts['schedule'][name]['skip_explicit'].append(time) + self.opts['schedule'][name]['skip_explicit'].append({'time': time, + 'time_fmt': time_fmt}) if 'run_explicit' not in self.opts['schedule'][name]: self.opts['schedule'][name]['run_explicit'] = [] - self.opts['schedule'][name]['run_explicit'].append(new_time) + self.opts['schedule'][name]['run_explicit'].append({'time': new_time, + 'time_fmt': time_fmt}) elif name in self._get_schedule(include_opts=False): log.warning("Cannot modify job %s, it's in the pillar!", name) # Fire the complete event back along with updated list of schedule evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False) - evt.fire_event({'complete': True, 'schedule': self._get_schedule()}, + evt.fire_event({'complete': True, + 'schedule': self._get_schedule()}, tag='/salt/minion/minion_schedule_postpone_job_complete') def skip_job(self, name, data): @@ -518,30 +540,35 @@ class Schedule(object): Ignores jobs from pillar ''' time = data['time'] + time_fmt = data.get('time_fmt', '%Y-%m-%dT%H:%M:%S') # ensure job exists, then disable it if name in self.opts['schedule']: if 'skip_explicit' not in self.opts['schedule'][name]: self.opts['schedule'][name]['skip_explicit'] = [] - self.opts['schedule'][name]['skip_explicit'].append(time) + self.opts['schedule'][name]['skip_explicit'].append({'time': time, + 'time_fmt': time_fmt}) elif name in self._get_schedule(include_opts=False): log.warning("Cannot modify job %s, it's in the pillar!", name) # Fire the complete event back along with updated list of schedule evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False) - evt.fire_event({'complete': True, 'schedule': self._get_schedule()}, + evt.fire_event({'complete': True, + 'schedule': self._get_schedule()}, tag='/salt/minion/minion_schedule_skip_job_complete') - def get_next_fire_time(self, name): + def get_next_fire_time(self, name, fmt='%Y-%m-%dT%H:%M:%S'): ''' - Return the next fire time for the specified job + Return the next fire time for the specified job ''' schedule = self._get_schedule() _next_fire_time = None if schedule: _next_fire_time = schedule.get(name, {}).get('_next_fire_time', None) + if _next_fire_time: + _next_fire_time = _next_fire_time.strftime(fmt) # Fire the complete event back along with updated list of schedule evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False) @@ -779,12 +806,16 @@ class Schedule(object): ''' Evaluate and execute the schedule - :param int now: Override current time with a Unix timestamp`` + :param datetime now: Override current time with a datetime object instance`` ''' log.trace('==== evaluating schedule now %s =====', now) + loop_interval = self.opts['loop_interval'] + if not isinstance(loop_interval, datetime.timedelta): + loop_interval = datetime.timedelta(seconds=loop_interval) + def _splay(splaytime): ''' Calculate splaytime @@ -815,24 +846,24 @@ class Schedule(object): data['_seconds'] = interval if not data['_next_fire_time']: - data['_next_fire_time'] = now + data['_seconds'] + data['_next_fire_time'] = now + datetime.timedelta(seconds=data['_seconds']) if interval < self.loop_interval: self.loop_interval = interval - data['_next_scheduled_fire_time'] = now + data['_seconds'] + data['_next_scheduled_fire_time'] = now + datetime.timedelta(seconds=data['_seconds']) return data - def _handle_once(data): + def _handle_once(job, data, loop_interval): ''' Handle schedule item with once ''' - if data['_next_fire_time'] and \ - data['_next_fire_time'] < now - self.opts['loop_interval'] and \ - data['_next_fire_time'] > now and \ - not data['_splay']: - data['_continue'] = True + if data['_next_fire_time']: + if data['_next_fire_time'] < now - loop_interval or \ + data['_next_fire_time'] > now and \ + not data['_splay']: + data['_continue'] = True if not data['_next_fire_time'] and \ not data['_splay']: @@ -840,31 +871,28 @@ class Schedule(object): try: once = datetime.datetime.strptime(data['once'], once_fmt) - data['_next_fire_time'] = int( - time.mktime(once.timetuple())) - data['_next_scheduled_fire_time'] = int( - time.mktime(once.timetuple())) except (TypeError, ValueError): - data['_error'] = ('Date string could not ', - 'be parsed: %s, %s', - data['once'], once_fmt) + data['_error'] = ('Date string could not ' + 'be parsed: {0}, {1}. ' + 'Ignoring job {2}.'.format( + data['once'], once_fmt, job)) log.error(data['_error']) return data - # If _next_fire_time is less than now or greater - # than now, continue. - if data['_next_fire_time'] < now - self.opts['loop_interval'] and \ - data['_next_fire_time'] > now: + # If _next_fire_time is less than now, continue + if once < now - loop_interval: data['_continue'] = True - + else: + data['_next_fire_time'] = once + data['_next_scheduled_fire_time'] = once return data - def _handle_when(data): + def _handle_when(job, data, loop_interval): ''' Handle schedule item with when ''' if not _WHEN_SUPPORTED: data['_error'] = ('Missing python-dateutil. ' - 'Ignoring job %s.', job) + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data @@ -876,13 +904,15 @@ class Schedule(object): if not isinstance(self.opts['pillar']['whens'], dict): data['_error'] = ('Pillar item "whens" ' - 'must be a dict. Ignoring.') + 'must be a dict. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) __when = self.opts['pillar']['whens'][i] try: when__ = dateutil_parser.parse(__when) except ValueError: - data['_error'] = 'Invalid date string. Ignoring.' + data['_error'] = ('Invalid date string. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data elif ('whens' in self.opts['grains'] and @@ -890,48 +920,27 @@ class Schedule(object): if not isinstance(self.opts['grains']['whens'], dict): data['_error'] = ('Grain "whens" must be dict.' - 'Ignoring.') + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data __when = self.opts['grains']['whens'][i] try: when__ = dateutil_parser.parse(__when) except ValueError: - data['_error'] = ('Invalid date string. Ignoring.') + data['_error'] = ('Invalid date string. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data else: try: when__ = dateutil_parser.parse(i) except ValueError: - data['_error'] = ('Invalid date string %s. ' - 'Ignoring job %s.', i, job) + data['_error'] = ('Invalid date string {0}. ' + 'Ignoring job {1}.'.format(i, job)) log.error(data['_error']) return data - if 'timezone' in data: - if not _PYTZ_SUPPORTED: - data['_error'] = ('PyTZ is unavailable, ' - 'Ignoring job %s.', - job) - log.error(data['_error']) - return data - - try: - TZ = pytz.timezone(data['timezone']) - except pytz.UnknownTimeZoneError: - data['_error'] = ('Invalid timezone %s. ' - 'Ignoring job %s.', - data['timezone'], - job) - log.error(data['_error']) - return data - - _UTC_EPOCH = datetime.datetime(1970, 1, 1, - tzinfo=pytz.utc) - _when.append(int((TZ.localize(when__) - _UTC_EPOCH).total_seconds())) - else: - _when.append(int(time.mktime(when__.timetuple()))) + _when.append(when__) if data['_splay']: _when.append(data['_splay']) @@ -942,7 +951,7 @@ class Schedule(object): # Copy the list so we can loop through it for i in copy.deepcopy(_when): if len(_when) > 1: - if i < now - self.opts['loop_interval']: + if i < now - loop_interval: # Remove all missed schedules except the latest one. # We need it to detect if it was triggered previously. _when.remove(i) @@ -954,7 +963,7 @@ class Schedule(object): if '_run' not in data: # Prevent run of jobs from the past - data['_run'] = bool(when >= now - self.opts['loop_interval']) + data['_run'] = bool(when >= now - loop_interval) if not data['_next_fire_time']: data['_next_fire_time'] = when @@ -976,64 +985,42 @@ class Schedule(object): data['when'] in self.opts['pillar']['whens']): if not isinstance(self.opts['pillar']['whens'], dict): data['_error'] = ('Pillar item "whens" must be dict.' - 'Ignoring.') + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data _when = self.opts['pillar']['whens'][data['when']] try: - when__ = dateutil_parser.parse(_when) + when = dateutil_parser.parse(_when) except ValueError: - data['_error'] = ('Invalid date string. Ignoring.') + data['_error'] = ('Invalid date string. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data elif ('whens' in self.opts['grains'] and data['when'] in self.opts['grains']['whens']): if not isinstance(self.opts['grains']['whens'], dict): - data['_error'] = ('Grain "whens" must be dict.', - ' Ignoring.') + data['_error'] = ('Grain "whens" must be dict. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data _when = self.opts['grains']['whens'][data['when']] try: - when__ = dateutil_parser.parse(_when) + when = dateutil_parser.parse(_when) except ValueError: - data['_error'] = ('Invalid date string. Ignoring.') + data['_error'] = ('Invalid date string. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data else: try: - when__ = dateutil_parser.parse(data['when']) + when = dateutil_parser.parse(data['when']) except ValueError: - data['_error'] = ('Invalid date string. Ignoring.') + data['_error'] = ('Invalid date string. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data - if 'timezone' in data: - if not _PYTZ_SUPPORTED: - data['_error'] = ('PyTZ is unavailable, ' - 'Ignoring job %s.', - job) - log.error(data['_error']) - return data - - try: - TZ = pytz.timezone(data['timezone']) - except pytz.UnknownTimeZoneError: - data['_error'] = ('Invalid timezone %s. ' - 'Ignoring job %s.', - data['timezone'], - job) - log.error(data['_error']) - return data - - _UTC_EPOCH = datetime.datetime(1970, 1, 1, - tzinfo=pytz.utc) - when = int((TZ.localize(when__) - _UTC_EPOCH).total_seconds()) - - else: - when = int(time.mktime(when__.timetuple())) - - if when < now - self.opts['loop_interval'] and \ + if when < now - loop_interval and \ not data.get('_run', False) and \ not data.get('run', False) and \ not data['_splay']: @@ -1055,13 +1042,13 @@ class Schedule(object): return data - def _handle_cron(data): + def _handle_cron(job, data, loop_interval): ''' Handle schedule item with cron ''' if not _CRON_SUPPORTED: - data['_error'] = ('Missing python-croniter. ', - 'Ignoring job %s.', job) + data['_error'] = ('Missing python-croniter. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data @@ -1069,12 +1056,11 @@ class Schedule(object): # Get next time frame for a "cron" job if it has been never # executed before or already executed in the past. try: - data['_next_fire_time'] = int( - croniter.croniter(data['cron'], now).get_next()) - data['_next_scheduled_fire_time'] = int( - croniter.croniter(data['cron'], now).get_next()) + data['_next_fire_time'] = croniter.croniter(data['cron'], now).get_next(datetime.datetime) + data['_next_scheduled_fire_time'] = croniter.croniter(data['cron'], now).get_next(datetime.datetime) except (ValueError, KeyError): - data['_error'] = 'Invalid cron string. Ignoring.' + data['_error'] = ('Invalid cron string. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data @@ -1082,50 +1068,57 @@ class Schedule(object): # configured loop interval is longer than that, we should # shorten it to get our job executed closer to the beginning # of desired time. - interval = now - data['_next_fire_time'] + interval = (now - data['_next_fire_time']).total_seconds() if interval >= 60 and interval < self.loop_interval: self.loop_interval = interval return data - def _handle_run_explicit(data): + def _handle_run_explicit(data, loop_interval): ''' Handle schedule item with run_explicit ''' - _run_explicit = data['run_explicit'] + _run_explicit = [] + for _run_time in data['run_explicit']: + if isinstance(_run_time, datetime.datetime): + _run_explicit.append(_run_time) + else: + _run_explicit.append(datetime.datetime.strptime(_run_time['time'], + _run_time['time_fmt'])) data['run'] = False - if isinstance(_run_explicit, six.integer_types): - _run_explicit = [_run_explicit] - # Copy the list so we can loop through it for i in copy.deepcopy(_run_explicit): if len(_run_explicit) > 1: - if int(i) < now - self.opts['loop_interval']: + if i < now - loop_interval: _run_explicit.remove(i) if _run_explicit: - if int(_run_explicit[0]) <= now < int(_run_explicit[0] + self.opts['loop_interval']): + if _run_explicit[0] <= now < _run_explicit[0] + loop_interval: data['run'] = True data['_next_fire_time'] = _run_explicit[0] return data - def _handle_skip_explicit(data): + def _handle_skip_explicit(data, loop_interval): ''' Handle schedule item with skip_explicit ''' - _skip_explicit = data['skip_explicit'] data['run'] = False - if isinstance(_skip_explicit, six.string_types): - _skip_explicit = [_skip_explicit] + _skip_explicit = [] + for _skip_time in data['skip_explicit']: + if isinstance(_skip_time, datetime.datetime): + _skip_explicit.append(_skip_time) + else: + _skip_explicit.append(datetime.datetime.strptime(_skip_time['time'], + _skip_time['time_fmt'])) # Copy the list so we can loop through it for i in copy.deepcopy(_skip_explicit): - if i < now - self.opts['loop_interval']: + if i < now - loop_interval: _skip_explicit.remove(i) if _skip_explicit: - if _skip_explicit[0] <= now <= (_skip_explicit[0] + self.opts['loop_interval']): + if _skip_explicit[0] <= now <= (_skip_explicit[0] + loop_interval): if self.skip_function: data['run'] = True data['func'] = self.skip_function @@ -1138,31 +1131,31 @@ class Schedule(object): data['run'] = True return data - def _handle_skip_during_range(data): + def _handle_skip_during_range(job, data, loop_interval): ''' Handle schedule item with skip_explicit ''' if not _RANGE_SUPPORTED: - data['_error'] = ('Missing python-dateutil. ', - 'Ignoring job %s.', job) + data['_error'] = ('Missing python-dateutil. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data else: if isinstance(data['skip_during_range'], dict): try: - start = int(time.mktime(dateutil_parser.parse(data['skip_during_range']['start']).timetuple())) + start = dateutil_parser.parse(data['skip_during_range']['start']) except ValueError: - data['_error'] = ('Invalid date string for start in ', - 'skip_during_range. Ignoring ', - 'job %s.', job) + data['_error'] = ('Invalid date string for start in ' + 'skip_during_range. Ignoring ' + 'job {0}.'.format(job)) log.error(data['_error']) return data try: - end = int(time.mktime(dateutil_parser.parse(data['skip_during_range']['end']).timetuple())) + end = dateutil_parser.parse(data['skip_during_range']['end']) except ValueError: - data['_error'] = ('Invalid date string for end in ', - 'skip_during_range. Ignoring ', - 'job %s.', job) + data['_error'] = ('Invalid date string for end in ' + 'skip_during_range. Ignoring ' + 'job {0}.'.format(job)) log.error(data['_error']) return data @@ -1174,9 +1167,10 @@ class Schedule(object): data['run_explicit'] = [] # Add a run_explicit for immediately after the # skip_during_range ends - _run_immediate = end + self.opts['loop_interval'] + _run_immediate = (end + loop_interval).strftime('%Y-%m-%dT%H:%M:%S') if _run_immediate not in data['run_explicit']: - data['run_explicit'].append(_run_immediate) + data['run_explicit'].append({'time': _run_immediate, + 'time_fmt': '%Y-%m-%dT%H:%M:%S'}) if end > start: if start <= now <= end: @@ -1191,42 +1185,42 @@ class Schedule(object): else: data['run'] = True else: - data['_error'] = ('schedule.handle_func: Invalid ', - 'range, end must be larger than ', - 'start. Ignoring job %s.', job) + data['_error'] = ('schedule.handle_func: Invalid ' + 'range, end must be larger than ' + 'start. Ignoring job {0}.'.format(job)) log.error(data['_error']) return data else: - data['_error'] = ('schedule.handle_func: Invalid, range ', - 'must be specified as a dictionary ', - 'Ignoring job %s.', job) + data['_error'] = ('schedule.handle_func: Invalid, range ' + 'must be specified as a dictionary ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data return data - def _handle_range(data): + def _handle_range(job, data): ''' Handle schedule item with skip_explicit ''' if not _RANGE_SUPPORTED: - data['_error'] = ('Missing python-dateutil. ', - 'Ignoring job %s', job) + data['_error'] = ('Missing python-dateutil. ' + 'Ignoring job {0}'.format(job)) log.error(data['_error']) return data else: if isinstance(data['range'], dict): try: - start = int(time.mktime(dateutil_parser.parse(data['range']['start']).timetuple())) + start = dateutil_parser.parse(data['range']['start']) except ValueError: - data['_error'] = ('Invalid date string for start. ', - 'Ignoring job {0}.', job) + data['_error'] = ('Invalid date string for start. ' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data try: - end = int(time.mktime(dateutil_parser.parse(data['range']['end']).timetuple())) + end = dateutil_parser.parse(data['range']['end']) except ValueError: - data['_error'] = ('Invalid date string for end.', - ' Ignoring job %s.', job) + data['_error'] = ('Invalid date string for end.' + ' Ignoring job {0}.'.format(job)) log.error(data['_error']) return data if end > start: @@ -1247,18 +1241,66 @@ class Schedule(object): data['_skip_reason'] = 'not_in_range' data['run'] = False else: - data['_error'] = ('schedule.handle_func: Invalid ', - 'range, end must be larger ', - 'than start. Ignoring job %s.', job) + data['_error'] = ('schedule.handle_func: Invalid ' + 'range, end must be larger ' + 'than start. Ignoring job {0}.'.format(job)) log.error(data['_error']) return data else: - data['_error'] = ('schedule.handle_func: Invalid, range ', - 'must be specified as a dictionary.', - 'Ignoring job %s.', job) + data['_error'] = ('schedule.handle_func: Invalid, range ' + 'must be specified as a dictionary.' + 'Ignoring job {0}.'.format(job)) log.error(data['_error']) return data + def _handle_after(job, data): + ''' + Handle schedule item with after + ''' + if not _WHEN_SUPPORTED: + data['_error'] = ('Missing python-dateutil. ' + 'Ignoring job {0}'.format(job)) + log.error(data['_error']) + else: + after = dateutil_parser.parse(data['after']) + + if after >= now: + log.debug( + 'After time has not passed skipping job: %s.', + data['name'] + ) + data['_skip_reason'] = 'after_not_passed' + data['_skipped_time'] = now + data['_skipped'] = True + data['run'] = False + else: + data['run'] = True + return data + + def _handle_until(job, data): + ''' + Handle schedule item with until + ''' + if not _WHEN_SUPPORTED: + data['_error'] = ('Missing python-dateutil. ' + 'Ignoring job {0}'.format(job)) + log.error(data['_error']) + else: + until = dateutil_parser.parse(data['until']) + + if until <= now: + log.debug( + 'Until time has passed skipping job: %s.', + data['name'] + ) + data['_skip_reason'] = 'until_passed' + data['_skipped_time'] = now + data['_skipped'] = True + data['run'] = False + else: + data['run'] = True + return data + schedule = self._get_schedule() if not isinstance(schedule, dict): raise ValueError('Schedule must be of type dict.') @@ -1266,12 +1308,18 @@ class Schedule(object): self.skip_function = schedule['skip_function'] if 'skip_during_range' in schedule: self.skip_during_range = schedule['skip_during_range'] + if 'enabled' in schedule: + self.enabled = schedule['enabled'] _hidden = ['enabled', 'skip_function', 'skip_during_range'] for job, data in six.iteritems(schedule): + # Skip anything that is a global setting + if job in _hidden: + continue + # Clear these out between runs for item in ['_continue', '_error', @@ -1280,9 +1328,6 @@ class Schedule(object): del data[item] run = False - if job in _hidden: - continue - if not isinstance(data, dict): log.error( 'Scheduled job "%s" should have a dict value, not %s', @@ -1317,33 +1362,7 @@ class Schedule(object): data['_run_on_start'] = True if not now: - now = int(time.time()) - - if 'until' in data: - if not _WHEN_SUPPORTED: - log.error('Missing python-dateutil. ' - 'Ignoring until.') - else: - until__ = dateutil_parser.parse(data['until']) - until = int(time.mktime(until__.timetuple())) - - if until <= now: - log.debug('Until time has passed ' - 'skipping job: %s.', data['name']) - continue - - if 'after' in data: - if not _WHEN_SUPPORTED: - log.error('Missing python-dateutil. ' - 'Ignoring after.') - else: - after__ = dateutil_parser.parse(data['after']) - after = int(time.mktime(after__.timetuple())) - - if after >= now: - log.debug('After time has not passed ' - 'skipping job: %s.', data['name']) - continue + now = datetime.datetime.now() # Used for quick lookups when detecting invalid option # combinations. @@ -1377,26 +1396,25 @@ class Schedule(object): continue if 'run_explicit' in data: - data = _handle_run_explicit(data) + data = _handle_run_explicit(data, loop_interval) run = data['run'] if True in [True for item in time_elements if item in data]: data = _handle_time_elements(data) elif 'once' in data: - data = _handle_once(data) + data = _handle_once(job, data, loop_interval) elif 'when' in data: - data = _handle_when(data) + data = _handle_when(job, data, loop_interval) elif 'cron' in data: - data = _handle_cron(data) + data = _handle_cron(job, data, loop_interval) else: continue # An error occurred so we bail out if '_error' in data and data['_error']: - log.debug('Sommething went wrong') continue - seconds = data['_next_fire_time'] - now + seconds = int((data['_next_fire_time'] - now).total_seconds()) if 'splay' in data: # Got "splay" configured, make decision to run a job based on that @@ -1405,10 +1423,10 @@ class Schedule(object): # still in the future. We should trigger job run # immediately otherwise. splay = _splay(data['splay']) - if now < data['_next_fire_time'] + splay: + if now < data['_next_fire_time'] + datetime.timedelta(seconds=splay): log.debug('schedule.handle_func: Adding splay of ' '%s seconds to next run.', splay) - data['_splay'] = data['_next_fire_time'] + splay + data['_splay'] = data['_next_fire_time'] + datetime.timedelta(seconds=splay) if 'when' in data: data['_run'] = True else: @@ -1417,12 +1435,13 @@ class Schedule(object): if data['_splay']: # The "splay" configuration has been already processed, just use it seconds = data['_splay'] - now + seconds = (data['_splay'] - now).total_seconds() if '_seconds' in data: if seconds <= 0: run = True elif 'when' in data and data['_run']: - if data['_next_fire_time'] <= now <= (data['_next_fire_time'] + self.opts['loop_interval']): + if data['_next_fire_time'] <= now <= (data['_next_fire_time'] + loop_interval): data['_run'] = False run = True elif 'cron' in data: @@ -1432,7 +1451,7 @@ class Schedule(object): data['_next_fire_time'] = None run = True elif 'once' in data: - if data['_next_fire_time'] <= now <= (data['_next_fire_time'] + self.opts['loop_interval']): + if data['_next_fire_time'] <= now <= (data['_next_fire_time'] + loop_interval): run = True elif seconds == 0: run = True @@ -1442,7 +1461,7 @@ class Schedule(object): data['_run_on_start'] = False elif run: if 'range' in data: - data = _handle_range(data) + data = _handle_range(job, data) # An error occurred so we bail out if '_error' in data and data['_error']: @@ -1459,7 +1478,7 @@ class Schedule(object): data['skip_during_range'] = self.skip_during_range if 'skip_during_range' in data and data['skip_during_range']: - data = _handle_skip_during_range(data) + data = _handle_skip_during_range(job, data, loop_interval) # An error occurred so we bail out if '_error' in data and data['_error']: @@ -1471,7 +1490,7 @@ class Schedule(object): func = data['func'] if 'skip_explicit' in data: - data = _handle_skip_explicit(data) + data = _handle_skip_explicit(data, loop_interval) # An error occurred so we bail out if '_error' in data and data['_error']: @@ -1482,12 +1501,35 @@ class Schedule(object): if 'func' in data: func = data['func'] + if 'until' in data: + data = _handle_until(job, data) + + # An error occurred so we bail out + if '_error' in data and data['_error']: + continue + + run = data['run'] + + if 'after' in data: + data = _handle_after(job, data) + + # An error occurred so we bail out + if '_error' in data and data['_error']: + continue + + run = data['run'] + # If the job item has continue, then we set run to False # so the job does not run but we still get the important # information calculated, eg. _next_fire_time if '_continue' in data and data['_continue']: run = False + # If there is no job specific enabled available, + # grab the global which defaults to True. + if 'enabled' not in data: + data['enabled'] = self.enabled + # Job is disabled, set run to False if 'enabled' in data and not data['enabled']: log.debug('Job: %s is disabled', job) @@ -1562,7 +1604,7 @@ class Schedule(object): if run: data['_last_run'] = now if '_seconds' in data: - data['_next_fire_time'] = now + data['_seconds'] + data['_next_fire_time'] = now + datetime.timedelta(seconds=data['_seconds']) data['_splay'] = None if salt.utils.platform.is_windows(): diff --git a/salt/utils/ssh.py b/salt/utils/ssh.py new file mode 100644 index 0000000000..665feb8403 --- /dev/null +++ b/salt/utils/ssh.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +# Import Python libs +from __future__ import absolute_import, print_function, unicode_literals +import re + +# Import salt libs +import salt.utils.files +import salt.utils.stringutils +from salt.exceptions import CommandExecutionError + + +def key_is_encrypted(key): + # NOTE: this is a temporary workaround until we can get salt/modules/ssh.py + # working on Windows. + try: + with salt.utils.files.fopen(key, 'r') as fp_: + key_data = salt.utils.stringutils.to_unicode(fp_.read()) + except (IOError, OSError) as exc: + # Raise a CommandExecutionError + salt.utils.files.process_read_exception(exc, key) + + is_private_key = re.search(r'BEGIN (?:\w+\s)*PRIVATE KEY', key_data) + is_encrypted = 'ENCRYPTED' in key_data + del key_data + + if not is_private_key: + raise CommandExecutionError('{0} is not a private key'.format(key)) + + return is_encrypted diff --git a/salt/utils/state.py b/salt/utils/state.py index c0fef6a04f..b90f36beaa 100644 --- a/salt/utils/state.py +++ b/salt/utils/state.py @@ -2,7 +2,7 @@ ''' Utility functions for state functions -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' # Import Python Libs diff --git a/salt/utils/stringutils.py b/salt/utils/stringutils.py index ba2dbb7893..df056f6459 100644 --- a/salt/utils/stringutils.py +++ b/salt/utils/stringutils.py @@ -5,6 +5,7 @@ Functions for manipulating or otherwise processing strings # Import Python libs from __future__ import absolute_import, print_function, unicode_literals +import base64 import errno import fnmatch import logging @@ -12,6 +13,7 @@ import os import shlex import re import time +import unicodedata # Import Salt libs from salt.utils.decorators.jinja import jinja_filter @@ -82,31 +84,34 @@ def to_str(s, encoding=None, errors='strict'): raise TypeError('expected str, bytearray, or unicode') -def to_unicode(s, encoding=None, errors='strict'): +def to_unicode(s, encoding=None, errors='strict', normalize=False): ''' Given str or unicode, return unicode (str for python 3) ''' + def _normalize(s): + return unicodedata.normalize('NFC', s) if normalize else s + if six.PY3: if isinstance(s, str): - return s + return _normalize(s) elif isinstance(s, (bytes, bytearray)): - return to_str(s, encoding, errors) + return _normalize(to_str(s, encoding, errors)) raise TypeError('expected str, bytes, or bytearray') else: # This needs to be str and not six.string_types, since if the string is # already a unicode type, it does not need to be decoded (and doing so # will raise an exception). if isinstance(s, unicode): # pylint: disable=incompatible-py3-code - return s + return _normalize(s) elif isinstance(s, (str, bytearray)): if encoding: - return s.decode(encoding, errors) + return _normalize(s.decode(encoding, errors)) else: try: - return s.decode(__salt_system_encoding__, errors) + return _normalize(s.decode(__salt_system_encoding__, errors)) except UnicodeDecodeError: # Fall back to UTF-8 - return s.decode('utf-8', errors) + return _normalize(s.decode('utf-8', errors)) raise TypeError('expected str or bytearray') @@ -203,7 +208,7 @@ def is_binary(data): @jinja_filter('random_str') def random(size=32): key = os.urandom(size) - return key.encode('base64').replace('\n', '')[:size] + return to_unicode(base64.b64encode(key).replace(b'\n', b'')[:size]) @jinja_filter('contains_whitespace') @@ -220,7 +225,7 @@ def human_to_bytes(size): return the number of bytes. Will return 0 if the argument has unexpected form. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 ''' sbytes = size[:-1] unit = size[-1] @@ -429,3 +434,38 @@ def print_cli(msg, retries=10, step=0.01): else: raise break + + +def get_context(template, line, num_lines=5, marker=None): + ''' + Returns debugging context around a line in a given string + + Returns:: string + ''' + template_lines = template.splitlines() + num_template_lines = len(template_lines) + + # In test mode, a single line template would return a crazy line number like, + # 357. Do this sanity check and if the given line is obviously wrong, just + # return the entire template + if line > num_template_lines: + return template + + context_start = max(0, line - num_lines - 1) # subt 1 for 0-based indexing + context_end = min(num_template_lines, line + num_lines) + error_line_in_context = line - context_start - 1 # subtr 1 for 0-based idx + + buf = [] + if context_start > 0: + buf.append('[...]') + error_line_in_context += 1 + + buf.extend(template_lines[context_start:context_end]) + + if context_end < num_template_lines: + buf.append('[...]') + + if marker: + buf[error_line_in_context] += marker + + return '---\n{0}\n---'.format('\n'.join(buf)) diff --git a/salt/utils/templates.py b/salt/utils/templates.py index 8e69a81502..09984c9594 100644 --- a/salt/utils/templates.py +++ b/salt/utils/templates.py @@ -95,41 +95,6 @@ class AliasedModule(object): return getattr(self.wrapped, name) -def get_context(template, line, num_lines=5, marker=None): - ''' - Returns debugging context around a line in a given string - - Returns:: string - ''' - template_lines = template.splitlines() - num_template_lines = len(template_lines) - - # in test, a single line template would return a crazy line number like, - # 357. do this sanity check and if the given line is obviously wrong, just - # return the entire template - if line > num_template_lines: - return template - - context_start = max(0, line - num_lines - 1) # subt 1 for 0-based indexing - context_end = min(num_template_lines, line + num_lines) - error_line_in_context = line - context_start - 1 # subtr 1 for 0-based idx - - buf = [] - if context_start > 0: - buf.append('[...]') - error_line_in_context += 1 - - buf.extend(template_lines[context_start:context_end]) - - if context_end < num_template_lines: - buf.append('[...]') - - if marker: - buf[error_line_in_context] += marker - - return '---\n{0}\n---'.format('\n'.join(buf)) - - def wrap_tmpl_func(render_str): def render_tmpl(tmplsrc, @@ -202,11 +167,9 @@ def wrap_tmpl_func(render_str): tmplsrc.close() try: output = render_str(tmplstr, context, tmplpath) - if six.PY2: - output = output.encode(SLS_ENCODING) if salt.utils.platform.is_windows(): newline = False - if salt.utils.stringutils.to_unicode(output).endswith(('\n', os.linesep)): + if salt.utils.stringutils.to_unicode(output, encoding=SLS_ENCODING).endswith(('\n', os.linesep)): newline = True # Write out with Windows newlines output = os.linesep.join(output.splitlines()) @@ -223,9 +186,7 @@ def wrap_tmpl_func(render_str): if to_str: # then render as string return dict(result=True, data=output) with tempfile.NamedTemporaryFile('wb', delete=False, prefix=salt.utils.files.TEMPFILE_PREFIX) as outf: - if six.PY3: - output = output.encode(SLS_ENCODING) - outf.write(output) + outf.write(salt.utils.stringutils.to_bytes(output, encoding=SLS_ENCODING)) # Note: If nothing is replaced or added by the rendering # function, then the contents of the output file will # be exactly the same as the input. @@ -315,7 +276,7 @@ def _get_jinja_error(trace, context=None): out = '\n{0}\n'.format(msg.splitlines()[0]) with salt.utils.files.fopen(template_path) as fp_: template_contents = salt.utils.stringutils.to_unicode(fp_.read()) - out += get_context( + out += salt.utils.stringutils.get_context( template_contents, line, marker=' <======================') @@ -417,15 +378,6 @@ def render_jinja_tmpl(tmplstr, context, tmplpath=None): template = jinja_env.from_string(tmplstr) template.globals.update(decoded_context) output = template.render(**decoded_context) - except jinja2.exceptions.TemplateSyntaxError as exc: - trace = traceback.extract_tb(sys.exc_info()[2]) - line, out = _get_jinja_error(trace, context=decoded_context) - if not line: - tmplstr = '' - raise SaltRenderError( - 'Jinja syntax error: {0}{1}'.format(exc, out), - line, - tmplstr) except jinja2.exceptions.UndefinedError as exc: trace = traceback.extract_tb(sys.exc_info()[2]) out = _get_jinja_error(trace, context=decoded_context)[1] @@ -436,6 +388,16 @@ def render_jinja_tmpl(tmplstr, context, tmplpath=None): 'Jinja variable {0}{1}'.format( exc, out), buf=tmplstr) + except (jinja2.exceptions.TemplateRuntimeError, + jinja2.exceptions.TemplateSyntaxError) as exc: + trace = traceback.extract_tb(sys.exc_info()[2]) + line, out = _get_jinja_error(trace, context=decoded_context) + if not line: + tmplstr = '' + raise SaltRenderError( + 'Jinja syntax error: {0}{1}'.format(exc, out), + line, + tmplstr) except (SaltInvocationError, CommandExecutionError) as exc: trace = traceback.extract_tb(sys.exc_info()[2]) line, out = _get_jinja_error(trace, context=decoded_context) diff --git a/salt/utils/value.py b/salt/utils/value.py index 4ca9fd86d4..cf564d7aa6 100644 --- a/salt/utils/value.py +++ b/salt/utils/value.py @@ -2,7 +2,7 @@ ''' Utility functions used for values. -.. versionadded:: Oxygen +.. versionadded:: 2018.3.0 ''' # Import Python libs diff --git a/salt/utils/vault.py b/salt/utils/vault.py index fd9bf4f4ed..1934673eda 100644 --- a/salt/utils/vault.py +++ b/salt/utils/vault.py @@ -98,7 +98,7 @@ def _get_vault_connection(): Get the connection details for calling Vault, from local configuration if it exists, or from the master otherwise ''' - if 'vault' in __opts__ and __opts__.get('__role', 'minion') == 'master': + def _use_local_config(): log.debug('Using Vault connection details from local config') try: if __opts__['vault']['auth']['method'] == 'approle': @@ -123,6 +123,11 @@ def _get_vault_connection(): except KeyError as err: errmsg = 'Minion has "vault" config section, but could not find key "{0}" within'.format(err.message) raise salt.exceptions.CommandExecutionError(errmsg) + + if 'vault' in __opts__ and __opts__.get('__role', 'minion') == 'master': + return _use_local_config() + elif any((__opts__['local'], __opts__['file_client'] == 'local', __opts__['master_type'] == 'disable')): + return _use_local_config() else: log.debug('Contacting master for Vault connection details') return _get_token_and_url_from_master() diff --git a/salt/utils/verify.py b/salt/utils/verify.py index 4bcf4689d4..0eeb95b402 100644 --- a/salt/utils/verify.py +++ b/salt/utils/verify.py @@ -31,7 +31,6 @@ import salt.utils.files import salt.utils.path import salt.utils.platform import salt.utils.user -import salt.utils.versions log = logging.getLogger(__name__) @@ -204,28 +203,16 @@ def verify_env( permissive=False, pki_dir='', skip_extra=False, - root_dir=ROOT_DIR, - sensitive_dirs=None): + root_dir=ROOT_DIR): ''' Verify that the named directories are in place and that the environment can shake the salt ''' - if pki_dir: - salt.utils.versions.warn_until( - 'Neon', - 'Use of \'pki_dir\' was detected: \'pki_dir\' has been deprecated ' - 'in favor of \'sensitive_dirs\'. Support for \'pki_dir\' will be ' - 'removed in Salt Neon.' - ) - sensitive_dirs = sensitive_dirs or [] - sensitive_dirs.append(list(pki_dir)) - if salt.utils.platform.is_windows(): return win_verify_env(root_dir, dirs, permissive=permissive, - skip_extra=skip_extra, - sensitive_dirs=sensitive_dirs) + skip_extra=skip_extra) import pwd # after confirming not running Windows try: pwnam = pwd.getpwnam(user) @@ -300,11 +287,10 @@ def verify_env( # to read in what it needs to integrate. # # If the permissions aren't correct, default to the more secure 700. - # If acls are enabled, the sensitive_dirs (i.e. pki_dir, key_dir) needs to - # remain readable, this is still secure because the private keys are still - # only readable by the user running the master - sensitive_dirs = sensitive_dirs or [] - if dir_ in sensitive_dirs: + # If acls are enabled, the pki_dir needs to remain readable, this + # is still secure because the private keys are still only readable + # by the user running the master + if dir_ == pki_dir: smode = stat.S_IMODE(mode.st_mode) if smode != 448 and smode != 488: if os.access(dir_, os.W_OK): @@ -555,22 +541,11 @@ def win_verify_env( dirs, permissive=False, pki_dir='', - skip_extra=False, - sensitive_dirs=None): + skip_extra=False): ''' Verify that the named directories are in place and that the environment can shake the salt ''' - if pki_dir: - salt.utils.versions.warn_until( - 'Neon', - 'Use of \'pki_dir\' was detected: \'pki_dir\' has been deprecated ' - 'in favor of \'sensitive_dirs\'. Support for \'pki_dir\' will be ' - 'removed in Salt Neon.' - ) - sensitive_dirs = sensitive_dirs or [] - sensitive_dirs.append(list(pki_dir)) - import salt.utils.win_functions import salt.utils.win_dacl import salt.utils.path @@ -647,9 +622,8 @@ def win_verify_env( sys.stderr.write(msg.format(dir_, err)) sys.exit(err.errno) - # The senitive_dirs (i.e. pki_dir, key_dir) gets its own permissions - sensitive_dirs = sensitive_dirs or [] - if dir_ in sensitive_dirs: + # The PKI dir gets its own permissions + if dir_ == pki_dir: try: # Make Administrators group the owner salt.utils.win_dacl.set_owner(path, 'S-1-5-32-544') diff --git a/salt/utils/vt.py b/salt/utils/vt.py index 4232289877..fdc6fbeb40 100644 --- a/salt/utils/vt.py +++ b/salt/utils/vt.py @@ -642,7 +642,7 @@ class Terminal(object): if self.child_fde in rlist: try: stderr = self._translate_newlines( - salt.utils.stringutils.to_str( + salt.utils.stringutils.to_unicode( os.read(self.child_fde, maxsize) ) ) @@ -675,7 +675,7 @@ class Terminal(object): if self.child_fd in rlist: try: stdout = self._translate_newlines( - salt.utils.stringutils.to_str( + salt.utils.stringutils.to_unicode( os.read(self.child_fd, maxsize) ) ) diff --git a/salt/utils/win_functions.py b/salt/utils/win_functions.py index d35b9d5ca1..a57c526700 100644 --- a/salt/utils/win_functions.py +++ b/salt/utils/win_functions.py @@ -5,6 +5,8 @@ missing functions in other modules ''' from __future__ import absolute_import, print_function, unicode_literals import platform +import re +import ctypes # Import Salt Libs from salt.exceptions import CommandExecutionError @@ -16,6 +18,7 @@ try: import win32api import win32net import win32security + from win32con import HWND_BROADCAST, WM_SETTINGCHANGE, SMTO_ABORTIFHUNG HAS_WIN32 = True except ImportError: HAS_WIN32 = False @@ -168,3 +171,122 @@ def enable_ctrl_logoff_handler(): lambda event: True if event == ctrl_logoff_event else False, 1 ) + + +def escape_argument(arg): + ''' + Escape the argument for the cmd.exe shell. + See http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx + + First we escape the quote chars to produce a argument suitable for + CommandLineToArgvW. We don't need to do this for simple arguments. + + Args: + arg (str): a single command line argument to escape for the cmd.exe shell + + Returns: + str: an escaped string suitable to be passed as a program argument to the cmd.exe shell + ''' + if not arg or re.search(r'(["\s])', arg): + arg = '"' + arg.replace('"', r'\"') + '"' + + return escape_for_cmd_exe(arg) + + +def escape_for_cmd_exe(arg): + ''' + Escape an argument string to be suitable to be passed to + cmd.exe on Windows + + This method takes an argument that is expected to already be properly + escaped for the receiving program to be properly parsed. This argument + will be further escaped to pass the interpolation performed by cmd.exe + unchanged. + + Any meta-characters will be escaped, removing the ability to e.g. use + redirects or variables. + + Args: + arg (str): a single command line argument to escape for cmd.exe + + Returns: + str: an escaped string suitable to be passed as a program argument to cmd.exe + ''' + meta_chars = '()%!^"<>&|' + meta_re = re.compile('(' + '|'.join(re.escape(char) for char in list(meta_chars)) + ')') + meta_map = {char: "^{0}".format(char) for char in meta_chars} + + def escape_meta_chars(m): + char = m.group(1) + return meta_map[char] + + return meta_re.sub(escape_meta_chars, arg) + + +def broadcast_setting_change(message='Environment'): + ''' + Send a WM_SETTINGCHANGE Broadcast to all Windows + + Args: + + message (str): + A string value representing the portion of the system that has been + updated and needs to be refreshed. Default is ``Environment``. These + are some common values: + + - "Environment" : to effect a change in the environment variables + - "intl" : to effect a change in locale settings + - "Policy" : to effect a change in Group Policy Settings + - a leaf node in the registry + - the name of a section in the ``Win.ini`` file + + See lParam within msdn docs for + `WM_SETTINGCHANGE `_ + for more information on Broadcasting Messages. + + See GWL_WNDPROC within msdn docs for + `SetWindowLong `_ + for information on how to retrieve those messages. + + .. note:: + This will only affect new processes that aren't launched by services. To + apply changes to the path or registry to services, the host must be + restarted. The ``salt-minion``, if running as a service, will not see + changes to the environment until the system is restarted. Services + inherit their environment from ``services.exe`` which does not respond + to messaging events. See + `MSDN Documentation `_ + for more information. + + CLI Example: + + ... code-block:: python + + import salt.utils.win_functions + salt.utils.win_functions.broadcast_setting_change('Environment') + ''' + # Listen for messages sent by this would involve working with the + # SetWindowLong function. This can be accessed via win32gui or through + # ctypes. You can find examples on how to do this by searching for + # `Accessing WGL_WNDPROC` on the internet. Here are some examples of how + # this might work: + # + # # using win32gui + # import win32con + # import win32gui + # old_function = win32gui.SetWindowLong(window_handle, win32con.GWL_WNDPROC, new_function) + # + # # using ctypes + # import ctypes + # import win32con + # from ctypes import c_long, c_int + # user32 = ctypes.WinDLL('user32', use_last_error=True) + # WndProcType = ctypes.WINFUNCTYPE(c_int, c_long, c_int, c_int) + # new_function = WndProcType + # old_function = user32.SetWindowLongW(window_handle, win32con.GWL_WNDPROC, new_function) + broadcast_message = ctypes.create_unicode_buffer(message) + user32 = ctypes.WinDLL('user32', use_last_error=True) + result = user32.SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, + broadcast_message, SMTO_ABORTIFHUNG, + 5000, 0) + return result == 1 diff --git a/salt/utils/win_osinfo.py b/salt/utils/win_osinfo.py index 98d8fc9c5b..ff409cdd1e 100644 --- a/salt/utils/win_osinfo.py +++ b/salt/utils/win_osinfo.py @@ -14,7 +14,8 @@ except (ImportError, ValueError): HAS_WIN32 = False if HAS_WIN32: - kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) + kernel32 = ctypes.WinDLL(str('kernel32'), # future lint: disable=blacklisted-function + use_last_error=True) # Although utils are often directly imported, it is also possible to use the diff --git a/salt/utils/win_runas.py b/salt/utils/win_runas.py index 66a22b3f1e..6dfa3008e2 100644 --- a/salt/utils/win_runas.py +++ b/salt/utils/win_runas.py @@ -46,8 +46,8 @@ def __virtual__(): if HAS_WIN32: # ctypes definitions - kernel32 = ctypes.WinDLL('kernel32') - advapi32 = ctypes.WinDLL('advapi32') + kernel32 = ctypes.WinDLL(str('kernel32')) # future lint: disable=blacklisted-function + advapi32 = ctypes.WinDLL(str('advapi32')) # future lint: disable=blacklisted-function INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value INVALID_DWORD_VALUE = wintypes.DWORD(-1).value # ~WinAPI diff --git a/salt/utils/yamldumper.py b/salt/utils/yamldumper.py index fd441c02d4..ae43154bf2 100644 --- a/salt/utils/yamldumper.py +++ b/salt/utils/yamldumper.py @@ -100,7 +100,7 @@ def get_dumper(dumper_name): def dump(data, stream=None, **kwargs): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Helper that wraps yaml.dump and ensures that we encode unicode strings unless explicitly told not to. diff --git a/salt/utils/yamlloader.py b/salt/utils/yamlloader.py index 9342818d02..fa1df6cc4c 100644 --- a/salt/utils/yamlloader.py +++ b/salt/utils/yamlloader.py @@ -5,10 +5,9 @@ Custom YAML loading in Salt # Import python libs from __future__ import absolute_import, print_function, unicode_literals +import re import warnings -# Import third party libs -import re import yaml # pylint: disable=blacklisted-import from yaml.nodes import MappingNode, SequenceNode from yaml.constructor import ConstructorError @@ -18,6 +17,8 @@ try: except Exception: pass +import salt.utils.stringutils + __all__ = ['SaltYamlSafeLoader', 'load', 'safe_load'] @@ -30,7 +31,7 @@ warnings.simplefilter('always', category=DuplicateKeyWarning) # with code integrated from https://gist.github.com/844388 -class SaltYamlSafeLoader(yaml.SafeLoader, object): +class SaltYamlSafeLoader(yaml.SafeLoader): ''' Create a custom YAML loader that uses the custom constructor. This allows for the YAML loading defaults to be manipulated based on needs within salt @@ -46,6 +47,9 @@ class SaltYamlSafeLoader(yaml.SafeLoader, object): self.add_constructor( 'tag:yaml.org,2002:omap', type(self).construct_yaml_map) + self.add_constructor( + 'tag:yaml.org,2002:str', + type(self).construct_yaml_str) self.add_constructor( 'tag:yaml.org,2002:python/unicode', type(self).construct_unicode) @@ -76,18 +80,25 @@ class SaltYamlSafeLoader(yaml.SafeLoader, object): self.flatten_mapping(node) + context = 'while constructing a mapping' mapping = self.dictclass() for key_node, value_node in node.value: key = self.construct_object(key_node, deep=deep) try: hash(key) except TypeError: - err = ('While constructing a mapping {0} found unacceptable ' - 'key {1}').format(node.start_mark, key_node.start_mark) - raise ConstructorError(err) + raise ConstructorError( + context, + node.start_mark, + "found unacceptable key {0}".format(key_node.value), + key_node.start_mark) value = self.construct_object(value_node, deep=deep) if key in mapping: - raise ConstructorError('Conflicting ID \'{0}\''.format(key)) + raise ConstructorError( + context, + node.start_mark, + "found conflicting ID '{0}'".format(key), + key_node.start_mark) mapping[key] = value return mapping @@ -112,6 +123,10 @@ class SaltYamlSafeLoader(yaml.SafeLoader, object): node.value = eval(node.value, {}, {}) # pylint: disable=W0123 return super(SaltYamlSafeLoader, self).construct_scalar(node) + def construct_yaml_str(self, node): + value = self.construct_scalar(node) + return salt.utils.stringutils.to_unicode(value) + def flatten_mapping(self, node): merge = [] index = 0 @@ -160,7 +175,7 @@ def load(stream, Loader=SaltYamlSafeLoader): def safe_load(stream, Loader=SaltYamlSafeLoader): ''' - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 Helper function which automagically uses our custom loader. ''' diff --git a/salt/utils/zeromq.py b/salt/utils/zeromq.py index 04151c5d52..27783223a6 100644 --- a/salt/utils/zeromq.py +++ b/salt/utils/zeromq.py @@ -5,21 +5,56 @@ ZMQ-specific functions # Import Python libs from __future__ import absolute_import, print_function, unicode_literals -# Import Salt libs +import logging +import tornado.ioloop from salt.exceptions import SaltSystemExit -# Import 3rd-party libs +log = logging.getLogger(__name__) + try: import zmq - HAS_ZMQ = True except ImportError: - HAS_ZMQ = False + zmq = None + log.debug('ZMQ module is not found') + +ZMQDefaultLoop = None +ZMQ_VERSION_INFO = (-1, -1, -1) +LIBZMQ_VERSION_INFO = (-1, -1, -1) + +try: + if zmq: + ZMQ_VERSION_INFO = tuple([int(v_el) for v_el in zmq.__version__.split('.')]) + LIBZMQ_VERSION_INFO = tuple([int(v_el) for v_el in zmq.zmq_version().split('.')]) + if ZMQ_VERSION_INFO[0] > 16: # 17.0.x+ deprecates zmq's ioloops + ZMQDefaultLoop = tornado.ioloop.IOLoop +except Exception: + log.exception('Error while getting LibZMQ/PyZMQ library version') + +if ZMQDefaultLoop is None: + try: + import zmq.eventloop.ioloop + # Support for ZeroMQ 13.x + if not hasattr(zmq.eventloop.ioloop, 'ZMQIOLoop'): + zmq.eventloop.ioloop.ZMQIOLoop = zmq.eventloop.ioloop.IOLoop + ZMQDefaultLoop = zmq.eventloop.ioloop.ZMQIOLoop + except ImportError: + ZMQDefaultLoop = tornado.ioloop.IOLoop + + +def install_zmq(): + ''' + While pyzmq 17 no longer needs any special integration for tornado, + older version still need one. + :return: + ''' + if zmq and ZMQ_VERSION_INFO[0] < 17: + zmq.eventloop.ioloop.install() def check_ipc_path_max_len(uri): # The socket path is limited to 107 characters on Solaris and # Linux, and 103 characters on BSD-based systems. - if not HAS_ZMQ: + if zmq is None: return ipc_path_max_len = getattr(zmq, 'IPC_PATH_MAX_LEN', 103) if ipc_path_max_len and len(uri) > ipc_path_max_len: diff --git a/salt/version.py b/salt/version.py index b19df19bba..ef5ab8758f 100644 --- a/salt/version.py +++ b/salt/version.py @@ -97,7 +97,7 @@ class SaltStackVersion(object): 'Boron' : (2016, 3), 'Carbon' : (2016, 11), 'Nitrogen' : (2017, 7), - 'Oxygen' : (MAX_SIZE - 101, 0), + 'Oxygen' : (2018, 3), 'Fluorine' : (MAX_SIZE - 100, 0), 'Neon' : (MAX_SIZE - 99, 0), 'Sodium' : (MAX_SIZE - 98, 0), diff --git a/setup.py b/setup.py index 56eb7a7410..30e459797e 100755 --- a/setup.py +++ b/setup.py @@ -522,8 +522,11 @@ class Sdist(sdist): self.run_command('write_salt_ssh_packaging_file') self.filelist.files.append(os.path.basename(PACKAGED_FOR_SALT_SSH_FILE)) - pkgfiles = [pkgfile if IS_PY3 else pkgfile.decode(__salt_system_encoding__) for pkgfile in files] - sdist.make_release_tree(self, base_dir, pkgfiles) + if not IS_PY3 and not isinstance(base_dir, str): + # Work around some bad code in distutils which logs unicode paths + # against a str format string. + base_dir = base_dir.encode('utf-8') + sdist.make_release_tree(self, base_dir, files) # Let's generate salt/_version.py to include in the sdist tarball self.distribution.running_salt_sdist = True diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index 576ab3cf9f..4092e4d3de 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -671,10 +671,15 @@ class TestDaemon(object): else: os.environ['SSH_DAEMON_RUNNING'] = 'True' roster_path = os.path.join(FILES, 'conf/_ssh/roster') + syndic_roster_path = os.path.join(FILES, 'conf/_ssh/syndic_roster') shutil.copy(roster_path, RUNTIME_VARS.TMP_CONF_DIR) + shutil.copy(syndic_roster_path, os.path.join(RUNTIME_VARS.TMP_SYNDIC_MASTER_CONF_DIR, 'roster')) with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.TMP_CONF_DIR, 'roster'), 'a') as roster: roster.write(' user: {0}\n'.format(RUNTIME_VARS.RUNNING_TESTS_USER)) roster.write(' priv: {0}/{1}'.format(RUNTIME_VARS.TMP_CONF_DIR, 'key_test')) + with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.TMP_SYNDIC_MASTER_CONF_DIR, 'roster'), 'a') as roster: + roster.write(' user: {0}\n'.format(RUNTIME_VARS.RUNNING_TESTS_USER)) + roster.write(' priv: {0}/{1}'.format(RUNTIME_VARS.TMP_CONF_DIR, 'key_test')) sys.stdout.write( ' {LIGHT_GREEN}STARTED!\n{ENDC}'.format( **self.colors diff --git a/tests/integration/cli/test_batch.py b/tests/integration/cli/test_batch.py index b63e7e7ecc..4faaf8ec39 100644 --- a/tests/integration/cli/test_batch.py +++ b/tests/integration/cli/test_batch.py @@ -19,7 +19,8 @@ class BatchTest(ShellCase): Tests executing a simple batch command to help catch regressions ''' ret = 'Executing run on [\'sub_minion\']' - cmd = self.run_salt('\'*\' test.echo \'batch testing\' -b 50%') + + cmd = self.run_salt('\'*minion\' test.echo \'batch testing\' -b 50%') self.assertIn(ret, cmd) def test_batch_run_number(self): @@ -28,7 +29,7 @@ class BatchTest(ShellCase): a percentage with full batch CLI call. ''' ret = "Executing run on ['minion', 'sub_minion']" - cmd = self.run_salt('\'*\' test.ping --batch-size 2') + cmd = self.run_salt('\'*minion\' test.ping --batch-size 2') self.assertIn(ret, cmd) def test_batch_run_grains_targeting(self): @@ -45,7 +46,7 @@ class BatchTest(ShellCase): os_grain = item os_grain = os_grain.strip() - cmd = self.run_salt('-G \'os:{0}\' -b 25% test.ping'.format(os_grain)) + cmd = self.run_salt('-C \'G@os:{0} and not localhost\' -b 25% test.ping'.format(os_grain)) self.assertIn(sub_min_ret, cmd) self.assertIn(min_ret, cmd) @@ -53,5 +54,5 @@ class BatchTest(ShellCase): ''' Test that a failed state returns a non-zero exit code in batch mode ''' - cmd = self.run_salt(' "*" state.single test.fail_without_changes name=test_me -b 25%', with_retcode=True) + cmd = self.run_salt(' "*minion" state.single test.fail_without_changes name=test_me -b 33%', with_retcode=True) self.assertEqual(cmd[-1], 2) diff --git a/tests/integration/cloud/providers/test_dimensiondata.py b/tests/integration/cloud/providers/test_dimensiondata.py new file mode 100644 index 0000000000..bd8425f528 --- /dev/null +++ b/tests/integration/cloud/providers/test_dimensiondata.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +''' +Integration tests for the Dimension Data cloud provider +''' + +# Import Python Libs +from __future__ import absolute_import, print_function, unicode_literals +import os +import random +import string + +# Import Salt Testing Libs +from tests.support.case import ShellCase +from tests.support.paths import FILES +from tests.support.helpers import expensiveTest + +# Import Salt Libs +from salt.config import cloud_providers_config +from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin + +# Create the cloud instance name to be used throughout the tests +INSTANCE_NAME = _random_name('CLOUD-TEST-') +PROVIDER_NAME = 'dimensiondata' + + +def _random_name(size=6): + ''' + Generates a random cloud instance name + ''' + return 'cloud-test-' + ''.join( + random.choice(string.ascii_lowercase + string.digits) + for x in range(size) + ) + + +class DimensionDataTest(ShellCase): + ''' + Integration tests for the Dimension Data cloud provider in Salt-Cloud + ''' + + @expensiveTest + def setUp(self): + ''' + Sets up the test requirements + ''' + super(DimensionDataTest, self).setUp() + + # check if appropriate cloud provider and profile files are present + profile_str = 'dimensiondata-config' + providers = self.run_cloud('--list-providers') + if profile_str + ':' not in providers: + self.skipTest( + 'Configuration file for {0} was not found. Check {0}.conf files ' + 'in tests/integration/files/conf/cloud.*.d/ to run these tests.' + .format(PROVIDER_NAME) + ) + + # check if user_id, key, and region are present + config = cloud_providers_config( + os.path.join( + FILES, + 'conf', + 'cloud.providers.d', + PROVIDER_NAME + '.conf' + ) + ) + + user_id = config[profile_str][PROVIDER_NAME]['user_id'] + key = config[profile_str][PROVIDER_NAME]['key'] + region = config[profile_str][PROVIDER_NAME]['region'] + + if user_id == '' or key == '' or region == '': + self.skipTest( + 'A user Id, password, and a region ' + 'must be provided to run these tests. Check ' + 'tests/integration/files/conf/cloud.providers.d/{0}.conf' + .format(PROVIDER_NAME) + ) + + def test_list_images(self): + ''' + Tests the return of running the --list-images command for the dimensiondata cloud provider + ''' + image_list = self.run_cloud('--list-images {0}'.format(PROVIDER_NAME)) + self.assertIn( + 'Ubuntu 14.04 2 CPU', + [i.strip() for i in image_list] + ) + + def test_list_locations(self): + ''' + Tests the return of running the --list-locations command for the dimensiondata cloud provider + ''' + _list_locations = self.run_cloud('--list-locations {0}'.format(PROVIDER_NAME)) + self.assertIn( + 'Australia - Melbourne MCP2', + [i.strip() for i in _list_locations] + ) + + def test_list_sizes(self): + ''' + Tests the return of running the --list-sizes command for the dimensiondata cloud provider + ''' + _list_sizes = self.run_cloud('--list-sizes {0}'.format(PROVIDER_NAME)) + self.assertIn( + 'default', + [i.strip() for i in _list_sizes] + ) + + def test_instance(self): + ''' + Test creating an instance on Dimension Data's cloud + ''' + # check if instance with salt installed returned + try: + self.assertIn( + INSTANCE_NAME, + [i.strip() for i in self.run_cloud('-p dimensiondata-test {0}'.format(INSTANCE_NAME), timeout=500)] + ) + except AssertionError: + self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME), timeout=500) + raise + + # delete the instance + try: + self.assertIn( + 'True', + [i.strip() for i in self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME), timeout=500)] + ) + except AssertionError: + raise + + # Final clean-up of created instance, in case something went wrong. + # This was originally in a tearDown function, but that didn't make sense + # To run this for each test when not all tests create instances. + if INSTANCE_NAME in [i.strip() for i in self.run_cloud('--query')]: + self.run_cloud('-d {0} --assume-yes'.format(INSTANCE_NAME), timeout=500) diff --git a/tests/integration/cloud/providers/test_gce.py b/tests/integration/cloud/providers/test_gce.py index 7a5720b661..902002ffc0 100644 --- a/tests/integration/cloud/providers/test_gce.py +++ b/tests/integration/cloud/providers/test_gce.py @@ -36,7 +36,7 @@ class GCETest(ShellCase): provider = 'gce' providers = self.run_cloud('--list-providers') # Create the cloud instance name to be used throughout the tests - self.INSTANCE_NAME = generate_random_name('cloud-test-') + self.INSTANCE_NAME = generate_random_name('cloud-test-').lower() if profile_str not in providers: self.skipTest( diff --git a/tests/integration/cloud/providers/test_msazure.py b/tests/integration/cloud/providers/test_msazure.py index fcecb43718..c02cabf5d2 100644 --- a/tests/integration/cloud/providers/test_msazure.py +++ b/tests/integration/cloud/providers/test_msazure.py @@ -45,7 +45,7 @@ def __has_required_azure(): else: version = LooseVersion(azure.common.__version__) - if REQUIRED_AZURE <= version: + if LooseVersion(REQUIRED_AZURE) <= version: return True return False diff --git a/tests/integration/files/conf/_ssh/syndic_roster b/tests/integration/files/conf/_ssh/syndic_roster new file mode 100644 index 0000000000..4c8ad5e2ff --- /dev/null +++ b/tests/integration/files/conf/_ssh/syndic_roster @@ -0,0 +1,5 @@ +syndic_localhost: + host: 127.0.0.1 + port: 2827 + mine_functions: + test.arg: ['itworked'] diff --git a/tests/integration/files/conf/cloud.profiles.d/digital_ocean.conf b/tests/integration/files/conf/cloud.profiles.d/digitalocean.conf similarity index 100% rename from tests/integration/files/conf/cloud.profiles.d/digital_ocean.conf rename to tests/integration/files/conf/cloud.profiles.d/digitalocean.conf diff --git a/tests/integration/files/conf/cloud.profiles.d/dimensiondata.conf b/tests/integration/files/conf/cloud.profiles.d/dimensiondata.conf new file mode 100644 index 0000000000..a698e7a5cc --- /dev/null +++ b/tests/integration/files/conf/cloud.profiles.d/dimensiondata.conf @@ -0,0 +1,11 @@ +dimensiondata-test: + provider: dimensiondata-config + image: 42816eb2-9846-4483-95c3-7d7fbddebf2c + size: default + location: AU10 + is_started: yes + description: 'Salt Ubuntu test' + network_domain: '' + vlan: '' + ssh_interface: private_ips + auth: '' diff --git a/tests/integration/files/conf/cloud.providers.d/digital_ocean.conf b/tests/integration/files/conf/cloud.providers.d/digitalocean.conf similarity index 100% rename from tests/integration/files/conf/cloud.providers.d/digital_ocean.conf rename to tests/integration/files/conf/cloud.providers.d/digitalocean.conf diff --git a/tests/integration/files/conf/cloud.providers.d/dimensiondata.conf b/tests/integration/files/conf/cloud.providers.d/dimensiondata.conf new file mode 100644 index 0000000000..f54d77f326 --- /dev/null +++ b/tests/integration/files/conf/cloud.providers.d/dimensiondata.conf @@ -0,0 +1,5 @@ +dimensiondata-config: + driver: dimensiondata + user_id: '' + key: '' + region: 'dd-au' diff --git a/tests/integration/files/conf/master b/tests/integration/files/conf/master index 06b9f32eb7..b29eda31b6 100644 --- a/tests/integration/files/conf/master +++ b/tests/integration/files/conf/master @@ -102,3 +102,7 @@ autosign_file: autosign_file # disable discovery for test suite saltstack/salt-jenkins#683 discovery: false + +# enable using ssh minions and regular minions +enable_ssh_minions: True +ignore_host_keys: True diff --git a/tests/integration/files/conf/syndic_master b/tests/integration/files/conf/syndic_master index c7c5edd05c..2778a35917 100644 --- a/tests/integration/files/conf/syndic_master +++ b/tests/integration/files/conf/syndic_master @@ -23,3 +23,7 @@ tcp_master_workers: 54515 # Syndic Settings order_masters: True + +# enable using ssh minions and regular minions +enable_ssh_minions: True +ignore_host_keys: True diff --git a/tests/integration/files/file/base/random_bytes b/tests/integration/files/file/base/random_bytes new file mode 100644 index 0000000000..bac5364ab8 --- /dev/null +++ b/tests/integration/files/file/base/random_bytes @@ -0,0 +1 @@ + diff --git a/tests/integration/files/file/prod/issue45893/custom.tar.gz b/tests/integration/files/file/prod/issue45893/custom.tar.gz new file mode 100644 index 0000000000..584852716c Binary files /dev/null and b/tests/integration/files/file/prod/issue45893/custom.tar.gz differ diff --git a/tests/integration/files/file/prod/issue45893/init.sls b/tests/integration/files/file/prod/issue45893/init.sls new file mode 100644 index 0000000000..28e4ff0fe2 --- /dev/null +++ b/tests/integration/files/file/prod/issue45893/init.sls @@ -0,0 +1,5 @@ +test_non_base_env: + archive.extracted: + - name: {{ pillar['issue45893.name'] }} + - source: salt://issue45893/custom.tar.gz + - keep: False diff --git a/tests/integration/modules/test_cmdmod.py b/tests/integration/modules/test_cmdmod.py index ae7adf9573..5701dd7f43 100644 --- a/tests/integration/modules/test_cmdmod.py +++ b/tests/integration/modules/test_cmdmod.py @@ -144,7 +144,7 @@ class CMDModuleTest(ModuleCase): ''' self.assertEqual(self.run_function('cmd.run', ['bad_command --foo']).rstrip(), - 'ERROR: This shell command is not permitted: "bad_command --foo"') + 'ERROR: The shell command "bad_command --foo" is not permitted') def test_script(self): ''' diff --git a/tests/integration/modules/test_cp.py b/tests/integration/modules/test_cp.py index 4f742b0fc9..f473283507 100644 --- a/tests/integration/modules/test_cp.py +++ b/tests/integration/modules/test_cp.py @@ -540,6 +540,7 @@ class CPModuleTest(ModuleCase): url = url_prefix + (code or 'actual_file') log.debug('attempting to cache %s', url) ret = self.run_function('cp.cache_file', [url]) + self.assertTrue(ret) with salt.utils.files.fopen(ret) as fp_: cached_contents = salt.utils.stringutils.to_unicode(fp_.read()) self.assertEqual(cached_contents, file_contents) diff --git a/tests/integration/modules/test_mac_user.py b/tests/integration/modules/test_mac_user.py index 617a1aa6bc..c68f2a7ee9 100644 --- a/tests/integration/modules/test_mac_user.py +++ b/tests/integration/modules/test_mac_user.py @@ -19,6 +19,7 @@ from salt.exceptions import CommandExecutionError # Import 3rd-party libs from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin +import salt.ext.six as six def __random_string(size=6): @@ -173,8 +174,11 @@ class MacUserModuleTest(ModuleCase): self.assertTrue(os.path.exists('/etc/kcpassword')) # Are the contents of the file correct - test_data = b".\xc3\xb8'B\xc2\xa0\xc3\x99\xc2\xad\xc2\x8b\xc3\x8d\xc3\x8dl" - with salt.utils.files.fopen('/etc/kcpassword', 'rb') as f: + if six.PY2: + test_data = b'.\xf8\'B\xa0\xd9\xad\x8b\xcd\xcdl' + else: + test_data = b".\xc3\xb8'B\xc2\xa0\xc3\x99\xc2\xad\xc2\x8b\xc3\x8d\xc3\x8dl" + with salt.utils.files.fopen('/etc/kcpassword', 'r' if six.PY2 else 'rb') as f: file_data = f.read() self.assertEqual(test_data, file_data) diff --git a/tests/integration/modules/test_state.py b/tests/integration/modules/test_state.py index c79730dfcc..8156854983 100644 --- a/tests/integration/modules/test_state.py +++ b/tests/integration/modules/test_state.py @@ -1379,6 +1379,20 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin): expected_result = 'Command "echo "Success!"" run' self.assertIn(expected_result, test_data) + def test_onchanges_requisite_with_duration(self): + ''' + Tests a simple state using the onchanges requisite + the state will not run but results will include duration + ''' + + # Only run the state once and keep the return data + state_run = self.run_function('state.sls', mods='requisites.onchanges_simple') + + # Then, test the result of the state run when changes are not expected to happen + # and ensure duration is included in the results + test_data = state_run['cmd_|-test_non_changing_state_|-echo "Should not run"_|-run'] + self.assertIn('duration', test_data) + # onfail tests def test_onfail_requisite(self): @@ -1450,6 +1464,18 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin): expected_result = 'State was not run because onfail req did not change' self.assertIn(expected_result, test_data) + def test_onfail_requisite_with_duration(self): + ''' + Tests a simple state using the onfail requisite + ''' + + # Only run the state once and keep the return data + state_run = self.run_function('state.sls', mods='requisites.onfail_simple') + + # Then, test the result of the state run when a failure is not expected to happen + test_data = state_run['cmd_|-test_non_failing_state_|-echo "Should not run"_|-run'] + self.assertIn('duration', test_data) + # listen tests def test_listen_requisite(self): diff --git a/tests/integration/netapi/rest_tornado/test_app.py b/tests/integration/netapi/rest_tornado/test_app.py index 3efec193d8..96bb42f0f9 100644 --- a/tests/integration/netapi/rest_tornado/test_app.py +++ b/tests/integration/netapi/rest_tornado/test_app.py @@ -18,12 +18,8 @@ from tests.support.unit import skipIf # Import 3rd-party libs from salt.ext import six -try: - import zmq - from zmq.eventloop.ioloop import ZMQIOLoop - HAS_ZMQ_IOLOOP = True -except ImportError: - HAS_ZMQ_IOLOOP = False +from salt.utils.zeromq import zmq, ZMQDefaultLoop as ZMQIOLoop +HAS_ZMQ_IOLOOP = bool(zmq) class _SaltnadoIntegrationTestCase(SaltnadoTestCase): # pylint: disable=abstract-method @@ -178,7 +174,7 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase): # TODO: verify pub function? Maybe look at how we test the publisher self.assertEqual(len(ret), 1) self.assertIn('jid', ret[0]) - self.assertEqual(ret[0]['minions'], sorted(['minion', 'sub_minion'])) + self.assertEqual(ret[0]['minions'], sorted(['minion', 'sub_minion', 'localhost'])) def test_multi_local_async_post(self): low = [{'client': 'local_async', @@ -204,8 +200,8 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase): self.assertEqual(len(ret), 2) self.assertIn('jid', ret[0]) self.assertIn('jid', ret[1]) - self.assertEqual(ret[0]['minions'], sorted(['minion', 'sub_minion'])) - self.assertEqual(ret[1]['minions'], sorted(['minion', 'sub_minion'])) + self.assertEqual(ret[0]['minions'], sorted(['minion', 'sub_minion', 'localhost'])) + self.assertEqual(ret[1]['minions'], sorted(['minion', 'sub_minion', 'localhost'])) def test_multi_local_async_post_multitoken(self): low = [{'client': 'local_async', @@ -239,8 +235,8 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase): self.assertIn('jid', ret[0]) # the first 2 are regular returns self.assertIn('jid', ret[1]) self.assertIn('Authentication error occurred.', ret[2]) # bad auth - self.assertEqual(ret[0]['minions'], sorted(['minion', 'sub_minion'])) - self.assertEqual(ret[1]['minions'], sorted(['minion', 'sub_minion'])) + self.assertEqual(ret[0]['minions'], sorted(['minion', 'sub_minion', 'localhost'])) + self.assertEqual(ret[1]['minions'], sorted(['minion', 'sub_minion', 'localhost'])) def test_simple_local_async_post_no_tgt(self): low = [{'client': 'local_async', @@ -271,7 +267,7 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase): ) response_obj = salt.utils.json.loads(response.body) self.assertEqual(len(response_obj['return']), 1) - self.assertEqual(set(response_obj['return'][0]), set(['minion', 'sub_minion'])) + self.assertEqual(set(response_obj['return'][0]), set(['localhost', 'minion', 'sub_minion'])) # runner_async tests def test_simple_local_runner_async_post(self): @@ -333,7 +329,7 @@ class TestMinionSaltAPIHandler(_SaltnadoIntegrationTestCase): self.assertEqual(response_obj['return'][0]['minion']['id'], 'minion') def test_post(self): - low = [{'tgt': '*', + low = [{'tgt': '*minion', 'fun': 'test.ping', }] response = self.fetch('/minions', @@ -355,7 +351,7 @@ class TestMinionSaltAPIHandler(_SaltnadoIntegrationTestCase): def test_post_with_client(self): # get a token for this test low = [{'client': 'local_async', - 'tgt': '*', + 'tgt': '*minion', 'fun': 'test.ping', }] response = self.fetch('/minions', diff --git a/tests/integration/netapi/test_client.py b/tests/integration/netapi/test_client.py index 3f1e66c806..2de5f7aa48 100644 --- a/tests/integration/netapi/test_client.py +++ b/tests/integration/netapi/test_client.py @@ -35,7 +35,7 @@ class NetapiClientTest(TestCase): low.update(self.eauth_creds) ret = self.netapi.run(low) - self.assertEqual(ret, {'minion': True, 'sub_minion': True}) + self.assertEqual(ret, {'minion': True, 'sub_minion': True, 'localhost': True}) def test_local_async(self): low = {'client': 'local_async', 'tgt': '*', 'fun': 'test.ping'} @@ -47,7 +47,7 @@ class NetapiClientTest(TestCase): self.assertIn('jid', ret) ret.pop('jid', None) ret['minions'] = sorted(ret['minions']) - self.assertEqual(ret, {'minions': sorted(['minion', 'sub_minion'])}) + self.assertEqual(ret, {'minions': sorted(['minion', 'sub_minion', 'localhost'])}) def test_wheel(self): low = {'client': 'wheel', 'fun': 'key.list_all'} diff --git a/tests/integration/pillar/test_git_pillar.py b/tests/integration/pillar/test_git_pillar.py index 8dc6ce01b0..e97e720bab 100644 --- a/tests/integration/pillar/test_git_pillar.py +++ b/tests/integration/pillar/test_git_pillar.py @@ -87,24 +87,27 @@ from tests.support.unit import skipIf # Import Salt libs import salt.utils.path import salt.utils.platform -from salt.utils.gitfs import GITPYTHON_MINVER, PYGIT2_MINVER -from salt.utils.versions import LooseVersion from salt.modules.virtualenv_mod import KNOWN_BINARY_NAMES as VIRTUALENV_NAMES from salt.ext.six.moves import range # pylint: disable=redefined-builtin +from salt.utils.gitfs import ( + GITPYTHON_VERSION, + GITPYTHON_MINVER, + PYGIT2_VERSION, + PYGIT2_MINVER, + LIBGIT2_VERSION, + LIBGIT2_MINVER +) # Check for requisite components try: - import git - HAS_GITPYTHON = \ - LooseVersion(git.__version__) >= LooseVersion(GITPYTHON_MINVER) + HAS_GITPYTHON = GITPYTHON_VERSION >= GITPYTHON_MINVER except ImportError: HAS_GITPYTHON = False try: - import pygit2 - HAS_PYGIT2 = \ - LooseVersion(pygit2.__version__) >= LooseVersion(PYGIT2_MINVER) -except ImportError: + HAS_PYGIT2 = PYGIT2_VERSION >= PYGIT2_MINVER \ + and LIBGIT2_VERSION >= LIBGIT2_MINVER +except AttributeError: HAS_PYGIT2 = False HAS_SSHD = bool(salt.utils.path.which('sshd')) @@ -419,7 +422,7 @@ class TestGitPythonAuthenticatedHTTP(TestGitPythonHTTP, GitPythonMixin): @skipIf(NO_MOCK, NO_MOCK_REASON) @skipIf(_windows_or_mac(), 'minion is windows or mac') @skip_if_not_root -@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} required'.format(PYGIT2_MINVER)) +@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} and libgit2 >= {1} required'.format(PYGIT2_MINVER, LIBGIT2_MINVER)) @skipIf(not HAS_SSHD, 'sshd not present') class TestPygit2SSH(GitPillarSSHTestBase): ''' @@ -433,12 +436,6 @@ class TestPygit2SSH(GitPillarSSHTestBase): username = USERNAME passphrase = PASSWORD - def setUp(self): - super(TestPygit2SSH, self).setUp() - if self.is_el7(): # pylint: disable=E1120 - self.skipTest( - 'skipped until EPEL7 fixes pygit2/libgit2 version mismatch') - @requires_system_grains def test_single_source(self, grains): ''' @@ -1199,19 +1196,13 @@ class TestPygit2SSH(GitPillarSSHTestBase): @skipIf(NO_MOCK, NO_MOCK_REASON) @skipIf(_windows_or_mac(), 'minion is windows or mac') @skip_if_not_root -@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} required'.format(PYGIT2_MINVER)) +@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} and libgit2 >= {1} required'.format(PYGIT2_MINVER, LIBGIT2_MINVER)) @skipIf(not HAS_NGINX, 'nginx not present') @skipIf(not HAS_VIRTUALENV, 'virtualenv not present') class TestPygit2HTTP(GitPillarHTTPTestBase): ''' Test git_pillar with pygit2 using SSH authentication ''' - def setUp(self): - super(TestPygit2HTTP, self).setUp() - if self.is_el7(): # pylint: disable=E1120 - self.skipTest( - 'skipped until EPEL7 fixes pygit2/libgit2 version mismatch') - def test_single_source(self): ''' Test using a single ext_pillar repo @@ -1452,7 +1443,7 @@ class TestPygit2HTTP(GitPillarHTTPTestBase): @skipIf(NO_MOCK, NO_MOCK_REASON) @skipIf(_windows_or_mac(), 'minion is windows or mac') @skip_if_not_root -@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} required'.format(PYGIT2_MINVER)) +@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} and libgit2 >= {1} required'.format(PYGIT2_MINVER, LIBGIT2_MINVER)) @skipIf(not HAS_NGINX, 'nginx not present') @skipIf(not HAS_VIRTUALENV, 'virtualenv not present') class TestPygit2AuthenticatedHTTP(GitPillarHTTPTestBase): @@ -1465,12 +1456,6 @@ class TestPygit2AuthenticatedHTTP(GitPillarHTTPTestBase): user = USERNAME password = PASSWORD - def setUp(self): - super(TestPygit2AuthenticatedHTTP, self).setUp() - if self.is_el7(): # pylint: disable=E1120 - self.skipTest( - 'skipped until EPEL7 fixes pygit2/libgit2 version mismatch') - def test_single_source(self): ''' Test using a single ext_pillar repo diff --git a/tests/integration/runners/test_cache.py b/tests/integration/runners/test_cache.py index 064e887b05..7c6d73761f 100644 --- a/tests/integration/runners/test_cache.py +++ b/tests/integration/runners/test_cache.py @@ -34,3 +34,15 @@ class ManageTest(ShellCase): ret = self.run_run_plus('cache.flush', bank='cachetest/runner', key='test_cache') ret = self.run_run_plus('cache.list', bank='cachetest/runner') self.assertNotIn('test_cache', ret['return']) + + def test_cache_invalid(self): + ''' + Store, list, fetch, then flush data + ''' + # Store the data + ret = self.run_run_plus( + 'cache.store', + ) + # Make sure we can see the new key + expected = 'Passed invalid arguments:' + self.assertIn(expected, ret['return']) diff --git a/tests/integration/runners/test_jobs.py b/tests/integration/runners/test_jobs.py index e9d6b19cf1..d63d0955f8 100644 --- a/tests/integration/runners/test_jobs.py +++ b/tests/integration/runners/test_jobs.py @@ -30,6 +30,14 @@ class ManageTest(ShellCase): self.assertEqual(ret['return'], {}) self.assertEqual(ret['out'], []) + def test_lookup_jid_invalid(self): + ''' + jobs.lookup_jid + ''' + ret = self.run_run_plus('jobs.lookup_jid') + expected = 'Passed invalid arguments:' + self.assertIn(expected, ret['return']) + @skipIf(True, 'to be re-enabled when #23623 is merged') def test_list_jobs(self): ''' diff --git a/tests/integration/runners/test_salt.py b/tests/integration/runners/test_salt.py index 37488f9a48..71683a8e25 100644 --- a/tests/integration/runners/test_salt.py +++ b/tests/integration/runners/test_salt.py @@ -25,3 +25,11 @@ class SaltRunnerTest(ShellCase): self.assertEqual(out_ret, 'True') self.assertTrue(return_ret) + + def test_salt_cmd_invalid(self): + ''' + test return values of salt.cmd invalid parameters + ''' + ret = self.run_run_plus('salt.cmd') + expected = 'Passed invalid arguments:' + self.assertIn(expected, ret['return']) diff --git a/tests/integration/runners/test_state.py b/tests/integration/runners/test_state.py index 6385b46910..dac7b3f033 100644 --- a/tests/integration/runners/test_state.py +++ b/tests/integration/runners/test_state.py @@ -18,6 +18,7 @@ from salt.ext.six.moves import queue from tests.support.case import ShellCase from tests.support.unit import skipIf from tests.support.paths import TMP +from tests.support.helpers import flaky # Import Salt Libs import salt.utils.platform @@ -44,6 +45,7 @@ class StateRunnerTest(ShellCase): q.put(ret) q.task_done() + @flaky def test_orchestrate_output(self): ''' Ensure the orchestrate runner outputs useful state data. diff --git a/tests/integration/scheduler/test_eval.py b/tests/integration/scheduler/test_eval.py index e5d03642c7..c16f0495e6 100644 --- a/tests/integration/scheduler/test_eval.py +++ b/tests/integration/scheduler/test_eval.py @@ -3,10 +3,10 @@ # Import Python libs from __future__ import absolute_import import copy +import datetime import logging import os import random -import time import dateutil.parser as dateutil_parser @@ -55,7 +55,7 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): self.schedule.opts['grains']['whens'] = {'tea time': '11/29/2017 12:00pm'} def tearDown(self): - del self.schedule + self.schedule.reset() def test_eval(self): ''' @@ -69,8 +69,8 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): } } } - run_time2 = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) - run_time1 = run_time2 - 1 + run_time2 = dateutil_parser.parse('11/29/2017 4:00pm') + run_time1 = run_time2 - datetime.timedelta(seconds=1) # Add the job to the scheduler self.schedule.opts.update(job) @@ -100,8 +100,8 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): } } } - run_time1 = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) - run_time2 = int(time.mktime(dateutil_parser.parse('11/29/2017 5:00pm').timetuple())) + run_time1 = dateutil_parser.parse('11/29/2017 4:00pm') + run_time2 = dateutil_parser.parse('11/29/2017 5:00pm') # Add the job to the scheduler self.schedule.opts.update(job) @@ -128,7 +128,7 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): } } } - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 12:00pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 12:00pm') # Add the job to the scheduler self.schedule.opts.update(job) @@ -154,16 +154,16 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): LOOP_INTERVAL = random.randint(30, 59) self.schedule.opts['loop_interval'] = LOOP_INTERVAL - run_time2 = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) + run_time2 = dateutil_parser.parse('11/29/2017 4:00pm') # Add the job to the scheduler self.schedule.opts.update(job) # Evaluate 1 second at the run time - self.schedule.eval(now=run_time2 + LOOP_INTERVAL) + self.schedule.eval(now=run_time2 + datetime.timedelta(seconds=LOOP_INTERVAL)) ret = self.schedule.job_status('job1') - self.assertEqual(ret['_last_run'], run_time2 + LOOP_INTERVAL) + self.assertEqual(ret['_last_run'], run_time2 + datetime.timedelta(seconds=LOOP_INTERVAL)) def test_eval_multiple_whens_loop_interval(self): ''' @@ -184,21 +184,21 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): LOOP_INTERVAL = random.randint(30, 59) self.schedule.opts['loop_interval'] = LOOP_INTERVAL - run_time1 = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) - run_time2 = int(time.mktime(dateutil_parser.parse('11/29/2017 5:00pm').timetuple())) + run_time1 = dateutil_parser.parse('11/29/2017 4:00pm') + datetime.timedelta(seconds=LOOP_INTERVAL) + run_time2 = dateutil_parser.parse('11/29/2017 5:00pm') + datetime.timedelta(seconds=LOOP_INTERVAL) # Add the job to the scheduler self.schedule.opts.update(job) # Evaluate 1 second at the run time - self.schedule.eval(now=run_time1 + LOOP_INTERVAL) + self.schedule.eval(now=run_time1) ret = self.schedule.job_status('job1') - self.assertEqual(ret['_last_run'], run_time1 + LOOP_INTERVAL) + self.assertEqual(ret['_last_run'], run_time1) # Evaluate 1 second at the run time - self.schedule.eval(now=run_time2 + LOOP_INTERVAL) + self.schedule.eval(now=run_time2) ret = self.schedule.job_status('job1') - self.assertEqual(ret['_last_run'], run_time2 + LOOP_INTERVAL) + self.assertEqual(ret['_last_run'], run_time2) def test_eval_once(self): ''' @@ -212,9 +212,10 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): } } } - run_time = int(time.mktime(dateutil_parser.parse('12/13/2017 1:00pm').timetuple())) + run_time = dateutil_parser.parse('12/13/2017 1:00pm') # Add the job to the scheduler + self.schedule.opts['schedule'] = {} self.schedule.opts.update(job) # Evaluate 1 second at the run time @@ -239,7 +240,7 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): self.schedule.opts['loop_interval'] = LOOP_INTERVAL # Run the job at the right plus LOOP_INTERVAL - run_time = int(time.mktime(dateutil_parser.parse('12/13/2017 1:00:{0}pm'.format(LOOP_INTERVAL)).timetuple())) + run_time = dateutil_parser.parse('12/13/2017 1:00pm') + datetime.timedelta(seconds=LOOP_INTERVAL) # Add the job to the scheduler self.schedule.opts.update(job) @@ -266,7 +267,7 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): # Add the job to the scheduler self.schedule.opts.update(job) - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 4:00pm') with patch('croniter.croniter.get_next', MagicMock(return_value=run_time)): self.schedule.eval(now=run_time) @@ -290,12 +291,12 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): # Add the job to the scheduler self.schedule.opts.update(job) - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 4:00pm') with patch('croniter.croniter.get_next', MagicMock(return_value=run_time)): self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') - self.assertEqual(ret['_error'], 'Invalid cron string. Ignoring.') + self.assertEqual(ret['_error'], 'Invalid cron string. Ignoring job job1.') @skipIf(not HAS_CRONITER, 'Cannot find croniter python module') def test_eval_cron_loop_interval(self): @@ -317,7 +318,7 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): # Add the job to the scheduler self.schedule.opts.update(job) - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 4:00pm') with patch('croniter.croniter.get_next', MagicMock(return_value=run_time)): self.schedule.eval(now=run_time) @@ -329,7 +330,7 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): verify that scheduled job does not run and returns the right error ''' - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 4:00pm') job = { 'schedule': { @@ -346,7 +347,7 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): # Evaluate 1 second before the run time self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') - self.assertEqual(ret['_error'], 'Invalid date string. Ignoring.') + self.assertEqual(ret['_error'], 'Invalid date string. Ignoring job job1.') def test_eval_once_invalid_datestring(self): ''' @@ -361,7 +362,7 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): } } } - run_time = int(time.mktime(dateutil_parser.parse('12/13/2017 1:00pm').timetuple())) + run_time = dateutil_parser.parse('12/13/2017 1:00pm') # Add the job to the scheduler self.schedule.opts.update(job) @@ -369,8 +370,148 @@ class SchedulerEvalTest(ModuleCase, SaltReturnAssertsMixin): # Evaluate 1 second at the run time self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') - _expected = ('Date string could not ', - 'be parsed: %s, %s', - '2017-13-13T13:00:00', - '%Y-%m-%dT%H:%M:%S') + _expected = ('Date string could not be parsed: ' + '2017-13-13T13:00:00, %Y-%m-%dT%H:%M:%S. ' + 'Ignoring job job1.') self.assertEqual(ret['_error'], _expected) + + def test_eval_until(self): + ''' + verify that scheduled job is skipped once the current + time reaches the specified until time + ''' + job = { + 'schedule': { + 'job_eval_after': { + 'function': 'test.ping', + 'hours': '1', + 'until': '11/29/2017 5:00pm' + } + } + } + + # Add job to schedule + self.schedule.delete_job('job_eval_after') + self.schedule.opts.update(job) + + # eval at 2:00pm to prime, simulate minion start up. + run_time = dateutil_parser.parse('11/29/2017 2:00pm') + self.schedule.eval(now=run_time) + ret = self.schedule.job_status('job_eval_after') + + # eval at 3:00pm, will run. + run_time = dateutil_parser.parse('11/29/2017 3:00pm') + self.schedule.eval(now=run_time) + ret = self.schedule.job_status('job_eval_after') + self.assertEqual(ret['_last_run'], run_time) + + # eval at 4:00pm, will run. + run_time = dateutil_parser.parse('11/29/2017 4:00pm') + self.schedule.eval(now=run_time) + ret = self.schedule.job_status('job_eval_after') + self.assertEqual(ret['_last_run'], run_time) + + # eval at 5:00pm, will not run + run_time = dateutil_parser.parse('11/29/2017 5:00pm') + self.schedule.eval(now=run_time) + ret = self.schedule.job_status('job_eval_after') + self.assertEqual(ret['_skip_reason'], 'until_passed') + self.assertEqual(ret['_skipped_time'], run_time) + + def test_eval_after(self): + ''' + verify that scheduled job is skipped until after the specified + time has been reached. + ''' + job = { + 'schedule': { + 'job1': { + 'function': 'test.ping', + 'hours': '1', + 'after': '11/29/2017 5:00pm' + } + } + } + + # Add job to schedule + self.schedule.delete_job('job1') + self.schedule.opts.update(job) + + # eval at 2:00pm to prime, simulate minion start up. + run_time = dateutil_parser.parse('11/29/2017 2:00pm') + self.schedule.eval(now=run_time) + ret = self.schedule.job_status('job1') + + # eval at 3:00pm, will not run. + run_time = dateutil_parser.parse('11/29/2017 3:00pm') + self.schedule.eval(now=run_time) + ret = self.schedule.job_status('job1') + self.assertEqual(ret['_skip_reason'], 'after_not_passed') + self.assertEqual(ret['_skipped_time'], run_time) + + # eval at 4:00pm, will not run. + run_time = dateutil_parser.parse('11/29/2017 4:00pm') + self.schedule.eval(now=run_time) + ret = self.schedule.job_status('job1') + self.assertEqual(ret['_skip_reason'], 'after_not_passed') + self.assertEqual(ret['_skipped_time'], run_time) + + # eval at 5:00pm, will not run + run_time = dateutil_parser.parse('11/29/2017 5:00pm') + self.schedule.eval(now=run_time) + ret = self.schedule.job_status('job1') + self.assertEqual(ret['_skip_reason'], 'after_not_passed') + self.assertEqual(ret['_skipped_time'], run_time) + + # eval at 6:00pm, will run + run_time = dateutil_parser.parse('11/29/2017 6:00pm') + self.schedule.eval(now=run_time) + ret = self.schedule.job_status('job1') + self.assertEqual(ret['_last_run'], run_time) + + def test_eval_enabled(self): + ''' + verify that scheduled job does not run + ''' + job = { + 'schedule': { + 'enabled': True, + 'job1': { + 'function': 'test.ping', + 'when': '11/29/2017 4:00pm', + } + } + } + run_time1 = dateutil_parser.parse('11/29/2017 4:00pm') + + # Add the job to the scheduler + self.schedule.opts.update(job) + + # Evaluate 1 second at the run time + self.schedule.eval(now=run_time1) + ret = self.schedule.job_status('job1') + self.assertEqual(ret['_last_run'], run_time1) + + def test_eval_disabled(self): + ''' + verify that scheduled job does not run + ''' + job = { + 'schedule': { + 'enabled': False, + 'job1': { + 'function': 'test.ping', + 'when': '11/29/2017 4:00pm', + } + } + } + run_time1 = dateutil_parser.parse('11/29/2017 4:00pm') + + # Add the job to the scheduler + self.schedule.opts.update(job) + + # Evaluate 1 second at the run time + self.schedule.eval(now=run_time1) + ret = self.schedule.job_status('job1') + self.assertNotIn('_last_run', ret) + self.assertEqual(ret['_skip_reason'], 'disabled') diff --git a/tests/integration/scheduler/test_postpone.py b/tests/integration/scheduler/test_postpone.py index 3191e97770..568f59fb22 100644 --- a/tests/integration/scheduler/test_postpone.py +++ b/tests/integration/scheduler/test_postpone.py @@ -3,9 +3,9 @@ # Import Python libs from __future__ import absolute_import import copy +import datetime import logging import os -import time import dateutil.parser as dateutil_parser @@ -45,7 +45,7 @@ class SchedulerPostponeTest(ModuleCase, SaltReturnAssertsMixin): self.schedule.opts['loop_interval'] = 1 def tearDown(self): - del self.schedule + self.schedule.reset() def test_postpone(self): ''' @@ -61,7 +61,7 @@ class SchedulerPostponeTest(ModuleCase, SaltReturnAssertsMixin): } # 11/29/2017 4pm - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 4:00pm') # 5 minute delay delay = 300 @@ -70,20 +70,19 @@ class SchedulerPostponeTest(ModuleCase, SaltReturnAssertsMixin): self.schedule.opts.update(job) # Postpone the job by 5 minutes - self.schedule.postpone_job('job1', {'time': run_time, - 'new_time': run_time + delay}) - + self.schedule.postpone_job('job1', {'time': run_time.strftime('%Y-%m-%dT%H:%M:%S'), + 'new_time': (run_time + datetime.timedelta(seconds=delay)).strftime('%Y-%m-%dT%H:%M:%S')}) # Run at the original time self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') self.assertNotIn('_last_run', ret) # Run 5 minutes later - self.schedule.eval(now=run_time + delay) + self.schedule.eval(now=run_time + datetime.timedelta(seconds=delay)) ret = self.schedule.job_status('job1') - self.assertEqual(ret['_last_run'], run_time + delay) + self.assertEqual(ret['_last_run'], run_time + datetime.timedelta(seconds=delay)) # Run 6 minutes later - self.schedule.eval(now=run_time + delay + 1) + self.schedule.eval(now=run_time + datetime.timedelta(seconds=delay + 1)) ret = self.schedule.job_status('job1') - self.assertEqual(ret['_last_run'], run_time + delay) + self.assertEqual(ret['_last_run'], run_time + datetime.timedelta(seconds=delay)) diff --git a/tests/integration/scheduler/test_skip.py b/tests/integration/scheduler/test_skip.py index 4ad2713dc6..3cc36965cc 100644 --- a/tests/integration/scheduler/test_skip.py +++ b/tests/integration/scheduler/test_skip.py @@ -5,7 +5,6 @@ from __future__ import absolute_import import copy import logging import os -import time import dateutil.parser as dateutil_parser @@ -45,7 +44,7 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): self.schedule.opts['loop_interval'] = 1 def tearDown(self): - del self.schedule + self.schedule.reset() def test_skip(self): ''' @@ -63,8 +62,9 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): # Add job to schedule self.schedule.opts.update(job) - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 4:00pm').timetuple())) - self.schedule.skip_job('job1', {'time': run_time}) + run_time = dateutil_parser.parse('11/29/2017 4:00pm') + self.schedule.skip_job('job1', {'time': run_time.strftime('%Y-%m-%dT%H:%M:%S'), + 'time_fmt': '%Y-%m-%dT%H:%M:%S'}) # Run 11/29/2017 at 4pm self.schedule.eval(now=run_time) @@ -74,7 +74,7 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): self.assertEqual(ret['_skipped_time'], run_time) # Run 11/29/2017 at 5pm - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 5:00pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 5:00pm') self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') self.assertEqual(ret['_last_run'], run_time) @@ -100,12 +100,12 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): self.schedule.opts.update(job) # eval at 1:30pm to prime. - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 1:30pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 1:30pm') self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') # eval at 2:30pm, will not run during range. - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 2:30pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 2:30pm') self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') self.assertNotIn('_last_run', ret) @@ -113,7 +113,7 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): self.assertEqual(ret['_skipped_time'], run_time) # eval at 3:30pm, will run. - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 3:30pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 3:30pm') self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') self.assertEqual(ret['_last_run'], run_time) @@ -122,7 +122,7 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): ''' verify that scheduled job is not not and returns the right error string ''' - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 2:30pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 2:30pm') job1 = { 'schedule': { @@ -160,10 +160,9 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): # Check the first job ret = self.schedule.job_status('job1') - _expected = ('Invalid date string for start in ', - 'skip_during_range. Ignoring ', - 'job %s.', 'job1') - log.debug('=== ret %s ===', ret) + _expected = ('Invalid date string for start in ' + 'skip_during_range. Ignoring ' + 'job job1.') self.assertEqual(ret['_error'], _expected) # Clear out schedule @@ -177,9 +176,9 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): # Check the second job ret = self.schedule.job_status('job2') - _expected = ('Invalid date string for end in ', - 'skip_during_range. Ignoring ', - 'job %s.', 'job2') + _expected = ('Invalid date string for end in ' + 'skip_during_range. Ignoring ' + 'job job2.') self.assertEqual(ret['_error'], _expected) def test_skip_during_range_global(self): @@ -203,12 +202,12 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): self.schedule.opts.update(job) # eval at 1:30pm to prime. - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 1:30pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 1:30pm') self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') # eval at 2:30pm, will not run during range. - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 2:30pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 2:30pm') self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') self.assertNotIn('_last_run', ret) @@ -216,7 +215,7 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): self.assertEqual(ret['_skipped_time'], run_time) # eval at 3:30pm, will run. - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 3:30pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 3:30pm') self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') self.assertEqual(ret['_last_run'], run_time) @@ -243,7 +242,7 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): self.schedule.opts.update(job) # eval at 2:30pm, will not run during range. - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 2:30pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 2:30pm') self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') self.assertNotIn('_last_run', ret) @@ -251,7 +250,7 @@ class SchedulerSkipTest(ModuleCase, SaltReturnAssertsMixin): self.assertEqual(ret['_skipped_time'], run_time) # eval at 3:00:01pm, will run. - run_time = int(time.mktime(dateutil_parser.parse('11/29/2017 3:00:01pm').timetuple())) + run_time = dateutil_parser.parse('11/29/2017 3:00:01pm') self.schedule.eval(now=run_time) ret = self.schedule.job_status('job1') self.assertEqual(ret['_last_run'], run_time) diff --git a/tests/integration/shell/test_cp.py b/tests/integration/shell/test_cp.py index 523b19a176..c10dbcf7e5 100644 --- a/tests/integration/shell/test_cp.py +++ b/tests/integration/shell/test_cp.py @@ -55,6 +55,8 @@ class CopyTest(ShellCase, ShellCaseCommonTestsMixin): testfile_contents = fh_.read() for idx, minion in enumerate(minions): + if 'localhost' in minion: + continue ret = self.run_salt( '--out yaml {0} file.directory_exists {1}'.format( pipes.quote(minion), TMP @@ -138,7 +140,7 @@ class CopyTest(ShellCase, ShellCaseCommonTestsMixin): ret = self.run_script( self._call_binary_, - '--out pprint --config-dir {0} \'*\' {1} {0}/{2}'.format( + '--out pprint --config-dir {0} \'*minion\' {1} {0}/{2}'.format( config_dir, fn_, os.path.basename(fn_), diff --git a/tests/integration/spm/test_man_spm.py b/tests/integration/spm/test_man_spm.py index 24fb77b846..51b9806c34 100644 --- a/tests/integration/spm/test_man_spm.py +++ b/tests/integration/spm/test_man_spm.py @@ -11,7 +11,7 @@ import tempfile # Import Salt Testing libs from tests.support.case import ModuleCase -from tests.support.helpers import destructiveTest +from tests.support.helpers import destructiveTest, flaky from tests.support.paths import CODE_DIR @@ -33,6 +33,7 @@ class SPMManTest(ModuleCase): def tearDown(self): shutil.rmtree(self.tmpdir) + @flaky def test_man_spm(self): ''' test man spm diff --git a/tests/integration/ssh/test_master.py b/tests/integration/ssh/test_master.py new file mode 100644 index 0000000000..2fa5cf95cd --- /dev/null +++ b/tests/integration/ssh/test_master.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +''' +Simple Smoke Tests for Connected SSH minions +''' + +# Import Python libs +from __future__ import absolute_import, print_function, unicode_literals + +# Import Salt Testing libs +from tests.support.case import ModuleCase +from tests.support.helpers import requires_sshd_server + + +@requires_sshd_server +class SSHMasterTestCase(ModuleCase): + ''' + Test minion blackout functionality + ''' + def test_can_it_ping(self): + ''' + Ensure the proxy can ping + ''' + ret = self.run_function('test.ping', minion_tgt='localhost') + self.assertEqual(ret, True) + + def test_service(self): + service = 'cron' + os_family = self.run_function('grains.get', ['os_family'], minion_tgt='localhost') + if os_family == 'RedHat': + service = 'crond' + elif os_family == 'Arch': + service = 'sshd' + ret = self.run_function('service.get_all', minion_tgt='localhost') + self.assertIn(service, ret) + self.run_function('service.stop', [service], minion_tgt='localhost') + ret = self.run_function('service.status', [service], minion_tgt='localhost') + self.assertFalse(ret) + self.run_function('service.start', [service], minion_tgt='localhost') + ret = self.run_function('service.status', [service], minion_tgt='localhost') + self.assertTrue(ret) + + def test_grains_items(self): + ret = self.run_function('grains.items', minion_tgt='localhost') + self.assertEqual(ret['kernel'], 'Linux') + + def test_state_apply(self): + ret = self.run_function('state.apply', ['core'], minion_tgt='localhost') + for key, value in ret.items(): + self.assertTrue(value['result']) + + def test_state_highstate(self): + ret = self.run_function('state.highstate', minion_tgt='localhost') + for key, value in ret.items(): + self.assertTrue(value['result']) diff --git a/tests/integration/ssh/test_state.py b/tests/integration/ssh/test_state.py index 4df91890d6..4524cf2f9c 100644 --- a/tests/integration/ssh/test_state.py +++ b/tests/integration/ssh/test_state.py @@ -9,6 +9,7 @@ import time # Import Salt Testing Libs from tests.support.case import SSHCase +from tests.support.helpers import flaky from tests.support.paths import TMP # Import Salt Libs @@ -162,6 +163,7 @@ class SSHStateTest(SSHCase): check_file = self.run_function('file.file_exists', [SSH_SLS_FILE], wipe=False) self.assertTrue(check_file) + @flaky def test_state_running(self): ''' test state.running with salt-ssh diff --git a/tests/integration/states/test_archive.py b/tests/integration/states/test_archive.py index ec3e227f12..cc7495b951 100644 --- a/tests/integration/states/test_archive.py +++ b/tests/integration/states/test_archive.py @@ -68,6 +68,16 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): log.debug('Checking for extracted file: %s', path) self.assertTrue(os.path.isfile(path)) + def run_function(self, *args, **kwargs): + ret = super(ArchiveTest, self).run_function(*args, **kwargs) + log.debug('ret = %s', ret) + return ret + + def run_state(self, *args, **kwargs): + ret = super(ArchiveTest, self).run_state(*args, **kwargs) + log.debug('ret = %s', ret) + return ret + def test_archive_extracted_skip_verify(self): ''' test archive.extracted with skip_verify @@ -75,7 +85,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): ret = self.run_state('archive.extracted', name=ARCHIVE_DIR, source=self.archive_tar_source, archive_format='tar', skip_verify=True) - log.debug('ret = %s', ret) if 'Timeout' in ret: self.skipTest('Timeout talking to local tornado server.') self.assertSaltTrueReturn(ret) @@ -91,7 +100,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): ret = self.run_state('archive.extracted', name=ARCHIVE_DIR, source=self.archive_tar_source, archive_format='tar', source_hash=ARCHIVE_TAR_HASH) - log.debug('ret = %s', ret) if 'Timeout' in ret: self.skipTest('Timeout talking to local tornado server.') @@ -111,7 +119,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): source=self.archive_tar_source, archive_format='tar', source_hash=ARCHIVE_TAR_HASH, user='root', group=r_group) - log.debug('ret = %s', ret) if 'Timeout' in ret: self.skipTest('Timeout talking to local tornado server.') @@ -128,7 +135,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): source_hash=ARCHIVE_TAR_HASH, options='--strip=1', enforce_toplevel=False) - log.debug('ret = %s', ret) if 'Timeout' in ret: self.skipTest('Timeout talking to local tornado server.') @@ -145,7 +151,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): source_hash=ARCHIVE_TAR_HASH, options='--strip-components=1', enforce_toplevel=False) - log.debug('ret = %s', ret) if 'Timeout' in ret: self.skipTest('Timeout talking to local tornado server.') @@ -160,7 +165,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): ret = self.run_state('archive.extracted', name=ARCHIVE_DIR, source=self.archive_tar_source, source_hash=ARCHIVE_TAR_HASH) - log.debug('ret = %s', ret) if 'Timeout' in ret: self.skipTest('Timeout talking to local tornado server.') self.assertSaltTrueReturn(ret) @@ -177,7 +181,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): source_hash=ARCHIVE_TAR_HASH, use_cmd_unzip=False, archive_format='tar') - log.debug('ret = %s', ret) if 'Timeout' in ret: self.skipTest('Timeout talking to local tornado server.') self.assertSaltTrueReturn(ret) @@ -190,7 +193,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): ''' ret = self.run_state('archive.extracted', name=ARCHIVE_DIR, source=ARCHIVE_LOCAL_TAR_SOURCE, archive_format='tar') - log.debug('ret = %s', ret) self.assertSaltTrueReturn(ret) @@ -203,7 +205,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): ret = self.run_state('archive.extracted', name=ARCHIVE_DIR, source=ARCHIVE_LOCAL_TAR_SOURCE, archive_format='tar', source_hash=ARCHIVE_TAR_BAD_HASH, skip_verify=True) - log.debug('ret = %s', ret) self.assertSaltTrueReturn(ret) @@ -216,7 +217,6 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): ret = self.run_state('archive.extracted', name=ARCHIVE_DIR, source=ARCHIVE_LOCAL_TAR_SOURCE, archive_format='tar', source_hash=ARCHIVE_TAR_HASH) - log.debug('ret = %s', ret) self.assertSaltTrueReturn(ret) @@ -229,6 +229,17 @@ class ArchiveTest(ModuleCase, SaltReturnAssertsMixin): ret = self.run_state('archive.extracted', name=ARCHIVE_DIR, source=ARCHIVE_LOCAL_TAR_SOURCE, archive_format='tar', source_hash=ARCHIVE_TAR_BAD_HASH) - log.debug('ret = %s', ret) self.assertSaltFalseReturn(ret) + + def test_archive_extracted_with_non_base_saltenv(self): + ''' + test archive.extracted with a saltenv other than `base` + ''' + ret = self.run_function( + 'state.sls', + ['issue45893'], + pillar={'issue45893.name': ARCHIVE_DIR}, + saltenv='prod') + self.assertSaltTrueReturn(ret) + self._check_extracted(os.path.join(ARCHIVE_DIR, UNTAR_FILE)) diff --git a/tests/integration/states/test_docker_container.py b/tests/integration/states/test_docker_container.py index ffa639cf1c..0396087d2d 100644 --- a/tests/integration/states/test_docker_container.py +++ b/tests/integration/states/test_docker_container.py @@ -444,6 +444,44 @@ class DockerContainerTestCase(ModuleCase, SaltReturnAssertsMixin): image_info['Config']['Cmd'] ) + @container_name + def test_running_with_port_bindings(self, name): + ''' + This tests that the ports which are being bound are also exposed, even + when not explicitly configured. This test will create a container with + only some of the ports exposed, including some which aren't even bound. + The resulting containers exposed ports should contain all of the ports + defined in the "ports" argument, as well as each of the ports which are + being bound. + ''' + # Create the container + ret = self.run_state( + 'docker_container.running', + name=name, + image=self.image, + command='sleep 600', + shutdown_timeout=1, + port_bindings=[1234, '1235-1236', '2234/udp', '2235-2236/udp'], + ports=[1235, '2235/udp', 9999], + ) + self.assertSaltTrueReturn(ret) + + # Check the created container's port bindings and exposed ports. The + # port bindings should only contain the ports defined in the + # port_bindings argument, while the exposed ports should also contain + # the extra port (9999/tcp) which was included in the ports argument. + cinfo = self.run_function('docker.inspect_container', [name]) + ports = ['1234/tcp', '1235/tcp', '1236/tcp', + '2234/udp', '2235/udp', '2236/udp'] + self.assertEqual( + sorted(cinfo['HostConfig']['PortBindings']), + ports + ) + self.assertEqual( + sorted(cinfo['Config']['ExposedPorts']), + ports + ['9999/tcp'] + ) + @container_name def test_absent_with_stopped_container(self, name): ''' diff --git a/tests/integration/states/test_file.py b/tests/integration/states/test_file.py index 7516c8f364..5c8e7f1f90 100644 --- a/tests/integration/states/test_file.py +++ b/tests/integration/states/test_file.py @@ -1185,8 +1185,8 @@ class FileTest(ModuleCase, SaltReturnAssertsMixin): source='salt://соль') self.assertSaltTrueReturn(ret) self.assertEqual( - sorted(salt.utils.data.decode(os.listdir(name))), - sorted(['foo.txt', 'спам.txt', 'яйца.txt']) + sorted(salt.utils.data.decode(os.listdir(name), normalize=True)), + sorted(['foo.txt', 'спам.txt', 'яйца.txt']), ) finally: shutil.rmtree(name, ignore_errors=True) diff --git a/tests/support/helpers.py b/tests/support/helpers.py index ca20b720a9..05989848b7 100644 --- a/tests/support/helpers.py +++ b/tests/support/helpers.py @@ -1344,7 +1344,7 @@ def generate_random_name(prefix, size=6): Generates a random name by combining the provided prefix with a randomly generated ascii string. - .. versionadded:: Oxygen + .. versionadded:: 2018.3.0 prefix The string to prefix onto the randomly generated ascii string. diff --git a/tests/support/mock.py b/tests/support/mock.py index 6da421dc35..da3d09480d 100644 --- a/tests/support/mock.py +++ b/tests/support/mock.py @@ -5,9 +5,12 @@ tests.support.mock ~~~~~~~~~~~~~~~~~~ - Helper module that wraps :mod:`mock ` and provides - some fake objects in order to properly set the function/class decorators - and yet skip the test cases execution. + Helper module that wraps `mock` and provides some fake objects in order to + properly set the function/class decorators and yet skip the test case's + execution. + + Note: mock >= 2.0.0 required since unittest.mock does not have + MagicMock.assert_called in Python < 3.6. ''' # pylint: disable=unused-import,function-redefined,blacklisted-module,blacklisted-external-module @@ -18,37 +21,20 @@ import sys from salt.ext import six try: - if sys.version_info >= (3,): - # Python 3 - from unittest.mock import ( - Mock, - MagicMock, - patch, - sentinel, - DEFAULT, - # ANY and call will be imported further down - create_autospec, - FILTER_DIR, - NonCallableMock, - NonCallableMagicMock, - PropertyMock, - __version__ - ) - else: - from mock import ( - Mock, - MagicMock, - patch, - sentinel, - DEFAULT, - # ANY and call will be imported further down - create_autospec, - FILTER_DIR, - NonCallableMock, - NonCallableMagicMock, - PropertyMock, - __version__ - ) + from mock import ( + Mock, + MagicMock, + patch, + sentinel, + DEFAULT, + # ANY and call will be imported further down + create_autospec, + FILTER_DIR, + NonCallableMock, + NonCallableMagicMock, + PropertyMock, + __version__ + ) NO_MOCK = False NO_MOCK_REASON = '' mock_version = [] @@ -99,11 +85,7 @@ except ImportError as exc: if NO_MOCK is False: try: - if sys.version_info >= (3,): - # Python 3 - from unittest.mock import call, ANY - else: - from mock import call, ANY + from mock import call, ANY except ImportError: NO_MOCK = True NO_MOCK_REASON = 'you need to upgrade your mock version to >= 0.8.0' diff --git a/tests/unit/auth/__init__.py b/tests/unit/auth/__init__.py new file mode 100644 index 0000000000..40a96afc6f --- /dev/null +++ b/tests/unit/auth/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/tests/unit/auth/test_ldap.py b/tests/unit/auth/test_ldap.py new file mode 100644 index 0000000000..bd398961c6 --- /dev/null +++ b/tests/unit/auth/test_ldap.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +# Import python libs +from __future__ import absolute_import + +# Import Salt Libs +import salt.auth.ldap + +# Import Salt Testing Libs +from tests.support.mock import patch, NO_MOCK, NO_MOCK_REASON +from tests.support.unit import skipIf, TestCase + +salt.auth.ldap.__opts__ = {} + + +class Bind(object): + ''' + fake search_s return + ''' + + @staticmethod + def search_s(*args, **kwargs): + return [ + ( + 'cn=saltusers,cn=groups,cn=compat,dc=saltstack,dc=com', + {'memberUid': [b'saltuser'], 'cn': [b'saltusers']}, + ), + ] + + +@skipIf(NO_MOCK, NO_MOCK_REASON) +@skipIf(not salt.auth.ldap.HAS_LDAP, 'Install python-ldap for this test') +class LDAPAuthTestCase(TestCase): + ''' + Unit tests for salt.auth.ldap + ''' + + def setUp(self): + self.opts = { + 'auth.ldap.binddn': 'uid={{username}},cn=users,cn=compat,dc=saltstack,dc=com', + 'auth.ldap.port': 389, + 'auth.ldap.tls': False, + 'auth.ldap.server': '172.18.0.2', + 'auth.ldap.accountattributename': 'memberUid', + 'auth.ldap.groupattribute': 'memberOf', + 'auth.ldap.group_basedn': 'cn=groups,cn=compat,dc=saltstack,dc=com', + 'auth.ldap.basedn': 'dc=saltstack,dc=com', + 'auth.ldap.group_filter': '(&(memberUid={{ username }})(objectClass=posixgroup))'} + + def tearDown(self): + self.opts['auth.ldap.freeipa'] = False + self.opts['auth.ldap.activedirectory'] = False + + def test_config(self): + ''' + Test that the _config function works correctly + ''' + with patch.dict(salt.auth.ldap.__opts__, self.opts): + self.assertEqual(salt.auth.ldap._config('basedn'), 'dc=saltstack,dc=com') + self.assertEqual(salt.auth.ldap._config('group_filter'), '(&(memberUid={{ username }})(objectClass=posixgroup))') + self.assertEqual(salt.auth.ldap._config('accountattributename'), 'memberUid') + self.assertEqual(salt.auth.ldap._config('groupattribute'), 'memberOf') + + def test_groups_freeipa(self): + ''' + test groups in freeipa + ''' + self.opts['auth.ldap.freeipa'] = True + with patch.dict(salt.auth.ldap.__opts__, self.opts): + with patch('salt.auth.ldap.auth', return_value=Bind): + self.assertIn('saltusers', salt.auth.ldap.groups('saltuser', password='password')) + + def test_groups(self): + ''' + test groups in ldap + ''' + with patch.dict(salt.auth.ldap.__opts__, self.opts): + with patch('salt.auth.ldap.auth', return_value=Bind): + self.assertIn('saltusers', salt.auth.ldap.groups('saltuser', password='password')) + + def test_groups_activedirectory(self): + ''' + test groups in activedirectory + ''' + self.opts['auth.ldap.activedirectory'] = True + with patch.dict(salt.auth.ldap.__opts__, self.opts): + with patch('salt.auth.ldap.auth', return_value=Bind): + self.assertIn('saltusers', salt.auth.ldap.groups('saltuser', password='password')) diff --git a/tests/unit/cache/test_localfs.py b/tests/unit/cache/test_localfs.py index ad119418b7..8256a041f2 100644 --- a/tests/unit/cache/test_localfs.py +++ b/tests/unit/cache/test_localfs.py @@ -5,6 +5,7 @@ unit tests for the localfs cache # Import Python libs from __future__ import absolute_import, print_function, unicode_literals +import os import shutil import tempfile @@ -45,16 +46,24 @@ class LocalFSTest(TestCase, LoaderModuleMockMixin): with patch.dict(localfs.__context__, {'serial': serializer}): localfs.store(bank='bank', key='key', data='payload data', cachedir=tmp_dir) - # 'store' function tests: 4 + # 'store' function tests: 5 - def test_store_no_base_cache_dir(self): + def test_handled_exception_cache_dir(self): ''' Tests that a SaltCacheError is raised when the base directory doesn't exist and cannot be created. ''' - with patch('os.path.isdir', MagicMock(return_value=None)): - with patch('os.makedirs', MagicMock(side_effect=OSError)): - self.assertRaises(SaltCacheError, localfs.store, bank='', key='', data='', cachedir='') + with patch('os.makedirs', MagicMock(side_effect=OSError(os.errno.EEXIST, ''))): + with patch('tempfile.mkstemp', MagicMock(side_effect=Exception)): + self.assertRaises(Exception, localfs.store, bank='', key='', data='', cachedir='') + + def test_unhandled_exception_cache_dir(self): + ''' + Tests that a SaltCacheError is raised when the base directory doesn't exist and + cannot be created. + ''' + with patch('os.makedirs', MagicMock(side_effect=OSError(1, ''))): + self.assertRaises(SaltCacheError, localfs.store, bank='', key='', data='', cachedir='') def test_store_close_mkstemp_file_handle(self): ''' @@ -64,7 +73,7 @@ class LocalFSTest(TestCase, LoaderModuleMockMixin): This test mocks the call to mkstemp, but forces an OSError to be raised when the close() function is called on a file descriptor that doesn't exist. ''' - with patch('os.path.isdir', MagicMock(return_value=True)): + with patch('os.makedirs', MagicMock(side_effect=OSError(os.errno.EEXIST, ''))): with patch('tempfile.mkstemp', MagicMock(return_value=(12345, 'foo'))): self.assertRaises(OSError, localfs.store, bank='', key='', data='', cachedir='') @@ -73,7 +82,7 @@ class LocalFSTest(TestCase, LoaderModuleMockMixin): Tests that a SaltCacheError is raised when there is a problem writing to the cache file. ''' - with patch('os.path.isdir', MagicMock(return_value=True)): + with patch('os.makedirs', MagicMock(side_effect=OSError(os.errno.EEXIST, ''))): with patch('tempfile.mkstemp', MagicMock(return_value=('one', 'two'))): with patch('os.close', MagicMock(return_value=None)): with patch('salt.utils.files.fopen', MagicMock(side_effect=IOError)): diff --git a/tests/unit/cloud/clouds/test_dimensiondata.py b/tests/unit/cloud/clouds/test_dimensiondata.py index 1a43410789..e912ed6193 100644 --- a/tests/unit/cloud/clouds/test_dimensiondata.py +++ b/tests/unit/cloud/clouds/test_dimensiondata.py @@ -31,10 +31,11 @@ VM_NAME = 'winterfell' # Use certifi if installed try: if HAS_LIBCLOUD: - # This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0. - # However, older versions of libcloud must still be supported with this work-around. - # This work-around can be removed when the required minimum version of libcloud is - # 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen). + # This work-around for Issue #32743 is no longer needed for libcloud >= + # 1.4.0. However, older versions of libcloud must still be supported + # with this work-around. This work-around can be removed when the + # required minimum version of libcloud is 2.0.0 (See PR #40837 - which + # is implemented in Salt 2018.3.0). if LooseVersion(libcloud.__version__) < LooseVersion('1.4.0'): import certifi libcloud.security.CA_CERTS_PATH.append(certifi.where()) diff --git a/tests/unit/cloud/clouds/test_gce.py b/tests/unit/cloud/clouds/test_gce.py index 4cb1b412f4..88210abdd6 100644 --- a/tests/unit/cloud/clouds/test_gce.py +++ b/tests/unit/cloud/clouds/test_gce.py @@ -36,10 +36,11 @@ DUMMY_TOKEN = { # Use certifi if installed try: if HAS_LIBCLOUD: - # This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0. - # However, older versions of libcloud must still be supported with this work-around. - # This work-around can be removed when the required minimum version of libcloud is - # 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen). + # This work-around for Issue #32743 is no longer needed for libcloud >= + # 1.4.0. However, older versions of libcloud must still be supported + # with this work-around. This work-around can be removed when the + # required minimum version of libcloud is 2.0.0 (See PR #40837 - which + # is implemented in Salt 2018.3.0). if LooseVersion(libcloud.__version__) < LooseVersion('1.4.0'): import certifi libcloud.security.CA_CERTS_PATH.append(certifi.where()) diff --git a/tests/unit/cloud/clouds/test_vmware.py b/tests/unit/cloud/clouds/test_vmware.py index 447e7dcdca..3887ee0982 100644 --- a/tests/unit/cloud/clouds/test_vmware.py +++ b/tests/unit/cloud/clouds/test_vmware.py @@ -1239,6 +1239,38 @@ class VMwareTestCase(ExtendedTestCase): kwargs={'name': 'cCD2GgJGPG1DUnPeFBoPeqtdmUxIWxDoVFbA14vIG0BPoUECkgbRMnnY6gaUPBvIDCcsZ5HU48ubgQu5c'}, call='function') + def test__add_new_hard_disk_helper(self): + with patch('salt.cloud.clouds.vmware._get_si', MagicMock(return_value=None)): + with patch('salt.utils.vmware.get_mor_using_container_view', side_effect=[None, None]): + self.assertRaises( + SaltCloudSystemExit, + vmware._add_new_hard_disk_helper, + disk_label='test', + size_gb=100, + unit_number=0, + datastore='whatever' + ) + with patch('salt.utils.vmware.get_mor_using_container_view', side_effect=['Datastore', None]): + self.assertRaises( + AttributeError, + vmware._add_new_hard_disk_helper, + disk_label='test', + size_gb=100, + unit_number=0, + datastore='whatever' + ) + vmware.salt.utils.vmware.get_mor_using_container_view.assert_called_with(None, vim.Datastore, 'whatever') + with patch('salt.utils.vmware.get_mor_using_container_view', side_effect=[None, 'Cluster']): + self.assertRaises( + AttributeError, + vmware._add_new_hard_disk_helper, + disk_label='test', + size_gb=100, + unit_number=0, + datastore='whatever' + ) + vmware.salt.utils.vmware.get_mor_using_container_view.assert_called_with(None, vim.StoragePod, 'whatever') + class CloneFromSnapshotTest(TestCase): ''' diff --git a/tests/unit/config/schemas/test_ssh.py b/tests/unit/config/schemas/test_ssh.py index 64c27c20a0..34a767c2a1 100644 --- a/tests/unit/config/schemas/test_ssh.py +++ b/tests/unit/config/schemas/test_ssh.py @@ -14,6 +14,7 @@ from tests.support.unit import TestCase, skipIf # Import Salt Libs from salt.config.schemas import ssh as ssh_schemas from salt.config.schemas.minion import MinionConfiguration +import salt.utils.stringutils from salt.utils.versions import LooseVersion as _LooseVersion # Import 3rd-party libs @@ -286,7 +287,7 @@ class RosterItemTest(TestCase): with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo: jsonschema.validate( - {'target-1:1': + {salt.utils.stringutils.to_str('target-1:1'): { 'host': 'localhost', 'user': 'root', diff --git a/tests/unit/fileserver/test_gitfs.py b/tests/unit/fileserver/test_gitfs.py index cc8bdbac3b..2d89b86bb5 100644 --- a/tests/unit/fileserver/test_gitfs.py +++ b/tests/unit/fileserver/test_gitfs.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- ''' - :codeauthor: :email:`Erik Johnson ` +:codeauthor: :email:`Erik Johnson ` ''' # Import Python libs from __future__ import absolute_import, print_function, unicode_literals +import copy import errno import os import shutil @@ -18,15 +19,6 @@ try: except ImportError: pass -# Import 3rd-party libs -try: - import git # pylint: disable=unused-import - HAS_GITPYTHON = True - GITFS_AVAILABLE = True -except ImportError: - HAS_GITPYTHON = False - GITFS_AVAILABLE = False - # Import Salt Testing Libs from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import TestCase, skipIf @@ -36,11 +28,36 @@ from tests.support.paths import TMP, FILES # Import salt libs import salt.fileserver.gitfs as gitfs import salt.utils.files -import salt.utils.gitfs import salt.utils.platform import salt.utils.win_functions import salt.utils.yaml +import salt.utils.gitfs +from salt.utils.gitfs import ( + GITPYTHON_VERSION, + GITPYTHON_MINVER, + PYGIT2_VERSION, + PYGIT2_MINVER, + LIBGIT2_VERSION, + LIBGIT2_MINVER +) + +try: + import git + # We still need to use GitPython here for temp repo setup, so we do need to + # actually import it. But we don't need import pygit2 in this module, we + # can just use the LooseVersion instances imported along with + # salt.utils.gitfs to check if we have a compatible version. + HAS_GITPYTHON = GITPYTHON_VERSION >= GITPYTHON_MINVER +except (ImportError, AttributeError): + HAS_GITPYTHON = False + +try: + HAS_PYGIT2 = PYGIT2_VERSION >= PYGIT2_MINVER \ + and LIBGIT2_VERSION >= LIBGIT2_MINVER +except AttributeError: + HAS_PYGIT2 = False + log = logging.getLogger(__name__) TMP_SOCK_DIR = tempfile.mkdtemp(dir=TMP) @@ -48,6 +65,38 @@ TMP_REPO_DIR = os.path.join(TMP, 'gitfs_root') INTEGRATION_BASE_FILES = os.path.join(FILES, 'file', 'base') UNICODE_FILENAME = 'питон.txt' UNICODE_DIRNAME = UNICODE_ENVNAME = 'соль' +TAG_NAME = 'mytag' + +OPTS = { + 'sock_dir': TMP_SOCK_DIR, + 'gitfs_remotes': ['file://' + TMP_REPO_DIR], + 'gitfs_root': '', + 'fileserver_backend': ['gitfs'], + 'gitfs_base': 'master', + 'fileserver_events': True, + 'transport': 'zeromq', + 'gitfs_mountpoint': '', + 'gitfs_saltenv': [], + 'gitfs_env_whitelist': [], + 'gitfs_env_blacklist': [], + 'gitfs_saltenv_whitelist': [], + 'gitfs_saltenv_blacklist': [], + 'gitfs_user': '', + 'gitfs_password': '', + 'gitfs_insecure_auth': False, + 'gitfs_privkey': '', + 'gitfs_pubkey': '', + 'gitfs_passphrase': '', + 'gitfs_refspecs': [ + '+refs/heads/*:refs/remotes/origin/*', + '+refs/tags/*:refs/tags/*' + ], + 'gitfs_ssl_verify': True, + 'gitfs_disable_saltenv_mapping': False, + 'gitfs_ref_types': ['branch', 'tag', 'sha'], + 'gitfs_update_interval': 60, + '__role': 'master', +} def _rmtree_error(func, path, excinfo): @@ -55,43 +104,23 @@ def _rmtree_error(func, path, excinfo): func(path) -@skipIf(not HAS_GITPYTHON, 'GitPython is not installed') +def _clear_instance_map(): + try: + del salt.utils.gitfs.GitFS.instance_map[tornado.ioloop.IOLoop.current()] + except KeyError: + pass + + +@skipIf(not HAS_GITPYTHON, 'GitPython >= {0} required'.format(GITPYTHON_MINVER)) class GitfsConfigTestCase(TestCase, LoaderModuleMockMixin): def setup_loader_modules(self): - self.tmp_cachedir = tempfile.mkdtemp(dir=TMP) + opts = copy.deepcopy(OPTS) + opts['cachedir'] = self.tmp_cachedir + opts['sock_dir'] = self.tmp_sock_dir return { gitfs: { - '__opts__': { - 'cachedir': self.tmp_cachedir, - 'sock_dir': TMP_SOCK_DIR, - 'gitfs_root': 'salt', - 'fileserver_backend': ['gitfs'], - 'gitfs_base': 'master', - 'fileserver_events': True, - 'transport': 'zeromq', - 'gitfs_mountpoint': '', - 'gitfs_saltenv': [], - 'gitfs_env_whitelist': [], - 'gitfs_env_blacklist': [], - 'gitfs_saltenv_whitelist': [], - 'gitfs_saltenv_blacklist': [], - 'gitfs_user': '', - 'gitfs_password': '', - 'gitfs_insecure_auth': False, - 'gitfs_privkey': '', - 'gitfs_pubkey': '', - 'gitfs_passphrase': '', - 'gitfs_refspecs': [ - '+refs/heads/*:refs/remotes/origin/*', - '+refs/tags/*:refs/tags/*' - ], - 'gitfs_ssl_verify': True, - 'gitfs_disable_saltenv_mapping': False, - 'gitfs_ref_types': ['branch', 'tag', 'sha'], - 'gitfs_update_interval': 60, - '__role': 'master', - } + '__opts__': opts, } } @@ -99,16 +128,27 @@ class GitfsConfigTestCase(TestCase, LoaderModuleMockMixin): def setUpClass(cls): # Clear the instance map so that we make sure to create a new instance # for this test class. - try: - del salt.utils.gitfs.GitFS.instance_map[tornado.ioloop.IOLoop.current()] - except KeyError: - pass + _clear_instance_map() + cls.tmp_cachedir = tempfile.mkdtemp(dir=TMP) + cls.tmp_sock_dir = tempfile.mkdtemp(dir=TMP) - def tearDown(self): - shutil.rmtree(self.tmp_cachedir) + @classmethod + def tearDownClass(cls): + ''' + Remove the temporary git repository and gitfs cache directory to ensure + a clean environment for the other test class(es). + ''' + for path in (cls.tmp_cachedir, cls.tmp_sock_dir): + try: + shutil.rmtree(path, onerror=_rmtree_error) + except OSError as exc: + if exc.errno != errno.EEXIST: + raise def test_per_saltenv_config(self): opts_override = textwrap.dedent(''' + gitfs_root: salt + gitfs_saltenv: - baz: # when loaded, the "salt://" prefix will be removed @@ -186,110 +226,27 @@ class GitfsConfigTestCase(TestCase, LoaderModuleMockMixin): LOAD = {'saltenv': 'base'} -@skipIf(not GITFS_AVAILABLE, "GitFS could not be loaded. Skipping GitFS tests!") -@skipIf(NO_MOCK, NO_MOCK_REASON) -class GitFSTest(TestCase, LoaderModuleMockMixin): +class GitFSTestFuncs(object): + ''' + These are where the tests go, so that they can be run using both GitPython + and pygit2. - def setup_loader_modules(self): - self.tmp_cachedir = tempfile.mkdtemp(dir=TMP) - return { - gitfs: { - '__opts__': { - 'cachedir': self.tmp_cachedir, - 'sock_dir': TMP_SOCK_DIR, - 'gitfs_remotes': ['file://' + TMP_REPO_DIR], - 'gitfs_root': '', - 'fileserver_backend': ['gitfs'], - 'gitfs_base': 'master', - 'fileserver_events': True, - 'transport': 'zeromq', - 'gitfs_mountpoint': '', - 'gitfs_saltenv': [], - 'gitfs_env_whitelist': [], - 'gitfs_env_blacklist': [], - 'gitfs_saltenv_whitelist': [], - 'gitfs_saltenv_blacklist': [], - 'gitfs_user': '', - 'gitfs_password': '', - 'gitfs_insecure_auth': False, - 'gitfs_privkey': '', - 'gitfs_pubkey': '', - 'gitfs_passphrase': '', - 'gitfs_refspecs': [ - '+refs/heads/*:refs/remotes/origin/*', - '+refs/tags/*:refs/tags/*' - ], - 'gitfs_ssl_verify': True, - 'gitfs_disable_saltenv_mapping': False, - 'gitfs_ref_types': ['branch', 'tag', 'sha'], - 'gitfs_update_interval': 60, - '__role': 'master', - } - } - } + NOTE: The gitfs.update() has to happen AFTER the setUp is called. This is + because running it inside the setUp will spawn a new singleton, which means + that tests which need to mock the __opts__ will be too late; the setUp will + have created a new singleton that will bypass our mocking. To ensure that + our tests are reliable and correct, we want to make sure that each test + uses a new gitfs object, allowing different manipulations of the opts to be + tested. - @classmethod - def setUpClass(cls): - # Clear the instance map so that we make sure to create a new instance - # for this test class. - try: - del salt.utils.gitfs.GitFS.instance_map[tornado.ioloop.IOLoop.current()] - except KeyError: - pass - - # Create the dir if it doesn't already exist - try: - shutil.copytree(INTEGRATION_BASE_FILES, TMP_REPO_DIR + '/') - except OSError: - # We probably caught an error because files already exist. Ignore - pass - - try: - repo = git.Repo(TMP_REPO_DIR) - except git.exc.InvalidGitRepositoryError: - repo = git.Repo.init(TMP_REPO_DIR) - - if 'USERNAME' not in os.environ: - try: - if salt.utils.platform.is_windows(): - os.environ['USERNAME'] = salt.utils.win_functions.get_current_user() - else: - os.environ['USERNAME'] = pwd.getpwuid(os.geteuid()).pw_name - except AttributeError: - log.error('Unable to get effective username, falling back to ' - '\'root\'.') - os.environ['USERNAME'] = 'root' - - repo.index.add([x for x in os.listdir(TMP_REPO_DIR) - if x != '.git']) - repo.index.commit('Test') - - # Add another branch with unicode characters in the name - repo.create_head(UNICODE_ENVNAME, 'HEAD') - - def setUp(self): - ''' - We don't want to check in another .git dir into GH because that just - gets messy. Instead, we'll create a temporary repo on the fly for the - tests to examine. - ''' - if not gitfs.__virtual__(): - self.skipTest("GitFS could not be loaded. Skipping GitFS tests!") - self.tmp_cachedir = tempfile.mkdtemp(dir=TMP) - gitfs.update() - - def tearDown(self): - ''' - Remove the temporary git repository and gitfs cache directory to ensure - a clean environment for each test. - ''' - try: - shutil.rmtree(self.tmp_cachedir, onerror=_rmtree_error) - except OSError as exc: - if exc.errno != errno.EEXIST: - raise + Therefore, keep the following in mind: + 1. Each test needs to call gitfs.update() *after* any patching, and + *before* calling the function being tested. + 2. Do *NOT* move the gitfs.update() into the setUp. + ''' def test_file_list(self): + gitfs.update() ret = gitfs.file_list(LOAD) self.assertIn('testfile', ret) self.assertIn(UNICODE_FILENAME, ret) @@ -298,11 +255,242 @@ class GitFSTest(TestCase, LoaderModuleMockMixin): self.assertIn('/'.join((UNICODE_DIRNAME, 'foo.txt')), ret) def test_dir_list(self): + gitfs.update() ret = gitfs.dir_list(LOAD) self.assertIn('grail', ret) self.assertIn(UNICODE_DIRNAME, ret) def test_envs(self): + gitfs.update() ret = gitfs.envs(ignore_cache=True) self.assertIn('base', ret) self.assertIn(UNICODE_ENVNAME, ret) + self.assertIn(TAG_NAME, ret) + + def test_ref_types_global(self): + ''' + Test the global gitfs_ref_types config option + ''' + with patch.dict(gitfs.__opts__, {'gitfs_ref_types': ['branch']}): + gitfs.update() + ret = gitfs.envs(ignore_cache=True) + # Since we are restricting to branches only, the tag should not + # appear in the envs list. + self.assertIn('base', ret) + self.assertIn(UNICODE_ENVNAME, ret) + self.assertNotIn(TAG_NAME, ret) + + def test_ref_types_per_remote(self): + ''' + Test the per_remote ref_types config option, using a different + ref_types setting than the global test. + ''' + remotes = [{'file://' + TMP_REPO_DIR: [{'ref_types': ['tag']}]}] + with patch.dict(gitfs.__opts__, {'gitfs_remotes': remotes}): + gitfs.update() + ret = gitfs.envs(ignore_cache=True) + # Since we are restricting to tags only, the tag should appear in + # the envs list, but the branches should not. + self.assertNotIn('base', ret) + self.assertNotIn(UNICODE_ENVNAME, ret) + self.assertIn(TAG_NAME, ret) + + def test_disable_saltenv_mapping_global_with_mapping_defined_globally(self): + ''' + Test the global gitfs_disable_saltenv_mapping config option, combined + with the per-saltenv mapping being defined in the global gitfs_saltenv + option. + ''' + opts = salt.utils.yaml.safe_load(textwrap.dedent('''\ + gitfs_disable_saltenv_mapping: True + gitfs_saltenv: + - foo: + - ref: base + ''')) + with patch.dict(gitfs.__opts__, opts): + gitfs.update() + ret = gitfs.envs(ignore_cache=True) + # Since we are restricting to tags only, the tag should appear in + # the envs list, but the branches should not. + self.assertEqual(ret, ['foo']) + + def test_disable_saltenv_mapping_global_with_mapping_defined_per_remote(self): + ''' + Test the global gitfs_disable_saltenv_mapping config option, combined + with the per-saltenv mapping being defined in the remote itself via the + "saltenv" per-remote option. + ''' + opts = salt.utils.yaml.safe_load(textwrap.dedent('''\ + gitfs_disable_saltenv_mapping: True + gitfs_remotes: + - file://{0}: + - saltenv: + - bar: + - ref: base + '''.format(TMP_REPO_DIR))) + with patch.dict(gitfs.__opts__, opts): + gitfs.update() + ret = gitfs.envs(ignore_cache=True) + # Since we are restricting to tags only, the tag should appear in + # the envs list, but the branches should not. + self.assertEqual(ret, ['bar']) + + def test_disable_saltenv_mapping_per_remote_with_mapping_defined_globally(self): + ''' + Test the per-remote disable_saltenv_mapping config option, combined + with the per-saltenv mapping being defined in the global gitfs_saltenv + option. + ''' + opts = salt.utils.yaml.safe_load(textwrap.dedent('''\ + gitfs_remotes: + - file://{0}: + - disable_saltenv_mapping: True + + gitfs_saltenv: + - hello: + - ref: base + ''')) + with patch.dict(gitfs.__opts__, opts): + gitfs.update() + ret = gitfs.envs(ignore_cache=True) + # Since we are restricting to tags only, the tag should appear in + # the envs list, but the branches should not. + self.assertEqual(ret, ['hello']) + + def test_disable_saltenv_mapping_per_remote_with_mapping_defined_per_remote(self): + ''' + Test the per-remote disable_saltenv_mapping config option, combined + with the per-saltenv mapping being defined in the remote itself via the + "saltenv" per-remote option. + ''' + opts = salt.utils.yaml.safe_load(textwrap.dedent('''\ + gitfs_remotes: + - file://{0}: + - disable_saltenv_mapping: True + - saltenv: + - world: + - ref: base + '''.format(TMP_REPO_DIR))) + with patch.dict(gitfs.__opts__, opts): + gitfs.update() + ret = gitfs.envs(ignore_cache=True) + # Since we are restricting to tags only, the tag should appear in + # the envs list, but the branches should not. + self.assertEqual(ret, ['world']) + + +class GitFSTestBase(object): + + @classmethod + def setUpClass(cls): + cls.tmp_cachedir = tempfile.mkdtemp(dir=TMP) + cls.tmp_sock_dir = tempfile.mkdtemp(dir=TMP) + + try: + shutil.rmtree(TMP_REPO_DIR) + except OSError as exc: + if exc.errno != errno.ENOENT: + raise + shutil.copytree(INTEGRATION_BASE_FILES, TMP_REPO_DIR + '/') + + repo = git.Repo.init(TMP_REPO_DIR) + + username_key = str('USERNAME') + orig_username = os.environ.get(username_key) + try: + if username_key not in os.environ: + try: + if salt.utils.platform.is_windows(): + os.environ[username_key] = \ + salt.utils.win_functions.get_current_user() + else: + os.environ[username_key] = \ + pwd.getpwuid(os.geteuid()).pw_name + except AttributeError: + log.error( + 'Unable to get effective username, falling back to ' + '\'root\'.' + ) + os.environ[username_key] = str('root') + + repo.index.add([x for x in os.listdir(TMP_REPO_DIR) + if x != '.git']) + repo.index.commit('Test') + + # Add another branch with unicode characters in the name + repo.create_head(UNICODE_ENVNAME, 'HEAD') + + # Add a tag + repo.create_tag(TAG_NAME, 'HEAD') + finally: + if orig_username is not None: + os.environ[username_key] = orig_username + else: + os.environ.pop(username_key, None) + + @classmethod + def tearDownClass(cls): + ''' + Remove the temporary git repository and gitfs cache directory to ensure + a clean environment for the other test class(es). + ''' + for path in (cls.tmp_cachedir, cls.tmp_sock_dir, TMP_REPO_DIR): + try: + shutil.rmtree(path, onerror=_rmtree_error) + except OSError as exc: + if exc.errno != errno.EEXIST: + raise + + def setUp(self): + ''' + We don't want to check in another .git dir into GH because that just + gets messy. Instead, we'll create a temporary repo on the fly for the + tests to examine. + + Also ensure we A) don't re-use the singleton, and B) that the cachedirs + are cleared. This keeps these performance enhancements from affecting + the results of subsequent tests. + ''' + if not gitfs.__virtual__(): + self.skipTest("GitFS could not be loaded. Skipping GitFS tests!") + + _clear_instance_map() + for subdir in ('gitfs', 'file_lists'): + try: + shutil.rmtree(os.path.join(self.tmp_cachedir, subdir)) + except OSError as exc: + if exc.errno != errno.ENOENT: + raise + + +@skipIf(not HAS_GITPYTHON, 'GitPython >= {0} required'.format(GITPYTHON_MINVER)) +@skipIf(NO_MOCK, NO_MOCK_REASON) +class GitPythonTest(GitFSTestBase, GitFSTestFuncs, TestCase, LoaderModuleMockMixin): + + def setup_loader_modules(self): + opts = copy.deepcopy(OPTS) + opts['cachedir'] = self.tmp_cachedir + opts['sock_dir'] = self.tmp_sock_dir + opts['gitfs_provider'] = 'gitpython' + return { + gitfs: { + '__opts__': opts, + } + } + + +@skipIf(not HAS_GITPYTHON, 'GitPython >= {0} required for temp repo setup'.format(GITPYTHON_MINVER)) +@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} and libgit2 >= {1} required'.format(PYGIT2_MINVER, LIBGIT2_MINVER)) +@skipIf(NO_MOCK, NO_MOCK_REASON) +class Pygit2Test(GitFSTestBase, GitFSTestFuncs, TestCase, LoaderModuleMockMixin): + + def setup_loader_modules(self): + opts = copy.deepcopy(OPTS) + opts['cachedir'] = self.tmp_cachedir + opts['sock_dir'] = self.tmp_sock_dir + opts['gitfs_provider'] = 'pygit2' + return { + gitfs: { + '__opts__': opts, + } + } diff --git a/tests/unit/grains/os-releases/debian-7 b/tests/unit/grains/os-releases/debian-7 new file mode 100644 index 0000000000..b2ec5e8bc2 --- /dev/null +++ b/tests/unit/grains/os-releases/debian-7 @@ -0,0 +1,10 @@ +# Taken from base-files 7.1wheezy11 +PRETTY_NAME="Debian GNU/Linux 7 (wheezy)" +NAME="Debian GNU/Linux" +VERSION_ID="7" +VERSION="7 (wheezy)" +ID=debian +ANSI_COLOR="1;31" +HOME_URL="http://www.debian.org/" +SUPPORT_URL="http://www.debian.org/support/" +BUG_REPORT_URL="http://bugs.debian.org/" diff --git a/tests/unit/grains/os-releases/debian-8 b/tests/unit/grains/os-releases/debian-8 new file mode 100644 index 0000000000..5bb776b08d --- /dev/null +++ b/tests/unit/grains/os-releases/debian-8 @@ -0,0 +1,9 @@ +# Taken from base-files 8+deb8u10 +PRETTY_NAME="Debian GNU/Linux 8 (jessie)" +NAME="Debian GNU/Linux" +VERSION_ID="8" +VERSION="8 (jessie)" +ID=debian +HOME_URL="http://www.debian.org/" +SUPPORT_URL="http://www.debian.org/support" +BUG_REPORT_URL="https://bugs.debian.org/" diff --git a/tests/unit/grains/os-releases/debian-9 b/tests/unit/grains/os-releases/debian-9 new file mode 100644 index 0000000000..bff278215b --- /dev/null +++ b/tests/unit/grains/os-releases/debian-9 @@ -0,0 +1,9 @@ +# Taken from base-files 9.9+deb9u3 +PRETTY_NAME="Debian GNU/Linux 9 (stretch)" +NAME="Debian GNU/Linux" +VERSION_ID="9" +VERSION="9 (stretch)" +ID=debian +HOME_URL="https://www.debian.org/" +SUPPORT_URL="https://www.debian.org/support" +BUG_REPORT_URL="https://bugs.debian.org/" diff --git a/tests/unit/grains/os-releases/ubuntu-16.04 b/tests/unit/grains/os-releases/ubuntu-16.04 new file mode 100644 index 0000000000..6f359b42be --- /dev/null +++ b/tests/unit/grains/os-releases/ubuntu-16.04 @@ -0,0 +1,12 @@ +# Taken from base-files 9.4ubuntu4.5 +NAME="Ubuntu" +VERSION="16.04.3 LTS (Xenial Xerus)" +ID=ubuntu +ID_LIKE=debian +PRETTY_NAME="Ubuntu 16.04.3 LTS" +VERSION_ID="16.04" +HOME_URL="http://www.ubuntu.com/" +SUPPORT_URL="http://help.ubuntu.com/" +BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" +VERSION_CODENAME=xenial +UBUNTU_CODENAME=xenial diff --git a/tests/unit/grains/os-releases/ubuntu-17.10 b/tests/unit/grains/os-releases/ubuntu-17.10 new file mode 100644 index 0000000000..a5d648e28f --- /dev/null +++ b/tests/unit/grains/os-releases/ubuntu-17.10 @@ -0,0 +1,13 @@ +# Taken from base-files 9.6ubuntu102 +NAME="Ubuntu" +VERSION="17.10 (Artful Aardvark)" +ID=ubuntu +ID_LIKE=debian +PRETTY_NAME="Ubuntu 17.10" +VERSION_ID="17.10" +HOME_URL="https://www.ubuntu.com/" +SUPPORT_URL="https://help.ubuntu.com/" +BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" +PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" +VERSION_CODENAME=artful +UBUNTU_CODENAME=artful diff --git a/tests/unit/grains/test_core.py b/tests/unit/grains/test_core.py index 000458201d..5582317fd8 100644 --- a/tests/unit/grains/test_core.py +++ b/tests/unit/grains/test_core.py @@ -10,6 +10,11 @@ import os import socket # Import Salt Testing Libs +try: + import pytest +except ImportError as import_error: + pytest = None + from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import TestCase, skipIf from tests.support.mock import ( @@ -21,6 +26,7 @@ from tests.support.mock import ( ) # Import Salt Libs +import salt.utils.files import salt.utils.network import salt.utils.platform import salt.grains.core as core @@ -43,9 +49,11 @@ IP4_ADD2 = '10.0.0.2' IP6_LOCAL = '::1' IP6_ADD1 = '2001:4860:4860::8844' IP6_ADD2 = '2001:4860:4860::8888' +OS_RELEASE_DIR = os.path.join(os.path.dirname(__file__), "os-releases") @skipIf(NO_MOCK, NO_MOCK_REASON) +@skipIf(not pytest, False) class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): ''' Test cases for core grains @@ -53,6 +61,35 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): def setup_loader_modules(self): return {core: {}} + @patch("os.path.isfile") + def test_parse_etc_os_release(self, path_isfile_mock): + path_isfile_mock.side_effect = lambda x: x == "/usr/lib/os-release" + with salt.utils.files.fopen(os.path.join(OS_RELEASE_DIR, "ubuntu-17.10")) as os_release_file: + os_release_content = os_release_file.readlines() + with patch("salt.utils.files.fopen", mock_open()) as os_release_file: + os_release_file.return_value.__iter__.return_value = os_release_content + os_release = core._parse_os_release(["/etc/os-release", "/usr/lib/os-release"]) + self.assertEqual(os_release, { + "NAME": "Ubuntu", + "VERSION": "17.10 (Artful Aardvark)", + "ID": "ubuntu", + "ID_LIKE": "debian", + "PRETTY_NAME": "Ubuntu 17.10", + "VERSION_ID": "17.10", + "HOME_URL": "https://www.ubuntu.com/", + "SUPPORT_URL": "https://help.ubuntu.com/", + "BUG_REPORT_URL": "https://bugs.launchpad.net/ubuntu/", + "PRIVACY_POLICY_URL": "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy", + "VERSION_CODENAME": "artful", + "UBUNTU_CODENAME": "artful", + }) + + @patch("os.path.isfile") + def test_missing_os_release(self, path_isfile_mock): + path_isfile_mock.return_value = False + os_release = core._parse_os_release(["/etc/os-release", "/usr/lib/os-release"]) + self.assertEqual(os_release, {}) + @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') def test_gnu_slash_linux_in_os_name(self): ''' @@ -151,9 +188,6 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): _path_exists_map = { '/proc/1/cmdline': False } - _path_isfile_map = { - '/etc/os-release': True, - } _os_release_map = { 'NAME': 'SLES', 'VERSION': '12-SP1', @@ -165,9 +199,6 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): } path_exists_mock = MagicMock(side_effect=lambda x: _path_exists_map[x]) - path_isfile_mock = MagicMock( - side_effect=lambda x: _path_isfile_map.get(x, False) - ) empty_mock = MagicMock(return_value={}) osarch_mock = MagicMock(return_value="amd64") os_release_mock = MagicMock(return_value=_os_release_map) @@ -195,7 +226,7 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): with patch('{0}.__import__'.format(built_in), side_effect=_import_mock): # Skip all the /etc/*-release stuff (not pertinent) - with patch.object(os.path, 'isfile', path_isfile_mock): + with patch.object(os.path, 'isfile', MagicMock(return_value=False)): with patch.object(core, '_parse_os_release', os_release_mock): # Mock linux_distribution to give us the OS # name that we want. @@ -214,11 +245,16 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): self.assertEqual(os_grains.get('os_family'), 'Suse') self.assertEqual(os_grains.get('os'), 'SUSE') - def _run_suse_os_grains_tests(self, os_release_map): - path_isfile_mock = MagicMock(side_effect=lambda x: x in os_release_map['files']) + def _run_os_grains_tests(self, os_release_filename, os_release_map, expectation): + path_isfile_mock = MagicMock(side_effect=lambda x: x in os_release_map.get('files', [])) empty_mock = MagicMock(return_value={}) osarch_mock = MagicMock(return_value="amd64") - os_release_mock = MagicMock(return_value=os_release_map.get('os_release_file')) + if os_release_filename: + os_release_data = core._parse_os_release( + [os.path.join(OS_RELEASE_DIR, os_release_filename)]) + else: + os_release_data = os_release_map.get('os_release_file', {}) + os_release_mock = MagicMock(return_value=os_release_data) orig_import = __import__ if six.PY2: @@ -248,10 +284,11 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): # Mock linux_distribution to give us the OS # name that we want. distro_mock = MagicMock( - return_value=('SUSE test', 'version', 'arch') + return_value=os_release_map['linux_distribution'] ) with patch('salt.utils.files.fopen', mock_open()) as suse_release_file: - suse_release_file.return_value.__iter__.return_value = os_release_map.get('suse_release_file', '').splitlines() + suse_release_file.return_value.__iter__.return_value = \ + os_release_map.get('suse_release_file', '').splitlines() with patch.object(core, 'linux_distribution', distro_mock): with patch.object(core, '_linux_gpu_data', empty_mock): with patch.object(core, '_linux_cpudata', empty_mock): @@ -260,13 +297,16 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): with patch.dict(core.__salt__, {'cmd.run': osarch_mock}): os_grains = core.os_data() - self.assertEqual(os_grains.get('os'), 'SUSE') - self.assertEqual(os_grains.get('os_family'), 'Suse') - self.assertEqual(os_grains.get('osfullname'), os_release_map['osfullname']) - self.assertEqual(os_grains.get('oscodename'), os_release_map['oscodename']) - self.assertEqual(os_grains.get('osrelease'), os_release_map['osrelease']) - self.assertListEqual(list(os_grains.get('osrelease_info')), os_release_map['osrelease_info']) - self.assertEqual(os_grains.get('osmajorrelease'), os_release_map['osmajorrelease']) + grains = {k: v for k, v in os_grains.items() + if k in set(["os", "os_family", "osfullname", "oscodename", "osfinger", + "osrelease", "osrelease_info", "osmajorrelease"])} + self.assertEqual(grains, expectation) + + def _run_suse_os_grains_tests(self, os_release_map, expectation): + os_release_map['linux_distribution'] = ('SUSE test', 'version', 'arch') + expectation['os'] = 'SUSE' + expectation['os_family'] = 'Suse' + self._run_os_grains_tests(None, os_release_map, expectation) @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') def test_suse_os_grains_sles11sp3(self): @@ -278,14 +318,17 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): VERSION = 11 PATCHLEVEL = 3 ''', + 'files': ["/etc/SuSE-release"], + } + expectation = { 'oscodename': 'SUSE Linux Enterprise Server 11 SP3', 'osfullname': "SLES", 'osrelease': '11.3', - 'osrelease_info': [11, 3], + 'osrelease_info': (11, 3), 'osmajorrelease': 11, - 'files': ["/etc/SuSE-release"], + 'osfinger': 'SLES-11', } - self._run_suse_os_grains_tests(_os_release_map) + self._run_suse_os_grains_tests(_os_release_map, expectation) @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') def test_suse_os_grains_sles11sp4(self): @@ -302,14 +345,16 @@ PATCHLEVEL = 3 'ANSI_COLOR': '0;32', 'CPE_NAME': 'cpe:/o:suse:sles:11:4' }, + } + expectation = { 'oscodename': 'SUSE Linux Enterprise Server 11 SP4', 'osfullname': "SLES", 'osrelease': '11.4', - 'osrelease_info': [11, 4], + 'osrelease_info': (11, 4), 'osmajorrelease': 11, - 'files': ["/etc/os-release"], + 'osfinger': 'SLES-11', } - self._run_suse_os_grains_tests(_os_release_map) + self._run_suse_os_grains_tests(_os_release_map, expectation) @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') def test_suse_os_grains_sles12(self): @@ -326,14 +371,16 @@ PATCHLEVEL = 3 'ANSI_COLOR': '0;32', 'CPE_NAME': 'cpe:/o:suse:sles:12' }, + } + expectation = { 'oscodename': 'SUSE Linux Enterprise Server 12', 'osfullname': "SLES", 'osrelease': '12', - 'osrelease_info': [12], + 'osrelease_info': (12,), 'osmajorrelease': 12, - 'files': ["/etc/os-release"], + 'osfinger': 'SLES-12', } - self._run_suse_os_grains_tests(_os_release_map) + self._run_suse_os_grains_tests(_os_release_map, expectation) @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') def test_suse_os_grains_sles12sp1(self): @@ -350,14 +397,16 @@ PATCHLEVEL = 3 'ANSI_COLOR': '0;32', 'CPE_NAME': 'cpe:/o:suse:sles:12:sp1' }, + } + expectation = { 'oscodename': 'SUSE Linux Enterprise Server 12 SP1', 'osfullname': "SLES", 'osrelease': '12.1', - 'osrelease_info': [12, 1], + 'osrelease_info': (12, 1), 'osmajorrelease': 12, - 'files': ["/etc/os-release"], + 'osfinger': 'SLES-12', } - self._run_suse_os_grains_tests(_os_release_map) + self._run_suse_os_grains_tests(_os_release_map, expectation) @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') def test_suse_os_grains_opensuse_leap_42_1(self): @@ -374,14 +423,16 @@ PATCHLEVEL = 3 'ANSI_COLOR': '0;32', 'CPE_NAME': 'cpe:/o:opensuse:opensuse:42.1' }, + } + expectation = { 'oscodename': 'openSUSE Leap 42.1 (x86_64)', 'osfullname': "Leap", 'osrelease': '42.1', - 'osrelease_info': [42, 1], + 'osrelease_info': (42, 1), 'osmajorrelease': 42, - 'files': ["/etc/os-release"], + 'osfinger': 'Leap-42', } - self._run_suse_os_grains_tests(_os_release_map) + self._run_suse_os_grains_tests(_os_release_map, expectation) @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') def test_suse_os_grains_tumbleweed(self): @@ -398,90 +449,116 @@ PATCHLEVEL = 3 'ANSI_COLOR': '0;32', 'CPE_NAME': 'cpe:/o:opensuse:opensuse:20160504' }, + } + expectation = { 'oscodename': 'openSUSE Tumbleweed (20160504) (x86_64)', 'osfullname': "Tumbleweed", 'osrelease': '20160504', - 'osrelease_info': [20160504], + 'osrelease_info': (20160504,), 'osmajorrelease': 20160504, - 'files': ["/etc/os-release"], + 'osfinger': 'Tumbleweed-20160504', } - self._run_suse_os_grains_tests(_os_release_map) + self._run_suse_os_grains_tests(_os_release_map, expectation) @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') - def test_ubuntu_os_grains(self): + def test_debian_7_os_grains(self): ''' - Test if OS grains are parsed correctly in Ubuntu Xenial Xerus + Test if OS grains are parsed correctly in Debian 7 "wheezy" ''' _os_release_map = { - 'os_release_file': { - 'NAME': 'Ubuntu', - 'VERSION': '16.04.1 LTS (Xenial Xerus)', - 'VERSION_ID': '16.04', - 'PRETTY_NAME': '', - 'ID': 'ubuntu', - }, + 'linux_distribution': ('debian', '7.11', ''), + } + expectation = { + 'os': 'Debian', + 'os_family': 'Debian', + 'oscodename': 'wheezy', + 'osfullname': 'Debian GNU/Linux', + 'osrelease': '7', + 'osrelease_info': (7,), + 'osmajorrelease': 7, + 'osfinger': 'Debian-7', + } + self._run_os_grains_tests("debian-7", _os_release_map, expectation) + + @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') + def test_debian_8_os_grains(self): + ''' + Test if OS grains are parsed correctly in Debian 8 "jessie" + ''' + _os_release_map = { + 'linux_distribution': ('debian', '8.10', ''), + } + expectation = { + 'os': 'Debian', + 'os_family': 'Debian', + 'oscodename': 'jessie', + 'osfullname': 'Debian GNU/Linux', + 'osrelease': '8', + 'osrelease_info': (8,), + 'osmajorrelease': 8, + 'osfinger': 'Debian-8', + } + self._run_os_grains_tests("debian-8", _os_release_map, expectation) + + @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') + def test_debian_9_os_grains(self): + ''' + Test if OS grains are parsed correctly in Debian 9 "stretch" + ''' + _os_release_map = { + 'linux_distribution': ('debian', '9.3', ''), + } + expectation = { + 'os': 'Debian', + 'os_family': 'Debian', + 'oscodename': 'stretch', + 'osfullname': 'Debian GNU/Linux', + 'osrelease': '9', + 'osrelease_info': (9,), + 'osmajorrelease': 9, + 'osfinger': 'Debian-9', + } + self._run_os_grains_tests("debian-9", _os_release_map, expectation) + + @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') + def test_ubuntu_xenial_os_grains(self): + ''' + Test if OS grains are parsed correctly in Ubuntu 16.04 "Xenial Xerus" + ''' + _os_release_map = { + 'linux_distribution': ('Ubuntu', '16.04', 'xenial'), + } + expectation = { + 'os': 'Ubuntu', + 'os_family': 'Debian', 'oscodename': 'xenial', 'osfullname': 'Ubuntu', 'osrelease': '16.04', - 'osrelease_info': [16, 4], + 'osrelease_info': (16, 4), 'osmajorrelease': 16, 'osfinger': 'Ubuntu-16.04', } - self._run_ubuntu_os_grains_tests(_os_release_map) + self._run_os_grains_tests("ubuntu-16.04", _os_release_map, expectation) - def _run_ubuntu_os_grains_tests(self, os_release_map): - path_isfile_mock = MagicMock(side_effect=lambda x: x in ['/etc/os-release']) - empty_mock = MagicMock(return_value={}) - osarch_mock = MagicMock(return_value="amd64") - os_release_mock = MagicMock(return_value=os_release_map.get('os_release_file')) - - if six.PY2: - built_in = '__builtin__' - else: - built_in = 'builtins' - - orig_import = __import__ - - def _import_mock(name, *args): - if name == 'lsb_release': - raise ImportError('No module named lsb_release') - return orig_import(name, *args) - - # Skip the first if statement - with patch.object(salt.utils.platform, 'is_proxy', - MagicMock(return_value=False)): - # Skip the selinux/systemd stuff (not pertinent) - with patch.object(core, '_linux_bin_exists', - MagicMock(return_value=False)): - # Skip the init grain compilation (not pertinent) - with patch.object(os.path, 'exists', path_isfile_mock): - # Ensure that lsb_release fails to import - with patch('{0}.__import__'.format(built_in), - side_effect=_import_mock): - # Skip all the /etc/*-release stuff (not pertinent) - with patch.object(os.path, 'isfile', path_isfile_mock): - with patch.object(core, '_parse_os_release', os_release_mock): - # Mock linux_distribution to give us the OS - # name that we want. - distro_mock = MagicMock(return_value=('Ubuntu', '16.04', 'xenial')) - with patch('salt.utils.files.fopen', mock_open()) as suse_release_file: - suse_release_file.return_value.__iter__.return_value = os_release_map.get( - 'suse_release_file', '').splitlines() - with patch.object(core, 'linux_distribution', distro_mock): - with patch.object(core, '_linux_gpu_data', empty_mock): - with patch.object(core, '_linux_cpudata', empty_mock): - with patch.object(core, '_virtual', empty_mock): - # Mock the osarch - with patch.dict(core.__salt__, {'cmd.run': osarch_mock}): - os_grains = core.os_data() - - self.assertEqual(os_grains.get('os'), 'Ubuntu') - self.assertEqual(os_grains.get('os_family'), 'Debian') - self.assertEqual(os_grains.get('osfullname'), os_release_map['osfullname']) - self.assertEqual(os_grains.get('oscodename'), os_release_map['oscodename']) - self.assertEqual(os_grains.get('osrelease'), os_release_map['osrelease']) - self.assertListEqual(list(os_grains.get('osrelease_info')), os_release_map['osrelease_info']) - self.assertEqual(os_grains.get('osmajorrelease'), os_release_map['osmajorrelease']) + @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') + def test_ubuntu_artful_os_grains(self): + ''' + Test if OS grains are parsed correctly in Ubuntu 17.10 "Artful Aardvark" + ''' + _os_release_map = { + 'linux_distribution': ('Ubuntu', '17.10', 'artful'), + } + expectation = { + 'os': 'Ubuntu', + 'os_family': 'Debian', + 'oscodename': 'artful', + 'osfullname': 'Ubuntu', + 'osrelease': '17.10', + 'osrelease_info': (17, 10), + 'osmajorrelease': 17, + 'osfinger': 'Ubuntu-17.10', + } + self._run_os_grains_tests("ubuntu-17.10", _os_release_map, expectation) def test_windows_iscsi_iqn_grains(self): cmd_run_mock = MagicMock( @@ -517,8 +594,8 @@ PATCHLEVEL = 3 self.assertEqual(_grains.get('iscsi_iqn'), ['iqn.localhost.hostid.7f000001']) - @skipIf(salt.utils.platform.is_darwin(), 'MacOSX iscsi grains not supported') - @skipIf(salt.utils.platform.is_windows(), 'System is Windows') + @patch('salt.grains.core.os.path.isfile', MagicMock(return_value=True)) + @patch('salt.grains.core.os.access', MagicMock(return_value=True)) def test_linux_iscsi_iqn_grains(self): _iscsi_file = '## DO NOT EDIT OR REMOVE THIS FILE!\n' \ '## If you remove this file, the iSCSI daemon will not start.\n' \ @@ -527,13 +604,13 @@ PATCHLEVEL = 3 '## for each iSCSI initiator. Do NOT duplicate iSCSI InitiatorNames.\n' \ 'InitiatorName=iqn.1993-08.org.debian:01:d12f7aba36\n' - with patch('os.path.isfile', MagicMock(return_value=True)): - with patch('salt.utils.files.fopen', mock_open()) as iscsi_initiator_file: - iscsi_initiator_file.return_value.__iter__.return_value = _iscsi_file.splitlines() - _grains = core.iscsi_iqn() + with patch('salt.utils.files.fopen', mock_open()) as iscsi_initiator_file: + iscsi_initiator_file.return_value.__iter__.return_value = _iscsi_file.splitlines() + iqn = core._linux_iqn() - self.assertEqual(_grains.get('iscsi_iqn'), - ['iqn.1993-08.org.debian:01:d12f7aba36']) + assert isinstance(iqn, list) + assert len(iqn) == 1 + assert iqn == ['iqn.1993-08.org.debian:01:d12f7aba36'] @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') def test_linux_memdata(self): @@ -811,6 +888,8 @@ SwapTotal: 4789244 kB''' _check_type(key, value, ip4_empty, ip6_empty) @skipIf(not salt.utils.platform.is_linux(), 'System is not Linux') + @patch.object(salt.utils.platform, 'is_windows', MagicMock(return_value=False)) + @patch('salt.grains.core.__opts__', {'ipv6': False}) def test_dns_return(self): ''' test the return for a dns grain. test for issue: @@ -860,3 +939,30 @@ SwapTotal: 4789244 kB''' with patch.object(socket, 'gethostbyaddr', side_effect=reverse_resolv_mock): fqdns = core.fqdns() self.assertEqual(fqdns, ret) + + @patch('salt.utils.files.fopen', MagicMock(side_effect=IOError(os.errno.EPERM, + 'The cables are not the same length.'))) + @patch('salt.grains.core.log', MagicMock()) + def test_linux_iqn_non_root(self): + ''' + Test if linux_iqn is running on salt-master as non-root + and handling access denial properly. + :return: + ''' + assert core._linux_iqn() == [] + core.log.debug.assert_called() + assert 'Error while accessing' in core.log.debug.call_args[0][0] + assert 'cables are not the same' in core.log.debug.call_args[0][2].strerror + assert core.log.debug.call_args[0][2].errno == os.errno.EPERM + assert core.log.debug.call_args[0][1] == '/etc/iscsi/initiatorname.iscsi' + + @patch('salt.utils.files.fopen', MagicMock(side_effect=IOError(os.errno.ENOENT, ''))) + @patch('salt.grains.core.log', MagicMock()) + def test_linux_iqn_no_iscsii_initiator(self): + ''' + Test if linux_iqn is running on salt-master as root. + iscsii initiator is not there accessible or is not supported. + :return: + ''' + assert core._linux_iqn() == [] + core.log.debug.assert_not_called() diff --git a/tests/unit/modules/test_cmdmod.py b/tests/unit/modules/test_cmdmod.py index fff5732baa..89acfb81e5 100644 --- a/tests/unit/modules/test_cmdmod.py +++ b/tests/unit/modules/test_cmdmod.py @@ -10,14 +10,17 @@ import sys import tempfile # Import Salt Libs +import salt.utils.files import salt.utils.platform import salt.modules.cmdmod as cmdmod from salt.exceptions import CommandExecutionError from salt.log import LOG_LEVELS +from salt.ext.six.moves import builtins # pylint: disable=import-error # Import Salt Testing Libs from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import TestCase, skipIf +from tests.support.paths import FILES from tests.support.mock import ( mock_open, Mock, @@ -33,6 +36,39 @@ MOCK_SHELL_FILE = '# List of acceptable shells\n' \ '/bin/bash\n' +class MockTimedProc(object): + ''' + Class used as a stand-in for salt.utils.timed_subprocess.TimedProc + ''' + class _Process(object): + ''' + Used to provide a dummy "process" attribute + ''' + def __init__(self, returncode=0, pid=12345): + self.returncode = returncode + self.pid = pid + + def __init__(self, stdout=None, stderr=None, returncode=0, pid=12345): + if stdout is not None and not isinstance(stdout, bytes): + raise TypeError('Must pass stdout to MockTimedProc as bytes') + if stderr is not None and not isinstance(stderr, bytes): + raise TypeError('Must pass stderr to MockTimedProc as bytes') + self._stdout = stdout + self._stderr = stderr + self.process = self._Process(returncode=returncode, pid=pid) + + def run(self): + pass + + @property + def stdout(self): + return self._stdout + + @property + def stderr(self): + return self._stderr + + @skipIf(NO_MOCK, NO_MOCK_REASON) class CMDMODTestCase(TestCase, LoaderModuleMockMixin): ''' @@ -303,3 +339,85 @@ class CMDMODTestCase(TestCase, LoaderModuleMockMixin): pass else: raise RuntimeError + + def test_run_all_binary_replace(self): + ''' + Test for failed decoding of binary data, for instance when doing + something silly like using dd to read from /dev/urandom and write to + /dev/stdout. + ''' + # Since we're using unicode_literals, read the random bytes from a file + rand_bytes_file = os.path.join(FILES, 'file', 'base', 'random_bytes') + with salt.utils.files.fopen(rand_bytes_file, 'rb') as fp_: + stdout_bytes = fp_.read() + + # stdout with the non-decodable bits replaced with the unicode + # replacement character U+FFFD. + stdout_unicode = '\ufffd\x1b\ufffd\ufffd\n' + stderr_bytes = b'1+0 records in\n1+0 records out\n' \ + b'4 bytes copied, 9.1522e-05 s, 43.7 kB/s\n' + stderr_unicode = stderr_bytes.decode() + + proc = MagicMock( + return_value=MockTimedProc( + stdout=stdout_bytes, + stderr=stderr_bytes + ) + ) + with patch('salt.utils.timed_subprocess.TimedProc', proc): + ret = cmdmod.run_all( + 'dd if=/dev/urandom of=/dev/stdout bs=4 count=1', + rstrip=False) + + self.assertEqual(ret['stdout'], stdout_unicode) + self.assertEqual(ret['stderr'], stderr_unicode) + + def test_run_all_none(self): + ''' + Tests cases when proc.stdout or proc.stderr are None. These should be + caught and replaced with empty strings. + ''' + proc = MagicMock(return_value=MockTimedProc(stdout=None, stderr=None)) + with patch('salt.utils.timed_subprocess.TimedProc', proc): + ret = cmdmod.run_all('some command', rstrip=False) + + self.assertEqual(ret['stdout'], '') + self.assertEqual(ret['stderr'], '') + + def test_run_all_unicode(self): + ''' + Ensure that unicode stdout and stderr are decoded properly + ''' + stdout_unicode = 'Here is some unicode: спам' + stderr_unicode = 'Here is some unicode: яйца' + stdout_bytes = stdout_unicode.encode('utf-8') + stderr_bytes = stderr_unicode.encode('utf-8') + + proc = MagicMock( + return_value=MockTimedProc( + stdout=stdout_bytes, + stderr=stderr_bytes + ) + ) + + with patch('salt.utils.timed_subprocess.TimedProc', proc), \ + patch.object(builtins, '__salt_system_encoding__', 'utf-8'): + ret = cmdmod.run_all('some command', rstrip=False) + + self.assertEqual(ret['stdout'], stdout_unicode) + self.assertEqual(ret['stderr'], stderr_unicode) + + def test_run_all_output_encoding(self): + ''' + Test that specifying the output encoding works as expected + ''' + stdout = 'Æ' + stdout_latin1_enc = stdout.encode('latin1') + + proc = MagicMock(return_value=MockTimedProc(stdout=stdout_latin1_enc)) + + with patch('salt.utils.timed_subprocess.TimedProc', proc), \ + patch.object(builtins, '__salt_system_encoding__', 'utf-8'): + ret = cmdmod.run_all('some command', output_encoding='latin1') + + self.assertEqual(ret['stdout'], stdout) diff --git a/tests/unit/modules/test_dockermod.py b/tests/unit/modules/test_dockermod.py index 4e061ce369..e697ae61e1 100644 --- a/tests/unit/modules/test_dockermod.py +++ b/tests/unit/modules/test_dockermod.py @@ -14,7 +14,8 @@ from tests.support.mock import ( Mock, NO_MOCK, NO_MOCK_REASON, - patch + patch, + call ) import logging log = logging.getLogger(__name__) @@ -23,7 +24,7 @@ log = logging.getLogger(__name__) import salt.config import salt.loader from salt.ext.six.moves import range -from salt.exceptions import CommandExecutionError +from salt.exceptions import CommandExecutionError, SaltInvocationError import salt.modules.dockermod as docker_mod @@ -781,3 +782,225 @@ class DockerTestCase(TestCase, LoaderModuleMockMixin): with patch.object(docker_mod, 'inspect_image', mock_not_found): self.assertIs(docker_mod.resolve_tag('foo'), False) self.assertIs(docker_mod.resolve_tag('foo', all=True), False) + + def test_prune(self): + ''' + Test the prune function + ''' + def _run(**kwargs): + side_effect = kwargs.pop('side_effect', None) + # No arguments passed, we should be pruning everything but volumes + client = Mock() + if side_effect is not None: + client.side_effect = side_effect + with patch.object(docker_mod, '_client_wrapper', client): + docker_mod.prune(**kwargs) + return client + + # Containers only, no filters + client = _run(containers=True) + client.assert_called_once_with( + 'prune_containers', + filters={} + ) + + # Containers only, with filters + client = _run(containers=True, until='24h', label='foo,bar=baz') + client.assert_called_once_with( + 'prune_containers', + filters={'until': ['24h'], 'label': ['foo', 'bar=baz']} + ) + + # Images only, no filters + client = _run(images=True) + client.assert_called_once_with( + 'prune_images', + filters={} + ) + + # Images only, with filters + client = _run(images=True, dangling=True, + until='24h', label='foo,bar=baz') + client.assert_called_once_with( + 'prune_images', + filters={'dangling': True, + 'until': ['24h'], + 'label': ['foo', 'bar=baz']} + ) + + # Networks only, no filters + client = _run(networks=True) + client.assert_called_once_with('prune_networks', filters={}) + + # Networks only, with filters + client = _run(networks=True, until='24h', label='foo,bar=baz') + client.assert_called_once_with( + 'prune_networks', + filters={'until': ['24h'], 'label': ['foo', 'bar=baz']} + ) + + # Volumes only, no filters + client = _run(system=False, volumes=True) + client.assert_called_once_with('prune_volumes', filters={}) + + # Volumes only, with filters + client = _run(system=False, volumes=True, label='foo,bar=baz') + client.assert_called_once_with( + 'prune_volumes', + filters={'label': ['foo', 'bar=baz']} + ) + + # Containers and images, no filters + client = _run(containers=True, images=True) + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', filters={}), + call('prune_images', filters={}), + ] + ) + + # Containers and images, with filters + client = _run(containers=True, images=True, + until='24h', label='foo,bar=baz') + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', + filters={'until': ['24h'], 'label': ['foo', 'bar=baz']}), + call('prune_images', + filters={'until': ['24h'], 'label': ['foo', 'bar=baz']}), + ] + ) + + # System, no volumes, no filters, assuming prune_build in docker-py + client = _run(system=True) + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', filters={}), + call('prune_images', filters={}), + call('prune_networks', filters={}), + call('prune_build', filters={}), + ] + ) + + # System, no volumes, no filters, assuming prune_build not in docker-py + client = _run( + system=True, + side_effect=[None, None, None, SaltInvocationError(), + None, None, None] + ) + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', filters={}), + call('prune_images', filters={}), + call('prune_networks', filters={}), + call('prune_build', filters={}), + call('_url', '/build/prune'), + call('_post', None), + call('_result', None, True), + ] + ) + + # System, no volumes, with filters, assuming prune_build in docker-py + client = _run(system=True, label='foo,bar=baz') + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', filters={'label': ['foo', 'bar=baz']}), + call('prune_images', filters={'label': ['foo', 'bar=baz']}), + call('prune_networks', filters={'label': ['foo', 'bar=baz']}), + call('prune_build', filters={'label': ['foo', 'bar=baz']}), + ] + ) + + # System, no volumes, with filters, assuming prune_build not in docker-py + client = _run( + system=True, + label='foo,bar=baz', + side_effect=[None, None, None, SaltInvocationError(), + None, None, None] + ) + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', filters={'label': ['foo', 'bar=baz']}), + call('prune_images', filters={'label': ['foo', 'bar=baz']}), + call('prune_networks', filters={'label': ['foo', 'bar=baz']}), + call('prune_build', filters={'label': ['foo', 'bar=baz']}), + call('_url', '/build/prune'), + call('_post', None), + call('_result', None, True), + ] + ) + + # System and volumes, no filters, assuming prune_build in docker-py + client = _run(system=True, volumes=True) + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', filters={}), + call('prune_images', filters={}), + call('prune_networks', filters={}), + call('prune_build', filters={}), + call('prune_volumes', filters={}), + ] + ) + + # System and volumes, no filters, assuming prune_build not in docker-py + client = _run( + system=True, + volumes=True, + side_effect=[None, None, None, SaltInvocationError(), + None, None, None, None] + ) + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', filters={}), + call('prune_images', filters={}), + call('prune_networks', filters={}), + call('prune_build', filters={}), + call('_url', '/build/prune'), + call('_post', None), + call('_result', None, True), + call('prune_volumes', filters={}), + ] + ) + + # System and volumes with filters, assuming prune_build in docker-py + client = _run(system=True, volumes=True, label='foo,bar=baz') + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', filters={'label': ['foo', 'bar=baz']}), + call('prune_images', filters={'label': ['foo', 'bar=baz']}), + call('prune_networks', filters={'label': ['foo', 'bar=baz']}), + call('prune_build', filters={'label': ['foo', 'bar=baz']}), + call('prune_volumes', filters={'label': ['foo', 'bar=baz']}), + ] + ) + + # System and volumes, with filters, assuming prune_build not in docker-py + client = _run( + system=True, + volumes=True, + label='foo,bar=baz', + side_effect=[None, None, None, SaltInvocationError(), + None, None, None, None] + ) + self.assertEqual( + client.call_args_list, + [ + call('prune_containers', filters={'label': ['foo', 'bar=baz']}), + call('prune_images', filters={'label': ['foo', 'bar=baz']}), + call('prune_networks', filters={'label': ['foo', 'bar=baz']}), + call('prune_build', filters={'label': ['foo', 'bar=baz']}), + call('_url', '/build/prune'), + call('_post', None), + call('_result', None, True), + call('prune_volumes', filters={'label': ['foo', 'bar=baz']}), + ] + ) diff --git a/tests/unit/modules/test_file.py b/tests/unit/modules/test_file.py index 10b6dcb447..c7ec9eff86 100644 --- a/tests/unit/modules/test_file.py +++ b/tests/unit/modules/test_file.py @@ -11,7 +11,7 @@ import textwrap from tests.support.mixins import LoaderModuleMockMixin from tests.support.paths import TMP from tests.support.unit import TestCase, skipIf -from tests.support.mock import MagicMock, patch, mock_open +from tests.support.mock import MagicMock, Mock, patch, mock_open try: import pytest @@ -19,6 +19,7 @@ except ImportError: pytest = None # Import Salt libs +from salt.ext import six import salt.config import salt.loader import salt.utils.files @@ -28,7 +29,7 @@ import salt.modules.file as filemod import salt.modules.config as configmod import salt.modules.cmdmod as cmdmod from salt.exceptions import CommandExecutionError -from salt.ext import six +from salt.utils.jinja import SaltCacheLoader SED_CONTENT = '''test some @@ -754,12 +755,13 @@ class FileModuleTestCase(TestCase, LoaderModuleMockMixin): ''' contents = 'This is a {{ template }}.' defaults = {'template': 'templated file'} - ret = filemod.apply_template_on_contents( - contents, - template='jinja', - context={'opts': filemod.__opts__}, - defaults=defaults, - saltenv='base') + with patch.object(SaltCacheLoader, 'file_client', Mock()): + ret = filemod.apply_template_on_contents( + contents, + template='jinja', + context={'opts': filemod.__opts__}, + defaults=defaults, + saltenv='base') self.assertEqual(ret, 'This is a templated file.') diff --git a/tests/unit/modules/test_git.py b/tests/unit/modules/test_git.py index 90207a3632..80763965f6 100644 --- a/tests/unit/modules/test_git.py +++ b/tests/unit/modules/test_git.py @@ -14,6 +14,7 @@ import subprocess from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import TestCase, skipIf from tests.support.mock import ( + Mock, MagicMock, patch, NO_MOCK, @@ -77,7 +78,13 @@ class GitTestCase(TestCase, LoaderModuleMockMixin): Test cases for salt.modules.git ''' def setup_loader_modules(self): - return {git_mod: {}} + return { + git_mod: { + '__utils__': { + 'ssh.key_is_encrypted': Mock(return_value=False) + }, + } + } def test_list_worktrees(self): ''' @@ -164,3 +171,50 @@ class GitTestCase(TestCase, LoaderModuleMockMixin): dict([(x, worktree_ret[x]) for x in WORKTREE_INFO if WORKTREE_INFO[x].get('stale', False)]) ) + + def test__git_run_tmp_wrapper(self): + ''' + When an identity file is specified, make sure we don't attempt to + remove a temp wrapper that wasn't created. Windows doesn't use temp + wrappers, and *NIX won't unless no username was specified and the path + is not executable. + ''' + file_remove_mock = Mock() + mock_true = Mock(return_value=True) + mock_false = Mock(return_value=False) + cmd_mock = MagicMock(return_value={ + 'retcode': 0, + 'stdout': '', + 'stderr': '', + }) + with patch.dict(git_mod.__salt__, {'file.file_exists': mock_true, + 'file.remove': file_remove_mock, + 'cmd.run_all': cmd_mock, + 'ssh.key_is_encrypted': mock_false}): + + # Non-windows + with patch('salt.utils.platform.is_windows', mock_false), \ + patch.object(git_mod, '_path_is_executable_others', + mock_true): + + # Command doesn't really matter here since we're mocking + git_mod._git_run( + ['git', 'rev-parse', 'HEAD'], + cwd='/some/path', + user=None, + identity='/root/.ssh/id_rsa') + + file_remove_mock.assert_not_called() + + file_remove_mock.reset_mock() + with patch('salt.utils.platform.is_windows', mock_true), \ + patch.object(git_mod, '_find_ssh_exe', + MagicMock(return_value=r'C:\Git\ssh.exe')): + # Command doesn't really matter here since we're mocking + git_mod._git_run( + ['git', 'rev-parse', 'HEAD'], + cwd=r'C:\some\path', + user=None, + identity=r'C:\ssh\id_rsa') + + file_remove_mock.assert_not_called() diff --git a/tests/unit/modules/test_kernelpkg.py b/tests/unit/modules/test_kernelpkg.py index 2498be8767..d65f45ceb4 100644 --- a/tests/unit/modules/test_kernelpkg.py +++ b/tests/unit/modules/test_kernelpkg.py @@ -3,7 +3,7 @@ :synopsis: Base class for kernelpkg modules :platform: Linux :maturity: develop - versionadded:: oxygen + versionadded:: 2018.3.0 ''' # pylint: disable=invalid-name,no-member diff --git a/tests/unit/modules/test_kernelpkg_linux_apt.py b/tests/unit/modules/test_kernelpkg_linux_apt.py index c2658ce9fa..7f0d540d5f 100644 --- a/tests/unit/modules/test_kernelpkg_linux_apt.py +++ b/tests/unit/modules/test_kernelpkg_linux_apt.py @@ -3,7 +3,7 @@ :synopsis: Unit Tests for 'module.aptkernelpkg' :platform: Linux :maturity: develop - versionadded:: oxygen + versionadded:: 2018.3.0 ''' # pylint: disable=invalid-name,no-member diff --git a/tests/unit/modules/test_kernelpkg_linux_yum.py b/tests/unit/modules/test_kernelpkg_linux_yum.py index 170b2a7df7..d0c1777bbb 100644 --- a/tests/unit/modules/test_kernelpkg_linux_yum.py +++ b/tests/unit/modules/test_kernelpkg_linux_yum.py @@ -3,7 +3,7 @@ :synopsis: Unit Tests for 'module.yumkernelpkg' :platform: Linux :maturity: develop - versionadded:: oxygen + versionadded:: 2018.3.0 ''' # pylint: disable=invalid-name,no-member diff --git a/tests/unit/modules/test_kubernetes.py b/tests/unit/modules/test_kubernetes.py index f7b93fd9fe..9f24df40ac 100644 --- a/tests/unit/modules/test_kubernetes.py +++ b/tests/unit/modules/test_kubernetes.py @@ -18,12 +18,7 @@ from tests.support.mock import ( NO_MOCK_REASON ) -try: - from salt.modules import kubernetes -except ImportError: - kubernetes = False -if not kubernetes.HAS_LIBS: - kubernetes = False +from salt.modules import kubernetes @contextmanager @@ -41,8 +36,8 @@ def mock_kubernetes_library(): @skipIf(NO_MOCK, NO_MOCK_REASON) -@skipIf(kubernetes is False, "Probably Kubernetes client lib is not installed. \ - Skipping test_kubernetes.py") +@skipIf(not kubernetes.HAS_LIBS, "Kubernetes client lib is not installed. " + "Skipping test_kubernetes.py") class KubernetesTestCase(TestCase, LoaderModuleMockMixin): ''' Test cases for salt.modules.kubernetes diff --git a/tests/unit/modules/test_localemod.py b/tests/unit/modules/test_localemod.py index 2d6665a385..05d3cf4c7e 100644 --- a/tests/unit/modules/test_localemod.py +++ b/tests/unit/modules/test_localemod.py @@ -64,7 +64,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): {'cmd.run': MagicMock(return_value='A\nB')}): assert localemod.list_avail() == ['A', 'B'] - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__salt__', {'cmd.run': MagicMock(return_value=locale_ctl_out)}) def test_localectl_status_parser(self): ''' @@ -119,7 +119,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert msg == ('Odd locale parameter "Fatal error right in front of screen" detected in dbus locale output.' ' This should not happen. You should probably investigate what caused this.') - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.log', MagicMock()) def test_localectl_status_parser_no_systemd(self): ''' @@ -131,21 +131,21 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert 'Unable to find "localectl"' in six.text_type(err) assert not localemod.log.debug.called - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__salt__', {'cmd.run': MagicMock(return_value=locale_ctl_out_empty)}) def test_localectl_status_parser_empty(self): with pytest.raises(CommandExecutionError) as err: localemod._localectl_status() assert 'Unable to parse result of "localectl"' in six.text_type(err) - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__salt__', {'cmd.run': MagicMock(return_value=locale_ctl_out_broken)}) def test_localectl_status_parser_broken(self): with pytest.raises(CommandExecutionError) as err: localemod._localectl_status() assert 'Unable to parse result of "localectl"' in six.text_type(err) - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__salt__', {'cmd.run': MagicMock(return_value=locale_ctl_out_structure)}) def test_localectl_status_parser_structure(self): out = localemod._localectl_status() @@ -156,7 +156,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert isinstance(out[key][in_key], six.text_type) assert isinstance(out['reason'], six.text_type) - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__grains__', {'os_family': 'Ubuntu', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod._parse_dbus_locale', MagicMock(return_value={'LANG': 'en_US.utf8'})) @@ -169,7 +169,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): ''' assert localemod.get_locale() == 'de_DE.utf8' - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__grains__', {'os_family': 'Ubuntu', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', True) @patch('salt.modules.localemod._parse_dbus_locale', MagicMock(return_value={'LANG': 'en_US.utf8'})) @@ -182,7 +182,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): ''' assert localemod.get_locale() == 'en_US.utf8' - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__grains__', {'os_family': 'Suse', 'osmajorrelease': 12}) @patch('salt.modules.localemod.dbus', True) @patch('salt.modules.localemod._parse_dbus_locale', MagicMock(return_value={'LANG': 'en_US.utf8'})) @@ -197,7 +197,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): localemod.get_locale() assert localemod.__salt__['cmd.run'].call_args[0][0] == 'grep "^RC_LANG" /etc/sysconfig/language' - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'RedHat', 'osmajorrelease': 12}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', {'cmd.run': MagicMock()}) @@ -210,7 +210,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): localemod.get_locale() assert localemod.__salt__['cmd.run'].call_args[0][0] == 'grep "^LANG=" /etc/sysconfig/i18n' - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'Debian', 'osmajorrelease': 12}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', {'cmd.run': MagicMock()}) @@ -223,7 +223,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): localemod.get_locale() assert localemod.__salt__['cmd.run'].call_args[0][0] == 'grep "^LANG=" /etc/default/locale' - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'Gentoo', 'osmajorrelease': 12}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', {'cmd.run': MagicMock()}) @@ -236,12 +236,12 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): localemod.get_locale() assert localemod.__salt__['cmd.run'].call_args[0][0] == 'eselect --brief locale show' - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'Solaris', 'osmajorrelease': 12}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', {'cmd.run': MagicMock()}) @patch('salt.utils.systemd.booted', MagicMock(return_value=False)) - def test_get_locale_with_no_systemd_slowlaris(self): + def test_get_locale_with_no_systemd_solaris(self): ''' Test getting current system locale with systemd and dbus available on Solaris. :return: @@ -249,7 +249,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): localemod.get_locale() assert localemod.__salt__['cmd.run'].call_args[0][0] == 'grep "^LANG=" /etc/default/init' - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'BSD', 'osmajorrelease': 8, 'oscodename': 'DrunkDragon'}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', {'cmd.run': MagicMock()}) @@ -263,7 +263,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): localemod.get_locale() assert '"DrunkDragon" is unsupported' in six.text_type(err) - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__grains__', {'os_family': 'Ubuntu', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', None) @patch('salt.utils.systemd.booted', MagicMock(return_value=True)) @@ -277,7 +277,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): localemod.set_locale(loc) assert localemod._localectl_set.call_args[0][0] == 'de_DE.utf8' - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__grains__', {'os_family': 'Ubuntu', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', True) @patch('salt.utils.systemd.booted', MagicMock(return_value=True)) @@ -291,7 +291,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): localemod.set_locale(loc) assert localemod._localectl_set.call_args[0][0] == 'de_DE.utf8' - @patch('salt.utils.which', MagicMock(return_value="/usr/bin/localctl")) + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) @patch('salt.modules.localemod.__grains__', {'os_family': 'Suse', 'osmajorrelease': 12}) @patch('salt.modules.localemod.dbus', True) @patch('salt.modules.localemod.__salt__', MagicMock()) @@ -310,7 +310,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert localemod.__salt__['file.replace'].call_args[0][1] == '^RC_LANG=.*' assert localemod.__salt__['file.replace'].call_args[0][2] == 'RC_LANG="{}"'.format(loc) - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'RedHat', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', MagicMock()) @@ -329,7 +329,6 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert localemod.__salt__['file.replace'].call_args[0][1] == '^LANG=.*' assert localemod.__salt__['file.replace'].call_args[0][2] == 'LANG="{}"'.format(loc) - @patch('salt.utils.which', MagicMock(return_value=None)) @patch('salt.utils.path.which', MagicMock(return_value='/usr/sbin/update-locale')) @patch('salt.modules.localemod.__grains__', {'os_family': 'Debian', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', None) @@ -349,7 +348,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert localemod.__salt__['file.replace'].call_args[0][1] == '^LANG=.*' assert localemod.__salt__['file.replace'].call_args[0][2] == 'LANG="{}"'.format(loc) - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'Debian', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', None) @@ -367,7 +366,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert not localemod._localectl_set.called assert 'Cannot set locale: "update-locale" was not found.' in six.text_type(err) - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'Gentoo', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', MagicMock()) @@ -383,16 +382,16 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert not localemod._localectl_set.called assert localemod.__salt__['cmd.retcode'].call_args[0][0] == 'eselect --brief locale set de_DE.utf8' - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'Solaris', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', {'locale.list_avail': MagicMock(return_value=['de_DE.utf8']), 'file.replace': MagicMock()}) @patch('salt.modules.localemod._localectl_set', MagicMock()) @patch('salt.utils.systemd.booted', MagicMock(return_value=False)) - def test_set_locale_with_no_systemd_slowlaris_with_list_avail(self): + def test_set_locale_with_no_systemd_solaris_with_list_avail(self): ''' - Test setting current system locale with systemd and dbus available on Slowlaris. + Test setting current system locale with systemd and dbus available on Solaris. The list_avail returns the proper locale. :return: ''' @@ -404,16 +403,16 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert localemod.__salt__['file.replace'].call_args[0][1] == '^LANG=.*' assert localemod.__salt__['file.replace'].call_args[0][2] == 'LANG="{}"'.format(loc) - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'Solaris', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', {'locale.list_avail': MagicMock(return_value=['en_GB.utf8']), 'file.replace': MagicMock()}) @patch('salt.modules.localemod._localectl_set', MagicMock()) @patch('salt.utils.systemd.booted', MagicMock(return_value=False)) - def test_set_locale_with_no_systemd_slowlaris_without_list_avail(self): + def test_set_locale_with_no_systemd_solaris_without_list_avail(self): ''' - Test setting current system locale with systemd and dbus is not available on Slowlaris. + Test setting current system locale with systemd and dbus is not available on Solaris. The list_avail does not return the proper locale. :return: ''' @@ -422,7 +421,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): assert not localemod._localectl_set.called assert not localemod.__salt__['file.replace'].called - @patch('salt.utils.which', MagicMock(return_value=None)) + @patch('salt.utils.path.which', MagicMock(return_value=None)) @patch('salt.modules.localemod.__grains__', {'os_family': 'BSD', 'osmajorrelease': 42}) @patch('salt.modules.localemod.dbus', None) @patch('salt.modules.localemod.__salt__', {'locale.list_avail': MagicMock(return_value=['en_GB.utf8']), @@ -610,6 +609,7 @@ class LocalemodTestCase(TestCase, LoaderModuleMockMixin): patch('os.listdir', MagicMock(return_value=['en_US'])): assert localemod.gen_locale('en_US.UTF-8', verbose=True) == ret + @patch('salt.utils.path.which', MagicMock(return_value="/usr/bin/localctl")) def test_parse_localectl(self): localectl_out = (' System Locale: LANG=en_US.UTF-8\n' ' LANGUAGE=en_US:en\n' diff --git a/tests/unit/modules/test_pip.py b/tests/unit/modules/test_pip.py index 3ad49aad71..25f8db567f 100644 --- a/tests/unit/modules/test_pip.py +++ b/tests/unit/modules/test_pip.py @@ -298,7 +298,7 @@ class PipTestCase(TestCase, LoaderModuleMockMixin): with patch.dict(pip.__salt__, {'cmd.run_all': mock}): if salt.utils.platform.is_windows(): venv_path = 'c:\\test_env' - bin_path = os.path.join(venv_path, 'Scripts', 'pip.exe').encode('string-escape') + bin_path = os.path.join(venv_path, 'Scripts', 'pip.exe') else: venv_path = '/test_env' bin_path = os.path.join(venv_path, 'bin', 'pip') diff --git a/tests/unit/modules/test_pkgng.py b/tests/unit/modules/test_pkgng.py index 7dcedc2d75..ff458a08aa 100644 --- a/tests/unit/modules/test_pkgng.py +++ b/tests/unit/modules/test_pkgng.py @@ -114,17 +114,35 @@ class PkgNgTestCase(TestCase, LoaderModuleMockMixin): """ The following 6 package(s) will be affected (of 0 checked): - New packages to be INSTALLED: - pkge: 5.0 [FreeBSD] - pkgf: 6.0 [FreeBSD] - Installed packages to be UPGRADED: - pkga: 1.0 -> 1.1 [FreeBSD] + pkga: 1.0 -> 1.1 pkgb: 2.0 -> 2.1 [FreeBSD] + pkgc: 3.0 -> 3.1 [FreeBSD] (dependency changed) + pkgd: 4.0 -> 4.1 (dependency changed) + + New packages to be INSTALLED: + pkge: 1.0 + pkgf: 2.0 [FreeBSD] + pkgg: 3.0 [FreeBSD] (dependency changed) + pkgh: 4.0 (dependency changed) Installed packages to be REINSTALLED: - pkgc-3.0 [FreeBSD] (direct dependency changed: pkga) - pkgd-4.0 [FreeBSD] (direct dependency changed: pkgb) + pkgi-1.0 + pkgj-2.0 [FreeBSD] + pkgk-3.0 [FreeBSD] (direct dependency changed: pkga) + pkgl-4.0 (direct dependency changed: pkgb) + + Installed packages to be DOWNGRADED: + pkgm: 1.1 -> 1.0 + pkgn: 2.1 -> 2.0 [FreeBSD] + pkgo: 3.1 -> 3.0 [FreeBSD] (dependency changed) + pkgp: 4.1 -> 4.0 (dependency changed) + + Installed packages to be REMOVED: + pkgq-1.0 + pkgr-2.0 [FreeBSD] + pkgs-3.0 [FreeBSD] (direct dependency changed: pkga) + pkgt-4.0 (direct dependency changed: pkgb) Number of packages to be upgraded: 2 Number of packages to be reinstalled: 2 @@ -137,7 +155,7 @@ class PkgNgTestCase(TestCase, LoaderModuleMockMixin): with patch.dict(pkgng.__salt__, {'cmd.run_stdout': pkg_cmd}): result = pkgng.list_upgrades(refresh=False) - self.assertDictEqual(result, {'pkga': '1.1', 'pkgb': '2.1'}) + self.assertDictEqual(result, {'pkga': '1.1', 'pkgb': '2.1', 'pkgc': '3.1', 'pkgd': '4.1'}) pkg_cmd.assert_called_with( ['pkg', 'upgrade', '--dry-run', '--quiet', '--no-repo-update'], output_loglevel='trace', python_shell=False, ignore_retcode=True diff --git a/tests/unit/modules/test_postgres.py b/tests/unit/modules/test_postgres.py index d4fff86223..7094767d0f 100644 --- a/tests/unit/modules/test_postgres.py +++ b/tests/unit/modules/test_postgres.py @@ -371,6 +371,7 @@ class PostgresTestCase(TestCase, LoaderModuleMockMixin): 'replication': None, 'password': 'test_password', 'connections': '-1', + 'groups': '', 'expiry time': '', 'defaults variables': None }])): @@ -402,6 +403,7 @@ class PostgresTestCase(TestCase, LoaderModuleMockMixin): 'can login': 't', 'replication': None, 'connections': '-1', + 'groups': '', 'expiry time': '2017-08-16 08:57:46', 'defaults variables': None }])): diff --git a/tests/unit/modules/test_win_path.py b/tests/unit/modules/test_win_path.py index 7d28b4c7fb..5986294dc9 100644 --- a/tests/unit/modules/test_win_path.py +++ b/tests/unit/modules/test_win_path.py @@ -22,43 +22,13 @@ import salt.modules.win_path as win_path import salt.utils.stringutils -class MockWin32API(object): - ''' - Mock class for win32api - ''' - def __init__(self): - pass - - @staticmethod - def SendMessage(*args): - ''' - Mock method for SendMessage - ''' - return [args[0]] - - -class MockWin32Con(object): - ''' - Mock class for win32con - ''' - HWND_BROADCAST = 1 - WM_SETTINGCHANGE = 1 - - def __init__(self): - pass - - @skipIf(NO_MOCK, NO_MOCK_REASON) class WinPathTestCase(TestCase, LoaderModuleMockMixin): ''' Test cases for salt.modules.win_path ''' def setup_loader_modules(self): - return {win_path: {'win32api': MockWin32API, - 'win32con': MockWin32Con, - 'SendMessage': MagicMock, - 'HWND_BROADCAST': MagicMock, - 'WM_SETTINGCHANGE': MagicMock}} + return {win_path: {}} def __init__(self, *args, **kwargs): super(WinPathTestCase, self).__init__(*args, **kwargs) @@ -79,12 +49,6 @@ class WinPathTestCase(TestCase, LoaderModuleMockMixin): salt.utils.stringutils.to_str(self.pathsep.join(new_path)) ) - def test_rehash(self): - ''' - Test to rehash the Environment variables - ''' - self.assertTrue(win_path.rehash()) - def test_get_path(self): ''' Test to Returns the system path diff --git a/tests/unit/modules/test_x509.py b/tests/unit/modules/test_x509.py new file mode 100644 index 0000000000..edafe4ff44 --- /dev/null +++ b/tests/unit/modules/test_x509.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# +# Author: Bo Maryniuk +# +# Copyright 2018 SUSE LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Import Salt Testing Libs +from __future__ import absolute_import, print_function, unicode_literals + +try: + import pytest +except ImportError as import_error: + pytest = None + +from tests.support.mixins import LoaderModuleMockMixin +from tests.support.unit import TestCase, skipIf +from tests.support.mock import ( + patch, + MagicMock, + NO_MOCK, + NO_MOCK_REASON +) + +from salt.modules import x509 + + +@skipIf(NO_MOCK, NO_MOCK_REASON) +@skipIf(not bool(pytest), False) +class X509TestCase(TestCase, LoaderModuleMockMixin): + + def setup_loader_modules(self): + return {x509: {}} + + @patch('salt.modules.x509.log', MagicMock()) + def test_private_func__parse_subject(self): + ''' + Test private function _parse_subject(subject) it handles a missing fields + :return: + ''' + class FakeSubject(object): + ''' + Class for faking x509'th subject. + ''' + def __init__(self): + self.nid = {'Darth Vader': 1} + + def __getattr__(self, item): + if item != 'nid': + raise TypeError('A star wars satellite accidentally blew up the WAN.') + + subj = FakeSubject() + x509._parse_subject(subj) + x509.log.trace.assert_called_once() + assert x509.log.trace.call_args[0][0] == "Missing attribute '%s'. Error: %s" + assert x509.log.trace.call_args[0][1] == list(subj.nid.keys())[0] + assert isinstance(x509.log.trace.call_args[0][2], TypeError) diff --git a/tests/unit/modules/test_yumpkg.py b/tests/unit/modules/test_yumpkg.py index 84e0a0ac52..28b6e1294c 100644 --- a/tests/unit/modules/test_yumpkg.py +++ b/tests/unit/modules/test_yumpkg.py @@ -8,6 +8,7 @@ import os from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import TestCase, skipIf from tests.support.mock import ( + Mock, MagicMock, patch, NO_MOCK, @@ -18,6 +19,39 @@ from tests.support.mock import ( import salt.modules.yumpkg as yumpkg import salt.modules.pkg_resource as pkg_resource +LIST_REPOS = { + 'base': { + 'file': '/etc/yum.repos.d/CentOS-Base.repo', + 'gpgcheck': '1', + 'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7', + 'mirrorlist': 'http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra', + 'name': 'CentOS-$releasever - Base' + }, + 'base-source': { + 'baseurl': 'http://vault.centos.org/centos/$releasever/os/Source/', + 'enabled': '0', + 'file': '/etc/yum.repos.d/CentOS-Sources.repo', + 'gpgcheck': '1', + 'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7', + 'name': 'CentOS-$releasever - Base Sources' + }, + 'updates': { + 'file': '/etc/yum.repos.d/CentOS-Base.repo', + 'gpgcheck': '1', + 'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7', + 'mirrorlist': 'http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra', + 'name': 'CentOS-$releasever - Updates' + }, + 'updates-source': { + 'baseurl': 'http://vault.centos.org/centos/$releasever/updates/Source/', + 'enabled': '0', + 'file': '/etc/yum.repos.d/CentOS-Sources.repo', + 'gpgcheck': '1', + 'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7', + 'name': 'CentOS-$releasever - Updates Sources' + } +} + @skipIf(NO_MOCK, NO_MOCK_REASON) class YumTestCase(TestCase, LoaderModuleMockMixin): @@ -25,7 +59,18 @@ class YumTestCase(TestCase, LoaderModuleMockMixin): Test cases for salt.modules.yumpkg ''' def setup_loader_modules(self): - return {yumpkg: {'rpm': None}} + return { + yumpkg: { + '__context__': { + 'yum_bin': 'yum', + }, + '__grains__': { + 'osarch': 'x86_64', + 'os_family': 'RedHat', + 'osmajorrelease': 7, + }, + } + } def test_list_pkgs(self): ''' @@ -186,3 +231,373 @@ class YumTestCase(TestCase, LoaderModuleMockMixin): }}.items(): self.assertTrue(pkgs.get(pkg_name)) self.assertEqual(pkgs[pkg_name], [pkg_attr]) + + def test_latest_version_with_options(self): + with patch.object(yumpkg, 'list_pkgs', MagicMock(return_value={})): + + # with fromrepo + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.latest_version( + 'foo', + refresh=False, + fromrepo='good', + branch='foo') + cmd.assert_called_once_with( + ['yum', '--quiet', '--disablerepo=*', '--enablerepo=good', + '--branch=foo', 'list', 'available', 'foo'], + ignore_retcode=True, + output_loglevel='trace', + python_shell=False) + + # without fromrepo + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.latest_version( + 'foo', + refresh=False, + enablerepo='good', + disablerepo='bad', + branch='foo') + cmd.assert_called_once_with( + ['yum', '--quiet', '--disablerepo=bad', '--enablerepo=good', + '--branch=foo', 'list', 'available', 'foo'], + ignore_retcode=True, + output_loglevel='trace', + python_shell=False) + + def test_list_repo_pkgs_with_options(self): + ''' + Test list_repo_pkgs with and without fromrepo + + NOTE: mock_calls is a stack. The most recent call is indexed + with 0, while the first call would have the highest index. + ''' + really_old_yum = MagicMock(return_value='3.2.0') + older_yum = MagicMock(return_value='3.4.0') + newer_yum = MagicMock(return_value='3.4.5') + list_repos_mock = MagicMock(return_value=LIST_REPOS) + kwargs = {'output_loglevel': 'trace', + 'ignore_retcode': True, + 'python_shell': False} + + with patch.object(yumpkg, 'list_repos', list_repos_mock): + + # Test with really old yum. The fromrepo argument has no effect on + # the yum commands we'd run. + with patch.dict(yumpkg.__salt__, {'cmd.run': really_old_yum}): + + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.list_repo_pkgs('foo') + # We should have called cmd.run_all twice + self.assertEqual(len(cmd.mock_calls), 2) + + # Check args from first call + self.assertEqual( + cmd.mock_calls[1][1], + (['yum', '--quiet', 'list', 'available'],) + ) + # Check kwargs from first call + self.assertEqual(cmd.mock_calls[1][2], kwargs) + + # Check args from second call + self.assertEqual( + cmd.mock_calls[0][1], + (['yum', '--quiet', 'list', 'installed'],) + ) + # Check kwargs from second call + self.assertEqual(cmd.mock_calls[0][2], kwargs) + + # Test with really old yum. The fromrepo argument has no effect on + # the yum commands we'd run. + with patch.dict(yumpkg.__salt__, {'cmd.run': older_yum}): + + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.list_repo_pkgs('foo') + # We should have called cmd.run_all twice + self.assertEqual(len(cmd.mock_calls), 2) + + # Check args from first call + self.assertEqual( + cmd.mock_calls[1][1], + (['yum', '--quiet', '--showduplicates', 'list', 'available'],) + ) + # Check kwargs from first call + self.assertEqual(cmd.mock_calls[1][2], kwargs) + + # Check args from second call + self.assertEqual( + cmd.mock_calls[0][1], + (['yum', '--quiet', '--showduplicates', 'list', 'installed'],) + ) + # Check kwargs from second call + self.assertEqual(cmd.mock_calls[0][2], kwargs) + + # Test with newer yum. We should run one yum command per repo, so + # fromrepo would limit how many calls we make. + with patch.dict(yumpkg.__salt__, {'cmd.run': newer_yum}): + + # When fromrepo is used, we would only run one yum command, for + # that specific repo. + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.list_repo_pkgs('foo', fromrepo='base') + # We should have called cmd.run_all once + self.assertEqual(len(cmd.mock_calls), 1) + + # Check args + self.assertEqual( + cmd.mock_calls[0][1], + (['yum', '--quiet', '--showduplicates', + 'repository-packages', 'base', 'list', 'foo'],) + ) + # Check kwargs + self.assertEqual(cmd.mock_calls[0][2], kwargs) + + # Test enabling base-source and disabling updates. We should + # get two calls, one for each enabled repo. Because dict + # iteration order will vary, different Python versions will be + # do them in different orders, which is OK, but it will just + # mean that we will have to check both the first and second + # mock call both times. + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.list_repo_pkgs( + 'foo', + enablerepo='base-source', + disablerepo='updates') + # We should have called cmd.run_all twice + self.assertEqual(len(cmd.mock_calls), 2) + + for repo in ('base', 'base-source'): + for index in (0, 1): + try: + # Check args + self.assertEqual( + cmd.mock_calls[index][1], + (['yum', '--quiet', '--showduplicates', + 'repository-packages', repo, 'list', + 'foo'],) + ) + # Check kwargs + self.assertEqual(cmd.mock_calls[index][2], kwargs) + break + except AssertionError: + continue + else: + self.fail("repo '{0}' not checked".format(repo)) + + def test_list_upgrades_dnf(self): + ''' + The subcommand should be "upgrades" with dnf + ''' + with patch.dict(yumpkg.__context__, {'yum_bin': 'dnf'}): + # with fromrepo + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.list_upgrades( + refresh=False, + fromrepo='good', + branch='foo') + cmd.assert_called_once_with( + ['dnf', '--quiet', '--disablerepo=*', '--enablerepo=good', + '--branch=foo', 'list', 'upgrades'], + output_loglevel='trace', + ignore_retcode=True, + python_shell=False) + + # without fromrepo + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.list_upgrades( + refresh=False, + enablerepo='good', + disablerepo='bad', + branch='foo') + cmd.assert_called_once_with( + ['dnf', '--quiet', '--disablerepo=bad', '--enablerepo=good', + '--branch=foo', 'list', 'upgrades'], + output_loglevel='trace', + ignore_retcode=True, + python_shell=False) + + def test_list_upgrades_yum(self): + ''' + The subcommand should be "updates" with yum + ''' + # with fromrepo + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.list_upgrades( + refresh=False, + fromrepo='good', + branch='foo') + cmd.assert_called_once_with( + ['yum', '--quiet', '--disablerepo=*', '--enablerepo=good', + '--branch=foo', 'list', 'updates'], + output_loglevel='trace', + ignore_retcode=True, + python_shell=False) + + # without fromrepo + cmd = MagicMock(return_value={'retcode': 0, 'stdout': ''}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.list_upgrades( + refresh=False, + enablerepo='good', + disablerepo='bad', + branch='foo') + cmd.assert_called_once_with( + ['yum', '--quiet', '--disablerepo=bad', '--enablerepo=good', + '--branch=foo', 'list', 'updates'], + output_loglevel='trace', + ignore_retcode=True, + python_shell=False) + + def test_refresh_db_with_options(self): + + with patch('salt.utils.pkg.clear_rtag', Mock()): + + # With check_update=True we will do a cmd.run to run the clean_cmd, and + # then a separate cmd.retcode to check for updates. + + # with fromrepo + clean_cmd = Mock() + update_cmd = MagicMock(return_value=0) + with patch.dict(yumpkg.__salt__, {'cmd.run': clean_cmd, + 'cmd.retcode': update_cmd}): + yumpkg.refresh_db( + check_update=True, + fromrepo='good', + branch='foo') + clean_cmd.assert_called_once_with( + ['yum', '--quiet', '--assumeyes', 'clean', 'expire-cache', '--disablerepo=*', + '--enablerepo=good', '--branch=foo'], + python_shell=False) + update_cmd.assert_called_once_with( + ['yum', '--quiet', '--assumeyes', 'check-update', + '--setopt=autocheck_running_kernel=false', '--disablerepo=*', + '--enablerepo=good', '--branch=foo'], + output_loglevel='trace', + ignore_retcode=True, + python_shell=False) + + # without fromrepo + clean_cmd = Mock() + update_cmd = MagicMock(return_value=0) + with patch.dict(yumpkg.__salt__, {'cmd.run': clean_cmd, + 'cmd.retcode': update_cmd}): + yumpkg.refresh_db( + check_update=True, + enablerepo='good', + disablerepo='bad', + branch='foo') + clean_cmd.assert_called_once_with( + ['yum', '--quiet', '--assumeyes', 'clean', 'expire-cache', '--disablerepo=bad', + '--enablerepo=good', '--branch=foo'], + python_shell=False) + update_cmd.assert_called_once_with( + ['yum', '--quiet', '--assumeyes', 'check-update', + '--setopt=autocheck_running_kernel=false', '--disablerepo=bad', + '--enablerepo=good', '--branch=foo'], + output_loglevel='trace', + ignore_retcode=True, + python_shell=False) + + # With check_update=False we will just do a cmd.run for the clean_cmd + + # with fromrepo + clean_cmd = Mock() + with patch.dict(yumpkg.__salt__, {'cmd.run': clean_cmd}): + yumpkg.refresh_db( + check_update=False, + fromrepo='good', + branch='foo') + clean_cmd.assert_called_once_with( + ['yum', '--quiet', '--assumeyes', 'clean', 'expire-cache', '--disablerepo=*', + '--enablerepo=good', '--branch=foo'], + python_shell=False) + + # without fromrepo + clean_cmd = Mock() + with patch.dict(yumpkg.__salt__, {'cmd.run': clean_cmd}): + yumpkg.refresh_db( + check_update=False, + enablerepo='good', + disablerepo='bad', + branch='foo') + clean_cmd.assert_called_once_with( + ['yum', '--quiet', '--assumeyes', 'clean', 'expire-cache', '--disablerepo=bad', + '--enablerepo=good', '--branch=foo'], + python_shell=False) + + def test_install_with_options(self): + parse_targets = MagicMock(return_value=({'foo': None}, 'repository')) + with patch.object(yumpkg, 'list_pkgs', MagicMock(return_value={})), \ + patch.object(yumpkg, 'list_holds', MagicMock(return_value=[])), \ + patch.dict(yumpkg.__salt__, {'pkg_resource.parse_targets': parse_targets}), \ + patch('salt.utils.systemd.has_scope', MagicMock(return_value=False)): + + # with fromrepo + cmd = MagicMock(return_value={'retcode': 0}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.install( + refresh=False, + fromrepo='good', + branch='foo') + cmd.assert_called_once_with( + ['yum', '-y', '--disablerepo=*', '--enablerepo=good', + '--branch=foo', 'install', 'foo'], + output_loglevel='trace', + python_shell=False, + redirect_stderr=True) + + # without fromrepo + cmd = MagicMock(return_value={'retcode': 0}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.install( + refresh=False, + enablerepo='good', + disablerepo='bad', + branch='foo') + cmd.assert_called_once_with( + ['yum', '-y', '--disablerepo=bad', '--enablerepo=good', + '--branch=foo', 'install', 'foo'], + output_loglevel='trace', + python_shell=False, + redirect_stderr=True) + + def test_upgrade_with_options(self): + with patch.object(yumpkg, 'list_pkgs', MagicMock(return_value={})), \ + patch('salt.utils.systemd.has_scope', MagicMock(return_value=False)): + + # with fromrepo + cmd = MagicMock(return_value={'retcode': 0}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.upgrade( + refresh=False, + fromrepo='good', + exclude='kernel*', + branch='foo') + cmd.assert_called_once_with( + ['yum', '--quiet', '-y', '--disablerepo=*', '--enablerepo=good', + '--branch=foo', '--exclude=kernel*', 'upgrade'], + output_loglevel='trace', + python_shell=False) + + # without fromrepo + cmd = MagicMock(return_value={'retcode': 0}) + with patch.dict(yumpkg.__salt__, {'cmd.run_all': cmd}): + yumpkg.upgrade( + refresh=False, + enablerepo='good', + disablerepo='bad', + exclude='kernel*', + branch='foo') + cmd.assert_called_once_with( + ['yum', '--quiet', '-y', '--disablerepo=bad', '--enablerepo=good', + '--branch=foo', '--exclude=kernel*', 'upgrade'], + output_loglevel='trace', + python_shell=False) diff --git a/tests/unit/returners/test_smtp_return.py b/tests/unit/returners/test_smtp_return.py index 24dea61c05..bce7d96c9a 100644 --- a/tests/unit/returners/test_smtp_return.py +++ b/tests/unit/returners/test_smtp_return.py @@ -17,6 +17,7 @@ from tests.support.mock import NO_MOCK, NO_MOCK_REASON, MagicMock, patch # Import salt libs import salt.returners.smtp_return as smtp +from salt.utils.jinja import SaltCacheLoader try: import gnupg # pylint: disable=unused-import @@ -54,7 +55,8 @@ class SMTPReturnerTestCase(TestCase, LoaderModuleMockMixin): 'gpgowner': '', 'subject': ''} - with patch('salt.returners.smtp_return._get_options', MagicMock(return_value=options)): + with patch('salt.returners.smtp_return._get_options', MagicMock(return_value=options)), \ + patch.object(SaltCacheLoader, 'file_client', MagicMock()): smtp.returner(ret) self.assertTrue(mocked_smtplib.return_value.sendmail.called) diff --git a/tests/unit/states/test_kernelpkg.py b/tests/unit/states/test_kernelpkg.py index b39844976b..f2ba87ecee 100644 --- a/tests/unit/states/test_kernelpkg.py +++ b/tests/unit/states/test_kernelpkg.py @@ -3,7 +3,7 @@ :synopsis: Unit Tests for 'module.aptkernelpkg' :platform: Linux :maturity: develop - versionadded:: oxygen + versionadded:: 2018.3.0 ''' # pylint: disable=invalid-name,no-member diff --git a/tests/unit/templates/test_jinja.py b/tests/unit/templates/test_jinja.py index 6fc083be02..f63bebd0a1 100644 --- a/tests/unit/templates/test_jinja.py +++ b/tests/unit/templates/test_jinja.py @@ -14,7 +14,7 @@ import tempfile # Import Salt Testing libs from tests.support.unit import skipIf, TestCase from tests.support.case import ModuleCase -from tests.support.mock import NO_MOCK, NO_MOCK_REASON, patch, MagicMock +from tests.support.mock import NO_MOCK, NO_MOCK_REASON, patch, MagicMock, Mock from tests.support.paths import TMP_CONF_DIR # Import Salt libs @@ -34,11 +34,8 @@ from salt.utils.jinja import ( ensure_sequence_filter ) from salt.utils.odict import OrderedDict -from salt.utils.templates import ( - get_context, - JINJA, - render_jinja_tmpl -) +from salt.utils.templates import JINJA, render_jinja_tmpl + # dateutils is needed so that the strftime jinja filter is loaded import salt.utils.dateutils # pylint: disable=unused-import import salt.utils.files @@ -74,7 +71,7 @@ class MockFileClient(object): class TestSaltCacheLoader(TestCase): def __init__(self, *args, **kws): - TestCase.__init__(self, *args, **kws) + super(TestSaltCacheLoader, self).__init__(*args, **kws) self.opts = { 'cachedir': TEMPLATES_DIR, 'file_roots': { @@ -92,7 +89,7 @@ class TestSaltCacheLoader(TestCase): tmp = tempfile.gettempdir() opts = copy.deepcopy(self.opts) opts.update({'cachedir': tmp}) - loader = SaltCacheLoader(opts, saltenv='test') + loader = self.get_loader(opts=opts, saltenv='test') assert loader.searchpath == [os.path.join(tmp, 'files', 'test')] def test_mockclient(self): @@ -100,8 +97,7 @@ class TestSaltCacheLoader(TestCase): A MockFileClient is used that records all file requests normally sent to the master. ''' - loader = SaltCacheLoader(self.opts, 'test') - fc = MockFileClient(loader) + loader = self.get_loader(opts=self.opts, saltenv='test') res = loader.get_source(None, 'hello_simple') assert len(res) == 3 # res[0] on Windows is unicode and use os.linesep so it works cross OS @@ -109,17 +105,28 @@ class TestSaltCacheLoader(TestCase): tmpl_dir = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_simple') self.assertEqual(res[1], tmpl_dir) assert res[2](), 'Template up to date?' - assert len(fc.requests) - self.assertEqual(fc.requests[0]['path'], 'salt://hello_simple') + assert len(loader._file_client.requests) + self.assertEqual(loader._file_client.requests[0]['path'], 'salt://hello_simple') + + def get_loader(self, opts=None, saltenv='base'): + ''' + Now that we instantiate the client in the __init__, we need to mock it + ''' + if opts is None: + opts = self.opts + with patch.object(SaltCacheLoader, 'file_client', Mock()): + loader = SaltCacheLoader(opts, saltenv) + # Create a mock file client and attach it to the loader + MockFileClient(loader) + return loader def get_test_saltenv(self): ''' Setup a simple jinja test environment ''' - loader = SaltCacheLoader(self.opts, 'test') - fc = MockFileClient(loader) + loader = self.get_loader(saltenv='test') jinja = Environment(loader=loader) - return fc, jinja + return loader._file_client, jinja def test_import(self): ''' @@ -155,7 +162,7 @@ class TestSaltCacheLoader(TestCase): class TestGetTemplate(TestCase): def __init__(self, *args, **kws): - TestCase.__init__(self, *args, **kws) + super(TestGetTemplate, self).__init__(*args, **kws) self.local_opts = { 'cachedir': TEMPLATES_DIR, 'file_client': 'local', @@ -379,36 +386,6 @@ class TestGetTemplate(TestCase): result = salt.utils.stringutils.to_unicode(fp.read(), 'utf-8') self.assertEqual(salt.utils.stringutils.to_unicode('Assunção' + os.linesep), result) - def test_get_context_has_enough_context(self): - template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' - context = get_context(template, 8) - expected = '---\n[...]\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\n[...]\n---' - self.assertEqual(expected, context) - - def test_get_context_at_top_of_file(self): - template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' - context = get_context(template, 1) - expected = '---\n1\n2\n3\n4\n5\n6\n[...]\n---' - self.assertEqual(expected, context) - - def test_get_context_at_bottom_of_file(self): - template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' - context = get_context(template, 15) - expected = '---\n[...]\na\nb\nc\nd\ne\nf\n---' - self.assertEqual(expected, context) - - def test_get_context_2_context_lines(self): - template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' - context = get_context(template, 8, num_lines=2) - expected = '---\n[...]\n6\n7\n8\n9\na\n[...]\n---' - self.assertEqual(expected, context) - - def test_get_context_with_marker(self): - template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' - context = get_context(template, 8, num_lines=2, marker=' <---') - expected = '---\n[...]\n6\n7\n8 <---\n9\na\n[...]\n---' - self.assertEqual(expected, context) - def test_render_with_syntax_error(self): template = 'hello\n\n{{ bad\n\nfoo' expected = r'.*---\nhello\n\n{{ bad\n\nfoo <======================\n---' @@ -547,7 +524,7 @@ class TestJinjaDefaultOptions(TestCase): class TestCustomExtensions(TestCase): def __init__(self, *args, **kws): - TestCase.__init__(self, *args, **kws) + super(TestCustomExtensions, self).__init__(*args, **kws) self.local_opts = { 'cachedir': TEMPLATES_DIR, 'file_client': 'local', @@ -1235,7 +1212,8 @@ class TestDotNotationLookup(ModuleCase): ''' tmpl_str = '''Hello, {{ salt['mocktest.ping']() }}.''' - ret = self.render(tmpl_str) + with patch.object(SaltCacheLoader, 'file_client', Mock()): + ret = self.render(tmpl_str) self.assertEqual(ret, 'Hello, True.') def test_dotlookup(self): @@ -1244,7 +1222,8 @@ class TestDotNotationLookup(ModuleCase): ''' tmpl_str = '''Hello, {{ salt.mocktest.ping() }}.''' - ret = self.render(tmpl_str) + with patch.object(SaltCacheLoader, 'file_client', Mock()): + ret = self.render(tmpl_str) self.assertEqual(ret, 'Hello, True.') def test_shadowed_dict_method(self): @@ -1254,5 +1233,6 @@ class TestDotNotationLookup(ModuleCase): ''' tmpl_str = '''Hello, {{ salt.mockgrains.get('id') }}.''' - ret = self.render(tmpl_str) + with patch.object(SaltCacheLoader, 'file_client', Mock()): + ret = self.render(tmpl_str) self.assertEqual(ret, 'Hello, jerry.') diff --git a/tests/unit/utils/test_data.py b/tests/unit/utils/test_data.py index 6ef6f891e2..ea87bcf679 100644 --- a/tests/unit/utils/test_data.py +++ b/tests/unit/utils/test_data.py @@ -19,6 +19,9 @@ log = logging.getLogger(__name__) _b = lambda x: x.encode('utf-8') # Some randomized data that will not decode BYTES = b'\x9c\xb1\xf7\xa3' +# This is an example of a unicode string with й constructed using two separate +# code points. Do not modify it. +EGGS = '\u044f\u0438\u0306\u0446\u0430' class DataTestCase(TestCase): @@ -30,17 +33,18 @@ class DataTestCase(TestCase): True, False, None, + EGGS, BYTES, - [123, 456.789, _b('спам'), True, False, None, BYTES], - (987, 654.321, _b('яйца'), None, (True, False, BYTES)), + [123, 456.789, _b('спам'), True, False, None, EGGS, BYTES], + (987, 654.321, _b('яйца'), EGGS, None, (True, EGGS, BYTES)), {_b('str_key'): _b('str_val'), None: True, 123: 456.789, - 'blob': BYTES, - _b('subdict'): {'unicode_key': 'unicode_val', - _b('tuple'): (123, 'hello', _b('world'), True, BYTES), - _b('list'): [456, _b('спам'), False, BYTES]}}, - OrderedDict([(_b('foo'), 'bar'), (123, 456), ('blob', BYTES)]) + EGGS: BYTES, + _b('subdict'): {'unicode_key': EGGS, + _b('tuple'): (123, 'hello', _b('world'), True, EGGS, BYTES), + _b('list'): [456, _b('спам'), False, EGGS, BYTES]}}, + OrderedDict([(_b('foo'), 'bar'), (123, 456), (EGGS, BYTES)]) ] def test_sorted_ignorecase(self): @@ -220,23 +224,25 @@ class DataTestCase(TestCase): True, False, None, + 'яйца', BYTES, - [123, 456.789, 'спам', True, False, None, BYTES], - (987, 654.321, 'яйца', None, (True, False, BYTES)), + [123, 456.789, 'спам', True, False, None, 'яйца', BYTES], + (987, 654.321, 'яйца', 'яйца', None, (True, 'яйца', BYTES)), {'str_key': 'str_val', None: True, 123: 456.789, - 'blob': BYTES, - 'subdict': {'unicode_key': 'unicode_val', - 'tuple': (123, 'hello', 'world', True, BYTES), - 'list': [456, 'спам', False, BYTES]}}, - OrderedDict([('foo', 'bar'), (123, 456), ('blob', BYTES)]) + 'яйца': BYTES, + 'subdict': {'unicode_key': 'яйца', + 'tuple': (123, 'hello', 'world', True, 'яйца', BYTES), + 'list': [456, 'спам', False, 'яйца', BYTES]}}, + OrderedDict([('foo', 'bar'), (123, 456), ('яйца', BYTES)]) ] ret = salt.utils.data.decode( self.test_data, encoding='utf-8', keep=True, + normalize=True, preserve_dict_class=True, preserve_tuples=True) self.assertEqual(ret, expected) @@ -249,19 +255,21 @@ class DataTestCase(TestCase): self.test_data, encoding='utf-8', keep=False, + normalize=True, preserve_dict_class=True, preserve_tuples=True) # Now munge the expected data so that we get what we would expect if we # disable preservation of dict class and tuples - expected[9] = [987, 654.321, 'яйца', None, [True, False, BYTES]] - expected[10]['subdict']['tuple'] = [123, 'hello', 'world', True, BYTES] - expected[11] = {'foo': 'bar', 123: 456, 'blob': BYTES} + expected[10] = [987, 654.321, 'яйца', 'яйца', None, [True, 'яйца', BYTES]] + expected[11]['subdict']['tuple'] = [123, 'hello', 'world', True, 'яйца', BYTES] + expected[12] = {'foo': 'bar', 123: 456, 'яйца': BYTES} ret = salt.utils.data.decode( self.test_data, encoding='utf-8', keep=True, + normalize=True, preserve_dict_class=False, preserve_tuples=False) self.assertEqual(ret, expected) @@ -275,6 +283,8 @@ class DataTestCase(TestCase): # Test single strings (not in a data structure) self.assertEqual(salt.utils.data.decode('foo'), 'foo') self.assertEqual(salt.utils.data.decode(_b('bar')), 'bar') + self.assertEqual(salt.utils.data.decode(EGGS, normalize=True), 'яйца') + self.assertEqual(salt.utils.data.decode(EGGS, normalize=False), EGGS) # Test binary blob self.assertEqual(salt.utils.data.decode(BYTES, keep=True), BYTES) @@ -305,17 +315,18 @@ class DataTestCase(TestCase): True, False, None, + _b(EGGS), BYTES, - [123, 456.789, _b('спам'), True, False, None, BYTES], - (987, 654.321, _b('яйца'), None, (True, False, BYTES)), + [123, 456.789, _b('спам'), True, False, None, _b(EGGS), BYTES], + (987, 654.321, _b('яйца'), _b(EGGS), None, (True, _b(EGGS), BYTES)), {_b('str_key'): _b('str_val'), None: True, 123: 456.789, - _b('blob'): BYTES, - _b('subdict'): {_b('unicode_key'): _b('unicode_val'), - _b('tuple'): (123, _b('hello'), _b('world'), True, BYTES), - _b('list'): [456, _b('спам'), False, BYTES]}}, - OrderedDict([(_b('foo'), _b('bar')), (123, 456), (_b('blob'), BYTES)]) + _b(EGGS): BYTES, + _b('subdict'): {_b('unicode_key'): _b(EGGS), + _b('tuple'): (123, _b('hello'), _b('world'), True, _b(EGGS), BYTES), + _b('list'): [456, _b('спам'), False, _b(EGGS), BYTES]}}, + OrderedDict([(_b('foo'), _b('bar')), (123, 456), (_b(EGGS), BYTES)]) ] # Both keep=True and keep=False should work because the BYTES data is @@ -335,11 +346,12 @@ class DataTestCase(TestCase): # Now munge the expected data so that we get what we would expect if we # disable preservation of dict class and tuples - expected[9] = [987, 654.321, _b('яйца'), None, [True, False, BYTES]] - expected[10][_b('subdict')][_b('tuple')] = [ - 123, _b('hello'), _b('world'), True, BYTES + expected[10] = [987, 654.321, _b('яйца'), _b(EGGS), None, [True, _b(EGGS), BYTES]] + expected[11][_b('subdict')][_b('tuple')] = [ + 123, _b('hello'), _b('world'), True, _b(EGGS), BYTES ] - expected[11] = {_b('foo'): _b('bar'), 123: 456, _b('blob'): BYTES} + expected[12] = {_b('foo'): _b('bar'), 123: 456, _b(EGGS): BYTES} + ret = salt.utils.data.encode( self.test_data, keep=True, diff --git a/tests/unit/utils/test_docker.py b/tests/unit/utils/test_docker.py index fd32242c1e..66c953c330 100644 --- a/tests/unit/utils/test_docker.py +++ b/tests/unit/utils/test_docker.py @@ -773,6 +773,29 @@ class TranslateBase(TestCase): ret[key] = val return ret + @staticmethod + def normalize_ports(ret): + ''' + When we translate exposed ports, we can end up with a mixture of ints + (representing TCP ports) and tuples (representing UDP ports). Python 2 + will sort an iterable containing these mixed types, but Python 3 will + not. This helper is used to munge the ports in the return data so that + the resulting list is sorted in a way that can reliably be compared to + the expected results in the test. + + This helper should only be needed for port_bindings and ports. + ''' + if 'ports' in ret[0]: + tcp_ports = [] + udp_ports = [] + for item in ret[0]['ports']: + if isinstance(item, six.integer_types): + tcp_ports.append(item) + else: + udp_ports.append(item) + ret[0]['ports'] = sorted(tcp_ports) + sorted(udp_ports) + return ret + def tearDown(self): ''' Test skip_translate kwarg @@ -798,6 +821,29 @@ class TranslateContainerInputTestCase(TranslateBase): ''' translator = salt.utils.docker.translate.container + @staticmethod + def normalize_ports(ret): + ''' + When we translate exposed ports, we can end up with a mixture of ints + (representing TCP ports) and tuples (representing UDP ports). Python 2 + will sort an iterable containing these mixed types, but Python 3 will + not. This helper is used to munge the ports in the return data so that + the resulting list is sorted in a way that can reliably be compared to + the expected results in the test. + + This helper should only be needed for port_bindings and ports. + ''' + if 'ports' in ret: + tcp_ports = [] + udp_ports = [] + for item in ret['ports']: + if isinstance(item, six.integer_types): + tcp_ports.append(item) + else: + udp_ports.append(item) + ret['ports'] = sorted(tcp_ports) + sorted(udp_ports) + return ret + @assert_bool(salt.utils.docker.translate.container) def test_auto_remove(self): ''' @@ -1288,9 +1334,11 @@ class TranslateContainerInputTestCase(TranslateBase): ) for val in (bindings, bindings.split(',')): self.assertEqual( - salt.utils.docker.translate_input( - self.translator, - port_bindings=val, + self.normalize_ports( + salt.utils.docker.translate_input( + self.translator, + port_bindings=val, + ) ), {'port_bindings': {80: [('10.1.2.3', 8080), ('10.1.2.3', 8888)], @@ -1302,8 +1350,9 @@ class TranslateContainerInputTestCase(TranslateBase): '3334/udp': ('10.4.5.6', 3334), '5505/udp': ('10.7.8.9', 15505), '5506/udp': ('10.7.8.9', 15506)}, - 'ports': [80, '81/udp', 3333, '3334/udp', - 4505, 4506, '5505/udp', '5506/udp']} + 'ports': [80, 3333, 4505, 4506, + (81, 'udp'), (3334, 'udp'), + (5505, 'udp'), (5506, 'udp')]} ) # ip::containerPort - Bind a specific IP and an ephemeral port to a @@ -1315,9 +1364,11 @@ class TranslateContainerInputTestCase(TranslateBase): ) for val in (bindings, bindings.split(',')): self.assertEqual( - salt.utils.docker.translate_input( - self.translator, - port_bindings=val, + self.normalize_ports( + salt.utils.docker.translate_input( + self.translator, + port_bindings=val, + ) ), {'port_bindings': {80: [('10.1.2.3',), ('10.1.2.3',)], 3333: ('10.4.5.6',), @@ -1327,8 +1378,9 @@ class TranslateContainerInputTestCase(TranslateBase): '3334/udp': ('10.4.5.6',), '5505/udp': ('10.7.8.9',), '5506/udp': ('10.7.8.9',)}, - 'ports': [80, '81/udp', 3333, '3334/udp', - 4505, 4506, '5505/udp', '5506/udp']} + 'ports': [80, 3333, 4505, 4506, + (81, 'udp'), (3334, 'udp'), + (5505, 'udp'), (5506, 'udp')]} ) # hostPort:containerPort - Bind a specific port on all of the host's @@ -1339,9 +1391,11 @@ class TranslateContainerInputTestCase(TranslateBase): ) for val in (bindings, bindings.split(',')): self.assertEqual( - salt.utils.docker.translate_input( - self.translator, - port_bindings=val, + self.normalize_ports( + salt.utils.docker.translate_input( + self.translator, + port_bindings=val, + ) ), {'port_bindings': {80: [8080, 8888], 3333: 3333, @@ -1351,8 +1405,9 @@ class TranslateContainerInputTestCase(TranslateBase): '3334/udp': 3334, '5505/udp': 15505, '5506/udp': 15506}, - 'ports': [80, '81/udp', 3333, '3334/udp', - 4505, 4506, '5505/udp', '5506/udp']} + 'ports': [80, 3333, 4505, 4506, + (81, 'udp'), (3334, 'udp'), + (5505, 'udp'), (5506, 'udp')]} ) # containerPort - Bind an ephemeral port on all of the host's @@ -1360,9 +1415,11 @@ class TranslateContainerInputTestCase(TranslateBase): bindings = '80,3333,4505-4506,81/udp,3334/udp,5505-5506/udp' for val in (bindings, bindings.split(',')): self.assertEqual( - salt.utils.docker.translate_input( - self.translator, - port_bindings=val, + self.normalize_ports( + salt.utils.docker.translate_input( + self.translator, + port_bindings=val, + ) ), {'port_bindings': {80: None, 3333: None, @@ -1372,8 +1429,9 @@ class TranslateContainerInputTestCase(TranslateBase): '3334/udp': None, '5505/udp': None, '5506/udp': None}, - 'ports': [80, '81/udp', 3333, '3334/udp', - 4505, 4506, '5505/udp', '5506/udp']}, + 'ports': [80, 3333, 4505, 4506, + (81, 'udp'), (3334, 'udp'), + (5505, 'udp'), (5506, 'udp')]} ) # Test a mixture of different types of input @@ -1384,9 +1442,11 @@ class TranslateContainerInputTestCase(TranslateBase): ) for val in (bindings, bindings.split(',')): self.assertEqual( - salt.utils.docker.translate_input( - self.translator, - port_bindings=val, + self.normalize_ports( + salt.utils.docker.translate_input( + self.translator, + port_bindings=val, + ) ), {'port_bindings': {80: ('10.1.2.3', 8080), 3333: ('10.4.5.6',), @@ -1402,10 +1462,10 @@ class TranslateContainerInputTestCase(TranslateBase): '19999/udp': None, '20000/udp': None, '20001/udp': None}, - 'ports': [80, '81/udp', 3333, '3334/udp', - 4505, 4506, '5505/udp', '5506/udp', - 9999, 10000, 10001, '19999/udp', - '20000/udp', '20001/udp']} + 'ports': [80, 3333, 4505, 4506, 9999, 10000, 10001, + (81, 'udp'), (3334, 'udp'), (5505, 'udp'), + (5506, 'udp'), (19999, 'udp'), + (20000, 'udp'), (20001, 'udp')]} ) # Error case: too many items (max 3) @@ -1506,11 +1566,13 @@ class TranslateContainerInputTestCase(TranslateBase): [1111, '2222/tcp', '3333/udp', '4505-4506'], ['1111', '2222/tcp', '3333/udp', '4505-4506']): self.assertEqual( - salt.utils.docker.translate_input( - self.translator, - ports=val, + self.normalize_ports( + salt.utils.docker.translate_input( + self.translator, + ports=val, + ) ), - {'ports': [1111, 2222, (3333, 'udp'), 4505, 4506]} + {'ports': [1111, 2222, 4505, 4506, (3333, 'udp')]} ) # Error case: non-integer and non/string value diff --git a/tests/unit/utils/test_files.py b/tests/unit/utils/test_files.py index 340ba268b5..d8f402d95d 100644 --- a/tests/unit/utils/test_files.py +++ b/tests/unit/utils/test_files.py @@ -11,6 +11,7 @@ import tempfile # Import Salt libs import salt.utils.files +from salt.ext import six # Import Salt Testing libs from tests.support.paths import TMP @@ -69,3 +70,32 @@ class FilesUtilTestCase(TestCase): ) finally: shutil.rmtree(tmp) + + @skipIf(not six.PY3, 'This test only applies to Python 3') + def test_fopen_with_disallowed_fds(self): + ''' + This is safe to have as a unit test since we aren't going to actually + try to read or write. We want to ensure that we are raising a + TypeError. Python 3's open() builtin will treat the booleans as file + descriptor numbers and try to open stdin/stdout. We also want to test + fd 2 which is stderr. + ''' + for invalid_fn in (False, True, 0, 1, 2): + try: + with salt.utils.files.fopen(invalid_fn): + pass + except TypeError: + # This is expected. We aren't using an assertRaises here + # because we want to ensure that if we did somehow open the + # filehandle, that it doesn't remain open. + pass + else: + # We probably won't even get this far if we actually opened + # stdin/stdout as a file descriptor. It is likely to cause the + # integration suite to die since, news flash, closing + # stdin/stdout/stderr is usually not a wise thing to do in the + # middle of a program's execution. + self.fail( + 'fopen() should have been prevented from opening a file ' + 'using {0} as the filename'.format(invalid_fn) + ) diff --git a/tests/unit/utils/test_parsers.py b/tests/unit/utils/test_parsers.py index bd67c41fbd..eb88197e84 100644 --- a/tests/unit/utils/test_parsers.py +++ b/tests/unit/utils/test_parsers.py @@ -5,9 +5,7 @@ # Import python libs from __future__ import absolute_import, print_function, unicode_literals -import logging import os -import logging # Import Salt Testing Libs from tests.support.unit import skipIf, TestCase @@ -26,6 +24,11 @@ import salt.syspaths import salt.utils.parsers import salt.utils.platform +try: + import pytest +except ImportError: + pytest = None + class ErrorMock(object): # pylint: disable=too-few-public-methods ''' @@ -996,6 +999,7 @@ class SaltAPIParserTestCase(LogSettingsParserTests): self.addCleanup(delattr, self, 'parser') +@skipIf(not pytest, False) @skipIf(NO_MOCK, NO_MOCK_REASON) class DaemonMixInTestCase(TestCase): ''' @@ -1006,39 +1010,57 @@ class DaemonMixInTestCase(TestCase): ''' Setting up ''' - # Set PID - self.pid = '/some/fake.pid' - # Setup mixin - self.mixin = salt.utils.parsers.DaemonMixIn() - self.mixin.config = {} - self.mixin.config['pidfile'] = self.pid + self.daemon_mixin = salt.utils.parsers.DaemonMixIn() + self.daemon_mixin.config = {} + self.daemon_mixin.config['pidfile'] = '/some/fake.pid' - # logger - self.logger = logging.getLogger('salt.utils.parsers') + def tearDown(self): + ''' + Tear down test + :return: + ''' + del self.daemon_mixin + @patch('os.unlink', MagicMock()) + @patch('os.path.isfile', MagicMock(return_value=True)) + @patch('salt.utils.parsers.logger', MagicMock()) def test_pid_file_deletion(self): ''' PIDfile deletion without exception. ''' - with patch('os.unlink', MagicMock()) as os_unlink: - with patch('os.path.isfile', MagicMock(return_value=True)): - with patch.object(self.logger, 'info') as mock_logger: - self.mixin._mixin_before_exit() - assert mock_logger.call_count == 0 - assert os_unlink.call_count == 1 + self.daemon_mixin._mixin_before_exit() + assert salt.utils.parsers.os.unlink.call_count == 1 + salt.utils.parsers.logger.info.assert_not_called() + salt.utils.parsers.logger.debug.assert_not_called() - def test_pid_file_deletion_with_oserror(self): + @patch('os.unlink', MagicMock(side_effect=OSError())) + @patch('os.path.isfile', MagicMock(return_value=True)) + @patch('os.getuid', MagicMock(return_value=0)) + @patch('salt.utils.parsers.logger', MagicMock()) + def test_pid_deleted_oserror_as_root(self): ''' - PIDfile deletion with exception + PIDfile deletion with exception, running as root. ''' - with patch('os.unlink', MagicMock(side_effect=OSError())) as os_unlink: - with patch('os.path.isfile', MagicMock(return_value=True)): - with patch.object(self.logger, 'info') as mock_logger: - self.mixin._mixin_before_exit() - assert os_unlink.call_count == 1 - mock_logger.assert_called_with( - 'PIDfile could not be deleted: {0}'.format(self.pid)) + self.daemon_mixin._mixin_before_exit() + assert salt.utils.parsers.os.unlink.call_count == 1 + salt.utils.parsers.logger.info.assert_called_with('PIDfile could not be deleted: %s', + format(self.daemon_mixin.config['pidfile'])) + salt.utils.parsers.logger.debug.assert_called() + + @patch('os.unlink', MagicMock(side_effect=OSError())) + @patch('os.path.isfile', MagicMock(return_value=True)) + @patch('os.getuid', MagicMock(return_value=1000)) + @patch('salt.utils.parsers.logger', MagicMock()) + def test_pid_deleted_oserror_as_non_root(self): + ''' + PIDfile deletion with exception, running as non-root. + ''' + self.daemon_mixin._mixin_before_exit() + assert salt.utils.parsers.os.unlink.call_count == 1 + salt.utils.parsers.logger.info.assert_not_called() + salt.utils.parsers.logger.debug.assert_not_called() + # Hide the class from unittest framework when it searches for TestCase classes in the module del LogSettingsParserTests diff --git a/tests/unit/utils/test_schedule.py b/tests/unit/utils/test_schedule.py index d92faae47a..894af64b85 100644 --- a/tests/unit/utils/test_schedule.py +++ b/tests/unit/utils/test_schedule.py @@ -6,8 +6,8 @@ # Import python libs from __future__ import absolute_import, print_function, unicode_literals import copy +import datetime import os -import time # Import Salt Testing Libs from tests.support.unit import skipIf, TestCase @@ -294,7 +294,7 @@ class ScheduleTestCase(TestCase): ''' self.schedule.opts.update({'pillar': {'schedule': {}}}) self.schedule.opts.update({'schedule': {'testjob': {'function': 'test.true', 'seconds': 60}}}) - now = int(time.time()) + now = datetime.datetime.now() self.schedule.eval() self.assertTrue(self.schedule.opts['schedule']['testjob']['_next_fire_time'] > now) @@ -305,9 +305,9 @@ class ScheduleTestCase(TestCase): self.schedule.opts.update({'pillar': {'schedule': {}}}) self.schedule.opts.update( {'schedule': {'testjob': {'function': 'test.true', 'seconds': 60, 'splay': 5}}}) - now = int(time.time()) + now = datetime.datetime.now() self.schedule.eval() - self.assertTrue(self.schedule.opts['schedule']['testjob']['_splay'] - now > 60) + self.assertTrue((self.schedule.opts['schedule']['testjob']['_splay'] - now).total_seconds() > 60) @skipIf(not _CRON_SUPPORTED, 'croniter module not installed') def test_eval_schedule_cron(self): @@ -316,7 +316,7 @@ class ScheduleTestCase(TestCase): ''' self.schedule.opts.update({'pillar': {'schedule': {}}}) self.schedule.opts.update({'schedule': {'testjob': {'function': 'test.true', 'cron': '* * * * *'}}}) - now = int(time.time()) + now = datetime.datetime.now() self.schedule.eval() self.assertTrue(self.schedule.opts['schedule']['testjob']['_next_fire_time'] > now) diff --git a/tests/unit/utils/test_stringutils.py b/tests/unit/utils/test_stringutils.py index 55e794d6e9..36ff9308a4 100644 --- a/tests/unit/utils/test_stringutils.py +++ b/tests/unit/utils/test_stringutils.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals +import textwrap # Import Salt libs from tests.support.mock import patch @@ -13,6 +14,9 @@ from salt.ext.six.moves import builtins, range # pylint: disable=redefined-buil UNICODE = '中国語 (繁体)' STR = BYTES = UNICODE.encode('utf-8') +# This is an example of a unicode string with й constructed using two separate +# code points. Do not modify it. +EGGS = '\u044f\u0438\u0306\u0446\u0430' class StringutilsTestCase(TestCase): @@ -90,6 +94,23 @@ class StringutilsTestCase(TestCase): self.assertEqual(salt.utils.stringutils.to_bytes(UNICODE, 'utf-8'), BYTES) def test_to_unicode(self): + self.assertEqual( + salt.utils.stringutils.to_unicode( + EGGS, + encoding='utf=8', + normalize=True + ), + 'яйца' + ) + self.assertNotEqual( + salt.utils.stringutils.to_unicode( + EGGS, + encoding='utf=8', + normalize=False + ), + 'яйца' + ) + if six.PY3: self.assertEqual(salt.utils.stringutils.to_unicode('plugh'), 'plugh') self.assertEqual(salt.utils.stringutils.to_unicode('áéíóúý'), 'áéíóúý') @@ -108,3 +129,43 @@ class StringutilsTestCase(TestCase): '(?:[\\s]+)?$' ret = salt.utils.stringutils.build_whitespace_split_regex(' '.join(LOREM_IPSUM.split()[:5])) self.assertEqual(ret, expected_regex) + + def test_get_context(self): + expected_context = textwrap.dedent('''\ + --- + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eget urna a arcu lacinia sagittis. + Sed scelerisque, lacus eget malesuada vestibulum, justo diam facilisis tortor, in sodales dolor + [...] + ---''') + ret = salt.utils.stringutils.get_context(LOREM_IPSUM, 1, num_lines=1) + self.assertEqual(ret, expected_context) + + def test_get_context_has_enough_context(self): + template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' + context = salt.utils.stringutils.get_context(template, 8) + expected = '---\n[...]\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\n[...]\n---' + self.assertEqual(expected, context) + + def test_get_context_at_top_of_file(self): + template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' + context = salt.utils.stringutils.get_context(template, 1) + expected = '---\n1\n2\n3\n4\n5\n6\n[...]\n---' + self.assertEqual(expected, context) + + def test_get_context_at_bottom_of_file(self): + template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' + context = salt.utils.stringutils.get_context(template, 15) + expected = '---\n[...]\na\nb\nc\nd\ne\nf\n---' + self.assertEqual(expected, context) + + def test_get_context_2_context_lines(self): + template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' + context = salt.utils.stringutils.get_context(template, 8, num_lines=2) + expected = '---\n[...]\n6\n7\n8\n9\na\n[...]\n---' + self.assertEqual(expected, context) + + def test_get_context_with_marker(self): + template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf' + context = salt.utils.stringutils.get_context(template, 8, num_lines=2, marker=' <---') + expected = '---\n[...]\n6\n7\n8 <---\n9\na\n[...]\n---' + self.assertEqual(expected, context) diff --git a/tests/unit/utils/test_templates.py b/tests/unit/utils/test_templates.py deleted file mode 100644 index 5da6dd78dd..0000000000 --- a/tests/unit/utils/test_templates.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -''' -Tests for salt.utils.data -''' - -# Import Python libs -from __future__ import absolute_import, print_function, unicode_literals -import textwrap - -# Import Salt libs -import salt.utils.templates -from tests.support.unit import TestCase, LOREM_IPSUM - - -class TemplatesTestCase(TestCase): - - def test_get_context(self): - expected_context = textwrap.dedent('''\ - --- - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eget urna a arcu lacinia sagittis. - Sed scelerisque, lacus eget malesuada vestibulum, justo diam facilisis tortor, in sodales dolor - [...] - ---''') - ret = salt.utils.templates.get_context(LOREM_IPSUM, 1, num_lines=1) - self.assertEqual(ret, expected_context) diff --git a/tests/unit/utils/test_verify.py b/tests/unit/utils/test_verify.py index ab1149a68e..fb801da217 100644 --- a/tests/unit/utils/test_verify.py +++ b/tests/unit/utils/test_verify.py @@ -113,20 +113,13 @@ class TestVerify(TestCase): root_dir = tempfile.mkdtemp(dir=TMP) var_dir = os.path.join(root_dir, 'var', 'log', 'salt') key_dir = os.path.join(root_dir, 'key_dir') - verify_env([var_dir, key_dir], getpass.getuser(), root_dir=root_dir, sensitive_dirs=[key_dir]) + verify_env([var_dir], getpass.getuser(), root_dir=root_dir) self.assertTrue(os.path.exists(var_dir)) - self.assertTrue(os.path.exists(key_dir)) - - var_dir_stat = os.stat(var_dir) - self.assertEqual(var_dir_stat.st_uid, os.getuid()) - self.assertEqual(var_dir_stat.st_mode & stat.S_IRWXU, stat.S_IRWXU) - self.assertEqual(var_dir_stat.st_mode & stat.S_IRWXG, 40) - self.assertEqual(var_dir_stat.st_mode & stat.S_IRWXO, 5) - - key_dir_stat = os.stat(key_dir) - self.assertEqual(key_dir_stat.st_mode & stat.S_IRWXU, stat.S_IRWXU) - self.assertEqual(key_dir_stat.st_mode & stat.S_IRWXG, 0) - self.assertEqual(key_dir_stat.st_mode & stat.S_IRWXO, 0) + dir_stat = os.stat(var_dir) + self.assertEqual(dir_stat.st_uid, os.getuid()) + self.assertEqual(dir_stat.st_mode & stat.S_IRWXU, stat.S_IRWXU) + self.assertEqual(dir_stat.st_mode & stat.S_IRWXG, 40) + self.assertEqual(dir_stat.st_mode & stat.S_IRWXO, 5) @requires_network(only_local_network=True) def test_verify_socket(self): diff --git a/tests/unit/utils/test_win_functions.py b/tests/unit/utils/test_win_functions.py new file mode 100644 index 0000000000..370994c479 --- /dev/null +++ b/tests/unit/utils/test_win_functions.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- + +# Import Python Libs +from __future__ import absolute_import, unicode_literals, print_function + +# Import Salt Testing Libs +from tests.support.unit import TestCase, skipIf +from tests.support.mock import ( + NO_MOCK, + NO_MOCK_REASON +) + +# Import Salt Libs +import salt.utils.platform +import salt.utils.win_functions as win_functions + + +@skipIf(NO_MOCK, NO_MOCK_REASON) +class WinFunctionsTestCase(TestCase): + ''' + Test cases for salt.utils.win_functions + ''' + + def test_escape_argument_simple(self): + ''' + Test to make sure we encode simple arguments correctly + ''' + encoded = win_functions.escape_argument('simple') + + self.assertEqual(encoded, 'simple') + + def test_escape_argument_with_space(self): + ''' + Test to make sure we encode arguments containing spaces correctly + ''' + encoded = win_functions.escape_argument('with space') + + self.assertEqual(encoded, '^"with space^"') + + def test_escape_argument_simple_path(self): + ''' + Test to make sure we encode simple path arguments correctly + ''' + encoded = win_functions.escape_argument('C:\\some\\path') + + self.assertEqual(encoded, 'C:\\some\\path') + + def test_escape_argument_path_with_space(self): + ''' + Test to make sure we encode path arguments containing spaces correctly + ''' + encoded = win_functions.escape_argument('C:\\Some Path\\With Spaces') + + self.assertEqual(encoded, '^"C:\\Some Path\\With Spaces^"') + + @skipIf(not salt.utils.platform.is_windows(), 'WinDLL only available on Windows') + def test_broadcast_setting_change(self): + ''' + Test to rehash the Environment variables + ''' + self.assertTrue(win_functions.broadcast_setting_change()) diff --git a/tests/unit/utils/test_yamlloader.py b/tests/unit/utils/test_yamlloader.py index bf39c32d02..48f81b462e 100644 --- a/tests/unit/utils/test_yamlloader.py +++ b/tests/unit/utils/test_yamlloader.py @@ -5,6 +5,7 @@ # Import python libs from __future__ import absolute_import, print_function, unicode_literals +import collections import textwrap # Import Salt Libs @@ -17,6 +18,9 @@ from salt.ext import six from tests.support.unit import TestCase, skipIf from tests.support.mock import patch, NO_MOCK, NO_MOCK_REASON, mock_open +# Import 3rd-party libs +from salt.ext import six + @skipIf(NO_MOCK, NO_MOCK_REASON) class YamlLoaderTestCase(TestCase): @@ -25,7 +29,7 @@ class YamlLoaderTestCase(TestCase): ''' @staticmethod - def _render_yaml(data): + def render_yaml(data): ''' Takes a YAML string, puts it into a mock file, passes that to the YAML SaltYamlSafeLoader and then returns the rendered/parsed YAML data @@ -41,12 +45,37 @@ class YamlLoaderTestCase(TestCase): with salt.utils.files.fopen(mocked_file) as mocked_stream: return SaltYamlSafeLoader(mocked_stream).get_data() + @staticmethod + def raise_error(value): + raise TypeError('{0!r} is not a unicode string'.format(value)) # pylint: disable=repr-flag-used-in-string + + def assert_unicode(self, value): + ''' + Make sure the entire data structure is unicode + ''' + if six.PY3: + return + if isinstance(value, six.string_types): + if not isinstance(value, six.text_type): + self.raise_error(value) + elif isinstance(value, collections.Mapping): + for k, v in six.iteritems(value): + self.assert_unicode(k) + self.assert_unicode(v) + elif isinstance(value, collections.Iterable): + for item in value: + self.assert_unicode(item) + + def assert_matches(self, ret, expected): + self.assertEqual(ret, expected) + self.assert_unicode(ret) + def test_yaml_basics(self): ''' Test parsing an ordinary path ''' - self.assertEqual( - self._render_yaml(textwrap.dedent('''\ + self.assert_matches( + self.render_yaml(textwrap.dedent('''\ p1: - alpha - beta''')), @@ -58,8 +87,8 @@ class YamlLoaderTestCase(TestCase): Test YAML anchors ''' # Simple merge test - self.assertEqual( - self._render_yaml(textwrap.dedent('''\ + self.assert_matches( + self.render_yaml(textwrap.dedent('''\ p1: &p1 v1: alpha p2: @@ -69,8 +98,8 @@ class YamlLoaderTestCase(TestCase): ) # Test that keys/nodes are overwritten - self.assertEqual( - self._render_yaml(textwrap.dedent('''\ + self.assert_matches( + self.render_yaml(textwrap.dedent('''\ p1: &p1 v1: alpha p2: @@ -80,8 +109,8 @@ class YamlLoaderTestCase(TestCase): ) # Test merging of lists - self.assertEqual( - self._render_yaml(textwrap.dedent('''\ + self.assert_matches( + self.render_yaml(textwrap.dedent('''\ p1: &p1 v1: &v1 - t1 @@ -96,12 +125,12 @@ class YamlLoaderTestCase(TestCase): Test that duplicates still throw an error ''' with self.assertRaises(ConstructorError): - self._render_yaml(textwrap.dedent('''\ + self.render_yaml(textwrap.dedent('''\ p1: alpha p1: beta''')) with self.assertRaises(ConstructorError): - self._render_yaml(textwrap.dedent('''\ + self.render_yaml(textwrap.dedent('''\ p1: &p1 v1: alpha p2: @@ -113,8 +142,8 @@ class YamlLoaderTestCase(TestCase): ''' Test proper loading of unicode literals ''' - self.assertEqual( - self._render_yaml(textwrap.dedent('''\ + self.assert_matches( + self.render_yaml(textwrap.dedent('''\ foo: a: Д b: {'a': u'\\u0414'}''')),