#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-http-headers"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}

ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
FRONT_APP_IMAGE="${ECR_IMAGE_PREFIX}/feapp"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/colorapp"
MANIFEST_VERSION="${1:-v1beta2}"

error() {
    echo $1
    exit 1
}

check_k8s_virtualrouter() {
    #check CRD
    crd=$(kubectl get crd virtualrouters.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualrouters.appmesh.k8s.aws CRD to support HTTP headers match. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_k8s_virtualservice() {
    #check CRD
    crd=$(kubectl get crd virtualservices.appmesh.k8s.aws -o json | jq -r '.. | .match?.properties.headers | select(. != null)')
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualservices.appmesh.k8s.aws CRD to support HTTP headers match. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md#v020"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    if [ "$MANIFEST_VERSION" = "v1beta2" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
        requiredver="v1.0.0"
        check_k8s_virtualrouter
    elif [ "$MANIFEST_VERSION" = "v1beta1" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':')
        requiredver="v0.2.0"
        check_k8s_virtualservice
    else
        error "$PROJECT_NAME unexpected manifest version input: $MANIFEST_VERSION. Should be v1beta2 or v1beta1 based on the AppMesh controller version. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in colorapp feapp; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"

PROJECT_NAME="howto-k8s-http-ingress-v2"
APP="colorapp"
ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${PROJECT_NAME}"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/${APP}"
MANIFEST_VERSION="${1:-v1beta2}"
GW_ROUTES="gatewayroutes"
AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)

MESH_NAME=${PROJECT_NAME}
APP_NAMESPACE=${PROJECT_NAME}

error() {
    echo $1
    exit 1
}

check_k8s_virtualgateway() {
    #check CRD
    crd=$(kubectl get crd virtualgateways.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualgateways.appmesh.k8s.aws CRD to support Ingress gateway. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_k8s_gatewayroutes() {
    #check CRD
    crd=$(kubectl get crd gatewayroutes.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires gatewayroutes.appmesh.k8s.aws CRD to support Ingress gateway. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    check aws-app-mesh-controller version
    if [ "$MANIFEST_VERSION" = "v1beta2" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
        requiredver="v1.4.0"
        check_k8s_virtualgateway
        check_k8s_gatewayroutes
    else
        error "$PROJECT_NAME unexpected manifest version input: $MANIFEST_VERSION. Should be v1beta2 or v1beta1 based on the AppMesh controller version. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    aws ecr describe-repositories --repository-name $PROJECT_NAME/${APP} >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/${APP} >/dev/null
    docker build -t ${ECR_IMAGE_PREFIX}/${APP} ${DIR}/${APP}
    ecr_login
    docker push ${ECR_IMAGE_PREFIX}/${APP}
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}

eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

eval "cat <<EOF
$(<${DIR}//${MANIFEST_VERSION}/${GW_ROUTES}/prefix-match.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/prefix-match.yaml

kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
kubectl apply -f ${EXAMPLES_OUT_DIR}/prefix-match.yaml
}

main() {
    # check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"

PROJECT_NAME="howto-k8s-http-ingress-v2"
MESH_NAME=${PROJECT_NAME}
APP_NAMESPACE=${PROJECT_NAME}
EXAMPLES_OUT_DIR="${DIR}/_output/"
GW_ROUTES="gatewayroutes"
MANIFEST_VERSION="${2:-v1beta2}"
mkdir -p ${EXAMPLES_OUT_DIR}

gwRouteForPathMatch() {
    echo "Adding GWRoute for Path based match"
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/${GW_ROUTES}/path-match.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/path-match.yaml

kubectl apply -f ${EXAMPLES_OUT_DIR}/path-match.yaml
}

gwRouteForHeaderMatch() {
    echo "Adding GWRoute for Header based match"
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/${GW_ROUTES}/header-match.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/header-match.yaml

kubectl apply -f ${EXAMPLES_OUT_DIR}/header-match.yaml
}

gwRouteForQueryMatch() {
    echo "Adding GWRoute for Query based match"
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/${GW_ROUTES}/query-match.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/query-match.yaml

kubectl apply -f ${EXAMPLES_OUT_DIR}/query-match.yaml
}

gwRouteForPrefixRewrite() {
    echo "Adding GWRoute with Prefix Rewrite"
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/${GW_ROUTES}/rewrite-prefix.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/prefix-rewrite.yaml

kubectl apply -f ${EXAMPLES_OUT_DIR}/prefix-rewrite.yaml
}

gwRouteForPathRewrite(){
    echo "Adding GWRoute with Path Rewrite"
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/${GW_ROUTES}/rewrite-path.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/path-rewrite.yaml

kubectl apply -f ${EXAMPLES_OUT_DIR}/path-rewrite.yaml
}

gwRouteForMethodMatch(){
    echo "Adding GWRoute with Metod match"
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/${GW_ROUTES}/method-match.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/method-match.yaml

kubectl apply -f ${EXAMPLES_OUT_DIR}/method-match.yaml
}

gwRouteForAll() {
    echo "Adding all GWRoutes"
    gwRouteForPathMatch
    gwRouteForHeaderMatch
    gwRouteForQueryMatch
    gwRouteForMethodMatch
    gwRouteForPrefixRewrite
    gwRouteForPathRewrite
}

for i in $@
do
    if [ $i == "path-match" ]; then
        gwRouteForPathMatch
    elif [ $i == "header-match" ]; then
        gwRouteForHeaderMatch
    elif [ $i == "query-match" ]; then
        gwRouteForQueryMatch
    elif [ $i == "method-match" ]; then
        gwRouteForMethodMatch
    elif [ $i == "prefix-rewrite" ]; then
        gwRouteForPrefixRewrite
    elif [ $i == "path-rewrite" ]; then
        gwRouteForPathRewrite
    elif [ $i == "all" ]; then
        gwRouteForAll
        break
    fi
done


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-http2"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}
CLOUDMAP_NAMESPACE="${APP_NAMESPACE}.svc.cluster.local"
ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
CLIENT_APP_IMAGE="${ECR_IMAGE_PREFIX}/color_client"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/color_server"
MANIFEST_VERSION="${1:-v1beta2}"
AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)

error() {
    echo $1
    exit 1
}

check_k8s_virtualrouter() {
    #check CRD
    crd=$(kubectl get crd virtualrouters.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualrouters.appmesh.k8s.aws CRD to support HTTP2. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_k8s_virtualservice() {
    #check CRD
    crd=$(kubectl get crd virtualservices.appmesh.k8s.aws -o json | jq -r '.. | .http2? | select(. != null)')
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualservices.appmesh.k8s.aws CRD to support HTTP2. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md#v030"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    if [ "$MANIFEST_VERSION" = "v1beta2" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
        requiredver="v1.0.0"
        check_k8s_virtualrouter
    elif [ "$MANIFEST_VERSION" = "v1beta1" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':')
        requiredver="v0.3.0"
        check_k8s_virtualservice
    else
        error "$PROJECT_NAME unexpected manifest version input: $MANIFEST_VERSION. Should be v1beta2 or v1beta1 based on the AppMesh controller version. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in color_client color_server; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app} --build-arg GO_PROXY=${GO_PROXY:-"https://proxy.golang.org"}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_cloudmap_ns() {
    nsId=($(aws servicediscovery list-namespaces --output json |
        jq -r ".Namespaces[] | select(.Name | contains(\"${CLOUDMAP_NAMESPACE}\")) | .Id"))

    if [ -z "${nsId}" ]; then
        if [ -z "${VPC_ID}" ]; then
            echo "VPC_ID must be set. VPC_ID corresponds to vpc where applications are deployed."
            exit 1
        fi

        aws servicediscovery create-private-dns-namespace \
            --name "${CLOUDMAP_NAMESPACE}" \
            --vpc "${VPC_ID}" >/dev/null
        echo "Created private-dns-namespace ${CLOUDMAP_NAMESPACE}"
        sleep 5
    fi
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    deploy_cloudmap_ns

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-ingress-gateway"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}

APP="colorapp"
ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${PROJECT_NAME}"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/${APP}"
MANIFEST_VERSION="${1:-v1beta2}"
AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)

error() {
    echo $1
    exit 1
}

check_k8s_virtualgateway() {
    #check CRD
    crd=$(kubectl get crd virtualgateways.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualgateways.appmesh.k8s.aws CRD to support Ingress gateway. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_k8s_gatewayroutes() {
    #check CRD
    crd=$(kubectl get crd gatewayroutes.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires gatewayroutes.appmesh.k8s.aws CRD to support Ingress gateway. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    if [ "$MANIFEST_VERSION" = "v1beta2" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
        requiredver="v1.1.0"
        check_k8s_virtualgateway
        check_k8s_gatewayroutes
    else
        error "$PROJECT_NAME unexpected manifest version input: $MANIFEST_VERSION. Should be v1beta2 or v1beta1 based on the AppMesh controller version. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    aws ecr describe-repositories --repository-name $PROJECT_NAME/${APP} >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/${APP} >/dev/null
    docker build -t ${ECR_IMAGE_PREFIX}/${APP} ${DIR}/${APP}
    ecr_login
    docker push ${ECR_IMAGE_PREFIX}/${APP}
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-ipv6"
APP_NAMESPACE=${PROJECT_NAME}
CLOUDMAP_NAMESPACE="${APP_NAMESPACE}.svc.cluster.local"
MESH_NAME=${PROJECT_NAME}

ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
FRONT_APP_IMAGE="${ECR_IMAGE_PREFIX}/color_client"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/color_server"
MANIFEST_VERSION="${2:-v1beta2}"

error() {
    echo $1
    exit 1
}

check_k8s_virtualrouter() {
    #check CRD
    crd=$(kubectl get crd virtualrouters.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualrouters.appmesh.k8s.aws CRD to support HTTP headers match. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_k8s_virtualservice() {
    #check CRD
    crd=$(kubectl get crd virtualservices.appmesh.k8s.aws -o json | jq -r '.. | .match?.properties.headers | select(. != null)')
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualservices.appmesh.k8s.aws CRD to support HTTP headers match. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md#v020"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    if [ "$MANIFEST_VERSION" = "v1beta2" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
        requiredver="v1.0.0"
        check_k8s_virtualrouter
    elif [ "$MANIFEST_VERSION" = "v1beta1" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':')
        requiredver="v0.2.0"
        check_k8s_virtualservice
    else
        error "$PROJECT_NAME unexpected manifest version input: $MANIFEST_VERSION. Should be v1beta2 or v1beta1 based on the AppMesh controller version. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in color_client color_server; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_cloudmap_ns() {
    nsId=($(aws servicediscovery list-namespaces --output json |
        jq -r ".Namespaces[] | select(.Name | contains(\"${CLOUDMAP_NAMESPACE}\")) | .Id"))

    if [ -z "${nsId}" ]; then
        if [ -z "${VPC_ID}" ]; then
            echo "VPC_ID must be set. VPC_ID corresponds to vpc where applications are deployed."
            exit 1
        fi

        aws servicediscovery create-private-dns-namespace \
            --name "${CLOUDMAP_NAMESPACE}" \
            --vpc "${VPC_ID}" >/dev/null
        echo "Created private-dns-namespace ${CLOUDMAP_NAMESPACE}"
        sleep 5
    fi
}

deploy_cloud() {
    EXAMPLES_OUT_DIR="${DIR}/_output/cloud"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/cloud/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

deploy_dns() {
    EXAMPLES_OUT_DIR="${DIR}/_output/dns"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/dns/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    #check_appmesh_k8s

    action="$1"

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    if [ "$action" = "cloudmap" ]; then
        echo "deploy cloudmap..."
        deploy_cloudmap_ns
        deploy_cloud
        exit 0
    fi

    if [ "$action" = "dns" ]; then
        deploy_dns
        exit 0
    fi
}

main $@


#!/usr/bin/env bash

set -e

if [ -z "$1" ]; then
  echo "A file name is required" >&2
  exit 1
fi

if [ -z "$AWS_ACCOUNT_ID" ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set." >&2
    exit 1
fi

if [ -z "$AWS_DEFAULT_REGION" ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set." >&2
    exit 1
fi

if [ -z "$ENVOY_IMAGE" ]; then
    echo "ENVOY_IMAGE environtment variable is not set, see https://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html" >&2
    exit 1
fi

if [ -z "$CLUSTER_NAME" ]; then
    echo "CLUSTER_NAME environment variable is not set." >&2
    exit 1
fi

if [ -z "$NAMESPACE_NAME" ]; then
    echo "NAMESPACE_NAME environment variable is not set." >&2
    exit 1
fi

eval "cat <<EOF
$(<"$1")
EOF"


#!/usr/bin/env bash

set -e

check_command() {
  if ! [ -x "$(command -v "$1")" ]; then
    echo "$1 is required to run this script"
    exit
  fi
}

check_command aws
check_command docker

if [ -z "$AWS_ACCOUNT_ID" ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z "$AWS_DEFAULT_REGION" ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

if [ -z "$NAMESPACE_NAME" ]; then
    echo "NAMESPACE_NAME environment variable is not set."
    exit 1
fi

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
AWS_CLI_VERSION="$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)"
ECR_URL="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com"
ECR_IMAGE_PREFIX="$ECR_URL/$NAMESPACE_NAME"
DJAPP_IMAGE="$ECR_IMAGE_PREFIX/djapp"
DASHBOARD_V1_IMAGE="$ECR_IMAGE_PREFIX/dashboard-v1"
GO_PROXY="${GO_PROXY:-"https://proxy.golang.org"}"

ecr_login() {
    if [ "$AWS_CLI_VERSION" -gt 1 ]; then
        aws ecr get-login-password --region "$AWS_DEFAULT_REGION" | \
            docker login --username AWS --password-stdin "$ECR_URL"
    else
        # Note: we want to execute the output
        $(aws ecr get-login --no-include-email)
    fi
}

create_repositories() {
    for f in djapp dashboard-v1; do
        aws ecr describe-repositories --repository-name "$NAMESPACE_NAME/$f" >/dev/null 2>&1 || \
            aws ecr create-repository --repository-name "$NAMESPACE_NAME/$f" >/dev/null
    done
}

deploy_images() {
    create_repositories
    ecr_login

    docker build -t "$DASHBOARD_V1_IMAGE" "$DIR/../howto-metrics-extension-ecs/src/dashboard-v1" && \
        docker push "$DASHBOARD_V1_IMAGE"
    docker build -t "$DJAPP_IMAGE" --build-arg GO_PROXY="$GO_PROXY" "$DIR/../howto-metrics-extension-ecs/src/djapp" && \
        docker push "$DJAPP_IMAGE"
}

delete_repositories() {
    for f in djapp dashboard-v1; do
        aws ecr delete-repository --force --repository-name "$NAMESPACE_NAME/$f" >/dev/null
    done
}

usage() {
    echo "usage: $(basename "$0") [upload | delete]"
    exit 1
}

action="$1"

case "$action" in
    upload)
      echo "Building and uploading images..."
      deploy_images
      echo "Done"
      ;;
    delete)
      echo "Deleting images..."
      delete_repositories
      echo "Done"
      ;;
    *)
      usage
      ;;
esac


#!/usr/bin/env bash

set -e

check_command() {
  if ! [ -x "$(command -v "$1")" ]; then
    echo "$1 is required to run this script"
    exit
  fi
}

check_command base64
check_command aws

if [ -x "$(command -v jq)" ]; then
  image_extract=(jq -r '.MetricWidgetImage')
else
  echo "jq is reccomended to run this script. Will fall back to parsing JSON with sed"
  image_extract=(sed -En 's/\{? *"MetricWidgetImage" *: *"([^"]+) *,? *\}?"/\1/p')
fi

case "$(uname -a)" in
  Linux*)
    open_cmd=xdg-open
    ;;
  Darwin*)
    open_cmd=open
    ;;
  *)
    echo "This command only works on Linux or MacOS"
    exit 1
    ;;
esac

if [ -z "$AWS_ACCOUNT_ID" ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z "$AWS_DEFAULT_REGION" ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

PROJECT_NAME="${PROJECT_NAME:-"howto-metrics-extension"}"

usage() {
  echo "usage: $(basename "$0") [-h]
  -m <metric name>            envoy.appmesh.RequestCountPerTarget
  [ -n <node name> ]          e.g. djapp
  [ -t <node type> ]          VirtualNode, VirtualGateway
  [ -q <search expression> ]  e.g. TargetVirtualNode=metal-v1
  [ -x <metric statistic> ]   Average, Sum, p50, etc. Default: Average
  [ -s <start time> ]         e.g. -PT3H, -P2D, etc. Default: -PT15M
  [ -p <period> ]             Period in seconds. Default: 60"
  exit 1
}

if [ -z "$1" ]; then
  usage
fi

statistic="Average"
start_time="-PT15M"
period="60"

while getopts ":m:x:s:t:n:q:p:h" options; do
  case "$options" in
    m)
      metric_name="$OPTARG"
      ;;
    x)
      statistic="$OPTARG"
      ;;
    s)
      start_time="$OPTARG"
      ;;
    t)
      node_type="$OPTARG"
      ;;
    n)
      node_name="$OPTARG"
      ;;
    q)
      query="$OPTARG"
      ;;
    p)
      period="$OPTARG"
      ;;
    h|:|*)
      usage
      ;;
  esac
done

if ! [ -z "$node_name" ]; then
  if [ -z "$node_type" ]; then
    echo "Node type must be specified with a node name"
    exit 1
  fi
fi

if ! [ -z "$node_type" ]; then
  if [ -z "$node_name" ]; then
    echo "Node name must be specified with a node type"
    exit 1
  fi
fi

if [ -z "$node_name" ]; then
  title="$metric_name $statistic"
  expression=$(cat <<EOF
{ "expression": "SEARCH('Namespace=\"$PROJECT_NAME\" MetricName=\"$metric_name\" $query', '$statistic', $period)" }
EOF
)
else
  title="$node_name - $metric_name $statistic"
  expression=$(cat <<EOF
{ "expression": "SEARCH('Namespace=\"$PROJECT_NAME\" Mesh=\"$PROJECT_NAME\" $node_type=\"$node_name\" MetricName=\"$metric_name\" $query', '$statistic', $period)" }
EOF
)
fi

widget=$(cat <<EOF
{
  "width": 1200,
  "height": 600,
  "period": $period,
  "start": "$start_time",
  "end": "PT0H",
  "title": "$title",
  "metrics": [
    [
      $expression
    ]
  ]
}
EOF
)

echo "Metric widget:"
echo "$widget"

file="$(mktemp -u).png"

echo "Saving metric snapshot to $file"

aws cloudwatch get-metric-widget-image --metric-widget "$widget" | "${image_extract[@]}" | base64 -d > "$file"

$open_cmd "$file"


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

action="$1"
if [ -z "$action" ]; then
    echo "Usage:"
    echo "mesh.sh [up|addGreen|removeGreen]"
fi

case "$action" in
up)
    FRONT_APP_CA_CERT=ca_1_cert.pem
    FRONT_APP_K8S_SECRET=front-ca1-tls
    ;;
addGreen)
    FRONT_APP_CA_CERT=ca_1_ca_2_bundle.pem
    FRONT_APP_K8S_SECRET=front-ca1-ca2-tls
    ;;
removeGreen)
    FRONT_APP_CA_CERT=ca_1_cert.pem
    FRONT_APP_K8S_SECRET=front-ca1-tls
    ;;
*)
    err "Invalid action specified: $action"
    ;;
esac

AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-mtls-file-based"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}

ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
FRONT_APP_IMAGE="${ECR_IMAGE_PREFIX}/feapp"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/colorapp"

error() {
    echo $1
    exit 1
}

check_k8s_virtualrouter() {
    #check CRD
    crd=$(kubectl get crd virtualrouters.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualrouters.appmesh.k8s.aws CRD to support HTTP headers match. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
    requiredver="v1.3.0"
    check_k8s_virtualrouter

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in colorapp feapp; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/v1beta2/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -e

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

# $1=<CA name>
generate_ca() {
  openssl genrsa -out $DIR/$1_key.pem 2048
  openssl req -new -key $DIR/$1_key.pem -out $DIR/$1_cert.csr -config $DIR/$1_cert.cfg -batch -sha256
  openssl x509 -req -days 3650 -in $DIR/$1_cert.csr -signkey $DIR/$1_key.pem -out $DIR/$1_cert.pem \
    -extensions v3_ca -extfile $DIR/$1_cert.cfg
}

# $1=<certificate name>
generate_rsa_key() {
  openssl genrsa -out $DIR/$1_key.pem 2048
}

# $1=<certificate_name>
generate_cert_config() {
  sed -e "s/\${services_domain}/${SERVICES_DOMAIN}/" $DIR/$1_cert.cfg > $DIR/$1_cert.cfg.generated
}

# $1=<certificate name> $2=<CA name>
generate_x509_cert() {
  generate_cert_config $1
  openssl req -new -key $DIR/$1_key.pem -out $DIR/$1_cert.csr -config $DIR/$1_cert.cfg.generated -batch -sha256
  openssl x509 -req -days 3650 -in $DIR/$1_cert.csr -sha256 -CA $DIR/$2_cert.pem -CAkey \
    $DIR/$2_key.pem -CAcreateserial -out $DIR/$1_cert.pem -extensions v3_req -extfile $DIR/$1_cert.cfg.generated
}

# $1=<certificate name> $2=<CA name>
generate_cert_chain() {
  cat $DIR/$1_cert.pem $DIR/$2_cert.pem > $DIR/$1_cert_chain.pem
}

# $1=<CA name> $2=<CA name>
generate_cert_bundle() {
  cat $DIR/$1_cert.pem $DIR/$2_cert.pem > $DIR/$1_$2_bundle.pem
}

# Generate cert for the CA.
echo "Generating CA certificates."
generate_ca ca_1
generate_ca ca_2

# Generate RSA cert for the frontend app
echo "Generating frontend certificate."
generate_rsa_key front ca_1
generate_x509_cert front ca_1
generate_cert_chain front ca_1

# Generate RSA cert for the blue color app
echo "Generating backend certificate."
generate_rsa_key colorapp-blue ca_1
generate_x509_cert colorapp-blue ca_1
generate_cert_chain colorapp-blue ca_1

# Generate cert for the green color app
echo "Generating backend certificate."
generate_rsa_key colorapp-green ca_2
generate_x509_cert colorapp-green ca_2
generate_cert_chain colorapp-green ca_2

#echo "Generating CA Bundle"
generate_cert_bundle ca_1 ca_2

rm $DIR/*.csr
rm $DIR/*.srl


#!/bin/bash

set -ex

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

# $1= Certificate Name
removeSecret() {
    echo "Removing $1"
    kubectl delete secret $1 -n howto-k8s-mtls-file-based
}

main() {
    rm $DIR/*.pem
    rm $DIR/*.generated

    # Front App
    removeSecret "front-ca1-tls"
    removeSecret "front-ca1-ca2-tls"
    # Blue Color App
    removeSecret "colorapp-blue-tls"
    # Green Color App
    removeSecret "colorapp-green-tls"
}

main $@


#!/bin/bash

set -e

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

# $1=Certificate Name; $2=AppCert/Private Key; $3=CA Cert Name
deployAppSecret() {
    echo $1
    kubectl create -n howto-k8s-mtls-file-based secret generic $1-tls --from-file=$DIR/$2_key.pem --from-file=$DIR/$2_cert_chain.pem --from-file=$DIR/$3.pem
}

#deployGenericSecret() {
#    kubectl create -n howto-k8s-mtls-file-based secret generic $1 --from-file=$DIR/$2
#}

main() {

    kubectl create ns howto-k8s-mtls-file-based
    # Front App
    deployAppSecret "front-ca1" "front" "ca_1_cert"
    deployAppSecret "front-ca1-ca2" "front" "ca_1_ca_2_bundle"
    # Blue Color App
    deployAppSecret "colorapp-blue" "colorapp-blue" "ca_1_cert"
    # Green Color App
    deployAppSecret "colorapp-green" "colorapp-green" "ca_1_cert"

   #deployGenericSecret ca1-ca2-bundle-tls ca_1_ca_2_bundle.pem
   #deployGenericSecret ca1-cert-tls ca_1_cert.pem
}

main $@


#!/bin/bash

main(){
  kubectl delete -f _output/manifest.yaml
  kubectl delete ns spire
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

if [ -z $ENVOY_IMAGE ]; then
    echo "ENVOY_IMAGE environment variable is not set to App Mesh Envoy, see https://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html"
    exit 1
fi

SVID_CA_TRUST_DOMAIN=spiffe://howto-k8s-mtls-sds-based.aws
FRONTEND_APP_SVID=spiffe://howto-k8s-mtls-sds-based.aws/front
COLORAPP_BLUE_SVID=spiffe://howto-k8s-mtls-sds-based.aws/colorblue
COLORAPP_GREEN_SVID=spiffe://howto-k8s-mtls-sds-based.aws/colorgreen
COLORAPP_RED_SVID=spiffe://howto-k8s-mtls-sds-based.aws/colorred

AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-mtls-sds-based"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}

ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
FRONT_APP_IMAGE="${ECR_IMAGE_PREFIX}/feapp"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/colorapp"

error() {
    echo $1
    exit 1
}

check_k8s_virtualrouter() {
    #check CRD
    crd=$(kubectl get crd virtualrouters.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualrouters.appmesh.k8s.aws CRD to support HTTP headers match. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
    requiredver="v1.3.0"
    check_k8s_virtualrouter

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in colorapp feapp; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/v1beta2/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -e

deploySpire() {
    kubectl apply -f spire/spire_setup.yaml
}

echo "Installing SPIRE Server and Agent"
deploySpire


#!/usr/bin/env bash

set -e

register_server_entries() {
    kubectl exec -n spire spire-server-0 -c spire-server -- /opt/spire/bin/spire-server entry create $@
}

if [ "$1" == "register" ]; then
  echo "Registering an entry for spire agent..."
  register_server_entries \
    -spiffeID spiffe://howto-k8s-mtls-sds-based.aws/ns/spire/sa/spire-agent \
    -selector k8s_sat:cluster:k8s-cluster \
    -selector k8s_sat:agent_ns:spire \
    -selector k8s_sat:agent_sa:spire-agent \
    -node

  echo "Registering an entry for the front app..."
  register_server_entries \
    -parentID spiffe://howto-k8s-mtls-sds-based.aws/ns/spire/sa/spire-agent \
    -spiffeID spiffe://howto-k8s-mtls-sds-based.aws/front \
    -selector k8s:ns:howto-k8s-mtls-sds-based \
    -selector k8s:sa:default \
    -selector k8s:pod-label:app:front \
    -selector k8s:container-name:envoy

  echo "Registering an entry for the color app - version:red..."
  register_server_entries \
    -parentID spiffe://howto-k8s-mtls-sds-based.aws/ns/spire/sa/spire-agent \
    -spiffeID spiffe://howto-k8s-mtls-sds-based.aws/colorred \
    -selector k8s:ns:howto-k8s-mtls-sds-based \
    -selector k8s:sa:default \
    -selector k8s:pod-label:app:color \
    -selector k8s:pod-label:version:red \
    -selector k8s:container-name:envoy

  echo "Registering an entry for the color app - version:blue..."
  register_server_entries \
    -parentID spiffe://howto-k8s-mtls-sds-based.aws/ns/spire/sa/spire-agent \
    -spiffeID spiffe://howto-k8s-mtls-sds-based.aws/colorblue \
    -selector k8s:ns:howto-k8s-mtls-sds-based \
    -selector k8s:sa:default \
    -selector k8s:pod-label:app:color \
    -selector k8s:pod-label:version:blue \
    -selector k8s:container-name:envoy
elif [ "$1" == "registerGreen" ]; then
  echo "Registering an entry for the color app - version:green..."
  register_server_entries \
    -parentID spiffe://howto-k8s-mtls-sds-based.aws/ns/spire/sa/spire-agent \
    -spiffeID spiffe://howto-k8s-mtls-sds-based.aws/colorgreen \
    -selector k8s:ns:howto-k8s-mtls-sds-based \
    -selector k8s:sa:default \
    -selector k8s:pod-label:app:color \
    -selector k8s:pod-label:version:green \
    -selector k8s:container-name:envoy
fi


#!/bin/bash

set -eo pipefail

if [ -z $AWS_REGION ]; then
    echo "AWS_REGION environment variable is not set."
    exit 1
fi

if [ -z $CLUSTER_NAME ]; then
    echo "CLUSTER_NAME environment variable is not set."
    exit 1
fi

if [ -z $ENVOY_IMAGE_REPO ]; then
    echo "ENVOY_IMAGE_REPO environment variable is not set."
    exit 1
fi

if [ -z $ENVOY_IMAGE_TAG ]; then
    echo "ENVOY_IMAGE_TAG environment variable is not set."
    exit 1
fi

echo "Enabling IAM OIDC Provider"
eksctl utils associate-iam-oidc-provider --region=$AWS_REGION \
    --cluster=$CLUSTER_NAME \
    --approve

echo "Creating namespace appmesh-system"
kubectl create ns appmesh-system

echo "Creating namespace howto-k8s-multi-region"
kubectl create ns howto-k8s-multi-region

echo "Creating AppMesh Controller IAM service account"
eksctl create iamserviceaccount --cluster $CLUSTER_NAME \
    --namespace appmesh-system \
    --name appmesh-controller \
    --attach-policy-arn arn:aws:iam::aws:policy/AWSCloudMapFullAccess,arn:aws:iam::aws:policy/AWSAppMeshFullAccess \
    --override-existing-serviceaccounts \
    --approve

echo "Creating Envoy IAM Service Account"
# The output is assigned to a variable just so that the script does not stop for a user input
PolicyARN=$(aws iam create-policy \
    --policy-name ${CLUSTER_NAME}-${AWS_REGION}-AWSAppMeshK8sEnvoyIAMPolicy \
    --policy-document file://envoy-iam-policy.json \
    --output json --query 'Policy.Arn')

eksctl create iamserviceaccount --cluster $CLUSTER_NAME \
    --namespace howto-k8s-multi-region \
    --name appmesh-controller \
    --attach-policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/${CLUSTER_NAME}-${AWS_REGION}-AWSAppMeshK8sEnvoyIAMPolicy \
    --approve

echo "Adding eks helm repo"
helm repo add eks https://aws.github.io/eks-charts

helm repo update

echo "Install appmesh-controller helm chart"
helm upgrade -i appmesh-controller eks/appmesh-controller \
    --namespace appmesh-system \
    --set region=$AWS_REGION \
    --set serviceAccount.create=false \
    --set serviceAccount.name=appmesh-controller \
    --set sidecar.image.repository=$ENVOY_IMAGE_REPO \
    --set sidecar.image.tag=$ENVOY_IMAGE_TAG


#!/bin/bash

set -eo pipefail

AWS_REGION_1=$1
AWS_REGION_2=$2
CLUSTER_NAME_1=$3
CLUSTER_NAME_2=$4
DOMAIN_NAME=$5
SUB_DOMAIN_NAME=$6
HOSTED_ZONE_ID=$7

if [ -z $AWS_REGION_1 ]; then
    echo "Not a valid value for AWS region A."
    exit 1
fi

if [ -z $AWS_REGION_2 ]; then
    echo "Not a valid value for AWS region B."
    exit 1
fi

if [ -z $CLUSTER_NAME_1 ]; then
    echo "Not a valid value for cluster name in region A."
    exit 1
fi

if [ -z $CLUSTER_NAME_2 ]; then
    echo "Not a valid value for cluster name in region B."
    exit 1
fi

if [ -z $DOMAIN_NAME ]; then
    echo "Not a valid value for domain name."
    exit 1
fi

if [ -z $SUB_DOMAIN_NAME ]; then
    SUB_DOMAIN_NAME=`echo myapp.walkthrough.$DOMAIN_NAME`
else
    SUB_DOMAIN_NAME=`echo $SUB_DOMAIN_NAME.$DOMAIN_NAME`
fi

echo "Creating health check records for region A"
export KUBECONFIG=~/.kube/eksctl/clusters/$CLUSTER_NAME_1
export GW_ENDPOINT_1=$(kubectl get svc ingress-gw -n howto-k8s-multi-region --output jsonpath='{.status.loadBalancer.ingress[0].hostname}')

uidRegioAWhite=`uuidgen`
uidRegioARed=`uuidgen`
uidRegioABlue=`uuidgen`

regionAWhite=`aws route53 create-health-check --caller-reference $uidRegioAWhite --health-check-config '{"Port": 80, "Type": "HTTP", "ResourcePath": "paths/white", "FullyQualifiedDomainName": "'"$GW_ENDPOINT_1"'"}' --query 'HealthCheck.Id' --output text`
regionARed=`aws route53 create-health-check --caller-reference $uidRegioARed --health-check-config '{"Port": 80, "Type": "HTTP", "ResourcePath": "paths/red", "FullyQualifiedDomainName": "'"$GW_ENDPOINT_1"'"}' --query 'HealthCheck.Id' --output text`
regionABlue=`aws route53 create-health-check --caller-reference $uidRegioABlue --health-check-config '{"Port": 80, "Type": "HTTP", "ResourcePath": "paths/blue", "FullyQualifiedDomainName": "'"$GW_ENDPOINT_1"'"}' --query 'HealthCheck.Id' --output text`

aws route53 change-tags-for-resource --resource-type healthcheck --resource-id $regionAWhite --add-tags Key=Name,Value=regionA-white
aws route53 change-tags-for-resource --resource-type healthcheck --resource-id $regionARed --add-tags Key=Name,Value=regionA-red
aws route53 change-tags-for-resource --resource-type healthcheck --resource-id $regionABlue --add-tags Key=Name,Value=regionA-blue

uidRegioACombined=`uuidgen`
regionACombinedHealthCheck=`aws route53 create-health-check --caller-reference $uidRegioACombined --health-check-config '{"Type": "CALCULATED", "HealthThreshold": 3, "ChildHealthChecks" : ["'"$regionAWhite"'","'"$regionARed"'","'"$regionABlue"'"]}' --query 'HealthCheck.Id' --output text`
aws route53 change-tags-for-resource --resource-type healthcheck --resource-id $regionACombinedHealthCheck --add-tags Key=Name,Value=regionA-health

echo "Region A white path health check ID : $regionAWhite"
echo "Region A red path health check ID : $regionARed"
echo "Region A blue path health check ID : $regionABlue"
echo "Region A combined health check ID : $regionACombinedHealthCheck"

echo "Creating health check records for region B"
export KUBECONFIG=~/.kube/eksctl/clusters/$CLUSTER_NAME_2
export GW_ENDPOINT_2=$(kubectl get svc ingress-gw -n howto-k8s-multi-region --output jsonpath='{.status.loadBalancer.ingress[0].hostname}')

uidRegioBWhite=`uuidgen`
uidRegioBRed=`uuidgen`
uidRegioBBlue=`uuidgen`

regionBWhite=`aws route53 create-health-check --caller-reference $uidRegioBWhite --health-check-config '{"Port": 80, "Type": "HTTP", "ResourcePath": "paths/white", "FullyQualifiedDomainName": "'"$GW_ENDPOINT_2"'"}' --query 'HealthCheck.Id' --output text`
regionBRed=`aws route53 create-health-check --caller-reference $uidRegioBRed --health-check-config '{"Port": 80, "Type": "HTTP", "ResourcePath": "paths/red", "FullyQualifiedDomainName": "'"$GW_ENDPOINT_2"'"}' --query 'HealthCheck.Id' --output text`
regionBBlue=`aws route53 create-health-check --caller-reference $uidRegioBBlue --health-check-config '{"Port": 80, "Type": "HTTP", "ResourcePath": "paths/blue", "FullyQualifiedDomainName": "'"$GW_ENDPOINT_2"'"}' --query 'HealthCheck.Id' --output text`

aws route53 change-tags-for-resource --resource-type healthcheck --resource-id $regionBWhite --add-tags Key=Name,Value=regionB-white
aws route53 change-tags-for-resource --resource-type healthcheck --resource-id $regionBRed --add-tags Key=Name,Value=regionB-red
aws route53 change-tags-for-resource --resource-type healthcheck --resource-id $regionBBlue --add-tags Key=Name,Value=regionB-blue

uidRegioBCombined=`uuidgen`
regionBCombinedHealthCheck=`aws route53 create-health-check --caller-reference $uidRegioBCombined --health-check-config '{"Type": "CALCULATED", "HealthThreshold": 3, "ChildHealthChecks" : ["'"$regionBWhite"'","'"$regionBRed"'","'"$regionBBlue"'"]}' --query 'HealthCheck.Id' --output text`
aws route53 change-tags-for-resource --resource-type healthcheck --resource-id $regionBCombinedHealthCheck --add-tags Key=Name,Value=regionB-health

echo "Region B white path health check ID : $regionBWhite"
echo "Region B red path health check ID : $regionBRed"
echo "Region B blue path health check ID : $regionBBlue"
echo "Region B combined health check ID : $regionBCombinedHealthCheck"

echo "Completed creating health check records"

if [ -z $HOSTED_ZONE_ID ]; then
    echo "Creating route53 hostedzone"
    uidHostedZone=`uuidgen`
    hostedZoneId=`aws route53 create-hosted-zone --name $DOMAIN_NAME --caller-reference $uidHostedZone --hosted-zone-config Comment="Hosted zone for app mesh multiregion walkthrough" --query 'HostedZone.Id' --output text`
    echo "Created new Hosted Zone with ID: $hostedZoneId"
else
    hostedZoneId=$HOSTED_ZONE_ID
    echo "Using existing Hosted Zone ID: $hostedZoneId"
fi

echo "Creating CNAME record for region A"
regionARecord=`aws route53 change-resource-record-sets --hosted-zone-id $hostedZoneId --change-batch '{"Changes": [{ "Action": "CREATE", "ResourceRecordSet":{ "Name": "'"$SUB_DOMAIN_NAME"'", "Type": "CNAME", "SetIdentifier": "regionARecordID", "Region": "'"$AWS_REGION_1"'", "TTL": 300, "ResourceRecords": [{ "Value": "'"$GW_ENDPOINT_1"'" }], "HealthCheckId": "'"$regionACombinedHealthCheck"'" }}]}'`

echo "Creating CNAME record for region B"
regionBRecord=`aws route53 change-resource-record-sets --hosted-zone-id $hostedZoneId --change-batch '{"Changes": [{ "Action": "CREATE", "ResourceRecordSet":{ "Name": "'"$SUB_DOMAIN_NAME"'", "Type": "CNAME", "SetIdentifier": "regionBRecordID", "Region": "'"$AWS_REGION_2"'", "TTL": 300, "ResourceRecords": [{ "Value": "'"$GW_ENDPOINT_2"'" }], "HealthCheckId": "'"$regionBCombinedHealthCheck"'" }}]}'`

echo "Completed configuring route53"


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_REGION ]; then
    echo "AWS_REGION environment variable is not set."
    exit 1
fi

if [ -z $ENVOY_IMAGE_REPO ]; then
    echo "ENVOY_IMAGE_REPO environment variable is not set."
    exit 1
fi

if [ -z $ENVOY_IMAGE_TAG ]; then
    echo "ENVOY_IMAGE_TAG environment variable is not set."
    exit 1
fi

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-multi-region"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}

APP="colorapp"
ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${PROJECT_NAME}"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/${APP}"
MANIFEST_VERSION="${1:-v1beta2}"
AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)

error() {
    echo $1
    exit 1
}

check_k8s_virtualgateway() {
    #check CRD
    crd=$(kubectl get crd virtualgateways.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualgateways.appmesh.k8s.aws CRD to support Ingress gateway. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_k8s_gatewayroutes() {
    #check CRD
    crd=$(kubectl get crd gatewayroutes.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires gatewayroutes.appmesh.k8s.aws CRD to support Ingress gateway. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    if [ "$MANIFEST_VERSION" = "v1beta2" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
        requiredver="v1.1.0"
        check_k8s_virtualgateway
        check_k8s_gatewayroutes
    else
        error "$PROJECT_NAME unexpected manifest version input: $MANIFEST_VERSION. Should be v1beta2 or v1beta1 based on the AppMesh controller version. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    aws ecr describe-repositories --repository-name $PROJECT_NAME/${APP} >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/${APP} >/dev/null
    docker build -t ${ECR_IMAGE_PREFIX}/${APP} ${DIR}/${APP}
    ecr_login
    docker push ${ECR_IMAGE_PREFIX}/${APP}
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_REGION ]; then
    echo "AWS_REGION environment variable is not set."
    exit 1
fi

if [ -z $CLUSTER_NAME ]; then
    echo "CLUSTER_NAME environment variable is not set."
    exit 1
fi

if [ -z $ENVOY_IMAGE_REPO ]; then
    echo "ENVOY_IMAGE_REPO environment variable is not set."
    exit 1
fi

if [ -z $ENVOY_IMAGE_TAG ]; then
    echo "ENVOY_IMAGE_TAG environment variable is not set."
    exit 1
fi

echo "Creating EKS cluster $CLUSTER_NAME in region $AWS_REGION"

eksctl create cluster --name=$CLUSTER_NAME --nodes=2 \
--region=$AWS_REGION --auto-kubeconfig


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-outlier-detection"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}
CLOUDMAP_NAMESPACE="${PROJECT_NAME}.pvt.aws.local"

ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
FRONT_APP_IMAGE="${ECR_IMAGE_PREFIX}/feapp"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/colorapp"
VEGETA_IMAGE="${ECR_URL}/appmesh/vegeta-trafficgen"

MANIFEST_VERSION="${1:-v1beta2}"

error() {
    echo $1
    exit 1
}

check_virtualnode_v1beta2(){
    #check CRD
    crd=$(kubectl get crd virtualnodes.appmesh.k8s.aws -o json | jq -r '.. | .awsCloudMap?.properties.namespaceName? | select(. != null)')
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualnodes.appmesh.k8s.aws CRD to support Cloud Map service-discovery. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    if [ "$MANIFEST_VERSION" = "v1beta2" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
        requiredver="v1.2.0"
        check_virtualnode_v1beta2
    else
        error "$PROJECT_NAME unexpected manifest version input: $MANIFEST_VERSION. Timeouts are only supported in v1beta2 and AppMesh controller version >= v1.2.0. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in colorapp feapp; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_cloudmap_ns() {
    nsId=($(aws servicediscovery list-namespaces |
        jq -r ".Namespaces[] | select(.Name | contains(\"${CLOUDMAP_NAMESPACE}\")) | .Id"))

    if [ -z "${nsId}" ]; then
        if [ -z "${VPC_ID}" ]; then
            echo "VPC_ID must be set. VPC_ID corresponds to vpc where applications are deployed."
            exit 1
        fi

        aws servicediscovery create-private-dns-namespace \
            --name "${CLOUDMAP_NAMESPACE}" \
            --vpc "${VPC_ID}"
        echo "Created private-dns-namespace ${CLOUDMAP_NAMESPACE}"
        sleep 5
    fi
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images

	echo "building the traffic gen tool vegeta"
	../common/tools/vegeta-trafficgen/build.sh $ECR_URL
    fi

    deploy_cloudmap_ns
    deploy_app
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-retry-policy"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}

ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
FRONT_APP_IMAGE="${ECR_IMAGE_PREFIX}/feapp"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/colorapp"

MANIFEST_VERSION="${1:-v1beta2}"

error() {
    echo $1
    exit 1
}

check_k8s_virtualrouter() {
    #check CRD
    crd=$(kubectl get crd virtualrouters.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualrouters.appmesh.k8s.aws CRD to support retryPolicy. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_k8s_virtualservice() {
    #check CRD
    crd=$(kubectl get crd virtualservices.appmesh.k8s.aws -o json | jq -e '.. | .retryPolicy? | select(. != null)')
    if [ "$crd" = "" ]; then
        echo "$PROJECT_NAME requires CRD that supports retryPolicy. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md#v020"
        exit 1
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    if [ "$MANIFEST_VERSION" = "v1beta2" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
        requiredver="v1.0.0"
        check_k8s_virtualrouter
    elif [ "$MANIFEST_VERSION" = "v1beta1" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':')
        requiredver="v0.3.0"
        check_k8s_virtualservice
    else
        error "$PROJECT_NAME unexpected manifest version input: $MANIFEST_VERSION. Should be v1beta2 or v1beta1 based on the AppMesh controller version. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in colorapp feapp; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

redeploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    kubectl delete -f ${EXAMPLES_OUT_DIR}/manifest.yaml
    deploy_app
}

main() {
    check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    if [ "$REDEPLOY" = true ]; then
        echo "redeploying app..."
        redeploy_app
        exit 0
    fi

    deploy_app
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-timeout-policy"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}
CLOUDMAP_NAMESPACE="${PROJECT_NAME}.pvt.aws.local"

ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
FRONT_APP_IMAGE="${ECR_IMAGE_PREFIX}/feapp"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/colorapp"

MANIFEST_VERSION="${1:-v1beta2}"

error() {
    echo $1
    exit 1
}

check_virtualnode_v1beta2(){
    #check CRD
    crd=$(kubectl get crd virtualnodes.appmesh.k8s.aws -o json | jq -r '.. | .awsCloudMap?.properties.namespaceName? | select(. != null)')
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualnodes.appmesh.k8s.aws CRD to support Cloud Map service-discovery. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    if [ "$MANIFEST_VERSION" = "v1beta2" ]; then
        currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
        requiredver="v1.0.0"
        check_virtualnode_v1beta2
    else
        error "$PROJECT_NAME unexpected manifest version input: $MANIFEST_VERSION. Timeouts are only supported in v1beta2 and AppMesh controller version >= v1.0.0. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in colorapp feapp; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_timeout_ns() {
    nsId=($(aws servicediscovery list-namespaces |
        jq -r ".Namespaces[] | select(.Name | contains(\"${CLOUDMAP_NAMESPACE}\")) | .Id"))

    if [ -z "${nsId}" ]; then
        if [ -z "${VPC_ID}" ]; then
            echo "VPC_ID must be set. VPC_ID corresponds to vpc where applications are deployed."
            exit 1
        fi

        aws servicediscovery create-private-dns-namespace \
            --name "${CLOUDMAP_NAMESPACE}" \
            --vpc "${VPC_ID}"
        echo "Created private-dns-namespace ${CLOUDMAP_NAMESPACE}"
        sleep 5
    fi
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/${MANIFEST_VERSION}/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    deploy_timeout_ns

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

action="$1"
if [ -z "$action" ]; then
    echo "Usage:"
    echo "mesh.sh [up]"
fi

AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-tls-acm"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}

ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
FRONT_APP_IMAGE="${ECR_IMAGE_PREFIX}/feapp"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/colorapp"

error() {
    echo $1
    exit 1
}

check_k8s_virtualrouter() {
    #check CRD
    crd=$(kubectl get crd virtualrouters.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualrouters.appmesh.k8s.aws CRD to support HTTP headers match. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
    requiredver="v1.0.0"
    check_k8s_virtualrouter

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in colorapp feapp; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/v1beta2/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -eo pipefail

if [ -z $AWS_ACCOUNT_ID ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z $AWS_DEFAULT_REGION ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

action="$1"
if [ -z "$action" ]; then
    echo "Usage:"
    echo "mesh.sh [up|addGreen|removeGreen]"
fi

case "$action" in
up)
    FRONTEND_APP_CERT=ca1-cert-tls
    FRONTEND_CERT_CHAIN=ca_1_cert.pem
    ;;
addGreen)
    FRONTEND_APP_CERT=ca1-ca2-bundle-tls
    FRONTEND_CERT_CHAIN=ca_1_ca_2_bundle.pem
    ;;
removeGreen)
    FRONTEND_APP_CERT=ca1-cert-tls
    FRONTEND_CERT_CHAIN=ca_1_cert.pem
    ;;
*)
    err "Invalid action specified: $action"
    ;;
esac

AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
PROJECT_NAME="howto-k8s-tls-file-based"
APP_NAMESPACE=${PROJECT_NAME}
MESH_NAME=${PROJECT_NAME}

ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
ECR_IMAGE_PREFIX="${ECR_URL}/${PROJECT_NAME}"
FRONT_APP_IMAGE="${ECR_IMAGE_PREFIX}/feapp"
COLOR_APP_IMAGE="${ECR_IMAGE_PREFIX}/colorapp"

error() {
    echo $1
    exit 1
}

check_k8s_virtualrouter() {
    #check CRD
    crd=$(kubectl get crd virtualrouters.appmesh.k8s.aws -o json )
    if [ -z "$crd" ]; then
        error "$PROJECT_NAME requires virtualrouters.appmesh.k8s.aws CRD to support HTTP headers match. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    else
        echo "CRD check passed!"
    fi
}

check_appmesh_k8s() {
    #check aws-app-mesh-controller version
    currentver=$(kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1)
    requiredver="v1.0.0"
    check_k8s_virtualrouter

    if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
        echo "aws-app-mesh-controller check passed! $currentver >= $requiredver"
    else
        error "$PROJECT_NAME requires aws-app-mesh-controller version >=$requiredver but found $currentver. See https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/master/CHANGELOG.md"
    fi
}

ecr_login() {
    if [ $AWS_CLI_VERSION -gt 1 ]; then
        aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
            docker login --username AWS --password-stdin ${ECR_URL}
    else
        $(aws ecr get-login --no-include-email)
    fi
}

deploy_images() {
    ecr_login
    for app in colorapp feapp; do
        aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
        docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app}
        docker push ${ECR_IMAGE_PREFIX}/${app}
    done
}

deploy_app() {
    EXAMPLES_OUT_DIR="${DIR}/_output/"
    mkdir -p ${EXAMPLES_OUT_DIR}
    eval "cat <<EOF
$(<${DIR}/v1beta2/manifest.yaml.template)
EOF
" >${EXAMPLES_OUT_DIR}/manifest.yaml

    kubectl apply -f ${EXAMPLES_OUT_DIR}/manifest.yaml
}

main() {
    check_appmesh_k8s

    if [ -z $SKIP_IMAGES ]; then
        echo "deploy images..."
        deploy_images
    fi

    deploy_app
}

main


#!/bin/bash

set -e

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

# $1=<CA name>
generate_ca() {
  openssl genrsa -out $DIR/$1_key.pem 2048
  openssl req -new -key $DIR/$1_key.pem -out $DIR/$1_cert.csr -config $DIR/$1_cert.cfg -batch -sha256
  openssl x509 -req -days 3650 -in $DIR/$1_cert.csr -signkey $DIR/$1_key.pem -out $DIR/$1_cert.pem \
    -extensions v3_ca -extfile $DIR/$1_cert.cfg
}

# $1=<certificate name>
generate_rsa_key() {
  openssl genrsa -out $DIR/$1_key.pem 2048
}

# $1=<certificate_name>
generate_cert_config() {
  sed -e "s/\${services_domain}/${SERVICES_DOMAIN}/" $DIR/$1_cert.cfg > $DIR/$1_cert.cfg.generated
}

# $1=<certificate name> $2=<CA name>
generate_x509_cert() {
  generate_cert_config $1
  openssl req -new -key $DIR/$1_key.pem -out $DIR/$1_cert.csr -config $DIR/$1_cert.cfg.generated -batch -sha256
  openssl x509 -req -days 3650 -in $DIR/$1_cert.csr -sha256 -CA $DIR/$2_cert.pem -CAkey \
    $DIR/$2_key.pem -CAcreateserial -out $DIR/$1_cert.pem -extensions v3_req -extfile $DIR/$1_cert.cfg.generated
}

# $1=<certificate name> $2=<CA name>
generate_cert_chain() {
  cat $DIR/$1_cert.pem $DIR/$2_cert.pem > $DIR/$1_cert_chain.pem
}

# $1=<CA name> $2=<CA name>
generate_cert_bundle() {
  cat $DIR/$1_cert.pem $DIR/$2_cert.pem > $DIR/$1_$2_bundle.pem
}

# Generate cert for the CA.
echo "Generating CA certificates."
generate_ca ca_1
generate_ca ca_2

# Generate RSA cert for the blue color app
echo "Generating backend certificate."
generate_rsa_key colorapp-blue ca_1
generate_x509_cert colorapp-blue ca_1
generate_cert_chain colorapp-blue ca_1

# Generate cert for the green color app
echo "Generating backend certificate."
generate_rsa_key colorapp-green ca_2
generate_x509_cert colorapp-green ca_2
generate_cert_chain colorapp-green ca_2

echo "Generating CA Bundle"
generate_cert_bundle ca_1 ca_2

rm $DIR/*.csr
rm $DIR/*.srl


#!/bin/bash

set -ex

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

# $1= Certificate Name
removeSecret() {
    echo "Removing $1"
    kubectl delete secret $1 -n howto-k8s-tls-file-based
}

main() {
    rm $DIR/*.pem
    rm $DIR/*.generated

    # Blue Color App
    removeSecret "colorapp-blue-tls"
    # Green Color App
    removeSecret "colorapp-green-tls"
    # Remove CA1 CA2 certs
    removeSecret "ca1-ca2-bundle-tls"
    removeSecret "ca1-cert-tls"
}

main $@


#!/bin/bash

set -e

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

# $1= Certificate Name
deployAppSecret() {
    echo $1
    kubectl create -n howto-k8s-tls-file-based secret generic $1-tls --from-file=$DIR/$1_key.pem --from-file=$DIR/$1_cert_chain.pem
}

deployGenericSecret() {
    kubectl create -n howto-k8s-tls-file-based secret generic $1 --from-file=$DIR/$2
}

main() {

    kubectl create ns howto-k8s-tls-file-based
    # Blue Color App
    deployAppSecret "colorapp-blue"
    # Green Color App
    deployAppSecret "colorapp-green"

    deployGenericSecret ca1-ca2-bundle-tls ca_1_ca_2_bundle.pem
    deployGenericSecret ca1-cert-tls ca_1_cert.pem
}

main $@


#!/bin/bash

set -ex

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

aws --region "${AWS_DEFAULT_REGION}" \
    cloudformation deploy \
    --stack-name "${ENVIRONMENT_NAME}-ecr-repositories" \
    --capabilities CAPABILITY_IAM \
    --template-file "${DIR}/ecr-repositories.yaml" \
    --parameter-overrides \
    ColorTellerImageName="${COLOR_TELLER_IMAGE_NAME}"


#!/bin/bash

set -ex

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

aws --region "${AWS_DEFAULT_REGION}" \
    cloudformation deploy \
    --stack-name "${ENVIRONMENT_NAME}-ecs-cluster" \
    --capabilities CAPABILITY_IAM \
    --template-file "${DIR}/ecs-cluster.yaml"  \
    --parameter-overrides \
    EnvironmentName="${ENVIRONMENT_NAME}" \
    KeyName="${KEY_PAIR_NAME}" \
    ECSServicesDomain="${SERVICES_DOMAIN}"


#!/bin/bash

set -e

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

aws --region "${AWS_DEFAULT_REGION}" \
    cloudformation deploy \
    --stack-name "${ENVIRONMENT_NAME}-ecs-service" \
    --capabilities CAPABILITY_IAM \
    --template-file "${DIR}/ecs-service.yaml"  \
    --parameter-overrides \
    EnvironmentName="${ENVIRONMENT_NAME}" \
    ECSServicesDomain="${SERVICES_DOMAIN}" \
    AppMeshMeshName="${MESH_NAME}" \
    EnvoyImage="${ENVOY_IMAGE}" \
    ColorTellerImageName="${COLOR_TELLER_IMAGE_NAME}"

print_bastion() {
    echo "Bastion endpoint:"
    ip=$(aws cloudformation describe-stacks \
        --stack-name="${ENVIRONMENT_NAME}-ecs-cluster" \
        --query="Stacks[0].Outputs[?OutputKey=='BastionIP'].OutputValue" \
        --output=text)
    echo "${ip}"
}

print_endpoint() {
    echo "ColorApp Endpoint:"
    prefix=$(aws cloudformation describe-stacks \
        --stack-name="${ENVIRONMENT_NAME}-ecs-service" \
        --query="Stacks[0].Outputs[?OutputKey=='ColorAppEndpoint'].OutputValue" \
        --output=text)
    echo "${prefix}"
}

print_bastion
print_endpoint


#!/bin/bash

set -ex

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

aws --region "${AWS_DEFAULT_REGION}" \
    cloudformation deploy \
    --stack-name "${ENVIRONMENT_NAME}-vpc" \
    --capabilities CAPABILITY_IAM \
    --template-file "${DIR}/vpc.yaml" \
    --parameter-overrides \
    EnvironmentName="${ENVIRONMENT_NAME}"


#!/usr/bin/env bash
# vim:syn=sh:ts=4:sw=4:et:ai
shopt -s nullglob

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
TEST_MESH_DIR="${DIR}"

print() {
    printf "[$(date)] : %s\n" "$*"
}

err() {
    msg="Error: $1"
    print "${msg}"
    code=${2:-"1"}
    exit ${code}
}

sanity_check() {
    if [ -z "${MESH_NAME}" ]; then
        err "MESH_NAME is not set"
    fi
}

appmesh_cmd="aws appmesh"

create_mesh() {
    spec_file=$1
    cmd=( $appmesh_cmd create-mesh --mesh-name "${MESH_NAME}" \
                --cli-input-json "file:///${spec_file}" \
                --query mesh.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to create mesh" "$?"
    print "--> ${uid}"
}

delete_mesh() {
    cmd=( $appmesh_cmd delete-mesh --mesh-name "${MESH_NAME}" \
                ${PROFILE_OPT} \
                --query mesh.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to delete mesh" "$?"
    print "--> ${uid}"
}

create_vgateway() {
    spec_file=$1
    vgateway_name=$2
    cli_input=$( jq -n \
    -f "$spec_file" )
    cmd=( $appmesh_cmd create-virtual-gateway \
                --mesh-name "${MESH_NAME}" \
                --virtual-gateway-name "${vgateway_name}" \
                --cli-input-json "$cli_input" \
                --query virtualGateway.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to create virtual gateway" "$?"
    print "--> ${uid}"
}

update_vgateway() {
    spec_file=$1
    vgateway_name=$2
    cli_input=$( jq -n \
    -f "$spec_file" )
    cmd=( $appmesh_cmd update-virtual-gateway \
                --mesh-name "${MESH_NAME}" \
                --virtual-gateway-name "${vgateway_name}" \
                --cli-input-json "$cli_input" \
                --query virtualGateway.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to update virtual gateway" "$?"
    print "--> ${uid}"
}

delete_vgateway() {
    vgateway_name=$1
    cmd=( $appmesh_cmd delete-virtual-gateway \
                --mesh-name "${MESH_NAME}" \
                --virtual-gateway-name "${vgateway_name}" \
                --query virtualGateway.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to delete virtual gateway" "$?"
    print "--> ${uid}"
}

create_gateway_route() {
    spec_file=$1
    vgateway_name=$2
    gatewayroute_name=$3
    cli_input=$( jq -n \
        --arg VIRTUALSERVICE_NAME "$4" \
        -f "$spec_file" )
    cmd=( $appmesh_cmd create-gateway-route \
                --mesh-name "${MESH_NAME}" \
                --virtual-gateway-name "${vgateway_name}" \
                --gateway-route-name "${gatewayroute_name}" \
                --cli-input-json "$cli_input" \
                --query gatewayRoute.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to create gateway route" "$?"
    print "--> ${uid}"
}

update_gateway_route() {
    spec_file=$1
    vgateway_name=$2
    gatewayroute_name=$3
    cli_input=$( jq -n \
        --arg VIRTUALSERVICE_NAME "$4" \
        -f "$spec_file" )
    cmd=( $appmesh_cmd update-gateway-route \
                --mesh-name "${MESH_NAME}" \
                --virtual-gateway-name "${vgateway_name}" \
                --gateway-route-name "${gatewayroute_name}" \
                --cli-input-json "$cli_input" \
                --query gatewayRoute.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to update gateway route" "$?"
    print "--> ${uid}"
}

delete_gateway_route() {
    vgateway_name=$1
    gatewayroute_name=$2
    cmd=( $appmesh_cmd delete-gateway-route \
                --mesh-name "${MESH_NAME}" \
                --virtual-gateway-name "${vgateway_name}" \
                --gateway-route-name "${gatewayroute_name}" \
                --query gatewayRoute.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to delete gateway route" "$?"
    print "--> ${uid}"
}

create_vnode() {
    spec_file=$1
    vnode_name=$2
    dns_hostname="$3.${SERVICES_DOMAIN}"
    cli_input=$( jq -n \
        --arg DNS_HOSTNAME "$3.${SERVICES_DOMAIN}" \
        -f "$spec_file" )
    cmd=( $appmesh_cmd create-virtual-node \
                --mesh-name "${MESH_NAME}" \
                --virtual-node-name "${vnode_name}" \
                --cli-input-json "$cli_input" \
                --query virtualNode.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to create virtual node" "$?"
    print "--> ${uid}"
}

update_vnode() {
    spec_file=$1
    vnode_name=$2
    dns_hostname="$3.${SERVICES_DOMAIN}"
    cli_input=$( jq -n \
        --arg DNS_HOSTNAME "$3.${SERVICES_DOMAIN}" \
        -f "$spec_file" )
    cmd=( $appmesh_cmd update-virtual-node \
                --mesh-name "${MESH_NAME}" \
                --virtual-node-name "${vnode_name}" \
                --cli-input-json "$cli_input" \
                --query virtualNode.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to update virtual node" "$?"
    print "--> ${uid}"
}

delete_vnode() {
    vnode_name=$1
    cmd=( $appmesh_cmd delete-virtual-node \
                --mesh-name "${MESH_NAME}" \
                --virtual-node-name "${vnode_name}" \
                --query virtualNode.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to delete virtual node" "$?"
    print "--> ${uid}"
}

create_vservice() {
    spec_file=$1
    vservice_name=$2
    cmd=( $appmesh_cmd create-virtual-service  \
                --mesh-name "${MESH_NAME}" \
                --virtual-service-name "${vservice_name}" \
                --cli-input-json "file:///${spec_file}" \
                --query virtualService.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to create virtual service" "$?"
    print "--> ${uid}"
}

delete_vservice() {
    vservice_name=$1
    cmd=( $appmesh_cmd delete-virtual-service \
                --mesh-name "${MESH_NAME}" \
                --virtual-service-name "${vservice_name}" \
                --query virtualService.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to delete virtual service" "$?"
    print "--> ${uid}"
}

create_vrouter() {
    spec_file=$1
    vrouter_name=$2
    cmd=( $appmesh_cmd create-virtual-router \
                --mesh-name "${MESH_NAME}" \
                --virtual-router-name "${vrouter_name}" \
                --cli-input-json "file:///${spec_file}" \
                --query virtualRouter.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to create virtual router" "$?"
    print "--> ${uid}"
}

delete_vrouter() {
    vrouter_name=$1
    cmd=( $appmesh_cmd delete-virtual-router \
                --mesh-name "${MESH_NAME}" \
                --virtual-router-name "${vrouter_name}" \
                --query virtualRouter.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to delete virtual router" "$?"
    print "--> ${uid}"
}

create_route() {
    spec_file=$1
    vrouter_name=$2
    route_name=$3
    cmd=( $appmesh_cmd create-route \
                --mesh-name "${MESH_NAME}" \
                --virtual-router-name "${vrouter_name}" \
                --route-name "${route_name}" \
                --cli-input-json "file:///${spec_file}" \
                --query route.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to create route" "$?"
    print "--> ${uid}"
}

update_route() {
    spec_file=$1
    vrouter_name=$2
    route_name=$3
    cmd=( $appmesh_cmd update-route \
                --mesh-name "${MESH_NAME}" \
                --virtual-router-name "${vrouter_name}" \
                --route-name "${route_name}" \
                --cli-input-json "file:///${spec_file}" \
                --query route.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to update route" "$?"
    print "--> ${uid}"
}

delete_route() {
    vrouter_name=$1
    route_name=$2
    cmd=( $appmesh_cmd delete-route \
                --mesh-name "${MESH_NAME}" \
                --virtual-router-name "${vrouter_name}" \
                --route-name "${route_name}" \
                --query route.metadata.uid --output text )
    print "${cmd[@]}"
    uid=$("${cmd[@]}") || err "Unable to delete route" "$?"
    print "--> ${uid}"
}

main() {
    action="$1"
    if [ -z "$action" ]; then
        echo "Usage:"
        echo "mesh.sh [up|down]"
    fi
    sanity_check

    update_resource="$2"
    resource_name="$3"

    case "$action" in
    up)
        create_mesh "${TEST_MESH_DIR}/mesh.json"

        create_vnode "${TEST_MESH_DIR}/colorteller-red-vn.json" "colorteller-red-vn" "colorteller-red"
        create_vrouter "${TEST_MESH_DIR}/colorteller-vr-1.json" "colorteller-vr-1"
        create_route "${TEST_MESH_DIR}/colorteller-route-1.json" "colorteller-vr-1" "colorteller-route-1"
        create_vservice "${TEST_MESH_DIR}/colorteller-vs-1.json" "colorteller-1.${SERVICES_DOMAIN}"

        create_vnode "${TEST_MESH_DIR}/colorteller-yellow-vn.json" "colorteller-yellow-vn" "colorteller-yellow"
        create_vrouter "${TEST_MESH_DIR}/colorteller-vr-2.json" "colorteller-vr-2"
        create_route "${TEST_MESH_DIR}/colorteller-route-2.json" "colorteller-vr-2" "colorteller-route-2"
        create_vservice "${TEST_MESH_DIR}/colorteller-vs-2.json" "colorteller-2.${SERVICES_DOMAIN}"

        create_vgateway "${TEST_MESH_DIR}/colorgateway-vg.json" "colorgateway-vg"
        create_gateway_route "${TEST_MESH_DIR}/colorgateway-route-1.json" "colorgateway-vg" "colorgateway-route-1" "colorteller-1.${SERVICES_DOMAIN}"
        create_gateway_route "${TEST_MESH_DIR}/colorgateway-route-2.json" "colorgateway-vg" "colorgateway-route-2" "colorteller-2.${SERVICES_DOMAIN}"
        ;;
    configure-query-parameter-match-rewrite)
        update_gateway_route "${TEST_MESH_DIR}/colorgateway-route-updated-rewrite.json" "colorgateway-vg" "colorgateway-route-1" "colorteller-1.${SERVICES_DOMAIN}"
        update_route "${TEST_MESH_DIR}/colorteller-route-updated-rewrite.json" "colorteller-vr-1" "colorteller-route-1"
        ;;
    disable-default-prefix-rewrite)
        update_gateway_route "${TEST_MESH_DIR}/colorgateway-route-updated-disabled_rewrite.json" "colorgateway-vg" "colorgateway-route-1" "colorteller-1.${SERVICES_DOMAIN}"
        update_route "${TEST_MESH_DIR}/colorteller-route-updated-rewrite.json" "colorteller-vr-1" "colorteller-route-1"
        ;;
    configure-hostname-match)
        update_gateway_route "${TEST_MESH_DIR}/colorgateway-route-updated-hostname-match.json" "colorgateway-vg" "colorgateway-route-1" "colorteller-1.${SERVICES_DOMAIN}"
        update_route "${TEST_MESH_DIR}/colorteller-route-1.json" "colorteller-vr-1" "colorteller-route-1"
        ;;
    down)
        delete_gateway_route "colorgateway-vg" "colorgateway-route-1"
        delete_gateway_route "colorgateway-vg" "colorgateway-route-2"
        delete_vgateway "colorgateway-vg"

        delete_vservice "colorteller-1.${SERVICES_DOMAIN}"
        delete_route "colorteller-vr-1" "colorteller-route-1"
        delete_vrouter "colorteller-vr-1"
        delete_vservice "colorteller-2.${SERVICES_DOMAIN}"

        delete_route "colorteller-vr-2" "colorteller-route-2"
        delete_vrouter "colorteller-vr-2"
        delete_vnode "colorteller-red-vn"
        delete_vnode "colorteller-yellow-vn"

        delete_mesh
        ;;
    *)
        err "Invalid action specified: $action"
        ;;
    esac
}
``
main $@


#!/usr/bin/env bash
# vim:syn=sh:ts=4:sw=4:et:ai

set -ex

if [ -z $COLOR_TELLER_IMAGE_NAME ]; then
    echo "COLOR_TELLER_IMAGE_NAME environment variable is not set"
    exit 1
fi

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
IMAGE="${ECR_URL}/${COLOR_TELLER_IMAGE_NAME}:latest"

# build
docker build -t $IMAGE $DIR --build-arg GO_PROXY=${GO_PROXY:-"https://proxy.golang.org"}

# login
AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
if [ $AWS_CLI_VERSION -gt 1 ]; then
    aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \
         docker login --username AWS --password-stdin ${ECR_URL}
else
    $(aws ecr get-login --no-include-email)
fi

# push
docker push $IMAGE


#!/usr/bin/env bash

check_command() {
  if ! [ -x "$(command -v "$1")" ]; then
    echo "$1 is required to run this script"
    exit
  fi
}

check_command aws

if [ -z "$AWS_ACCOUNT_ID" ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z "$AWS_DEFAULT_REGION" ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"

usage() {
  echo "usage: $(basename "$0") [-h]
    -c <command>                         deploy or delete
    -s <stack name>                      Cloudformation stack name
    [ -q <metric namespace> ]            Metric namespace name
    [ -d <dashboard name> ]              Cloudformation dashboard name
    [ -i <dashboard lambda image uri> ]  Dashboard generator lambda image URI
    [ -m <mesh name> ]                   Mesh name
    [ -g <virtual gateway name> ]        Virtual gateway name.
    [ -n <virtual nodes> ]               Comma separated list of virtual node names."
  exit 1
}

delete_cfn_stack() {
    stack_name="$1"
    aws cloudformation delete-stack --stack-name "$stack_name"
    echo "Waiting for the stack $stack_name to be deleted, this may take a few minutes..."
    aws cloudformation wait stack-delete-complete --stack-name "$stack_name"
    echo "Done"
}

check_opt() {
  name="$1"
  msg="$2"
  if [ -z "$name" ]; then
    echo "$msg"
    exit 1
  fi
}

if [ -z "$1" ]; then
  usage
fi

while getopts ":c:s:q:d:i:m:g:n:h" options; do
  case "$options" in
    c)
      cmd="$OPTARG"
      ;;
    s)
      stack_name="$OPTARG"
      ;;
    q)
      metric_namespace="$OPTARG"
      ;;
    d)
      dashboard_name="$OPTARG"
      ;;
    i)
      dashboard_image="$OPTARG"
      ;;
    m)
      mesh_name="$OPTARG"
      ;;
    g)
      resource_type=VirtualGateway
      resources="$OPTARG"
      ;;
    n)
      resource_type=VirtualNodes
      resources="$OPTARG"
      ;;
    h|:|*)
      usage
      ;;
  esac
done

check_opt "$cmd" "A command, deploy or delete must be specified"
check_opt "$stack_name" "Stack name is required"

case "$cmd" in
  delete)
    delete_cfn_stack "$stack_name"
    ;;
  deploy)
    check_opt "$dashboard_image" "Dashboard generator image URI is required"
    check_opt "$metric_namespace" "Metric namespace is required"
    check_opt "$mesh_name" "Mesh name is required"
    check_opt "$dashboard_name" "Dashboard name is required"
    check_opt "$resources" "Either a list of virtual node names or a virtual gateway name is required"

    echo "Deploying stack $stack_name, this may take a few minutes..."
    aws cloudformation deploy \
        --no-fail-on-empty-changeset \
        --stack-name "$stack_name" \
        --template-file "$DIR/deploy/dashboard-v1.yaml" \
        --capabilities CAPABILITY_IAM \
        --parameter-overrides \
        "DashboardImage=$dashboard_image" \
        "MetricNamespace=$metric_namespace" \
        "MeshName=$mesh_name" \
        "Name=$dashboard_name" \
        "$resource_type=$resources"
    ;;
  *)
    echo "Command must be either deploy or delete"
    exit 1
    ;;
esac


#!/usr/bin/env bash

set -e

check_command() {
  if ! [ -x "$(command -v "$1")" ]; then
    echo "$1 is required to run this script"
    exit
  fi
}

check_command aws
check_command docker

if [ -z "$AWS_ACCOUNT_ID" ]; then
    echo "AWS_ACCOUNT_ID environment variable is not set."
    exit 1
fi

if [ -z "$AWS_DEFAULT_REGION" ]; then
    echo "AWS_DEFAULT_REGION environment variable is not set."
    exit 1
fi

if [ -z "$ENVOY_IMAGE" ]; then
    echo "ENVOY_IMAGE environtment variable is not set, see https://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html"
    exit 1
fi

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
AWS_CLI_VERSION="$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)"

PROJECT_NAME="${PROJECT_NAME:-"howto-metrics-extension"}"
STACK_NAME="appmesh-$PROJECT_NAME"
ECR_URL="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com"
ECR_IMAGE_PREFIX="$ECR_URL/$PROJECT_NAME"
CW_AGENT_IMAGE="$ECR_IMAGE_PREFIX/cwagent"
DJAPP_IMAGE="$ECR_IMAGE_PREFIX/djapp"
DASHBOARD_V1_IMAGE="$ECR_IMAGE_PREFIX/dashboard-v1"
GO_PROXY="${GO_PROXY:-"https://proxy.golang.org"}"

ecr_login() {
    if [ "$AWS_CLI_VERSION" -gt 1 ]; then
        aws ecr get-login-password --region "$AWS_DEFAULT_REGION" | \
            docker login --username AWS --password-stdin "$ECR_URL"
    else
        # Note: we want to execute the output
        $(aws ecr get-login --no-include-email)
    fi
}

create_repositories() {
    for f in cwagent djapp dashboard-v1; do
        aws ecr describe-repositories --repository-name "$PROJECT_NAME/$f" >/dev/null 2>&1 || \
            aws ecr create-repository --repository-name "$PROJECT_NAME/$f" >/dev/null
    done
}

deploy_images() {
    create_repositories
    ecr_login

    docker build -t "$CW_AGENT_IMAGE" "$DIR/src/cwagent" && \
        docker push "$CW_AGENT_IMAGE"
    docker build -t "$DASHBOARD_V1_IMAGE" "$DIR/src/dashboard-v1" && \
        docker push "$DASHBOARD_V1_IMAGE"
    docker build -t "$DJAPP_IMAGE" --build-arg GO_PROXY="$GO_PROXY" "$DIR/src/djapp" && \
        docker push "$DJAPP_IMAGE"
}

delete_repositories() {
    for f in cwagent djapp dashboard-v1; do
        aws ecr delete-repository --force --repository-name "$PROJECT_NAME/$f" >/dev/null
    done
}

deploy() {
    stage="$1"

    echo "Deploying stack $STACK_NAME, this may take a few minutes..."
    aws cloudformation deploy \
        --no-fail-on-empty-changeset \
        --stack-name "$STACK_NAME" \
        --template-file "$DIR/deploy/$stage.yaml" \
        --capabilities CAPABILITY_IAM \
        --parameter-overrides \
        "ProjectName=$PROJECT_NAME" \
        "EnvoyImage=$ENVOY_IMAGE" \
        "CloudWatchAgentImage=$CW_AGENT_IMAGE" \
        "DJAppImage=$DJAPP_IMAGE"
}

delete_cfn_stack() {
    stack_name="$1"
    aws cloudformation delete-stack --stack-name "$stack_name"
    echo "Waiting for the stack $stack_name to be deleted, this may take a few minutes..."
    aws cloudformation wait stack-delete-complete --stack-name "$stack_name"
    echo "Done"
}

confirm_service_linked_role() {
    if ! (aws iam get-role --role-name AWSServiceRoleForAppMesh >/dev/null); then
        echo "Error: no service linked role for App Mesh exists"
        echo "see https://docs.aws.amazon.com/app-mesh/latest/userguide/using-service-linked-roles.html"
        exit 1
    fi
}

print_endpoint() {
    echo "Public endpoint is now available. Export it for later use:"
    prefix="$(aws cloudformation describe-stacks \
        --stack-name="$STACK_NAME" \
        --query="Stacks[0].Outputs[?OutputKey=='PublicEndpoint'].OutputValue" \
        --output=text)"
    echo "export PUBLIC_ENDPOINT=\"${prefix}\""
}

deploy_stacks() {
    if [ -z "$SKIP_IMAGES" ]; then
        echo "deploy images..."
        deploy_images
    fi

    echo "deploy app using stage $stage"
    deploy "$stage"

    if [ "$stage" == "djapp-v1" ]; then
    	confirm_service_linked_role
    fi
    print_endpoint
}

action="${1:-"deploy"}"
stage="${2:-"djapp-v1"}"

if [ "$action" == "delete" ]; then
    delete_cfn_stack "$STACK_NAME"
    delete_repositories
    exit 0
fi

deploy_stacks