Skip to content

Instantly share code, notes, and snippets.

@shamasis
Last active April 9, 2025 08:23
Show Gist options
  • Save shamasis/20b721a01c0a7618007918e3db3d6b35 to your computer and use it in GitHub Desktop.
Save shamasis/20b721a01c0a7618007918e3db3d6b35 to your computer and use it in GitHub Desktop.
Postman Insights Agent Installation Script. (Experimental)
#!/usr/bin/env bash
# 3-Clause BSD License
#
# Copyright (c) 2009, Boxed Ice <[email protected]>
# Copyright (c) 2010-2016, Datadog <[email protected]>
# Copyright (c) 2020-present, Postman, Inc. <[email protected]>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Portions of this script are adapted from
# https://github.com/DataDog/dd-agent/blob/master/packaging/datadog-agent/source/install_agent.sh
set -eo pipefail
# ANSI colours
ansiRed="$(echo -e '\033[31m')"
ansiBlue="$(echo -e '\033[34m')"
ansiNorm="$(echo -e '\033[0m')"
function on_error() {
cat <<EOF
${ansiRed}ERROR${errorMessage}
*****
It looks like you hit an issue when trying to install the Postman Insights
Agent. Documentation is available at:
https://learning.postman.com/docs/insights/insights-early-access/
If you are still having problems, please send an email to
[email protected].
${ansiNorm}
EOF
}
trap on_error ERR
# Retries a command some number of times, waiting between each attempt.
#
# Usage: retry numAttempts delayInSecs explanation cmd...
function retry() {
local numAttempts="$1"
shift
local delayInSecs="$1"
shift
local explanation="$1"
shift
for (( count=0; count<numAttempts; count++ )); do
if [[ ${count} -ne 0 ]]; then
cat >&2 <<EOF
${explanation}
Will retry in ${delayInSecs} seconds...
EOF
sleep "${delayInSecs}"
fi
if "$@"; then
return 0
fi
echo 'Failed' >&2
done
return 1
}
# Checks that a set of commands is available on the system. If any commands are
# missing, a message is printed with a list of missing commands, and the script
# exits with an error.
#
# Usage: requireCommands cmd1 cmd2 ...
function requireCommands() {
notFound=()
for cmd in "$@"; do
if ! command -v "${cmd}" >/dev/null; then
notFound+=("${cmd}")
fi
done
if [[ ${#notFound[@]} -gt 0 ]]; then
cat >&2 <<EOF
${ansiRed}ERROR
This script requires the following commands, but they were not found on your
system. Please ensure they are installed and in your \$PATH.
${ansiNorm}
EOF
for cmd in "${notFound[@]}"; do
echo " * ${cmd}" >&2
done
echo
exit 1
fi
}
# Usage: status 'status message'
function status() {
cat <<EOF
${ansiBlue}
* $1
${ansiNorm}
EOF
}
# Parses JSON response to find the download URL for the specified architecture
# "*_linux_<arch>_static.zip" from a JSON file.
# Parameters:
# $1 - path to the JSON file (e.g. /tmp/postman-insights-release.json)
# $2 - architecture string (e.g. "amd64" or "arm64")
function parseDownloadUrl() {
local json_file="$1"
local arch="$2"
local pattern="_linux_${arch}_static.zip"
# Flatten the JSON and extract the assets array just to make it easier to work with
local flattened_json=$(tr -d '\n' < "$json_file")
# Extract the assets array using response pattern
# This pattern looks for the assets array and captures everything until the matching ]
local assets_array=$(echo "$flattened_json" | sed -n 's/.*"assets":\[\([^]]*\)\].*/\1/p')
# Split the assets array into individual items
# @devnote Using a method that handles nested objects
local items=$(echo "$assets_array" | sed 's/},{/}\n{/g')
# Process each item
while IFS= read -r item; do
# Extract the browser_download_url
local url=$(echo "$item" | sed -n 's/.*"browser_download_url":"\([^"]*\)".*/\1/p')
# Check if URL matches our pattern
if [[ "$url" == *"$pattern" ]]; then
echo "$url"
return 0
fi
done <<< "$items"
return 1
}
# Downloads the latest agent binary
function downloadAgent() {
# Create temporary files
local release_json=$(mktemp)
local agent_zip=$(mktemp)
# Ensure cleanup of temporary files
# @devnote
# Since traps in bash are global, the trap set within the function applies to the entire script.
# This is acceptable if (and only if) we call downloadAgent just once per execution. If you might call downloadAgent multiple times, we
# should be sure that subsequent calls won't inadvertently overwrite earlier temporary file paths or that we update the trap accordingly.
trap 'rm -f "$release_json" "$agent_zip"' EXIT
status 'Finding the latest download URL'
errorMessage='
Failed to find the URL for the latest Postman Insights Agent binary.
See the logs above to determine the cause. If the cause is unclear, please
contact support at [email protected].
'
# Use wget to download the JSON file and capture the HTTP status code
wget_output=$(wget -q --server-response -O "$release_json" https://api.github.com/repos/postmanlabs/postman-insights-agent/releases/latest 2>&1)
http_code=$(echo "$wget_output" | grep "HTTP/" | tail -n1 | awk '{print $2}')
# Check if the request was successful
if [ "$http_code" -ne 200 ]; then
errorMessage='
Failed to fetch the latest release information from GitHub. Please try again later. Response code: '"$http_code"
return 1
fi
# Extract the download URL for the latest release
url=$(parseDownloadUrl "$(cat "$release_json")" "${arch}")
# Check if the URL was found
if [ -z "${url}" ]; then
errorMessage='
Failed to find the URL for the latest Postman Insights Agent binary.
See the logs above to determine the cause. If the cause is unclear, please
contact support at [email protected].
'
return 1
fi
status 'Downloading the Postman Insights Agent binary'
errorMessage='
Failed to download the latest Postman Insights Agent binary. See the logs above
to determine the cause. If the cause is unclear, please contact support at
[email protected].
'
retry 5 10 \
"Downloads from GitHub are sometimes unreliable" \
wget -q -O "$agent_zip" "${url}"
# Return the path to the downloaded file
echo "$agent_zip"
}
# Installs the downloaded agent binary
function installAgent() {
local agent_zip="$1"
status 'Unpacking the Postman Insights Agent binary'
errorMessage='
Failed to unpack the Postman Insights Agent binary. See the logs above
to determine the cause. If the cause is unclear, please contact support at
[email protected].
'
${sudo} unzip "$agent_zip" -d /usr/local/bin
status 'Setting permissions on Postman Insights Agent binary'
errorMessage=''
# If we have setcap installed, try setting cap_net_raw and cap_setgid,
# which allows us to install our binaries without the setuid bit.
program='/usr/local/bin/postman-insights-agent'
${sudo} chown root:root ${program}
if command -v setcap > /dev/null; then
${sudo} chmod u=rwx,g=rx,o=rx ${program}
if ! setcap cap_net_raw,cap_setgid=eip ${program}; then
echo 'Falling back to setuid instead of setcap' >&2
${sudo} chmod u+s ${program}
fi
else
echo "Setcap is not installed, falling back to setuid" >&2
${sudo} chmod u=rwxs,g=rx,o=rx ${program}
fi
status "Postman Insights Agent installed as ${program}"
errorMessage=''
}
# Installs via Homebrew.
function macOsInstall() {
requireCommands brew
status 'Installing Postman Insights Agent via Homebrew'
errorMessage='
Failed to install the Postman Insights Agent package via Homebrew. See the logs
above to determine the cause. If the cause is unclear, please contact support
at [email protected].
'
brew tap postmanlabs/postman-insights-agent
brew install postman-insights-agent
errorMessage=''
}
# Installs dependencies via our APT package repository and then install agent directly from APT.
# Currently only supports amd64.
function debianInstall() {
requireCommands apt-get
status 'Installing prerequisite utilities'
${sudo} apt-get update \
|| echo "${ansiRed}'apt-get update' failed. The script will not install the latest version of its prerequisites.${ansiNorm}"
${sudo} apt-get install -y apt-transport-https wget gnupg
status 'Installing APT package sources for Postman Insights Agent'
${sudo} sh -c "echo 'deb [arch=amd64] https://apt.releases.observability.postman.com/ stable main' > /etc/apt/sources.list.d/postman-insights-agent.list"
wget -qO- https://releases.observability.postman.com/keys/postman-insights-agent-apt.pub.gpg | ${sudo} apt-key add -
status 'Installing the Postman Insights Agent package'
errorMessage='
Failed to update the sources after adding the Postman Insights Agent
repository. This may be due to any of the configured APT sources failing. See
the logs above to determine the cause. If the failing repository is Postman or
if the cause is unclear, please contact support at
[email protected].
'
${sudo} apt-get update \
-o Dir::Etc::sourcelist=sources.list.d/postman-insights-agent.list \
-o Dir::Etc::sourceparts=- \
-o APT::Get::List-Cleanup=0
errorMessage='
Failed to install the Postman Insights Agent package. Sometimes, it may
be due to another APT source failing. See the logs above to determine the
cause. If the cause is unclear, please contact support at
[email protected].
'
${sudo} apt-get install -y postman-insights-agent
errorMessage=''
}
# Installs dependencies via YUM package manager for RHEL-based distributions
# (Amazon Linux, RHEL, CentOS)
function rhelBasedInstall() {
requireCommands yum
status 'Installing prerequisite utilities'
${sudo} yum update -y
${sudo} yum install -y wget unzip
local agent_zip=$(downloadAgent)
installAgent "$agent_zip"
}
# Installs dependencies via Alpine package manager
function alpineInstall() {
requireCommands apk
status 'Installing prerequisite utilities'
${sudo} apk update
${sudo} apk add --no-cache wget gnupg unzip
local agent_zip=$(downloadAgent)
installAgent "$agent_zip"
}
# Installs dependencies via binary download from GitHub.
function otherLinuxInstall() {
requireCommands wget unzip
local agent_zip=$(downloadAgent)
installAgent "$agent_zip"
}
# Detect platform architecture. Currently we only support amd64/x86-64 and
# arm64.
unameM=$(uname -m)
case "${unameM}" in
i686|i386|x86)
arch="x86"
cat >&2 <<EOF
${ansiRed}ERROR
${unameM} not supported. Please run on an amd64 platform.
*****
${ansiNorm}
EOF
exit 1
;;
aarch64|arm64)
arch="arm64"
;;
*)
arch="amd64"
;;
esac
# Detect macOS / Linux distribution.
knownDistribution='(Debian|Ubuntu|RedHat|CentOS|Amazon|Alpine)'
distribution="$(\
lsb_release -d 2>/dev/null | grep -Eo "${knownDistribution}" \
|| grep -Eo "${knownDistribution}" /etc/issue 2>/dev/null \
|| grep -Eo "${knownDistribution}" /etc/Eos-release 2>/dev/null \
|| grep -m1 -Eo "${knownDistribution}" /etc/os-release 2>/dev/null \
|| uname -s \
)"
if [[ "${distribution}" == 'Darwin' ]]; then
os='macOS'
elif command -v apt-get >/dev/null \
|| [[ -f /etc/debian_version \
|| "${distribution}" == 'Debian' \
|| "${distribution}" == 'Ubuntu' ]]; then
os='Debian'
elif [[ -f /etc/redhat-release \
|| -f /etc/system-release \
|| "${distribution}" == 'RedHat' \
|| "${distribution}" == 'CentOS' \
|| "${distribution}" == 'Amazon' ]]; then
os='RedHat'
elif [[ -f /etc/alpine-release \
|| "${distribution}" == 'Alpine' ]]; then
os='Alpine'
else
os='unknown'
fi
# Root user detection
if [ "$(echo "$UID")" = "0" ]; then
sudo=''
else
sudo='sudo'
fi
case "${os}:${arch}" in
macOS:*) macOsInstall ;;
Debian:amd64) debianInstall ;;
Alpine:*) alpineInstall ;;
Amazon:*) rhelBasedInstall ;;
RedHat:*) rhelBasedInstall ;;
CentOS:*) rhelBasedInstall ;;
*:*) otherLinuxInstall ;;
esac
# Metrics are submitted, echo some instructions and exit
printf "\033[32m
You have successfully installed the Postman Insights Agent!
For more information on how to start capturing API traffic and
create an endpoint collection, see the Insights docs at:
https://learning.postman.com/docs/insights/insights-gs/
\033[0m"
# #Changelog
# ==========
# - removed curl and jq dependency
# - added dedicated alpine support
# - wider shebang
# - added RedHat CentOS and Amazon support
# - consolidated up Agent Binary download & install code (+ cleanup of downloaded files)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment