Skip to content

Commit

Permalink
IOPZ-1445 Make create-k8s-chained-sessions.sh idempotent
Browse files Browse the repository at this point in the history
This commit makes the `create-k8s-chained-sessions.sh` script
idempotent (it no longer breaks or behaves weirdly if some or
all chained sessions already exist). In addition, it tidies up
some aspects of the script, removes unnecessary output, and
makes improvements so the script now passes the ShellCheck linter.

fixed a bug in leapp filtering now that there are multiple sso sessions
with the same name per account.  Also updated the script to create
chained sessions for each of the k8s developer "profiles" we have i.e.
"reader", "writer", and "admin" depending on what base sso roles the
user has.

fixed bugs in profile lookup.
Removed integration env

refactored profile creation

cleaned up log output
  • Loading branch information
JacobEvelyn authored and Pat-Ayres committed Dec 14, 2023
1 parent 2bcfa4e commit d39a6ec
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 36 deletions.
98 changes: 63 additions & 35 deletions create-k8s-chained-sessions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,94 @@
# This script takes no arguments.
# Execute this script after doing your initial setup to automatically generate
# the sessions necessary for working with kubectl.
# Do not run this script more than once without resetting your Leapp
# instance beforehand.

. ./utils.sh

# global variables
declare PROFILE_ID
declare CHAINED_SESSION_IDS="name,id\n"
declare REGION='us-east-1'

###### FUNCTIONS ######
#
# function to create a chained leapp session given a parent session id
# Args:
# 1: parent session id name from leapp
# appends new session id from the new chained session to CHAINED_SESSION_IDS
# 2: sso role name to use for the parent session
# 3: role name to use for the chained session
function createLeappSession {
green_echo "creating chained session for $1 with role $3"
parent_session_name=$1
chained_session_name="chained-from-${parent_session_name}"
echo "starting session for ${parent_session_name} to get role arn"
# this has funky piping because `--filter` is a fuzzy lookup and `panorama-k8s-playground` fuzzy matches `panorama-k8s-playground-2` as the first result
parent_session_id=$(leapp session list -x --filter="Session Name=${parent_session_name}" --no-header | sort -k2 | sed -n 1p | awk '{print $1}')
# start leapp session
leapp session start --sessionId $parent_session_id
# call to aws to get the role arn for `TerraformRole`
role_arn=$(aws iam get-role --role-name TerraformRole --query Role.Arn | tr -d '"')
# stop the leapp session
leapp session stop --sessionId $parent_session_id
parent_role_name=$2
chained_role_name=$3
# check if the parent session exists for the role. We do this because
# regular developers won't have the AWSAdministratorAccess role, so we
# don't want to create a chained session for them.
parent_session_id=$(leappSessionId "$parent_session_name" "$parent_role_name")
if [[ -z "${parent_session_id}" ]]; then
green_echo " No parent session found for ${parent_session_name} with role ${parent_role_name}"
return
fi

chained_session_name="${parent_session_name}-${chained_role_name}"

green_echo " looking for existing session ${chained_session_name}"
chained_session_id=$(leappSessionId "$chained_session_name" "$chained_role_name")

if [[ -z "${chained_session_id}" ]]; then
green_echo " no existing session found; starting session for ${parent_session_name} to get role arn"

# use the parent session to get the role arn
# so we don't have to hard-code account ids
leapp session start --sessionId "$parent_session_id" > /dev/null 2> >(logStdErr)
role_arn=$(aws iam get-role --role-name "$chained_role_name" --query Role.Arn | tr -d '"')
leapp session stop --sessionId "$parent_session_id" > /dev/null 2> >(logStdErr)

# create a named profile per account so they can be used simultaneously
echo "creating new profile"
createLeappProfile $parent_session_name
green_echo " creating new profile"
profile_id=$(createLeappProfile "$parent_session_name")

echo "creating new session"
# create new chained leapp session from parent
leapp session add --providerType aws --sessionType awsIamRoleChained \
--sessionName $chained_session_name --region $REGION \
--roleArn $role_arn --parentSessionId $parent_session_id \
--profileId $PROFILE_ID
# add session id from the new session to CHAINED_SESSION_IDS
chained_session_id=$(leapp session list --columns=ID --filter="Session Name=${chained_session_name}" --no-header)
CHAINED_SESSION_IDS="${CHAINED_SESSION_IDS}${chained_session_name},${chained_session_id}\n"
green_echo " creating new session"
leapp session add --providerType aws --sessionType awsIamRoleChained \
--sessionName "$chained_session_name" --region "$REGION" \
--roleArn "$role_arn" --parentSessionId "$parent_session_id" \
--profileId "$profile_id" > /dev/null 2> >(logStdErr)

else
yellow_echo " existing session found"
fi
}

