Last active
April 9, 2025 08:23
-
-
Save shamasis/20b721a01c0a7618007918e3db3d6b35 to your computer and use it in GitHub Desktop.
Postman Insights Agent Installation Script. (Experimental)
This file contains hidden or 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
#!/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