#!/bin/bash #------------------------------------------------------------------------------ set -u # This script adds a bunch of users from a users_to_add.csv file of the form: # <user>,<email>,<full_name>[,<group1 group2 group3 ...] # This first line of the uses_to_add.csv file is assumed to be a header and # is always ignored. # Usage: # Set your Perforce contect, login as a super user. # cd /dir/where/this/is # vi users_to_add.csv # ./add_users.sh 2>&1 | tee add_users.$(date +'%Y%m%d-%H%M').log function msg () { echo -e "$*"; } function warnmsg () { msg "\nWarning: ${1:-Unknown Warning}\n" >&2; } function errmsg () { msg "\nError: ${1:-Unknown Error}\n" >&2; } function bail () { errmsg "${1:-Unknown Error}"; exit ${2:-1}; } #------------------------------------------------------------------------------ # add_user_to_group ($user, $group) # # Add one user to one group. #------------------------------------------------------------------------------ function add_user_to_group () { declare user=${1:-Unset} declare group=${2:-Unset} [[ $user == Unset || $group == Unset ]] && return # If both Users and Groups fields are empty, the group does not # exist. if [[ -z "$(p4 -ztag -F %Users0% group -o $group)" ]]; then if [[ -z "$(p4 -ztag -F %Owners0% group -o $group)" ]]; then warnmsg "Skipping add of user [$user] to unknown group [$group]." fi fi msg "Adding user [$user] to group [$group]." p4 group -o $group > $TmpFile2 echo -e "\t$user" >> $TmpFile2 p4 -s group -i < $TmpFile2 } declare Version=1.2.5 declare UserDataFile=users_to_add.csv declare FullName= declare Email= declare User= declare Group= declare AccessGroups declare -i FirstLine=1 declare -i InternalUser declare -i ExistingUser declare -i SkippedUserCount=0 declare -i NewUserCount=0 declare UserCount=0 declare UserLimit=0 declare -i LicensesAvailable=0 declare -i LicensesNeeded=0 declare PasswordFile=$(mktemp) declare TmpFile=$(mktemp) declare TmpFile2=$(mktemp) H1="\n==============================================================================" H2="\n------------------------------------------------------------------------------" msg "Started ${0##*/} v$Version at $(date)." touch $PasswordFile chmod 600 $PasswordFile echo -e "Welcome1\nWelcome1" > $PasswordFile [[ -r $UserDataFile ]] || bail "Missing or unreadable user data file: $UserDataFile." msg "${H1}\nPreflight check." UserCount=$(p4 -ztag -F %userCount% license -u) UserCount=${UserCount%#} UserLimit=$(p4 -ztag -F %userLimit% license -u) [[ -z "$UserCount" || -z "$UserLimit" ]] && bail "Could not determine license info." if [[ "$UserLimit" != unlimited ]]; then LicensesAvailable=$((UserLimit - UserCount)) else LicensesAvailable=9999 fi while read userData; do # Skip the first line (assumed to be a header). if [[ $FirstLine -eq 1 ]]; then FirstLine=0 continue fi # Skip blank lines and comments. [[ -z "$(echo $userData)" ]] && continue [[ "$userData" == "#"* ]] && continue User=$(echo $userData|cut -d ',' -f 1) Email=$(echo $userData|cut -d ',' -f 2) FullName=$(echo $userData|cut -d ',' -f 3) AccessGroups=$(echo $userData|cut -d ',' -f 4) if [[ -n "$(p4 -ztag -F %Access% user -o $User)" ]]; then ExistingUser=1 else ExistingUser=0 fi if [[ $ExistingUser -eq 1 ]]; then msg "Skipping creation of existing user [$User]." SkippedUserCount=$((SkippedUserCount+1)) else NewUserCount=$((NewUserCount+1)) fi done < $UserDataFile msg "\nPreflight Summary: \tNew Users to Create: $NewUserCount \tExisting uses to skip: $SkippedUserCount \tCurrent User Count: $UserCount \tLicensed User Limit: $UserLimit \tLicenses Available: $LicensesAvailable\n\n" if [[ "$NewUserCount" -le "$LicensesAvailable" ]]; then msg "Verified: Enough seats are available to create new users." else LicensesNeeded=$((NewUserCount - LicensesAvailable)) bail "There are not enough licenses available! Contact sales@perforce.com and order at least $LicensesNeeded more licenses, or else remove $LicensesNeeded or more inactive users.\n" fi msg "${H1}\nAdding $NewUserCount users." FirstLine=1 SkippedUserCount=0 NewUserCount=0 while read userData; do # Skip the first line (assumed to be a header). if [[ $FirstLine -eq 1 ]]; then FirstLine=0 continue fi # Skip blank lines and comments. [[ -z "$(echo $userData)" ]] && continue [[ "$userData" == "#"* ]] && continue User=$(echo $userData|cut -d ',' -f 1) Email=$(echo $userData|cut -d ',' -f 2) FullName=$(echo $userData|cut -d ',' -f 3) AccessGroups=$(echo $userData|cut -d ',' -f 4) if [[ -n "$(p4 -ztag -F %Access% user -o $User)" ]]; then ExistingUser=1 else ExistingUser=0 fi if [[ $ExistingUser -eq 1 ]]; then msg "Skipping creation of existing user [$User]." SkippedUserCount=$((SkippedUserCount+1)) else NewUserCount=$((NewUserCount+1)) echo -e "User: $User\n\nEmail: $Email\n\nFullName: $FullName\n\n" > $TmpFile msg "Creating user $User" p4 -s user -f -i < $TmpFile ||\ bail "Could not create user $User with this spec:\n$(cat $TmpFile)\n" msg "Setting Password for user $User." p4 -s passwd $User < $PasswordFile ||\ bail "Failed to set password for user $User." ### Commented out sample call to 'p4 admin resetpassword'; this only ### applies when there is no LDAP, no MFA, and no external auth trigger. #msg "Doing 'p4 admin resetpassword -u $User' to require password reset." #p4 admin resetpassword -u $User if [[ -n "$AccessGroups" ]]; then for Group in $AccessGroups; do add_user_to_group "$User" "$Group" done fi fi done < $UserDataFile msg "\nAccount Creation Summary:\n\tCreated $NewUserCount new users.\n\tSkipped $SkippedUserCount existing users.\n"
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#4 | 26652 | Robert Cowham |
This is Tom's change: Introduced new 'Unsupported' directory to clarify that some files in the SDP are not officially supported. These files are samples for illustration, to provide examples, or are deprecated but not yet ready for removal from the package. The Maintenance and many SDP triggers have been moved under here, along with other SDP scripts and triggers. Added comments to p4_vars indicating that it should not be edited directly. Added reference to an optional site_global_vars file that, if it exists, will be sourced to provide global user settings without needing to edit p4_vars. As an exception to the refactoring, the totalusers.py Maintenance script will be moved to indicate that it is supported. Removed settings to support long-sunset P4Web from supported structure. Structure under new .../Unsupported folder is: Samples/bin Sample scripts. Samples/triggers Sample trigger scripts. Samples/triggers/tests Sample trigger script tests. Samples/broker Sample broker filter scripts. Deprecated/triggers Deprecated triggers. To Do in a subsequent change: Make corresponding doc changes. |
||
#3 | 23911 | C. Thomas Tyler |
For add_user.sh, uses reset_password only if needed, based on AuthMethod. Cleans up generated password file. |
||
#2 | 23906 | C. Thomas Tyler |
Fixed a typo. Thanks for @rmarin for spotting the typo! Also commented out sample call to 'p4 admin resetpassword'; mostly sites authenticate off some other identity management system, rather than storing passwords in Perforce. #review-23907 @rmarin |
||
#1 | 23616 | C. Thomas Tyler |
Add add_users.sh. Thanks for @rmarin for spotting the typo! #review @rmarin |