# @return the Leapp session ID of the session whose name is the first argument
# to this function, if one exists.
function leappSessionId {
# The ^ and $ in the session filter are regex anchors to ensure we don't
# match e.g. both `chained-from-panorama-k8s-playground` and
# `chained-from-panorama-k8s-playground-2`.
leapp session list -x --filter="Session Name=^${1}$" --output json | jq -r ".[] | select(.role==\"${2}\") | .id"
}

# function to create a leapp profile to associate with the chained k8s sessions
# stores the new profile id in PROFILE_ID
function createLeappProfile {
# The ^ and $ in the session filter are regex anchors to ensure we don't
# match e.g. both `kubectl-access-role-panorama-k8s-playground` and
# `kubectl-access-role-panorama-k8s-playground-2`.
profile_name="kubectl-access-role-${1}"
leapp profile create --profileName $profile_name
PROFILE_ID=$(leapp profile list --columns=ID --filter="Profile Name=${profile_name}" --no-header)
profile_id=$(leapp profile list -x --output json --filter="Profile Name=^${profile_name}$" | jq -r '.[].id')
if [[ -n "${profile_id}" ]]; then
echo "${profile_id}"
return
fi
leapp profile create --profileName "$profile_name" > /dev/null 2> >(logStdErr)
leapp profile list -x --output json --filter="Profile Name=^${profile_name}$" | jq -r '.[].id'
}
#
###### END FUNCTIONS ######

echo "Creating Leapp Chained k8s sessions for k8s accounts"
# session names from Leapp for each k8s account
PARENT_SESSION_NAMES="panorama-k8s-playground panorama-k8s-playground-2 panorama-k8s-integration panorama-k8s-staging panorama-k8s-production"
PARENT_SESSION_NAMES="panorama-k8s-playground panorama-k8s-playground-2 panorama-k8s-staging panorama-k8s-production"

for session in $PARENT_SESSION_NAMES
do
createLeappSession $session
createLeappSession "$session" "AWSAdministratorAccess" "eks-admin-1.24"
createLeappSession "$session" "PanoramaK8sEngineeringDefault" "panorama-dev-writer-1.24"
createLeappSession "$session" "PanoramaK8sEngineeringDefault" "panorama-dev-reader-1.24"
done

echo "all sessions created. store IDs for future use:"
echo -e $CHAINED_SESSION_IDS
2 changes: 1 addition & 1 deletion setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
MIN_OS_VERSION="12.4.0"
CURRENT_OS_VERSION=$(sw_vers -productVersion)

red_echo () { echo -ne "\033[1;31m"; echo -n "$@"; echo -e "\033[0m"; }
. ./utils.sh

# use version sorting to check if the current version is less than $MIN_OS_VERSION
if [[ $MIN_OS_VERSION != "$(printf "$MIN_OS_VERSION\n$CURRENT_OS_VERSION" | sort -V | sed -n 1p)" ]]; then
Expand Down
17 changes: 17 additions & 0 deletions utils.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# A collection of utility functions to be sourced by other scripts

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

red_echo () { echo -e "${RED}$*${NC}"; }
green_echo () { echo -e "${GREEN}$*${NC}"; }
yellow_echo () { echo -e "${YELLOW}$*${NC}"; }

logStdErr() {
while read -r line; do
red_echo "$line" >&2
done
}

0 comments on commit d39a6ec

Please sign in to comment.