Skip to content

Commit

Permalink
Add helm-values command (#122)
Browse files Browse the repository at this point in the history
- Added helm-values command for outputting all the helm overrides for a project
- Consolidated how aladdin computes helm values to inject
- Updated logging in bash scripts to use stderr
- Updated "check-branch" setting to use the project default branch instead of hardcoded from config
  • Loading branch information
jarojasm95 authored Feb 25, 2022
1 parent 7d964d7 commit d25b5cf
Show file tree
Hide file tree
Showing 29 changed files with 345 additions and 207 deletions.
52 changes: 30 additions & 22 deletions aladdin-container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@ export SCRIPT_DIR
export ALADDIN_CONFIG_DIR
export PY_MAIN

source "$SCRIPT_DIR/shared.sh" # to load _extract_cluster_config_value
source "$SCRIPT_DIR/shared.sh"

# Test user's aws configuration
function _test_aws_config() {
# Test aws configuration for a given profile: $1
echo "Testing aws configuration..."
echoerr "Testing aws configuration..."
local profile=$1
# See if we the current aws profile configured
if ! aws configure list --profile "$profile" >/dev/null; then
echo "Could not find aws profile: $profile; please check your ~/.aws/config and ~/.aws/credentials files"
echoerr "Could not find aws profile: $profile; please check your ~/.aws/config and ~/.aws/credentials files"
exit 1
fi
# Do a test aws cli call for the current aws profile
if ! aws sts get-caller-identity --profile "$profile" >/dev/null; then
echo "Your aws $profile credentials or config may be malformed; please check your ~/.aws/config and ~/.aws/credentials files"
echoerr "Your aws $profile credentials or config may be malformed; please check your ~/.aws/config and ~/.aws/credentials files"
exit 1
fi
echo "aws configuration check successful!"
echoerr "aws configuration check successful!"
}

function source_cluster_env() {
Expand All @@ -43,11 +43,11 @@ function source_cluster_env() {

# check which env it is and import appropriate environment variables
if [ ! -f "$env_file_path" ]; then
echo "Error: Unable to find environment file ${env_file_path} for specified cluster ${CLUSTER_CODE}"
echoerr "Error: Unable to find environment file ${env_file_path} for specified cluster ${CLUSTER_CODE}"
exit 1
fi

echo "Including environment variables from script ${env_file_path}"
echoerr "Including environment variables from script ${env_file_path}"
source "$env_file_path"
}

Expand All @@ -71,13 +71,13 @@ function exec_command_or_plugin() {
exec "$plugin_path" "$@"
fi

echo "Error: unknown command $command for aladdin"
echoerr "Error: unknown command $command for aladdin"
}

function environment_init() {
echo "START ENVIRONMENT CONFIGURATION============================================="
echo "CLUSTER_CODE = $CLUSTER_CODE"
echo "NAMESPACE = $NAMESPACE"
echoerr "START ENVIRONMENT CONFIGURATION============================================="
echoerr "CLUSTER_CODE = $CLUSTER_CODE"
echoerr "NAMESPACE = $NAMESPACE"

_handle_aws_config

Expand All @@ -87,7 +87,13 @@ function environment_init() {

# Make sure we are on local or that cluster has been created before creating namespaces, etc
if _is_cluster_ready; then

# If we're doing ssh-agent forwarding add a dummy ssh config
if [ ! -f $HOME/.ssh/config ] && [ ! -z "$SSH_AUTH_SOCK" ]
then
mkdir -p $HOME/.ssh/
git config --global url.ssh://git@github.com/.insteadOf https://github.com/
echo -e "Host github.com\n\tStrictHostKeyChecking no\n\tForwardAgent yes\n" > $HOME/.ssh/config
fi
if "$IS_LOCAL"; then
mkdir -p $HOME/.kube/
sed "s;https://0.0.0.0:$K3D_API_PORT;https://$HOST_ADDR:$K3D_API_PORT;g" $HOME/.kube_local/config > $HOME/.kube/config
Expand All @@ -107,7 +113,7 @@ function environment_init() {
fi
fi

echo "END ENVIRONMENT CONFIGURATION==============================================="
echoerr "END ENVIRONMENT CONFIGURATION==============================================="

}

Expand Down Expand Up @@ -187,20 +193,22 @@ function _handle_aws_config() {
publish_profile="$(jq -r '.aws_profile' <<< $publish_config)"
publish_role="$(jq -r '.aws_role_to_assume' <<< $publish_config)"
publish_mfa_enabled="$(jq -r '.aws_role_mfa_required' <<< $publish_config)"
if aws configure list --profile "$publish_profile" >/dev/null; then
echo "Conflicting AWS profile already exists: $publish_profile; please check your ~/.aws/config and ~/.aws/credentials files"
if aws configure list --profile "$publish_profile" &> /dev/null; then
echoerr "Conflicting AWS profile already exists: $publish_profile; please check your ~/.aws/config and ~/.aws/credentials files"
exit 1
fi
"$add_assume_role_config" "$publish_role" "$publish_profile" "$publish_mfa_enabled" 3600 # 1 hour
# Need to add aws configuration for current cluster's aws account
aws_profile="$(_extract_cluster_config_value bastion_account_profile_to_assume)"
aws_role="$(_extract_cluster_config_value bastion_account_role_to_assume)"
aws_mfa_enabled="$(_extract_cluster_config_value bastion_account_mfa_enabled)"
if aws configure list --profile "$aws_profile" >/dev/null; then
echo "Conflicting AWS profile already exists: $aws_profile; please check your ~/.aws/config and ~/.aws/credentials files"
exit 1
if [[ ! "$publish_profile" == "$aws_profile" ]]; then
# Need to add aws configuration for current cluster's aws account
aws_role="$(_extract_cluster_config_value bastion_account_role_to_assume)"
aws_mfa_enabled="$(_extract_cluster_config_value bastion_account_mfa_enabled)"
if aws configure list --profile "$aws_profile" &> /dev/null; then
echoerr "Conflicting AWS profile already exists: $aws_profile; please check your ~/.aws/config and ~/.aws/credentials files"
exit 1
fi
"$add_assume_role_config" "$aws_role" "$aws_profile" "$aws_mfa_enabled" 3600 # 1 hour
fi
"$add_assume_role_config" "$aws_role" "$aws_profile" "$aws_mfa_enabled" 3600 # 1 hour
# We reset AWS_DEFAULT_PROFILE here because that entry will be present in aws config files now
export AWS_DEFAULT_PROFILE="$aws_default_profile_temp"
else
Expand Down
32 changes: 16 additions & 16 deletions aladdin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ trap ctrl_trap INT
# Set defaults on command line args
ALADDIN_DEV=${ALADDIN_DEV:-false}
INIT=false
CLUSTER_CODE=LOCAL
NAMESPACE=default
CLUSTER_CODE=${CLUSTER_CODE:-LOCAL}
NAMESPACE=${NAMESPACE:-default}
IS_TERMINAL=true
SKIP_PROMPTS=false
KUBERNETES_VERSION="1.19.7"
Expand All @@ -23,7 +23,7 @@ SCRIPT_DIR="$ALADDIN_DIR/scripts"
ALADDIN_BIN="$HOME/.aladdin/bin"
PATH="$ALADDIN_BIN":"$PATH"

source "$SCRIPT_DIR/shared.sh" # to load _extract_cluster_config_value
source "$SCRIPT_DIR/shared.sh"

# Check for cluster name aliases and alias them accordingly
function check_cluster_alias() {
Expand All @@ -39,7 +39,7 @@ function get_config_variables() {
HOST_DIR=$(jq -r .host_dir $HOME/.aladdin/config/config.json)
if [[ "$HOST_DIR" == null ]]; then
# defaults to osx
HOST_DIR="/Users"
HOST_DIR="$HOME"
fi
fi
# Get k3d service port
Expand Down Expand Up @@ -115,15 +115,15 @@ function _start_k3d() {

function check_or_start_k3d() {
if docker info | grep "Cgroup Version: 2" > /dev/null && [[ "$KUBERNETES_VERSION" == "1.19.7" ]]; then
echo "ERROR: Current version of k3d is not compatible with cgroups v2"
echo "ERROR: If using Docker Desktop please downgrade to v4.2.0"
echoerr "ERROR: Current version of k3d is not compatible with cgroups v2"
echoerr "ERROR: If using Docker Desktop please downgrade to v4.2.0"
fi
if ! k3d cluster list | grep LOCAL > /dev/null; then
echo "Starting k3d LOCAL cluster... (this will take a moment)"
echoerr "Starting k3d LOCAL cluster... (this will take a moment)"
_start_k3d
else
if ! kubectl version | grep "Server" | grep "$KUBERNETES_VERSION" > /dev/null; then
echo "k3d detected on the incorrect version, stopping and restarting"
echoerr "k3d detected on the incorrect version, stopping and restarting"
k3d cluster delete LOCAL > /dev/null
check_or_start_k3d
fi
Expand Down Expand Up @@ -175,14 +175,14 @@ function pathnorm(){

function confirm_production() {
if $IS_TERMINAL ; then # if this is an interactive shell and not jenkins or piped input, then verify
echo "Script is running in a terminal. Let us make user aware that this is production";
echo -ne '\033[;31mYou are on production. Please type "production" to continue: \033[0m'; read -r
echoerr "Script is running in a terminal. Let us make user aware that this is production";
echoerr -ne '\033[;31mYou are on production. Please type "production" to continue: \033[0m'; read -r
if [[ ! $REPLY = "production" ]]; then
echo 'Exiting since you did not type production'
echoerr 'Exiting since you did not type production'
exit 0
fi
else
echo "This is production environment. This script is NOT running in a terminal, hence supressing user prompt to type 'production'";
echoerr "This is production environment. This script is NOT running in a terminal, hence supressing user prompt to type 'production'";
fi
}

Expand All @@ -199,12 +199,12 @@ function handle_ostypes() {
}
;;
win*|bsd*|solaris*) # Windows
echo "Not sure how to launch docker here. Exiting ..."
echoerr "Not sure how to launch docker here. Exiting ..."
return 1
;;
*)
echo "unknown OS: $OSTYPE"
echo "Not sure how to launch docker here. Exiting ..."
echoerr "unknown OS: $OSTYPE"
echoerr "Not sure how to launch docker here. Exiting ..."
return 1
;;
esac
Expand Down Expand Up @@ -236,7 +236,7 @@ function prepare_ssh_options() {
if $(jq -r '.ssh.agent // false' $HOME/.aladdin/config/config.json ); then
# Give the container access to the agent socket and tell it where to find it
if [[ -z ${SSH_AUTH_SOCK:-} ]]; then
echo >&2 "Aladdin is configured to use the host's ssh agent (ssh.agent == true) but SSH_AUTH_SOCK is empty."
echoerr "Aladdin is configured to use the host's ssh agent (ssh.agent == true) but SSH_AUTH_SOCK is empty."
exit 1
fi
case "$OSTYPE" in
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
set -eu -o pipefail
source "$SCRIPT_DIR/shared.sh"

function add_aws_assume_role_config {
# This command edits your aws config and credentials file to add aws_access_key_id,
Expand All @@ -8,7 +9,7 @@ function add_aws_assume_role_config {
# $4 seconds.

if ! "$BASTION_ACCOUNT_ENABLED"; then
echo >&2 "aladdin: error: bastion account is not enabled currently. update your aladdin-config to enable"
echoerr "aladdin: error: bastion account is not enabled currently. update your aladdin-config to enable"
exit 1
fi

Expand All @@ -26,7 +27,7 @@ function add_aws_assume_role_config {
--query 'MFADevices[0].SerialNumber' --output text)"

# Ask the user for their MFA token in yellow color
echo -ne '\e[33mPlease enter your AWS MFA token: \e[0m'; read -r token
echoerr -ne '\e[33mPlease enter your AWS MFA token: \e[0m'; read -r token

payload="$(aws --profile $BASTION_ACCOUNT_PROFILE sts assume-role \
--role-arn $role --duration-seconds $duration --serial-number $mfa_serial \
Expand Down
3 changes: 2 additions & 1 deletion aladdin/bash/container/bash/bash
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env bash
set -eu -o pipefail
source "$SCRIPT_DIR/shared.sh"

function run_bash {
if "$IS_PROD"; then
export PS1="\[\033[38;31m\]$CLUSTER_CODE:$NAMESPACE> \[\033[0m\]"
else
export PS1="$CLUSTER_CODE:$NAMESPACE> "
fi
echo "Launching bash shell. Press CTRL+D to exit."
echoerr "Launching bash shell. Press CTRL+D to exit."

# If authentication is enabled, switch to the AUTHENTICATION_DEFAULT_ROLE level
if "$AUTHENTICATION_ENABLED"; then
Expand Down
7 changes: 4 additions & 3 deletions aladdin/bash/container/change-permissions/change-permissions
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#!/usr/bin/env bash
set -eu -o pipefail
source "$SCRIPT_DIR/shared.sh"

function change_permissions {
# If authentication is enabled, allow the user to switch permission levels if it is one of the
# $AUTHENTICATION_ALLOWED_CHANGE_ROLES
if ! "$AUTHENTICATION_ENABLED"; then
echo >&2 "aladdin: error: authentication is not enabled currently. update your aladdin-config to enable"
echoerr "aladdin: error: authentication is not enabled currently. update your aladdin-config to enable"
exit 1
fi
if [[ "$(jq -r --arg role $1 '. | index($role)' <<< $AUTHENTICATION_ALLOWED_CHANGE_ROLES)" == null ]]; then
echo >&2 "aladdin: error: this permission does not exist, or you are not allowed to change to it"
echoerr "aladdin: error: this permission does not exist, or you are not allowed to change to it"
exit 1
fi
kubectl config set-context "$NAMESPACE.$CLUSTER_NAME" --cluster "$CLUSTER_NAME" \
Expand All @@ -22,7 +23,7 @@ function usage {
positional arguments:
permission the permission you want to elevate to
optional arguments:
-h, --help show this help message and exit
EOF
Expand Down
5 changes: 5 additions & 0 deletions aladdin/charts/merger/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: v2
name: merger
description: A Helm chart for merging Helm chart values
type: application
version: 0.1.0
1 change: 1 addition & 0 deletions aladdin/charts/merger/templates/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{- toYaml .Values -}}
Empty file.
67 changes: 20 additions & 47 deletions aladdin/commands/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from aladdin.lib.arg_tools import (
COMMON_OPTION_PARSER, HELM_OPTION_PARSER, CHART_OPTION_PARSER, container_command
)
from aladdin.lib.aws.certificate import get_cluster_certificate_arn, get_service_certificate_arn
from aladdin.lib.cluster_rules import ClusterRules
from aladdin.commands import sync_ingress, sync_dns
from aladdin.config import load_git_configs
Expand Down Expand Up @@ -42,7 +41,7 @@ def deploy_args(args):
args.project,
args.git_ref,
args.namespace,
args.chart,
args.chart or args.project,
args.dry_run,
args.force,
args.force_helm,
Expand Down Expand Up @@ -71,70 +70,44 @@ def deploy(
pr = PublishRules()
helm = Helm()
cr = ClusterRules(namespace=namespace)
helm_chart_path = "{}/{}".format(tmpdirname, chart or project)
hr = HelmRules(cr, chart or project)
helm_chart_path = "{}/{}".format(tmpdirname, chart)
git_account = load_git_configs()["account"]
repo = repo or project
git_url = f"git@github.com:{git_account}/{repo}.git"
git_ref = Git.extract_hash(git_ref, git_url)

if not force and cr.check_branch and Git.extract_hash(cr.check_branch, git_url) != git_ref:
if not force and cr.check_branch and Git.extract_hash("HEAD", git_url) != git_ref:
logging.error(
f"You are deploying hash {git_ref} which does not match branch"
f" {cr.check_branch} on cluster {cr.cluster_name} for project"
f" {project}... exiting"
f"You are deploying hash {git_ref} which does not match default branch"
f" on cluster {cr.cluster_name} for project {project}... exiting"
)
sys.exit(1)

helm.pull_packages(project, pr, git_ref, tmpdirname)
helm.pull_packages(project, pr, git_ref, tmpdirname, chart_name=chart)

# We need to use --set-string in case the git ref is all digits
helm_args = ["--set-string", f"deploy.imageTag={git_ref}"]

# Values precedence is command < cluster rules < --set-override-values
# Deploy command values
values = {
"deploy.ecr": pr.docker_registry,
"deploy.namespace": namespace,
values = HelmRules.get_helm_values()
values.update({
"project.name": project,
"service.certificateScope": cr.service_certificate_scope,
"service.domainName": cr.service_domain_name_suffix,
"service.clusterCertificateScope": cr.cluster_certificate_scope,
"service.clusterDomainName": cr.cluster_domain_name_suffix,
"service.clusterName": cr.cluster_domain_name, # aka root_dns
}
if cr.certificate_lookup:
values.update({
"service.certificateArn": get_service_certificate_arn(),
"service.clusterCertificateArn": get_cluster_certificate_arn(),
})
# Update with cluster rule values
values.update(cr.values)
})
# Add user-specified values files
if values_files:
for file_path in values_files:
helm_args.append(f"--values={os.path.join(helm_chart_path, 'values', file_path)}")
# Update with --set-override-values
values.update(dict(value.split("=") for value in set_override_values))

if dry_run:
helm.dry_run(
hr,
helm_chart_path,
cr.cluster_name,
namespace,
helm_args=helm_args,
**values
)
else:
helm.start(
hr,
helm_chart_path,
cr.cluster_name,
namespace,
force_helm,
helm_args=helm_args,
**values,
)
helm.upgrade(
HelmRules.get_release_name(chart),
helm_chart_path,
cr.cluster_name,
namespace,
force=force_helm,
dry_run=dry_run,
helm_args=helm_args,
**values,
)
if not dry_run:
sync_ingress.sync_ingress(namespace)
sync_dns.sync_dns(namespace)
Loading

0 comments on commit d25b5cf

Please sign in to comment.