@@ -256,14 +256,14 @@ return_mac_architecture() {
256256# - $1: version of jq to install (optional, defaults to latest). Example format of valid version is "1.8.1".
257257# - $2: location to install jq to (optional, defaults to /usr/local/bin)
258258# - $3: if set to true, skips installation if jq is already detected (optional, defaults to true)
259- # - $4: the exact url to download jq from (optional, defaults to https://github.com/jqlang/jq/releases/latest/download/jq-${os}-${ arch} )
259+ # - $4: the exact url to download jq from (optional, defaults to https://github.com/jqlang/jq/releases/latest/download/jq-<os>-< arch> )
260260#
261261# RETURNS:
262262# 0 - Success (jq installation successful)
263263# 1 - Failure (jq installation failed)
264264# 2 - Failure (incorrect usage of function)
265265#
266- # USAGE: install_jq "latest" "/usr/local/bin" "true"
266+ # USAGE: install_jq "latest" "/usr/local/bin" "true" "https://github.com/jqlang/jq/releases/latest/download/jq-<os>-<arch>"
267267# ===============================================================
268268install_jq () {
269269
@@ -352,6 +352,107 @@ install_jq() {
352352 return ${RETURN_CODE_SUCCESS}
353353}
354354
355+ # ===============================================================
356+ # FUNCTION: install_kubectl
357+ # DESCRIPTION: Installs kubectl binary
358+ #
359+ # ENVIRONMENT VARIABLES:
360+ # - VERBOSE: If set to true, print verbose output (optional, defaults to false)
361+ #
362+ # ARGUMENTS:
363+ # - $1: version of kubectl to install (optional, defaults to current latest stable). Example format of valid version is "v1.34.2".
364+ # - $2: location to install kubectl to (optional, defaults to /usr/local/bin)
365+ # - $3: if set to true, skips installation of kubectl if already detected (optional, defaults to true)
366+ # - $4: the exact url to download kubectl from (optional, defaults to https://dl.k8s.io/release/<version>/bin/<os>/<arch>/kubectl)
367+ #
368+ # RETURNS:
369+ # 0 - Success (kubectl installation successful)
370+ # 1 - Failure (kubectl installation failed)
371+ # 2 - Failure (incorrect usage of function)
372+ #
373+ # USAGE: kubectl "latest" "/usr/local/bin" "true" "https://dl.k8s.io/release/<version>/bin/<os>/<arch>/kubectl"
374+ # ===============================================================
375+ install_kubectl () {
376+
377+ local version=${1:- " latest" }
378+ local location=${2:- " /usr/local/bin" }
379+ local skip_if_detected=${3:- " true" }
380+ local link_to_binary=${4:- " " }
381+ local verbose=${VERBOSE:- false}
382+
383+ # Validate $3 arg is boolean
384+ if ! is_boolean " ${skip_if_detected} " ; then
385+ echo " Unsupported value detected for the 3rd argument. Only 'true' or 'false' is supported. Found: ${skip_if_detected} ." >&2
386+ return ${RETURN_CODE_ERROR_INCORRECT_USAGE}
387+ fi
388+
389+ # return 0 if kubectl already installed and skip_if_detected is true
390+ if [ " ${skip_if_detected} " == " true" ]; then
391+ if check_required_bins kubectl; then
392+ if [ " ${verbose} " = true ]; then
393+ echo " Found kubectl already installed. Taking no action."
394+ fi
395+ return ${RETURN_CODE_SUCCESS}
396+ fi
397+ fi
398+ # ensure curl is installed
399+ check_required_bins curl || return $?
400+ # if no link to binary passed, determine the download link based on detected os and arch
401+ if [ -z " ${link_to_binary} " ]; then
402+ # determine the OS and architecture
403+ local os=" linux"
404+ local arch=" amd64"
405+ if [[ ${OSTYPE} == ' darwin' * ]]; then
406+ arch=$( return_mac_architecture)
407+ fi
408+ # determine download link to binary
409+ link_to_binary=" https://dl.k8s.io/release/${version} /bin/${os} /${arch} /kubectl"
410+ if [ " ${version} " = " latest" ]; then
411+ link_to_binary=" https://dl.k8s.io/release/$( curl -L -s https://dl.k8s.io/release/stable.txt) /bin/${os} /${arch} /kubectl"
412+ fi
413+ fi
414+ if [ " ${verbose} " = true ]; then
415+ echo " Using download link: ${link_to_binary} "
416+ fi
417+
418+ # use sudo if needed
419+ local arg=" "
420+ if ! [ -w " ${location} " ]; then
421+ echo " No write permission to ${location} . Using sudo..."
422+ arg=sudo
423+ fi
424+
425+ # remove if already exists
426+ ${arg} rm -f " ${location} /kubectl"
427+
428+ # download binary
429+ set +e
430+ if ! ${arg} curl --silent \
431+ --connect-timeout 5 \
432+ --max-time 10 \
433+ --retry 3 \
434+ --retry-delay 2 \
435+ --retry-connrefused \
436+ --fail \
437+ --show-error \
438+ --location \
439+ --output " ${location} /kubectl" \
440+ " ${link_to_binary} "
441+ then
442+ echo " Failed to download ${link_to_binary} "
443+ return ${RETURN_CODE_ERROR}
444+ fi
445+ set -e
446+
447+ # make executable
448+ ${arg} chmod +x " ${location} /kubectl"
449+
450+ if [ " ${verbose} " = true ]; then
451+ echo " Successfully completed installation to ${location} /kubectl"
452+ fi
453+ return ${RETURN_CODE_SUCCESS}
454+ }
455+
355456# ===============================================================
356457# UNIT TESTS
357458# ===============================================================
@@ -441,6 +542,37 @@ _test() {
441542 printf " %s\n\n" " ✅ PASS"
442543 fi
443544
545+ # install_kubectl
546+ # -----------------------------------
547+ if [ " ${make_api_calls} " = true ]; then
548+ # Check if kubectl already exists on $PATH
549+ local kubectl_installed=true
550+ check_required_bins kubectl || kubectl_installed=false
551+
552+ # - Test installing kubectl using defaults (when it does not already exist)
553+ if [ ${kubectl_installed} = false ]; then
554+ printf " %s\n" " Running 'install_kubectl' (when kubectl does not already exists)"
555+ rc=${RETURN_CODE_SUCCESS}
556+ install_kubectl > /dev/null 2>&1 || rc=$?
557+ assert_pass " ${rc} "
558+ printf " %s\n\n" " ✅ PASS"
559+ fi
560+
561+ # - Test installing it when kubectl already exists with default args (should be skipped)
562+ printf " %s\n" " Running 'install_kubectl' (when kubectl already exists - install will be skipped)"
563+ rc=${RETURN_CODE_SUCCESS}
564+ install_kubectl > /dev/null 2>&1 || rc=$?
565+ assert_pass " ${rc} "
566+ printf " %s\n\n" " ✅ PASS"
567+
568+ # - Test installing exact version to /tmp even if kubectl already detected on $PATH
569+ printf " %s\n" " Running 'install_kubectl v1.34.2 /tmp false'"
570+ rc=${RETURN_CODE_SUCCESS}
571+ install_kubectl " v1.34.2" " /tmp" " false" > /dev/null 2>&1 || rc=$?
572+ assert_pass " ${rc} "
573+ printf " %s\n\n" " ✅ PASS"
574+ fi
575+
444576 # -----------------------------------
445577 echo " ✅ All tests passed!"
446578}
0 commit comments