A script to sync an on-premise distribution from your JCDS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/zsh | |
## Bits shamelessly borrowed from Graham Pugh - https://gist.github.com/grahampugh/836547859c18fefe1dba6ba8c093accc | |
## Then reversed to only pull down files which either do not exist in the DP or whose md5 doesn't match | |
## | |
## This script relies on a Jamf API role/client and a local identity file of the following format: | |
## {"client_name":"test_for_screenshot","client_id":"a7682e67-a276-448b-83af-9c83be5e02f4","client_secret":"ubPrXqRRyc0jRLFOY9iJYGpCjHiJc1M-tRLlCFb9aWZhtqf7iC9UpQG_dO1ZkvNF","grant_type":"client_credentials"} | |
## | |
## This is most easily obtained by creating an api client, enabling it and copying the data from the popup, then pasting it into a file | |
## | |
## | |
usage() { | |
echo "Usage: sync_jcds_local_dp.zsh --id /path/to/identity_file --jss your.jamf.server --localpath /path/to/dp/share --log /path/to/log/file" | |
echo "(don't include https:// but do include the port if needed)" | |
} | |
logStatement(){ | |
# Function to log informational output for review | |
echo "$(date) - $1" >> "$logFile" | |
} | |
## Borrowed from https://gist.github.com/lucasad/6474224 | |
urlencode() { | |
setopt localoptions extendedglob | |
input=( ${(s::)1} ) | |
print ${(j::)input/(#b)([^A-Za-z0-9_.\!~*\'\(\)-])/%${(l:2::0:)$(([##16]#match))}} | |
} | |
getToken() { | |
client_id=$(plutil -extract client_id raw "$identity_file") | |
client_secret=$(plutil -extract client_secret raw "$identity_file") | |
cred_type=$(plutil -extract grant_type raw "$identity_file") | |
token=$(curl --silent --location --request POST "${jss_url}/api/oauth/token" \ | |
--header "Content-Type: application/x-www-form-urlencoded" \ | |
--data-urlencode "client_id=${client_id}" \ | |
--data-urlencode "grant_type=${cred_type}" \ | |
--data-urlencode "client_secret=${client_secret}" \ | |
| plutil -extract access_token raw -) | |
# echo "$token" | |
} | |
getPackageList(){ | |
# list all the packages | |
echo "Getting a list of packages from JCDS" | |
logStatement "Getting a list of packages from JCDS" | |
getToken | |
http_response=$( | |
curl --request GET \ | |
--silent \ | |
--header "authorization: Bearer $token" \ | |
--header 'Accept: application/json' \ | |
"$jss_url/api/v1/jcds/files" \ | |
--write-out "%{http_code}" \ | |
--output "$output_file_list" | |
) | |
logStatement "Package List response code: $http_response" | |
# echo "HTTP response: $http_response" | |
} | |
syncPackages(){ | |
if [[ $http_response -eq 200 ]]; then | |
# convert the list to a plist so we can actually work with it in bash | |
plutil -convert xml1 "$output_file_list" | |
# count the number of items in the list | |
pkg_count=$(grep -c fileName "$output_file_list") | |
# loop through each item in the JSON response | |
jcds_pkg="" | |
jcds_pkg_md5="" # assign empty value to avoid errors | |
local_pkg="" | |
local_pkg_md5="" | |
echo "Looping through $pkg_count files" | |
for ((i=1; i<=pkg_count; i++)); do | |
jcds_pkg=$(/usr/libexec/PlistBuddy -c "Print :$i:fileName" "$output_file_list") | |
jcds_pkg_md5=$(/usr/libexec/PlistBuddy -c "Print :$i:md5" "$output_file_list") | |
local_pkg="${rsync_path}/${jcds_pkg}" | |
if [ -f "${local_pkg}" ]; then | |
local_pkg_md5=$(md5 -q "${local_pkg}") | |
fi | |
if [[ "$local_pkg_md5" == "$jcds_pkg_md5" ]]; then | |
echo "$jcds_pkg is the same" | |
logStatement "$jcds_pkg is the same" | |
else | |
getToken | |
# urlencode package names for paces | |
download_pkg=$(urlencode "$jcds_pkg") | |
# retrieve the download URL from the API endpoint | |
get_download_url=$(curl --request GET \ | |
--silent \ | |
--location \ | |
--header "authorization: Bearer $token" \ | |
--header 'Accept: application/json' \ | |
"$jss_url/api/v1/jcds/files/${download_pkg}" ) | |
download_url=$(echo "$get_download_url" | plutil -extract uri raw -) | |
# Get the file, please | |
echo "Downloading $jcds_pkg ..." | |
logStatement "Downloading $jcds_pkg ..." | |
curl "${download_url}" -o "${rsync_path}/${jcds_pkg}" | |
fi | |
done | |
fi | |
} | |
while test $# -gt 0 ; do | |
case "$1" in | |
-i|--id) | |
shift | |
identity_file="$1" | |
;; | |
--localpath) | |
shift | |
rsync_path="$1" | |
;; | |
--log) | |
shift | |
logFile="$1" | |
;; | |
--jss) | |
shift | |
jss="$1" | |
;; | |
*) | |
usage | |
exit | |
;; | |
esac | |
shift | |
done | |
if [[ ! "$identity_file" || ! "$rsync_path" ]]; then | |
usage | |
exit | |
fi | |
jss_url="https://${jss}" | |
output_file_list="/tmp/jcds.txt" | |
getPackageList | |
syncPackages |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment