mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch '2017.7' into 'develop'
Conflicts: - salt/modules/win_groupadd.py - salt/modules/yumpkg.py - salt/state.py - salt/utils/url.py
This commit is contained in:
commit
0eafc59f33
11 changed files with 440 additions and 167 deletions
|
@ -15,91 +15,119 @@
|
|||
# This script is run as a part of the macOS Salt Installation
|
||||
#
|
||||
###############################################################################
|
||||
echo "Post install started on:" > /tmp/postinstall.txt
|
||||
date >> /tmp/postinstall.txt
|
||||
|
||||
###############################################################################
|
||||
# Define Variables
|
||||
###############################################################################
|
||||
# Get Minor Version
|
||||
OSX_VERSION=$(sw_vers | grep ProductVersion | cut -f 2 -d: | tr -d '[:space:]')
|
||||
MINOR=$(echo ${OSX_VERSION} | cut -f 2 -d.)
|
||||
# Path Variables
|
||||
INSTALL_DIR="/opt/salt"
|
||||
BIN_DIR="$INSTALL_DIR/bin"
|
||||
CONFIG_DIR="/etc/salt"
|
||||
TEMP_DIR="/tmp"
|
||||
SBIN_DIR="/usr/local/sbin"
|
||||
|
||||
###############################################################################
|
||||
# Set up logging and error handling
|
||||
###############################################################################
|
||||
echo "Post install script started on:" > "$TEMP_DIR/postinstall.txt"
|
||||
date "+%Y/%m/%d %H:%m:%S" >> "$TEMP_DIR/postinstall.txt"
|
||||
trap 'quit_on_error $LINENO $BASH_COMMAND' ERR
|
||||
|
||||
quit_on_error() {
|
||||
echo "$(basename $0) caught error on line : $1 command was: $2" >> /tmp/postinstall.txt
|
||||
echo "$(basename $0) caught error on line : $1 command was: $2" >> "$TEMP_DIR/postinstall.txt"
|
||||
exit -1
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Check for existing minion config, copy if it doesn't exist
|
||||
###############################################################################
|
||||
if [ ! -f /etc/salt/minion ]; then
|
||||
echo "Config copy: Started..." >> /tmp/postinstall.txt
|
||||
cp /etc/salt/minion.dist /etc/salt/minion
|
||||
echo "Config copy: Successful" >> /tmp/postinstall.txt
|
||||
if [ ! -f "$CONFIG_DIR/minion" ]; then
|
||||
echo "Config: Copy Started..." >> "$TEMP_DIR/postinstall.txt"
|
||||
cp "$CONFIG_DIR/minion.dist" "$CONFIG_DIR/minion"
|
||||
echo "Config: Copied Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
fi
|
||||
|
||||
###############################################################################
|
||||
# Create symlink to salt-config.sh
|
||||
###############################################################################
|
||||
# echo "Symlink: Creating symlink for salt-config..." >> /tmp/postinstall.txt
|
||||
if [ ! -d "/usr/local/sbin" ]; then
|
||||
mkdir /usr/local/sbin
|
||||
if [ ! -d "$SBIN_DIR" ]; then
|
||||
echo "Symlink: Creating $SBIN_DIR..." >> "$TEMP_DIR/postinstall.txt"
|
||||
mkdir "$SBIN_DIR"
|
||||
echo "Symlink: Created Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
fi
|
||||
ln -sf /opt/salt/bin/salt-config.sh /usr/local/sbin/salt-config
|
||||
echo "Symlink: Creating symlink for salt-config..." >> "$TEMP_DIR/postinstall.txt"
|
||||
ln -sf "$BIN_DIR/salt-config.sh" "$SBIN_DIR/salt-config"
|
||||
echo "Symlink: Created Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
###############################################################################
|
||||
# Add salt to paths.d
|
||||
###############################################################################
|
||||
# echo "Path: Adding salt to the path..." >> /tmp/postinstall.txt
|
||||
if [ ! -d "/etc/paths.d" ]; then
|
||||
echo "Path: Creating paths.d directory..." >> "$TEMP_DIR/postinstall.txt"
|
||||
mkdir /etc/paths.d
|
||||
echo "Path: Created Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
fi
|
||||
sh -c 'echo "/opt/salt/bin" > /etc/paths.d/salt'
|
||||
sh -c 'echo "/usr/local/sbin" >> /etc/paths.d/salt'
|
||||
echo "Path: Adding salt to the path..." >> "$TEMP_DIR/postinstall.txt"
|
||||
sh -c "echo \"$BIN_DIR\" > /etc/paths.d/salt"
|
||||
sh -c "echo \"$SBIN_DIR\" >> /etc/paths.d/salt"
|
||||
echo "Path: Added Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
###############################################################################
|
||||
# Register Salt as a service
|
||||
###############################################################################
|
||||
setup_services_maverick() {
|
||||
echo "Using old (< 10.10) launchctl interface" >> /tmp/postinstall.txt
|
||||
echo "Service: Using old (< 10.10) launchctl interface" >> "$TEMP_DIR/postinstall.txt"
|
||||
if /bin/launchctl list "com.saltstack.salt.minion" &> /dev/null; then
|
||||
echo "Stop running service..." >> /tmp/postinstall.txt
|
||||
echo "Service: Stopping salt-minion..." >> "$TEMP_DIR/postinstall.txt"
|
||||
launchctl unload -w /Library/LaunchDaemons/com.saltstack.salt.minion.plist
|
||||
echo "Service: Stopped Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
fi;
|
||||
echo "Service: Starting salt-minion..." >> "$TEMP_DIR/postinstall.txt"
|
||||
launchctl load -w /Library/LaunchDaemons/com.saltstack.salt.minion.plist || return 1
|
||||
echo "Service: Started Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
echo "Service start: Successful" >> /tmp/postinstall.txt
|
||||
|
||||
echo "Service disable: Disabling Master, Syndic, and API" >> /tmp/postinstall.txt
|
||||
|
||||
echo "Service: Disabling Master, Syndic, and API services..." >> "$TEMP_DIR/postinstall.txt"
|
||||
launchctl unload -w /Library/LaunchDaemons/com.saltstack.salt.api.plist
|
||||
launchctl unload -w /Library/LaunchDaemons/com.saltstack.salt.master.plist
|
||||
launchctl unload -w /Library/LaunchDaemons/com.saltstack.salt.syndic.plist
|
||||
echo "Service: Disabled Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
setup_services_yosemite_and_later() {
|
||||
echo "Using new (>= 10.10) launchctl interface" >> /tmp/postinstall.txt
|
||||
echo "Service: Using new (>= 10.10) launchctl interface" >> "$TEMP_DIR/postinstall.txt"
|
||||
echo "Service: Enabling salt-minion..." >> "$TEMP_DIR/postinstall.txt"
|
||||
launchctl enable system/com.saltstack.salt.minion
|
||||
echo "Service start: Bootstrapping service..." >> /tmp/postinstall.txt
|
||||
echo "Service: Enabled Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
echo "Service: Bootstrapping salt-minion..." >> "$TEMP_DIR/postinstall.txt"
|
||||
launchctl bootstrap system /Library/LaunchDaemons/com.saltstack.salt.minion.plist
|
||||
echo "Service: Bootstrapped Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
if /bin/launchctl list "com.saltstack.salt.minion" &> /dev/null; then
|
||||
echo "Service is running" >> /tmp/postinstall.txt
|
||||
echo "Service: Service Running" >> "$TEMP_DIR/postinstall.txt"
|
||||
else
|
||||
echo "Service start: Kickstarting service..." >> /tmp/postinstall.txt
|
||||
echo "Service: Kickstarting Service..." >> "$TEMP_DIR/postinstall.txt"
|
||||
launchctl kickstart -kp system/com.saltstack.salt.minion
|
||||
echo "Service: Kickstarted Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
fi
|
||||
|
||||
echo "Service start: Successful" >> /tmp/postinstall.txt
|
||||
|
||||
echo "Service disable: Disabling Master, Syndic, and API" >> /tmp/postinstall.txt
|
||||
echo "Service: Started Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
echo "Service: Disabling Master, Syndic, and API services" >> "$TEMP_DIR/postinstall.txt"
|
||||
launchctl disable system/com.saltstack.salt.master
|
||||
launchctl disable system/com.saltstack.salt.syndic
|
||||
launchctl disable system/com.saltstack.salt.api
|
||||
echo "Service: Disabled Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
OSX_VERSION=$(sw_vers | grep ProductVersion | cut -f 2 -d: | tr -d '[:space:]')
|
||||
MINOR=$(echo ${OSX_VERSION} | cut -f 2 -d.)
|
||||
|
||||
echo "Service start: Enabling service..." >> /tmp/postinstall.txt
|
||||
echo "Service: Configuring..." >> "$TEMP_DIR/postinstall.txt"
|
||||
case $MINOR in
|
||||
9 )
|
||||
setup_services_maverick;
|
||||
|
@ -108,7 +136,9 @@ case $MINOR in
|
|||
setup_services_yosemite_and_later;
|
||||
;;
|
||||
esac
|
||||
echo "Service: Configured Successfully" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
echo "Post install completed successfully" >> /tmp/postinstall.txt
|
||||
echo "Post install completed successfully on:" >> "$TEMP_DIR/postinstall.txt"
|
||||
date "+%Y/%m/%d %H:%m:%S" >> "$TEMP_DIR/postinstall.txt"
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
# Date: December 2015
|
||||
#
|
||||
# Description: This script stops the salt minion service before attempting to
|
||||
# install Salt on macOS
|
||||
# install Salt on macOS. It also removes the /opt/salt/bin
|
||||
# directory, symlink to salt-config, and salt from paths.d.
|
||||
#
|
||||
# Requirements:
|
||||
# - None
|
||||
|
@ -15,12 +16,29 @@
|
|||
# This script is run as a part of the macOS Salt Installation
|
||||
#
|
||||
###############################################################################
|
||||
echo "Preinstall started on:" > /tmp/preinstall.txt
|
||||
date >> /tmp/preinstall.txt
|
||||
|
||||
###############################################################################
|
||||
# Define Variables
|
||||
###############################################################################
|
||||
# Get Minor Version
|
||||
OSX_VERSION=$(sw_vers | grep ProductVersion | cut -f 2 -d: | tr -d '[:space:]')
|
||||
MINOR=$(echo ${OSX_VERSION} | cut -f 2 -d.)
|
||||
# Path Variables
|
||||
INSTALL_DIR="/opt/salt"
|
||||
BIN_DIR="$INSTALL_DIR/bin"
|
||||
CONFIG_DIR="/etc/salt"
|
||||
TEMP_DIR="/tmp"
|
||||
SBIN_DIR="/usr/local/sbin"
|
||||
|
||||
###############################################################################
|
||||
# Set up logging and error handling
|
||||
###############################################################################
|
||||
echo "Preinstall started on:" > "$TEMP_DIR/preinstall.txt"
|
||||
date "+%Y/%m/%d %H:%m:%S" >> "$TEMP_DIR/preinstall.txt"
|
||||
trap 'quit_on_error $LINENO $BASH_COMMAND' ERR
|
||||
|
||||
quit_on_error() {
|
||||
echo "$(basename $0) caught error on line : $1 command was: $2" >> /tmp/preinstall.txt
|
||||
echo "$(basename $0) caught error on line : $1 command was: $2" >> "$TEMP_DIR/preinstall.txt"
|
||||
exit -1
|
||||
}
|
||||
|
||||
|
@ -31,24 +49,58 @@ MINOR=$(echo ${OSX_VERSION} | cut -f 2 -d.)
|
|||
# Stop the service
|
||||
###############################################################################
|
||||
stop_service_maverick() {
|
||||
echo "Using old (< 10.10) launchctl interface" >> /tmp/preinstall.txt
|
||||
echo "Service: Using old (< 10.10) launchctl interface" >> "$TEMP_DIR/preinstall.txt"
|
||||
if /bin/launchctl list "com.saltstack.salt.minion" &> /dev/null; then
|
||||
echo "Stop service: Started..." >> /tmp/preinstall.txt
|
||||
echo "Service: Unloading minion..." >> "$TEMP_DIR/preinstall.txt"
|
||||
launchctl unload -w /Library/LaunchDaemons/com.saltstack.salt.minion.plist
|
||||
echo "Stop service: Successful" >> /tmp/preinstall.txt
|
||||
echo "Service: Unloaded Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
if /bin/launchctl list "com.saltstack.salt.master" &> /dev/null; then
|
||||
echo "Service: Unloading master..." >> "$TEMP_DIR/preinstall.txt"
|
||||
launchctl unload -w /Library/LaunchDaemons/com.saltstack.salt.master.plist
|
||||
echo "Service: Unloaded Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
if /bin/launchctl list "com.saltstack.salt.syndic" &> /dev/null; then
|
||||
echo "Service: Unloading syndic..." >> "$TEMP_DIR/preinstall.txt"
|
||||
launchctl unload -w /Library/LaunchDaemons/com.saltstack.salt.syndic.plist
|
||||
echo "Service: Unloaded Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
if /bin/launchctl list "com.saltstack.salt.api" &> /dev/null; then
|
||||
echo "Service: Unloading api..." >> "$TEMP_DIR/preinstall.txt"
|
||||
launchctl unload -w /Library/LaunchDaemons/com.saltstack.salt.api.plist
|
||||
echo "Service: Unloaded Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
}
|
||||
|
||||
stop_service_yosemite_and_later() {
|
||||
echo "Using new (>= 10.10) launchctl interface" >> /tmp/preinstall.txt
|
||||
echo "Service: Using new (>= 10.10) launchctl interface" >> "$TEMP_DIR/preinstall.txt"
|
||||
if /bin/launchctl list "com.saltstack.salt.minion" &> /dev/null; then
|
||||
echo "Stop service: Started..." >> /tmp/preinstall.txt
|
||||
echo "Service: Stopping minion..." >> "$TEMP_DIR/preinstall.txt"
|
||||
launchctl disable system/com.saltstack.salt.minion
|
||||
launchctl bootout system /Library/LaunchDaemons/com.saltstack.salt.minion.plist
|
||||
echo "Stop service: Successful" >> /tmp/preinstall.txt
|
||||
echo "Service: Stopped Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
if /bin/launchctl list "com.saltstack.salt.master" &> /dev/null; then
|
||||
echo "Service: Stopping master..." >> "$TEMP_DIR/preinstall.txt"
|
||||
launchctl disable system/com.saltstack.salt.master
|
||||
launchctl bootout system /Library/LaunchDaemons/com.saltstack.salt.master.plist
|
||||
echo "Service: Stopped Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
if /bin/launchctl list "com.saltstack.salt.syndic" &> /dev/null; then
|
||||
echo "Service: Stopping syndic..." >> "$TEMP_DIR/preinstall.txt"
|
||||
launchctl disable system/com.saltstack.salt.syndic
|
||||
launchctl bootout system /Library/LaunchDaemons/com.saltstack.salt.syndic.plist
|
||||
echo "Service: Stopped Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
if /bin/launchctl list "com.saltstack.salt.api" &> /dev/null; then
|
||||
echo "Service: Stopping api..." >> "$TEMP_DIR/preinstall.txt"
|
||||
launchctl disable system/com.saltstack.salt.api
|
||||
launchctl bootout system /Library/LaunchDaemons/com.saltstack.salt.api.plist
|
||||
echo "Service: Stopped Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Service: Configuring..." >> "$TEMP_DIR/preinstall.txt"
|
||||
case $MINOR in
|
||||
9 )
|
||||
stop_service_maverick;
|
||||
|
@ -57,6 +109,36 @@ case $MINOR in
|
|||
stop_service_yosemite_and_later;
|
||||
;;
|
||||
esac
|
||||
echo "Preinstall Completed Successfully" >> /tmp/preinstall.txt
|
||||
echo "Service: Configured Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
|
||||
###############################################################################
|
||||
# Remove the Symlink to salt-config.sh
|
||||
###############################################################################
|
||||
if [ -L "$SBIN_DIR/salt-config" ]; then
|
||||
echo "Cleanup: Removing Symlink $BIN_DIR/salt-config" >> "$TEMP_DIR/preinstall.txt"
|
||||
rm "$SBIN_DIR/salt-config"
|
||||
echo "Cleanup: Removed Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
|
||||
###############################################################################
|
||||
# Remove the $INSTALL_DIR directory
|
||||
###############################################################################
|
||||
if [ -d "$INSTALL_DIR" ]; then
|
||||
echo "Cleanup: Removing $INSTALL_DIR" >> "$TEMP_DIR/preinstall.txt"
|
||||
rm -rf "$INSTALL_DIR"
|
||||
echo "Cleanup: Removed Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
|
||||
###############################################################################
|
||||
# Remove the salt from the paths.d
|
||||
###############################################################################
|
||||
if [ ! -f "/etc/paths.d/salt" ]; then
|
||||
echo "Path: Removing salt from the path..." >> "$TEMP_DIR/preinstall.txt"
|
||||
rm "/etc/paths.d/salt"
|
||||
echo "Path: Removed Successfully" >> "$TEMP_DIR/preinstall.txt"
|
||||
fi
|
||||
|
||||
echo "Preinstall Completed Successfully on:" >> "$TEMP_DIR/preinstall.txt"
|
||||
date "+%Y/%m/%d %H:%m:%S" >> "$TEMP_DIR/preinstall.txt"
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -12,6 +12,7 @@ from __future__ import absolute_import
|
|||
|
||||
# Import Salt libs
|
||||
import salt.utils.platform
|
||||
import salt.utils.win_functions
|
||||
|
||||
|
||||
try:
|
||||
|
@ -35,10 +36,18 @@ def __virtual__():
|
|||
return (False, "Module win_groupadd: module only works on Windows systems")
|
||||
|
||||
|
||||
def add(name, gid=None, system=False):
|
||||
def add(name, **kwargs):
|
||||
'''
|
||||
Add the specified group
|
||||
|
||||
Args:
|
||||
|
||||
name (str):
|
||||
The name of the group to add
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of results
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -57,29 +66,32 @@ def add(name, gid=None, system=False):
|
|||
compObj = nt.GetObject('', 'WinNT://.,computer')
|
||||
newGroup = compObj.Create('group', name)
|
||||
newGroup.SetInfo()
|
||||
ret['changes'].append((
|
||||
'Successfully created group {0}'
|
||||
).format(name))
|
||||
ret['changes'].append('Successfully created group {0}'.format(name))
|
||||
except pywintypes.com_error as com_err:
|
||||
ret['result'] = False
|
||||
if len(com_err.excepinfo) >= 2:
|
||||
friendly_error = com_err.excepinfo[2].rstrip('\r\n')
|
||||
ret['comment'] = (
|
||||
'Failed to create group {0}. {1}'
|
||||
).format(name, friendly_error)
|
||||
ret['comment'] = 'Failed to create group {0}. {1}' \
|
||||
''.format(name, friendly_error)
|
||||
else:
|
||||
ret['result'] = None
|
||||
ret['comment'] = (
|
||||
'The group {0} already exists.'
|
||||
).format(name)
|
||||
ret['comment'] = 'The group {0} already exists.'.format(name)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def delete(name):
|
||||
def delete(name, **kwargs):
|
||||
'''
|
||||
Remove the named group
|
||||
|
||||
Args:
|
||||
|
||||
name (str):
|
||||
The name of the group to remove
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of results
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -118,6 +130,14 @@ def info(name):
|
|||
'''
|
||||
Return information about a group
|
||||
|
||||
Args:
|
||||
|
||||
name (str):
|
||||
The name of the group for which to get information
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of information about the group
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -151,6 +171,17 @@ def getent(refresh=False):
|
|||
'''
|
||||
Return info on all groups
|
||||
|
||||
Args:
|
||||
|
||||
refresh (bool):
|
||||
Refresh the info for all groups in ``__context__``. If False only
|
||||
the groups in ``__context__`` wil be returned. If True the
|
||||
``__context__`` will be refreshed with current data and returned.
|
||||
Default is False
|
||||
|
||||
Returns:
|
||||
A list of groups and their information
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -182,16 +213,26 @@ def getent(refresh=False):
|
|||
return ret
|
||||
|
||||
|
||||
def adduser(name, username):
|
||||
def adduser(name, username, **kwargs):
|
||||
'''
|
||||
add a user to a group
|
||||
Add a user to a group
|
||||
|
||||
Args:
|
||||
|
||||
name (str):
|
||||
The name of the group to modify
|
||||
|
||||
username (str):
|
||||
The name of the user to add to the group
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of results
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.adduser foo username
|
||||
|
||||
'''
|
||||
|
||||
ret = {'name': name,
|
||||
|
@ -209,7 +250,7 @@ def adduser(name, username):
|
|||
'/', '\\').encode('ascii', 'backslashreplace').lower())
|
||||
|
||||
try:
|
||||
if __fixlocaluser(username.lower()) not in existingMembers:
|
||||
if salt.utils.win_functions.get_sam_name(username) not in existingMembers:
|
||||
if not __opts__['test']:
|
||||
groupObj.Add('WinNT://' + username.replace('\\', '/'))
|
||||
|
||||
|
@ -231,16 +272,26 @@ def adduser(name, username):
|
|||
return ret
|
||||
|
||||
|
||||
def deluser(name, username):
|
||||
def deluser(name, username, **kwargs):
|
||||
'''
|
||||
remove a user from a group
|
||||
Remove a user from a group
|
||||
|
||||
Args:
|
||||
|
||||
name (str):
|
||||
The name of the group to modify
|
||||
|
||||
username (str):
|
||||
The name of the user to remove from the group
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of results
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.deluser foo username
|
||||
|
||||
'''
|
||||
|
||||
ret = {'name': name,
|
||||
|
@ -258,7 +309,7 @@ def deluser(name, username):
|
|||
'/', '\\').encode('ascii', 'backslashreplace').lower())
|
||||
|
||||
try:
|
||||
if __fixlocaluser(username.lower()) in existingMembers:
|
||||
if salt.utils.win_functions.get_sam_name(username) in existingMembers:
|
||||
if not __opts__['test']:
|
||||
groupObj.Remove('WinNT://' + username.replace('\\', '/'))
|
||||
|
||||
|
@ -280,16 +331,27 @@ def deluser(name, username):
|
|||
return ret
|
||||
|
||||
|
||||
def members(name, members_list):
|
||||
def members(name, members_list, **kwargs):
|
||||
'''
|
||||
remove a user from a group
|
||||
Ensure a group contains only the members in the list
|
||||
|
||||
Args:
|
||||
|
||||
name (str):
|
||||
The name of the group to modify
|
||||
|
||||
members_list (str):
|
||||
A single user or a comma separated list of users. The group will
|
||||
contain only the users specified in this list.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of results
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.members foo 'user1,user2,user3'
|
||||
|
||||
'''
|
||||
|
||||
ret = {'name': name,
|
||||
|
@ -297,7 +359,7 @@ def members(name, members_list):
|
|||
'changes': {'Users Added': [], 'Users Removed': []},
|
||||
'comment': []}
|
||||
|
||||
members_list = [__fixlocaluser(thisMember) for thisMember in members_list.lower().split(",")]
|
||||
members_list = [salt.utils.win_functions.get_sam_name(m) for m in members_list.split(",")]
|
||||
if not isinstance(members_list, list):
|
||||
ret['result'] = False
|
||||
ret['comment'].append('Members is not a list object')
|
||||
|
@ -364,27 +426,26 @@ def members(name, members_list):
|
|||
return ret
|
||||
|
||||
|
||||
def __fixlocaluser(username):
|
||||
'''
|
||||
prefixes a username w/o a backslash with the computername
|
||||
|
||||
i.e. __fixlocaluser('Administrator') would return 'computername\administrator'
|
||||
'''
|
||||
if '\\' not in username:
|
||||
username = ('{0}\\{1}').format(__salt__['grains.get']('host'), username)
|
||||
|
||||
return username.lower()
|
||||
|
||||
|
||||
def list_groups(refresh=False):
|
||||
'''
|
||||
Return a list of groups
|
||||
|
||||
Args:
|
||||
|
||||
refresh (bool):
|
||||
Refresh the info for all groups in ``__context__``. If False only
|
||||
the groups in ``__context__`` wil be returned. If True, the
|
||||
``__context__`` will be refreshed with current data and returned.
|
||||
Default is False
|
||||
|
||||
Returns:
|
||||
list: A list of groups on the machine
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' group.getent
|
||||
salt '*' group.list_groups
|
||||
'''
|
||||
if 'group.list_groups' in __context__ and not refresh:
|
||||
return __context__['group.getent']
|
||||
|
|
|
@ -34,8 +34,10 @@ try:
|
|||
import yum
|
||||
HAS_YUM = True
|
||||
except ImportError:
|
||||
from salt.ext.six.moves import configparser
|
||||
HAS_YUM = False
|
||||
|
||||
from salt.ext.six.moves import configparser
|
||||
|
||||
# pylint: enable=import-error,redefined-builtin
|
||||
|
||||
# Import Salt libs
|
||||
|
@ -2814,41 +2816,32 @@ def _parse_repo_file(filename):
|
|||
'''
|
||||
Turn a single repo file into a dict
|
||||
'''
|
||||
repos = {}
|
||||
header = ''
|
||||
repo = ''
|
||||
with salt.utils.files.fopen(filename, 'r') as rfile:
|
||||
for line in rfile:
|
||||
if line.startswith('['):
|
||||
repo = line.strip().replace('[', '').replace(']', '')
|
||||
repos[repo] = {}
|
||||
parsed = configparser.ConfigParser()
|
||||
config = {}
|
||||
|
||||
# Even though these are essentially uselss, I want to allow the
|
||||
# user to maintain their own comments, etc
|
||||
if not line:
|
||||
if not repo:
|
||||
header += line
|
||||
if line.startswith('#'):
|
||||
if not repo:
|
||||
header += line
|
||||
else:
|
||||
if 'comments' not in repos[repo]:
|
||||
repos[repo]['comments'] = []
|
||||
repos[repo]['comments'].append(line.strip())
|
||||
continue
|
||||
try:
|
||||
parsed.read(filename)
|
||||
except configparser.MissingSectionHeaderError as err:
|
||||
log.error(
|
||||
'Failed to parse file {0}, error: {1}'.format(filename, err.message)
|
||||
)
|
||||
return ('', {})
|
||||
|
||||
# These are the actual configuration lines that matter
|
||||
if '=' in line:
|
||||
try:
|
||||
comps = line.strip().split('=')
|
||||
repos[repo][comps[0].strip()] = '='.join(comps[1:])
|
||||
except KeyError:
|
||||
log.error(
|
||||
'Failed to parse line in %s, offending line was '
|
||||
'\'%s\'', filename, line.rstrip()
|
||||
)
|
||||
for section in parsed._sections:
|
||||
section_dict = dict(parsed._sections[section])
|
||||
section_dict.pop('__name__')
|
||||
config[section] = section_dict
|
||||
|
||||
return (header, repos)
|
||||
# Try to extract leading comments
|
||||
headers = ''
|
||||
with salt.utils.fopen(filename, 'r') as rawfile:
|
||||
for line in rawfile:
|
||||
if line.strip().startswith('#'):
|
||||
headers += '{0}\n'.format(line.strip())
|
||||
else:
|
||||
break
|
||||
|
||||
return (headers, config)
|
||||
|
||||
|
||||
def file_list(*packages):
|
||||
|
|
|
@ -2127,11 +2127,14 @@ class State(object):
|
|||
reqs[r_state].append(chunk)
|
||||
continue
|
||||
try:
|
||||
if (fnmatch.fnmatch(chunk[u'name'], req_val) or
|
||||
fnmatch.fnmatch(chunk[u'__id__'], req_val)):
|
||||
if req_key == u'id' or chunk[u'state'] == req_key:
|
||||
found = True
|
||||
reqs[r_state].append(chunk)
|
||||
if isinstance(req_val, six.string_types):
|
||||
if (fnmatch.fnmatch(chunk[u'name'], req_val) or
|
||||
fnmatch.fnmatch(chunk[u'__id__'], req_val)):
|
||||
if req_key == u'id' or chunk[u'state'] == req_key:
|
||||
found = True
|
||||
reqs[r_state].append(chunk)
|
||||
else:
|
||||
raise KeyError
|
||||
except KeyError as exc:
|
||||
raise SaltRenderError(
|
||||
u'Could not locate requisite of [{0}] present in state with name [{1}]'.format(
|
||||
|
@ -2309,13 +2312,17 @@ class State(object):
|
|||
req_val = lreq[req_key]
|
||||
comment += \
|
||||
u'{0}{1}: {2}\n'.format(u' ' * 23, req_key, req_val)
|
||||
running[tag] = {u'changes': {},
|
||||
u'result': False,
|
||||
u'comment': comment,
|
||||
u'__run_num__': self.__run_num,
|
||||
u'__sls__': low[u'__sls__']}
|
||||
if low.get('__prereq__'):
|
||||
run_dict = self.pre
|
||||
else:
|
||||
run_dict = running
|
||||
run_dict[tag] = {u'changes': {},
|
||||
u'result': False,
|
||||
u'comment': comment,
|
||||
u'__run_num__': self.__run_num,
|
||||
u'__sls__': low[u'__sls__']}
|
||||
self.__run_num += 1
|
||||
self.event(running[tag], len(chunks), fire_event=low.get(u'fire_event'))
|
||||
self.event(run_dict[tag], len(chunks), fire_event=low.get(u'fire_event'))
|
||||
return running
|
||||
for chunk in reqs:
|
||||
# Check to see if the chunk has been run, only run it if
|
||||
|
|
|
@ -1458,8 +1458,6 @@ def latest(name,
|
|||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True):
|
||||
merge_rev = remote_rev if rev == 'HEAD' \
|
||||
else desired_upstream
|
||||
|
||||
if git_ver >= _LooseVersion('1.8.1.6'):
|
||||
# --ff-only added in version 1.8.1.6. It's not
|
||||
|
@ -1476,7 +1474,7 @@ def latest(name,
|
|||
|
||||
__salt__['git.merge'](
|
||||
target,
|
||||
rev=merge_rev,
|
||||
rev=remote_rev,
|
||||
opts=merge_opts,
|
||||
user=user,
|
||||
password=password)
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
r'''
|
||||
Management of user groups
|
||||
=========================
|
||||
|
||||
The group module is used to create and manage unix group settings, groups
|
||||
can be either present or absent:
|
||||
The group module is used to create and manage group settings, groups can be
|
||||
either present or absent. User/Group names can be passed to the ``adduser``,
|
||||
``deluser``, and ``members`` parameters. ``adduser`` and ``deluser`` can be used
|
||||
together but not with ``members``.
|
||||
|
||||
In Windows, if no domain is specified in the user or group name (ie:
|
||||
`DOMAIN\username``) the module will assume a local user or group.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -36,6 +41,10 @@ import sys
|
|||
# Import 3rd-party libs
|
||||
from salt.ext import six
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils
|
||||
import salt.utils.win_functions
|
||||
|
||||
|
||||
def _changes(name,
|
||||
gid=None,
|
||||
|
@ -50,6 +59,18 @@ def _changes(name,
|
|||
if not lgrp:
|
||||
return False
|
||||
|
||||
# User and Domain names are not case sensitive in Windows. Let's make them
|
||||
# all lower case so we can compare properly
|
||||
if salt.utils.is_windows():
|
||||
if lgrp['members']:
|
||||
lgrp['members'] = [user.lower() for user in lgrp['members']]
|
||||
if members:
|
||||
members = [salt.utils.win_functions.get_sam_name(user) for user in members]
|
||||
if addusers:
|
||||
addusers = [salt.utils.win_functions.get_sam_name(user) for user in addusers]
|
||||
if delusers:
|
||||
delusers = [salt.utils.win_functions.get_sam_name(user) for user in delusers]
|
||||
|
||||
change = {}
|
||||
if gid:
|
||||
if lgrp['gid'] != gid:
|
||||
|
@ -57,7 +78,7 @@ def _changes(name,
|
|||
|
||||
if members:
|
||||
# -- if new member list if different than the current
|
||||
if set(lgrp['members']) ^ set(members):
|
||||
if set(lgrp['members']).symmetric_difference(members):
|
||||
change['members'] = members
|
||||
|
||||
if addusers:
|
||||
|
@ -79,31 +100,58 @@ def present(name,
|
|||
addusers=None,
|
||||
delusers=None,
|
||||
members=None):
|
||||
'''
|
||||
r'''
|
||||
Ensure that a group is present
|
||||
|
||||
name
|
||||
The name of the group to manage
|
||||
Args:
|
||||
|
||||
gid
|
||||
The group id to assign to the named group; if left empty, then the next
|
||||
available group id will be assigned
|
||||
name (str):
|
||||
The name of the group to manage
|
||||
|
||||
system
|
||||
Whether or not the named group is a system group. This is essentially
|
||||
the '-r' option of 'groupadd'.
|
||||
gid (str):
|
||||
The group id to assign to the named group; if left empty, then the
|
||||
next available group id will be assigned. Ignored on Windows
|
||||
|
||||
addusers
|
||||
List of additional users to be added as a group members.
|
||||
system (bool):
|
||||
Whether or not the named group is a system group. This is essentially
|
||||
the '-r' option of 'groupadd'. Ignored on Windows
|
||||
|
||||
delusers
|
||||
Ensure these user are removed from the group membership.
|
||||
addusers (list):
|
||||
List of additional users to be added as a group members. Cannot
|
||||
conflict with names in delusers. Cannot be used in conjunction with
|
||||
members.
|
||||
|
||||
members
|
||||
Replace existing group members with a list of new members.
|
||||
delusers (list):
|
||||
Ensure these user are removed from the group membership. Cannot
|
||||
conflict with names in addusers. Cannot be used in conjunction with
|
||||
members.
|
||||
|
||||
Note: Options 'members' and 'addusers/delusers' are mutually exclusive and
|
||||
can not be used together.
|
||||
members (list):
|
||||
Replace existing group members with a list of new members. Cannot be
|
||||
used in conjunction with addusers or delusers.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Adds DOMAIN\db_admins and Administrators to the local db_admin group
|
||||
# Removes Users
|
||||
db_admin:
|
||||
group.present:
|
||||
- addusers:
|
||||
- DOMAIN\db_admins
|
||||
- Administrators
|
||||
- delusers:
|
||||
- Users
|
||||
|
||||
# Ensures only DOMAIN\domain_admins and the local Administrator are
|
||||
# members of the local Administrators group. All other users are
|
||||
# removed
|
||||
Administrators:
|
||||
group.present:
|
||||
- members:
|
||||
- DOMAIN\domain_admins
|
||||
- Administrator
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
|
@ -233,8 +281,17 @@ def absent(name):
|
|||
'''
|
||||
Ensure that the named group is absent
|
||||
|
||||
name
|
||||
The name of the group to remove
|
||||
Args:
|
||||
name (str):
|
||||
The name of the group to remove
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Removes the local group `db_admin`
|
||||
db_admin:
|
||||
group.absent
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
|
|
|
@ -62,15 +62,15 @@ def is_escaped(url):
|
|||
'''
|
||||
test whether `url` is escaped with `|`
|
||||
'''
|
||||
if salt.utils.platform.is_windows():
|
||||
return False
|
||||
|
||||
scheme = urlparse(url).scheme
|
||||
if not scheme:
|
||||
return url.startswith('|')
|
||||
elif scheme == 'salt':
|
||||
path, saltenv = parse(url)
|
||||
return path.startswith('|')
|
||||
if salt.utils.platform.is_windows() and '|' in url:
|
||||
return path.startswith('_')
|
||||
else:
|
||||
return path.startswith('|')
|
||||
else:
|
||||
return False
|
||||
|
||||
|
@ -102,15 +102,15 @@ def unescape(url):
|
|||
'''
|
||||
remove escape character `|` from `url`
|
||||
'''
|
||||
if salt.utils.platform.is_windows():
|
||||
return url
|
||||
|
||||
scheme = urlparse(url).scheme
|
||||
if not scheme:
|
||||
return url.lstrip('|')
|
||||
elif scheme == 'salt':
|
||||
path, saltenv = parse(url)
|
||||
return create(path.lstrip('|'), saltenv)
|
||||
if salt.utils.platform.is_windows() and '|' in url:
|
||||
return create(path.lstrip('_'), saltenv)
|
||||
else:
|
||||
return create(path.lstrip('|'), saltenv)
|
||||
else:
|
||||
return url
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ Various functions to be used by windows during start up and to monkey patch
|
|||
missing functions in other modules
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
import platform
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
# Import 3rd Party Libs
|
||||
|
@ -138,3 +141,19 @@ def get_current_user():
|
|||
return False
|
||||
|
||||
return user_name
|
||||
|
||||
|
||||
def get_sam_name(username):
|
||||
'''
|
||||
Gets the SAM name for a user. It basically prefixes a username without a
|
||||
backslash with the computer name. If the username contains a backslash, it
|
||||
is returned as is.
|
||||
|
||||
Everything is returned lower case
|
||||
|
||||
i.e. salt.utils.fix_local_user('Administrator') would return 'computername\administrator'
|
||||
'''
|
||||
if '\\' not in username:
|
||||
username = '{0}\\{1}'.format(platform.node(), username)
|
||||
|
||||
return username.lower()
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.unit import TestCase
|
||||
|
@ -13,6 +14,7 @@ from tests.support.unit import TestCase
|
|||
# Import Salt libs
|
||||
import tests.integration as integration
|
||||
import salt.modules.cmdmod
|
||||
import salt.utils
|
||||
|
||||
|
||||
class DocTestCase(TestCase):
|
||||
|
@ -32,8 +34,15 @@ class DocTestCase(TestCase):
|
|||
https://github.com/saltstack/salt/issues/12788
|
||||
'''
|
||||
salt_dir = integration.CODE_DIR
|
||||
salt_dir += '/'
|
||||
cmd = 'grep -r :doc: ' + salt_dir
|
||||
|
||||
if salt.utils.is_windows():
|
||||
# No grep in Windows, use findstr
|
||||
# findstr in windows doesn't prepend 'Binary` to binary files, so
|
||||
# use the '/P' switch to skip files with unprintable characters
|
||||
cmd = 'findstr /C:":doc:" /S /P {0}\\*'.format(salt_dir)
|
||||
else:
|
||||
salt_dir += '/'
|
||||
cmd = 'grep -r :doc: ' + salt_dir
|
||||
|
||||
grep_call = salt.modules.cmdmod.run_stdout(cmd=cmd).split('\n')
|
||||
|
||||
|
@ -43,25 +52,30 @@ class DocTestCase(TestCase):
|
|||
if line.startswith('Binary'):
|
||||
continue
|
||||
|
||||
key, val = line.split(':', 1)
|
||||
if salt.utils.is_windows():
|
||||
# Need the space after the colon so it doesn't split the drive
|
||||
# letter
|
||||
key, val = line.split(': ', 1)
|
||||
else:
|
||||
key, val = line.split(':', 1)
|
||||
|
||||
# Don't test man pages, this file,
|
||||
# the page that documents to not use ":doc:", or
|
||||
# the doc/conf.py file
|
||||
if 'man' in key \
|
||||
or key.endswith('test_doc.py') \
|
||||
or key.endswith('doc/conf.py') \
|
||||
or key.endswith('/conventions/documentation.rst') \
|
||||
or key.endswith('doc/topics/releases/2016.11.2.rst') \
|
||||
or key.endswith('doc/topics/releases/2016.11.3.rst') \
|
||||
or key.endswith('doc/topics/releases/2016.3.5.rst'):
|
||||
or key.endswith(os.sep.join(['doc', 'conf.py'])) \
|
||||
or key.endswith(os.sep.join(['conventions', 'documentation.rst'])) \
|
||||
or key.endswith(os.sep.join(['doc', 'topics', 'releases', '2016.11.2.rst'])) \
|
||||
or key.endswith(os.sep.join(['doc', 'topics', 'releases', '2016.11.3.rst'])) \
|
||||
or key.endswith(os.sep.join(['doc', 'topics', 'releases', '2016.3.5.rst'])):
|
||||
continue
|
||||
|
||||
# Set up test return dict
|
||||
if test_ret.get(key) is None:
|
||||
test_ret[key] = [val.lstrip()]
|
||||
test_ret[key] = [val.strip()]
|
||||
else:
|
||||
test_ret[key].append(val.lstrip())
|
||||
test_ret[key].append(val.strip())
|
||||
|
||||
# Allow test results to show files with :doc: ref, rather than truncating
|
||||
self.maxDiff = None
|
||||
|
|
|
@ -38,6 +38,8 @@ class UrlTestCase(TestCase):
|
|||
'''
|
||||
path = '?funny/path with {interesting|chars}'
|
||||
url = 'salt://' + path
|
||||
if salt.utils.is_windows():
|
||||
path = '_funny/path with {interesting_chars}'
|
||||
|
||||
self.assertEqual(salt.utils.url.parse(url), (path, None))
|
||||
|
||||
|
@ -48,6 +50,8 @@ class UrlTestCase(TestCase):
|
|||
saltenv = 'ambience'
|
||||
path = '?funny/path&with {interesting|chars}'
|
||||
url = 'salt://' + path + '?saltenv=' + saltenv
|
||||
if salt.utils.is_windows():
|
||||
path = '_funny/path&with {interesting_chars}'
|
||||
|
||||
self.assertEqual(salt.utils.url.parse(url), (path, saltenv))
|
||||
|
||||
|
@ -59,6 +63,8 @@ class UrlTestCase(TestCase):
|
|||
'''
|
||||
path = '? interesting/&path.filetype'
|
||||
url = 'salt://' + path
|
||||
if salt.utils.is_windows():
|
||||
url = 'salt://_ interesting/&path.filetype'
|
||||
|
||||
self.assertEqual(salt.utils.url.create(path), url)
|
||||
|
||||
|
@ -68,6 +74,8 @@ class UrlTestCase(TestCase):
|
|||
'''
|
||||
saltenv = 'raumklang'
|
||||
path = '? interesting/&path.filetype'
|
||||
if salt.utils.is_windows():
|
||||
path = '_ interesting/&path.filetype'
|
||||
|
||||
url = 'salt://' + path + '?saltenv=' + saltenv
|
||||
|
||||
|
@ -149,6 +157,8 @@ class UrlTestCase(TestCase):
|
|||
'''
|
||||
path = 'dir/file.conf'
|
||||
escaped_path = '|' + path
|
||||
if salt.utils.is_windows():
|
||||
escaped_path = path
|
||||
|
||||
self.assertEqual(salt.utils.url.escape(path), escaped_path)
|
||||
|
||||
|
@ -167,6 +177,8 @@ class UrlTestCase(TestCase):
|
|||
path = 'dir/file.conf'
|
||||
url = 'salt://' + path
|
||||
escaped_url = 'salt://|' + path
|
||||
if salt.utils.is_windows():
|
||||
escaped_url = url
|
||||
|
||||
self.assertEqual(salt.utils.url.escape(url), escaped_url)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue