diff --git a/basis/bin/add_api_portal.sh b/basis/bin/add_api_portal.sh index bab213e8..ddf06232 100755 --- a/basis/bin/add_api_portal.sh +++ b/basis/bin/add_api_portal.sh @@ -16,7 +16,7 @@ add_api_portal() { if [ "$APIM_HOST" != "" ]; then FIRST_LETTER_UPPERCASE=`echo $TF_VAR_prefix | sed -e "s/\b\(.\)/\u\1/g"` - if [ "$TF_VAR_ui_strategy" == "api" ]; then + if [ "$TF_VAR_ui_type" == "api" ]; then APIGW_URL=https://${APIGW_HOSTNAME}/${TF_VAR_prefix} for APP_DIR in `app_dir_list`; do if [ -f src/${APP_DIR}/openapi_spec.yaml ]; then diff --git a/basis/bin/auto_env.sh b/basis/bin/auto_env.sh index e1638d2e..c063c5e0 100755 --- a/basis/bin/auto_env.sh +++ b/basis/bin/auto_env.sh @@ -1,10 +1,14 @@ #!/bin/bash + +# Enable BASH history for Stack Trace. But do not store it. +set -o history -o histexpand +unset HISTFILE + if [[ -z "${BIN_DIR}" ]]; then export BIN_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) fi if [[ -z "${PROJECT_DIR}" ]]; then - echo "Error: PROJECT_DIR not set" - exit + error_exit "PROJECT_DIR not set" fi # Target DIR @@ -48,18 +52,18 @@ livelabs_green_button # XXX -> It would be safer to check also for TF_VAR_xxx containing __TO_FILL__ too if declare -p | grep -q "__TO_FILL__"; then - echo "Error: missing environment variables." + echo + echo "ERROR: missing environment variables" + echo declare -p | grep __TO_FILL__ echo echo "Edit the file env.sh. Some variables needs to be filled:" cat env.sh | grep __TO_FILL__ - exit 1 + error_exit "Missing environment variables." fi if ! command -v jq &> /dev/null; then - echo "Command jq could not be found. Please install it" - echo "Ex on linux: sudo yum install jq -y" - exit 1 + error_exit "Unix command jq not found. Please install it." fi #-- PRE terraform ---------------------------------------------------------- @@ -116,7 +120,7 @@ else auto_echo TF_VAR_region=$TF_VAR_region # Kubernetes and OCIR - if [ "$TF_VAR_deploy_strategy" == "kubernetes" ] || [ "$TF_VAR_deploy_strategy" == "function" ] || [ "$TF_VAR_deploy_strategy" == "container_instance" ] || [ -f $PROJECT_DIR/src/terraform/oke.tf ]; then + if [ "$TF_VAR_deploy_type" == "kubernetes" ] || [ "$TF_VAR_deploy_type" == "function" ] || [ "$TF_VAR_deploy_type" == "container_instance" ] || [ -f $PROJECT_DIR/src/terraform/oke.tf ]; then export TF_VAR_namespace=`oci os ns get | jq -r .data` auto_echo TF_VAR_namespace=$TF_VAR_namespace export TF_VAR_email=mail@domain.com @@ -134,7 +138,7 @@ else export TF_VAR_openapi_spec=$(cat $PROJECT_DIR/src/app/openapi_spec.yaml) fi - if [ "$TF_VAR_deploy_strategy" == "hpc" ]; then + if [ "$TF_VAR_deploy_type" == "hpc" ]; then # Create synonyms for variables with another name in the oci-hpc stack export TF_VAR_ssh_key=$TF_VAR_ssh_public_key export TF_VAR_targetCompartment=$TF_VAR_compartment_ocid @@ -142,6 +146,11 @@ else export TF_VAR_bastion_ad=$TF_VAR_ad fi + # TLS + if [ "$TF_VAR_dns_name" != "" ] && [ "$TF_VAR_certificate_ocid" == "" ]; then + export TF_VAR_certificate_ocid=`oci certs-mgmt certificate list --all --compartment-id $TF_VAR_compartment_ocid --name $TF_VAR_dns_name | jq -r .data.items[].id` + fi + # GIT if [ `git rev-parse --is-inside-work-tree 2>/dev/null` ]; then export GIT_BRANCH=`git rev-parse --abbrev-ref HEAD` @@ -149,20 +158,25 @@ else export TF_VAR_git_url=`git config --get remote.origin.url` if [[ "$TF_VAR_git_url" == *"github.com"* ]]; then S1=${TF_VAR_git_url/git@github.com:/https:\/\/github.com\/} - export TF_VAR_git_url=${S1/.git/\/blob\/}${GIT_BRANCH} + if [[ "$TF_VAR_git_url" == *".git"* ]]; then + export TF_VAR_git_url=${S1/.git/\/blob\/}${GIT_BRANCH} + else + export TF_VAR_git_url=${S1}/blob/${GIT_BRANCH} + fi elif [[ "$TF_VAR_git_url" == *"gitlab.com"* ]]; then S1=${TF_VAR_git_url/git@gitlab.com:/https:\/\/gitlab.com\/} export TF_VAR_git_url=${S1/.git/\/-\/blob\/}${GIT_BRANCH} fi cd $PROJECT_DIR export GIT_RELATIVE_PATH=`git rev-parse --show-prefix` - cd - + cd - > /dev/null export TF_VAR_git_url=${TF_VAR_git_url}/${GIT_RELATIVE_PATH} - echo $TF_VAR_git_url + auto_echo TF_VAR_git_url=$TF_VAR_git_url fi fi fi + #-- POST terraform ---------------------------------------------------------- export STATE_FILE=$TARGET_DIR/terraform.tfstate if [ -f $STATE_FILE ]; then @@ -170,15 +184,25 @@ if [ -f $STATE_FILE ]; then export OBJECT_STORAGE_URL=https://objectstorage.${TF_VAR_region}.oraclecloud.com # API GW - if [ "$TF_VAR_deploy_strategy" == "function" ] || [ "$TF_VAR_deploy_strategy" == "container_instance" ] || [ "$TF_VAR_ui_strategy" == "api" ]; then + if [ "$TF_VAR_deploy_type" == "function" ] || [ "$TF_VAR_deploy_type" == "container_instance" ] || [ "$TF_VAR_ui_type" == "api" ]; then # APIGW URL get_attribute_from_tfstate "APIGW_HOSTNAME" "starter_apigw" "hostname" # APIGW Deployment id get_attribute_from_tfstate "APIGW_DEPLOYMENT_OCID" "starter_apigw_deployment" "id" fi + # Instance Pool + if [ "$TF_VAR_deploy_type" == "instance_pool" ]; then + # XXX Does not work with Resource Manager XXX + # Check in the terraform state is the compute is already created. + get_id_from_tfstate "COMPUTE_OCID" "starter_instance" + if [ "$COMPUTE_OCID" != "" ]; then + export TF_VAR_compute_ready="true" + fi + fi + # Functions - if [ "$TF_VAR_deploy_strategy" == "function" ]; then + if [ "$TF_VAR_deploy_type" == "function" ]; then # OBJECT Storage URL export BUCKET_URL="https://objectstorage.${TF_VAR_region}.oraclecloud.com/n/${TF_VAR_namespace}/b/${TF_VAR_prefix}-public-bucket/o" @@ -195,7 +219,7 @@ if [ -f $STATE_FILE ]; then fi # Container Instance - if [ "$TF_VAR_deploy_strategy" == "container_instance" ]; then + if [ "$TF_VAR_deploy_type" == "container_instance" ]; then if [ -f $TARGET_DIR/docker_image_ui.txt ] || [ -f $TARGET_DIR/docker_image_app.txt ] ; then if [ -f $TARGET_DIR/docker_image_ui.txt ]; then export TF_VAR_docker_image_ui=`cat $TARGET_DIR/docker_image_ui.txt` @@ -220,19 +244,22 @@ if [ -f $STATE_FILE ]; then get_output_from_tfstate "JDBC_URL" "jdbc_url" get_output_from_tfstate "DB_URL" "db_url" - if [ "$TF_VAR_db_strategy" == "autonomous" ]; then + + if [ "$TF_VAR_db_type" == "autonomous" ]; then get_output_from_tfstate "ORDS_URL" "ords_url" fi - if [ "$TF_VAR_db_strategy" == "database" ]; then + if [ "$TF_VAR_db_type" == "database" ]; then get_attribute_from_tfstate "DB_NODE_IP" "starter_node_vnic" "private_ip_address" - elif [ "$TF_VAR_db_strategy" == "db_free" ]; then + elif [ "$TF_VAR_db_type" == "db_free" ]; then get_output_from_tfstate "DB_NODE_IP" "db_free_ip" fi - if [ "$TF_VAR_deploy_strategy" == "kubernetes" ] || [ -f $PROJECT_DIR/src/terraform/oke.tf ]; then + if [ "$TF_VAR_deploy_type" == "kubernetes" ] || [ -f $PROJECT_DIR/src/terraform/oke.tf ]; then # OKE get_output_from_tfstate "OKE_OCID" "oke_ocid" + export TF_VAR_ingress_ip=`kubectl get service -n ingress-nginx ingress-nginx-controller -o jsonpath="{.status.loadBalancer.ingress[0].ip}"` + export INGRESS_LB_OCID=`oci lb load-balancer list --compartment-id $TF_VAR_compartment_ocid | jq -r '.data[] | select(.["ip-addresses"][0]["ip-address"]=="'$TF_VAR_ingress_ip'") | .id'` fi # JMS diff --git a/basis/bin/build_all.sh b/basis/bin/build_all.sh index 018493fe..96a09ff6 100755 --- a/basis/bin/build_all.sh +++ b/basis/bin/build_all.sh @@ -14,7 +14,13 @@ title "OCI Starter - Build" if [ "$TF_VAR_ssh_private_path" == "" ]; then . $BIN_DIR/sshkey_generate.sh fi + . env.sh +if [ "$TF_VAR_tls" != "" ]; then + title "Certificate" + certificate_dir_before_terraform +fi + title "Terraform Apply" src/terraform/apply.sh --auto-approve -no-color exit_on_error @@ -52,24 +58,29 @@ if [ -f src/ui/build_ui.sh ]; then fi # Deploy -title "Deploy $TF_VAR_deploy_strategy" -if [ "$TF_VAR_deploy_strategy" == "compute" ]; then +title "Deploy $TF_VAR_deploy_type" +if [ "$TF_VAR_deploy_type" == "compute" ]; then $BIN_DIR/deploy_compute.sh exit_on_error -elif [ "$TF_VAR_deploy_strategy" == "instance_pool" ]; then +elif [ "$TF_VAR_deploy_type" == "instance_pool" ]; then $BIN_DIR/deploy_compute.sh exit_on_error export TF_VAR_compute_ready="true" src/terraform/apply.sh --auto-approve -no-color exit_on_error -elif [ "$TF_VAR_deploy_strategy" == "kubernetes" ]; then +elif [ "$TF_VAR_deploy_type" == "kubernetes" ]; then $BIN_DIR/oke_deploy.sh exit_on_error -elif [ "$TF_VAR_deploy_strategy" == "container_instance" ]; then +elif [ "$TF_VAR_deploy_type" == "container_instance" ]; then $BIN_DIR/ci_deploy.sh exit_on_error fi +if [ "$TF_VAR_tls" != "" ]; then + title "Certificate - Post Deploy" + certificate_post_deploy +fi + $BIN_DIR/add_api_portal.sh title "Done" diff --git a/basis/bin/build_common.sh b/basis/bin/build_common.sh index 256833a1..90e8e090 100755 --- a/basis/bin/build_common.sh +++ b/basis/bin/build_common.sh @@ -2,17 +2,17 @@ #!/bin/bash if [[ -z "${BIN_DIR}" ]]; then echo "Error: BIN_DIR not set" - exit + exit 1 fi if [[ -z "${PROJECT_DIR}" ]]; then echo "Error: PROJECT_DIR not set" - exit + exit 1 fi APP_DIR=`echo ${SCRIPT_DIR} |sed -E "s#(.*)/(.*)#\2#"` cd $SCRIPT_DIR -if [ -z "$TF_VAR_deploy_strategy" ]; then +if [ -z "$TF_VAR_deploy_type" ]; then . $PROJECT_DIR/env.sh else . $BIN_DIR/shared_bash_function.sh diff --git a/basis/bin/destroy_all.sh b/basis/bin/destroy_all.sh index 6d4dc370..cfca2367 100755 --- a/basis/bin/destroy_all.sh +++ b/basis/bin/destroy_all.sh @@ -29,7 +29,7 @@ fi if [ -f $PROJECT_DIR/src/terraform/oke.tf ]; then title "OKE Destroy" bin/oke_destroy.sh --auto-approve -elif [ "$TF_VAR_deploy_strategy" == "function" ]; then +elif [ "$TF_VAR_deploy_type" == "function" ]; then title "Delete Object Storage files" oci os object bulk-delete -bn ${TF_VAR_prefix}-public-bucket --force fi diff --git a/basis/bin/done.sh b/basis/bin/done.sh index de0f115a..2c5cfe6d 100755 --- a/basis/bin/done.sh +++ b/basis/bin/done.sh @@ -2,7 +2,7 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) cd $SCRIPT_DIR/.. -if [ -z "$TF_VAR_deploy_strategy" ]; then +if [ -z "$TF_VAR_deploy_type" ]; then . ./env.sh -silent else . bin/shared_bash_function.sh @@ -18,7 +18,7 @@ if [ ! -z "$UI_URL" ]; then if [ ! -z "$TEST_NAME" ]; then echo $UI_URL > /tmp/ui_url.txt - if [ "$TF_VAR_deploy_strategy" == "kubernetes" ]; then + if [ "$TF_VAR_deploy_type" == "kubernetes" ]; then kubectl wait --for=condition=ready pod ${TF_VAR_prefix}-app kubectl wait --for=condition=ready pod ${TF_VAR_prefix}-ui kubectl get all @@ -40,7 +40,7 @@ if [ ! -z "$UI_URL" ]; then sleep 5 x=$(( $x + 1 )) done - if [ "$TF_VAR_ui_strategy" != "api" ]; then + if [ "$TF_VAR_ui_type" != "api" ]; then if [ -f "/tmp/cookie.txt" ]; then rm /tmp/cookie.txt fi @@ -53,9 +53,12 @@ if [ ! -z "$UI_URL" ]; then fi curl $UI_URL/app/info -b /tmp/cookie.txt -c /tmp/cookie.txt -L --retry 5 --retry-max-time 20 -D /tmp/result_info.log > /tmp/result.info fi - if [ "$TF_VAR_ui_strategy" != "api" ]; then + if [ "$TF_VAR_ui_type" != "api" ]; then echo - User Interface: $UI_URL/ fi + if [ "$UI_HTTP" != "" ]; then + echo - HTTP : $UI_HTTP/ + fi for APP_DIR in `app_dir_list`; do if [ -f $PROJECT_DIR/src/$APP_DIR/openapi_spec.yaml ]; then python3 $BIN_DIR/openapi_list.py $PROJECT_DIR/src/$APP_DIR/openapi_spec.yaml $UI_URL @@ -63,11 +66,11 @@ if [ ! -z "$UI_URL" ]; then # echo - Rest DB API : $UI_URL/$APP_DIR/dept # echo - Rest Info API : $UI_URL/$APP_DIR/info done - if [ "$TF_VAR_deploy_strategy" == "compute" ] && [ "$TF_VAR_ui_strategy" == "api" ]; then + if [ "$TF_VAR_deploy_type" == "compute" ] && [ "$TF_VAR_ui_type" == "api" ]; then export APIGW_URL=https://${APIGW_HOSTNAME}/${TF_VAR_prefix} echo - API Gateway URL : $APIGW_URL/app/dept fi - if [ "$TF_VAR_language" == "java" ] && [ "$TF_VAR_java_framework" == "springboot" ] && [ "$TF_VAR_ui_strategy" == "html" ] && [ "$TF_VAR_db_node_count" == "2" ]; then + if [ "$TF_VAR_language" == "java" ] && [ "$TF_VAR_java_framework" == "springboot" ] && [ "$TF_VAR_ui_type" == "html" ] && [ "$TF_VAR_db_node_count" == "2" ]; then echo - RAC Page : $UI_URL/rac.html fi fi diff --git a/basis/bin/shared_bash_function.sh b/basis/bin/shared_bash_function.sh index f6706bcf..aae62344 100755 --- a/basis/bin/shared_bash_function.sh +++ b/basis/bin/shared_bash_function.sh @@ -35,7 +35,7 @@ build_ui() { if is_deploy_compute; then mkdir -p ../../target/compute/ui cp -r ui/* ../../target/compute/ui/. - elif [ "$TF_VAR_deploy_strategy" == "function" ]; then + elif [ "$TF_VAR_deploy_type" == "function" ]; then oci os object bulk-upload -ns $TF_VAR_namespace -bn ${TF_VAR_prefix}-public-bucket --src-dir ui --overwrite --content-type auto else # Kubernetes and Container Instances @@ -103,13 +103,31 @@ replace_db_user_password_in_file() { sed -i "s/##DB_PASSWORD##/$TF_VAR_db_password/" $CONFIG_FILE } +error_exit() { + echo + LEN=${#BASH_LINENO[@]} + printf "%-40s %-10s %-20s\n" "STACK TRACE" "LINE" "FUNCTION" + for (( INDEX=0; INDEX<$LEN; INDEX++ )) + do + printf " %-37s %-10s %-20s\n" ${BASH_SOURCE[${INDEX}]#$PROJECT_DIR/} ${BASH_LINENO[$(($INDEX-1))]} ${FUNCNAME[${INDEX}]} + done + + if [ "$1" != "" ]; then + echo + echo "ERROR: $1" + fi + exit 1 +} + exit_on_error() { RESULT=$? if [ $RESULT -eq 0 ]; then echo "Success" else - echo "Failed (RESULT=$RESULT)" - exit $RESULT + echo + echo "EXIT ON ERROR - HISTORY" + history 2 + error_exit "Command Failed (RESULT=$RESULT)" fi } @@ -234,19 +252,41 @@ get_user_details() { # Get the user interface URL get_ui_url() { - if [ "$TF_VAR_deploy_strategy" == "compute" ]; then - get_output_from_tfstate UI_URL ui_url - elif [ "$TF_VAR_deploy_strategy" == "instance_pool" ]; then - get_output_from_tfstate UI_URL pool_lb_url - elif [ "$TF_VAR_deploy_strategy" == "kubernetes" ]; then - export UI_URL=http://`kubectl get service -n ingress-nginx ingress-nginx-controller -o jsonpath="{.status.loadBalancer.ingress[0].ip}"`/${TF_VAR_prefix} - elif [ "$TF_VAR_deploy_strategy" == "function" ] || [ "$TF_VAR_deploy_strategy" == "container_instance" ]; then + if [ "$TF_VAR_deploy_type" == "compute" ]; then + if [ "$TF_VAR_tls" == "existing_ocid" ]; then + export UI_URL=https://${TF_VAR_dns_name}/${TF_VAR_prefix} + else + export UI_URL=http://${COMPUTE_IP} + if [ "$TF_VAR_certificate_ocid" != "" ]; then + export UI_HTTP=$UI_URL + export UI_URL=https://${TF_VAR_dns_name} + fi + fi + elif [ "$TF_VAR_deploy_type" == "instance_pool" ]; then + get_output_from_tfstate INSTANCE_POOL_LB_IP instance_pool_lb_ip + export UI_URL=http://${INSTANCE_POOL_LB_IP} + if [ "$TF_VAR_certificate_ocid" != "" ]; then + export UI_HTTP=$UI_URL + export UI_URL=https://${TF_VAR_dns_name} + fi + elif [ "$TF_VAR_deploy_type" == "kubernetes" ]; then + export TF_VAR_ingress_ip=`kubectl get service -n ingress-nginx ingress-nginx-controller -o jsonpath="{.status.loadBalancer.ingress[0].ip}"` + export UI_URL=http://${TF_VAR_ingress_ip}/${TF_VAR_prefix} + if [ "$TF_VAR_certificate_ocid" != "" ]; then + export UI_HTTP=$UI_URL + export UI_URL=https://${TF_VAR_dns_name}/${TF_VAR_prefix} + fi + elif [ "$TF_VAR_deploy_type" == "function" ] || [ "$TF_VAR_deploy_type" == "container_instance" ]; then export UI_URL=https://${APIGW_HOSTNAME}/${TF_VAR_prefix} + if [ "$TF_VAR_certificate_ocid" != "" ]; then + export UI_HTTP=$UI_URL + export UI_URL=https://${TF_VAR_dns_name}/${TF_VAR_prefix} + fi fi } is_deploy_compute() { - if [ "$TF_VAR_deploy_strategy" == "compute" ] || [ "$TF_VAR_deploy_strategy" == "instance_pool" ]; then + if [ "$TF_VAR_deploy_type" == "compute" ] || [ "$TF_VAR_deploy_type" == "instance_pool" ]; then return 0 else return 1 @@ -415,3 +455,93 @@ java_find_version() { fi } +certificate_validity() { + CERT_DATE_VALIDITY=`oci certs-mgmt certificate get --certificate-id $TF_VAR_certificate_ocid | jq -r '.data["current-version"].validity["time-of-validity-not-after"]'` + CERT_VALIDITY_DAY=`echo $((($(date -d $CERT_DATE_VALIDITY +%s) - $(date +%s))/86400))` + echo "Certificate valid until: $CERT_DATE_VALIDITY" + echo "Days left: $CERT_VALIDITY_DAY" +} + +certificate_create() { + echo "Creating or Updating certificate $TF_VAR_dns_name" + CERT_CERT=$(cat $TF_VAR_certificate_dir/cert.pem) + CERT_CHAIN=$(cat $TF_VAR_certificate_dir/chain.pem) + CERT_PRIVKEY=$(cat $TF_VAR_certificate_dir/privkey.pem) + if [ "$TF_VAR_certificate_ocid" == "" ]; then + oci certs-mgmt certificate create-by-importing-config --compartment-id=$TF_VAR_compartment_ocid --name=$TF_VAR_dns_name --cert-chain-pem="$CERT_CHAIN" --certificate-pem="$CERT_CERT" --private-key-pem="$CERT_PRIVKEY" --wait-for-state ACTIVE --wait-for-state FAILED + else + oci certs-mgmt certificate update-certificate-by-importing-config-details --certificate-id=$TF_VAR_certificate_ocid --cert-chain-pem="$CERT_CHAIN" --certificate-pem="$CERT_CERT" --private-key-pem="$CERT_PRIVKEY" --wait-for-state ACTIVE --wait-for-state FAILED + fi + exit_on_error + TF_VAR_certificate_ocid=`oci certs-mgmt certificate list --all --compartment-id $TF_VAR_compartment_ocid --name $TF_VAR_dns_name | jq -r .data.items[0].id` +} + +certificate_dir_before_terraform() { + if [ "$TF_VAR_dns_name" == "" ]; then + echo "ERROR: certificate_dir_before_terraform: TF_VAR_dns_name not defined" + exit 1 + fi + if [ -d $PROJECT_DIR/src/tls/$TF_VAR_dns_name ]; then + export TF_VAR_certificate_dir=$PROJECT_DIR/src/tls/$TF_VAR_dns_name + echo Using existing TF_VAR_certificate_dir=$TF_VAR_certificate_dir + elif [ -d $TF_VAR_certificate_dir ]; then + echo Using existing TF_VAR_certificate_dir=$TF_VAR_certificate_dir + elif [ "$TF_VAR_tls" == "new_dns_01" ]; then + # Create a new certificate via DNS-01 + $BIN_DIR/tls_dns_create.sh + exit_on_error + export TF_VAR_certificate_dir=$PROJECT_DIR/src/tls/$TF_VAR_dns_name + fi + + if [ "$TF_VAR_deploy_type" == "compute" ]; then + if [ -d target/compute/certificate ]; then + echo "Certificate Directory exists already" + elif [ "$TF_VAR_certificate_dir" != "" ]; then + mkdir -p target/compute/certificate + cp $TF_VAR_certificate_dir/* target/compute/certificate/. + cp src/tls/nginx_tls.conf target/compute/. + sed -i "s/##DNS_NAME##/$TF_VAR_dns_name/" target/compute/nginx_tls.conf + elif [ "$TF_VAR_tls" == "new_http_01" ]; then + echo "New Certificate will be created after the deployment." + else + echo "ERROR: compute: certificate_dir_before_terraform: missing variables TF_VAR_certificate_dir" + exit 1 + fi + elif [ "$TF_VAR_certificate_ocid" == "" ] && [ "$TF_VAR_certificate_dir" != "" ] ; then + certificate_create + elif [ "$TF_VAR_certificate_ocid" != "" ]; then + certificate_validity + else + exit_error "certificate_dir_before_terraform: missing variables TF_VAR_certificate_ocid or TF_VAR_certificate_dir" + fi +} + +# Certificate - Post Deploy +certificate_post_deploy() { + if [ "$TF_VAR_deploy_type" == "kubernetes" ]; then + # Set the TF_VAR_ingress_ip + get_ui_url + src/terraform/apply.sh --auto-approve -no-color + exit_on_error + elif [ "$TF_VAR_tls" == "new_http_01" ]; then + if [ "$TF_VAR_deploy_type" == "compute" ]; then + certificate_run_certbot_http_01 + fi + fi +} + +# Generate a certificate on compute +certificate_run_certbot_http_01() +{ + if [ -z "$TF_VAR_certificate_email" ]; then + exit_error "TF_VAR_certificate_email is not defined." + fi + + # Generate the certificate with Let'Encrypt on the COMPUTE + scp -r -o StrictHostKeyChecking=no -i $TF_VAR_ssh_private_path src/tls opc@$COMPUTE_IP:/home/opc/. + exit_on_error + ssh -o StrictHostKeyChecking=no -i $TF_VAR_ssh_private_path opc@$COMPUTE_IP "export TF_VAR_dns_name=\"$TF_VAR_dns_name\";export TF_VAR_certificate_email=\"$TF_VAR_certificate_email\"; bash tls/certbot_http_01.sh 2>&1 | tee -a tls/certbot_http_01.log" + scp -r -o StrictHostKeyChecking=no -i $TF_VAR_ssh_private_path opc@$COMPUTE_IP:tls/certificate target/. + exit_on_error + export TF_VAR_certificate_dir=$PROJECT_DIR/target/certificate/$TF_VAR_dns_name +} diff --git a/basis/bin/tls/dns_certbot_entrypoint.sh b/basis/bin/tls/dns_certbot_entrypoint.sh new file mode 100755 index 00000000..8cb0f609 --- /dev/null +++ b/basis/bin/tls/dns_certbot_entrypoint.sh @@ -0,0 +1,14 @@ +export TF_VAR_dns_name=$1 +echo TF_VAR_dns_name=$TF_VAR_dns_name +certbot -d $TF_VAR_dns_name --agree-tos --register-unsafely-without-email --manual --preferred-challenges dns \ + --manual-auth-hook /certbot_shared/dns_challenge.sh \ + --disable-hook-validation --force-renewal certonly + +ls -lR /etc/letsencrypt > /certbot_shared/etc_letsencrypt.log + +# Copy the certificate to the shared directory +cp -Lr /etc/letsencrypt/live/$TF_VAR_dns_name /certbot_shared/. +chmod -R 777 /certbot_shared/$TF_VAR_dns_name + +# Request OCI to clean the OCI DNS entry +echo clean > /certbot_shared/CERTBOT_DOMAIN_CLEAN \ No newline at end of file diff --git a/basis/bin/tls/dns_challenge.sh b/basis/bin/tls/dns_challenge.sh new file mode 100755 index 00000000..44452d28 --- /dev/null +++ b/basis/bin/tls/dns_challenge.sh @@ -0,0 +1,10 @@ +echo "-- dns_challenge.sh" +echo $CERTBOT_DOMAIN > /certbot_shared/CERTBOT_DOMAIN +echo $CERTBOT_VALIDATION > /certbot_shared/CERTBOT_VALIDATION +env > /certbot_shared/dns_challenge_env.log + +. /certbot_shared/dns_shared_function.sh + +wait_file /certbot_shared/DNS_CREATED + + diff --git a/basis/bin/tls/dns_challenge_clean.sh b/basis/bin/tls/dns_challenge_clean.sh new file mode 100755 index 00000000..f212cb9e --- /dev/null +++ b/basis/bin/tls/dns_challenge_clean.sh @@ -0,0 +1,7 @@ +echo "-- dns_challenge_clean.sh" + +ls -lR /etc/letsencrypt > /certbot_shared/etc_letsencrypt.log +cp -Lr /etc/letsencrypt/live/$CERTBOT_DOMAIN /certbot_shared/. +chmod 777 /certbot_shared/$CERTBOT_DOMAIN + +echo clean > /certbot_shared/CERTBOT_DOMAIN_CLEAN diff --git a/basis/bin/tls/dns_oci_background.sh b/basis/bin/tls/dns_oci_background.sh new file mode 100755 index 00000000..f5421601 --- /dev/null +++ b/basis/bin/tls/dns_oci_background.sh @@ -0,0 +1,17 @@ +# Wait that Certbot create the validation token +. $BIN_DIR/tls/dns_shared_function.sh + +wait_file $TARGET_DIR/certbot_shared/CERTBOT_DOMAIN ] + +export CERBOT_DOMAIN=`cat $TARGET_DIR/certbot_shared/CERTBOT_DOMAIN` +export CERTBOT_VALIDATION=`cat $TARGET_DIR/certbot_shared/CERTBOT_VALIDATION` +export TF_VAR_dns_acme_challenge=_acme-challenge.${CERBOT_DOMAIN} +export TF_VAR_dns_data=$CERTBOT_VALIDATION +oci dns record rrset update --force --zone-name-or-id $TF_VAR_dns_zone_name --domain $TF_VAR_dns_acme_challenge --rtype 'TXT' --items '[{"domain":"'$TF_VAR_dns_acme_challenge'", "rdata":"'$TF_VAR_dns_data'", "rtype":"TXT","ttl":300}]' +# XXX Check that DNS is really propagated ? +sleep 10 +echo "done" > $TARGET_DIR/certbot_shared/DNS_CREATED + +# Wait that Certbot create the validation token +wait_file $TARGET_DIR/certbot_shared/CERTBOT_DOMAIN_CLEAN ] +oci dns record rrset delete --force --zone-name-or-id $TF_VAR_dns_zone_name --domain $TF_VAR_dns_acme_challenge --rtype 'TXT' diff --git a/basis/bin/tls/dns_shared_function.sh b/basis/bin/tls/dns_shared_function.sh new file mode 100755 index 00000000..63a51f80 --- /dev/null +++ b/basis/bin/tls/dns_shared_function.sh @@ -0,0 +1,15 @@ +wait_file() { + echo "Waiting File $1" + x=60 + until [ -f $1 ] + do + x=$(( $x - 1 )) + if [ $x -eq 0 ]; then + echo "ERROR: $1 not found" + exit 1 + fi + echo "- waiting 5 secs" + sleep 5 + done + echo "File found" +} \ No newline at end of file diff --git a/basis/bin/tls_dns_create.sh b/basis/bin/tls_dns_create.sh new file mode 100755 index 00000000..2fca1d62 --- /dev/null +++ b/basis/bin/tls_dns_create.sh @@ -0,0 +1,33 @@ +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd $SCRIPT_DIR/.. +. env.sh -silent +. $BIN_DIR/tls/dns_shared_function.sh + +# Start OCI Commands in Backgroud waiting from files coming from certbot +# (Since Certbot Docker has not OCI CLI access) +$BIN_DIR/tls/dns_oci_background.sh > $TARGET_DIR/dns_oci_background.log 2>&1 & + +if [ "$TF_VAR_dns_name" == "" ]; then + echo "ERROR: TF_VAR_dns_name not defined" + exit 1 +fi + +# Delete the directory in case of a previous run +if [ -d $TARGET_DIR/certbot_shared ]; then + rm -Rf $TARGET_DIR/certbot_shared +fi +mkdir -p $TARGET_DIR/certbot_shared +cp $BIN_DIR/tls/dns* $TARGET_DIR/certbot_shared/. + +# docker run -it --rm --name certbot --entrypoint /bin/sh certbot/certbot +docker run -it --rm --name certbot -v "$TARGET_DIR/certbot_shared:/certbot_shared" --entrypoint /bin/sh certbot/certbot /certbot_shared/dns_certbot_entrypoint.sh $TF_VAR_dns_name + +# Copy the certificate directory to src/tls +if [ -d $TARGET_DIR/certbot_shared/$TF_VAR_dns_name ]; then + mkdir -p $PROJECT_DIR/src/tls + cp -R $TARGET_DIR/certbot_shared/$TF_VAR_dns_name $PROJECT_DIR/src/tls/. + rm -R $TARGET_DIR/certbot_shared/$TF_VAR_dns_name +else + echo "ERROR: certificate not found. Check for errors before." + exit 1 +fi \ No newline at end of file diff --git a/basis/bin/upgrade.sh b/basis/bin/upgrade.sh new file mode 100755 index 00000000..99b795af --- /dev/null +++ b/basis/bin/upgrade.sh @@ -0,0 +1,45 @@ +#!/bin/bash +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd $SCRIPT_DIR/.. +. env.sh + +## Remove variable that should not be exposed +export `compgen -A variable | grep _ocid | grep _ocid | sed 's/$/=__TO_FILL__/'` +export TF_VAR_db_password=__TO_FILL__ +export TF_VAR_auth_token=__TO_FILL__ + +PARAM_LIST="" + +IFS=',' +read -ra ARR <<<"$OCI_STARTER_PARAMS" +for p in "${ARR[@]}"; +do + VAR_NAME="TF_VAR_${p}" + VAR_VALUE=${!VAR_NAME} + echo "$p - $VAR_NAME - $VAR_VALUE" + if [ "$VAR_VALUE" != "" ]; then + PARAM_LIST="${PARAM_LIST}${p}=${!VAR_NAME}&" + fi +done +PARAM_LIST=`echo $PARAM_LIST|sed 's/&$//'` + +echo "curl -k https://www.ocistarter.com/app/zip?$PARAM_LIST" + +UPGRADE_DIR="upgrade$(date +%Y%m%d%H%M%S)" + +cd $PROJECT_DIR +mkdir $UPGRADE_DIR +cd $UPGRADE_DIR +curl -k "https://www.ocistarter.com/app/zip?$PARAM_LIST" --output upgrade.zip +unzip upgrade.zip +rm upgrade.zip +mv $TF_VAR_prefix/* $TF_VAR_prefix/.* . +rmdir $TF_VAR_prefix +mkdir orig +mv src orig +mv env.sh orig +cp -r ../src . +cp ../env.sh . + +echo +echo "Upgrade directory created: $UPGRADE_DIR" diff --git a/basis/src/app/app.j2.yaml b/basis/src/app/app.j2.yaml new file mode 100644 index 00000000..8b84f6ad --- /dev/null +++ b/basis/src/app/app.j2.yaml @@ -0,0 +1,81 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ prefix }}-dep + labels: + app: {{ prefix }}-app +spec: + replicas: 1 + selector: + matchLabels: + app: {{ prefix }}-app + template: + metadata: + labels: + app: {{ prefix }}-app + spec: + containers: + - name: app + image: ##DOCKER_PREFIX##/{{ prefix }}-app + ports: + - containerPort: 8080 + name: app-port + env: +{%- if language == "java" %} +{%- if java_framework == "helidon" or java_framework == "helidon4" %} + - name: JAVAX_SQL_DATASOURCE_DS1_DATASOURCE_URL + valueFrom: + secretKeyRef: + name: {{ prefix }}-db-secret + key: jdbc_url +{%- else %} +{%- if java_framework == "springboot" %} + - name: SPRING_APPLICATION_JSON + valueFrom: + secretKeyRef: + name: {{ prefix }}-db-secret + key: spring_application_json +{%- endif %} + - name: JDBC_URL + valueFrom: + secretKeyRef: + name: {{ prefix }}-db-secret + key: jdbc_url +{%- endif %} +{%- else %} + - name: DB_URL + valueFrom: + secretKeyRef: + name: {{ prefix }}-db-secret + key: db_url +{%- endif %} + - name: DB_USER + valueFrom: + secretKeyRef: + name: {{ prefix }}-db-secret + key: db_user + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ prefix }}-db-secret + key: db_password + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + imagePullSecrets: + - name: ocirsecret +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ prefix }}-app-service +spec: + selector: + app: {{ prefix }}-app + ports: + - name: http-service-port + protocol: TCP + port: 80 + targetPort: app-port +--- \ No newline at end of file diff --git a/basis/src/app/app.yaml b/basis/src/app/app.yaml deleted file mode 100644 index bb91c36c..00000000 --- a/basis/src/app/app.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: ##PREFIX##-app - labels: - app: ##PREFIX##-app -spec: - containers: - - name: app - image: ##DOCKER_PREFIX##/##PREFIX##-app - ports: - - containerPort: 8080 - name: app-port - env: - - name: DB_URL - valueFrom: - secretKeyRef: - name: ##PREFIX##-db-secret - key: db_url - - name: DB_USER - valueFrom: - secretKeyRef: - name: ##PREFIX##-db-secret - key: db_user - - name: DB_PASSWORD - valueFrom: - secretKeyRef: - name: ##PREFIX##-db-secret - key: db_password - imagePullSecrets: - - name: ocirsecret ---- -apiVersion: v1 -kind: Service -metadata: - name: ##PREFIX##-app-service -spec: - selector: - app: ##PREFIX##-app - ports: - - name: http-service-port - protocol: TCP - port: 80 - targetPort: app-port ---- \ No newline at end of file diff --git a/basis/src/terraform/variable.tf b/basis/src/terraform/variable.tf index b33fdb0b..5f27ed96 100644 --- a/basis/src/terraform/variable.tf +++ b/basis/src/terraform/variable.tf @@ -43,6 +43,9 @@ variable group_name { default="" } # Log Group variable log_group_ocid { default="" } +# Certificate +variable "certificate_ocid" { default = "" } + locals { group_name = var.group_name == "" ? "none" : var.group_name diff --git a/coderepo.tf b/coderepo.tf index 19903212..c94efedf 100644 --- a/coderepo.tf +++ b/coderepo.tf @@ -32,12 +32,12 @@ resource "null_resource" "clonerepo" { export TF_VAR_vcn_strategy="${local.vcn_strategy}" export TF_VAR_vcn_ocid="${var.vcn_ocid}" export TF_VAR_subnet_ocid="${var.subnet_ocid}" - export TF_VAR_ui_strategy="${var.ui_strategy}" - export TF_VAR_deploy_strategy="${local.deploy_strategy}" + export TF_VAR_ui_type="${var.ui_type}" + export TF_VAR_deploy_type="${local.deploy_type}" export TF_VAR_kubernetes_strategy="${var.kubernetes_strategy}" export TF_VAR_oke_strategy="${local.oke_strategy}" export TF_VAR_oke_ocid="${var.oke_ocid}" - export TF_VAR_db_strategy="${local.db_strategy}" + export TF_VAR_db_type="${local.db_type}" export TF_VAR_db_existing_strategy="${local.db_existing_strategy}" export TF_VAR_atp_ocid="${var.atp_ocid}" export TF_VAR_db_ocid="${var.db_ocid}" @@ -68,10 +68,10 @@ locals { git_url = "https://${local.encode_user}:${local.encode_token}@devops.scmservice.${var.region}.oci.oraclecloud.com/namespaces/${local.ocir_namespace}/projects/${oci_devops_project.test_project.name}/repositories/${oci_devops_repository.test_repository.name}" # Simplify the parameter values - deploy_strategy = lookup({"Virtual Machine": "compute", "Kubernetes": "kubernetes", "Function": "function"}, var.deploy_strategy, "error" ) + deploy_type = lookup({"Virtual Machine": "compute", "Kubernetes": "kubernetes", "Function": "function"}, var.deploy_type, "error" ) java_framework = lower(var.java_framework) language = lower(var.language) - db_strategy = lookup({"Autonomous Transaction Processing Database": "autonomous", "Database System": "database", "MySQL": "mysql"}, var.db_strategy, "error" ) + db_type = lookup({"Autonomous Transaction Processing Database": "autonomous", "Database System": "database", "MySQL": "mysql"}, var.db_type, "error" ) java_vm = lookup({"JDK": "jdk", "GraalVM": "graalvm"}, var.java_vm, "error" ) db_existing_strategy = lookup({"Create New DB": "new", "Use Existing DB": "existing"}, var.db_existing_strategy, "error" ) vcn_strategy = lookup({"Create New VCN": "new", "Use Existing VCN": "existing"}, var.vcn_strategy, "error" ) diff --git a/oci_starter.sh b/oci_starter.sh index 5e10f482..0c41b940 100755 --- a/oci_starter.sh +++ b/oci_starter.sh @@ -10,3 +10,4 @@ cd $SCRIPT_DIR rm -rf ./output python3 py_oci_starter.py "$@" +exit $RESULT \ No newline at end of file diff --git a/option/compute/compute_bootstrap.sh b/option/compute/compute_bootstrap.sh index 06e6948c..c41ea489 100755 --- a/option/compute/compute_bootstrap.sh +++ b/option/compute/compute_bootstrap.sh @@ -122,6 +122,13 @@ else sudo awk -i inplace '/404.html/ && !x {print " include conf.d/nginx_app.locations;"; x=1} 1' /etc/nginx/nginx.conf fi +# TLS +if [ -f nginx_tls.conf ]; then + echo "Adding nginx_tls.conf" + sudo cp nginx_tls.conf /etc/nginx/conf.d/. + sudo awk -i inplace '/# HTTPS server/ && !x {print " include conf.d/nginx_tls.conf;"; x=1} 1' /etc/nginx/nginx.conf +fi + # SE Linux (for proxy_pass) sudo setsebool -P httpd_can_network_connect 1 @@ -136,6 +143,7 @@ fi # Firewalld sudo firewall-cmd --zone=public --add-port=80/tcp --permanent +sudo firewall-cmd --zone=public --add-port=443/tcp --permanent sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent sudo firewall-cmd --reload diff --git a/option/container_instance/ci_deploy.sh b/option/container_instance/ci_deploy.sh index 191042ad..4ba335fc 100755 --- a/option/container_instance/ci_deploy.sh +++ b/option/container_instance/ci_deploy.sh @@ -6,7 +6,7 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) # Call build_common to push the ${TF_VAR_prefix}-app:latest and ui:latest to OCIR Docker registry ocir_docker_push -if [ "$TF_VAR_ui_strategy" != "api" ]; then +if [ "$TF_VAR_ui_type" != "api" ]; then echo "${DOCKER_PREFIX}/${TF_VAR_prefix}-ui:latest" > $TARGET_DIR/docker_image_ui.txt fi if [ "$TF_VAR_language" != "ords" ]; then diff --git a/option/oke/ingress-app.yaml b/option/oke/ingress-app.yaml index 32154d37..02442f97 100644 --- a/option/oke/ingress-app.yaml +++ b/option/oke/ingress-app.yaml @@ -4,14 +4,16 @@ kind: Ingress metadata: name: ##PREFIX##-app-ingress annotations: - kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/rewrite-target: /$2 + # nginx.ingress.kubernetes.io/affinity: "cookie" + # nginx.ingress.kubernetes.io/session-cookie-path: "/" spec: + ingressClassName: nginx rules: - http: paths: - path: /##PREFIX##/app(/|$)(.*) - pathType: Prefix + pathType: ImplementationSpecific backend: service: name: ##PREFIX##-app-service diff --git a/option/oke/ingress-ui.yaml b/option/oke/ingress-ui.yaml index 0cfc7181..27240ea9 100644 --- a/option/oke/ingress-ui.yaml +++ b/option/oke/ingress-ui.yaml @@ -3,15 +3,14 @@ kind: Ingress metadata: name: ##PREFIX##-ui-ingress annotations: - kubernetes.io/ingress.class: "nginx" - nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: + ingressClassName: nginx rules: - http: paths: - path: /##PREFIX##(/|$)(.*) - pathType: Prefix + pathType: ImplementationSpecific backend: service: name: ##PREFIX##-ui-service diff --git a/option/oke/oke_deploy.sh b/option/oke/oke_deploy.sh index f3cfff38..d2653497 100755 --- a/option/oke/oke_deploy.sh +++ b/option/oke/oke_deploy.sh @@ -11,17 +11,23 @@ ocir_docker_push if [ ! -f $KUBECONFIG ]; then create_kubeconfig - # Deploy ingress-nginx + # Deploy Latest ingress-nginx kubectl create clusterrolebinding starter_clst_adm --clusterrole=cluster-admin --user=$TF_VAR_user_ocid - kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.4.0/deploy/static/provider/cloud/deploy.yaml - kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=240s + LATEST_INGRESS_CONTROLLER=`curl --silent "https://api.github.com/repos/kubernetes/ingress-nginx/releases/latest" | jq -r .name` + echo LATEST_INGRESS_CONTROLLER=$LATEST_INGRESS_CONTROLLER + kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/$LATEST_INGRESS_CONTROLLER/deploy/static/provider/cloud/deploy.yaml + + # Wait for the deployment + echo "Waiting for Ingress Controller Pods..." + kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=600s kubectl wait --namespace ingress-nginx --for=condition=Complete job/ingress-nginx-admission-patch + # Wait for the ingress external IP - external_ip="" - while [ -z $external_ip ]; do - echo "Waiting for external IP..." - external_ip=$(kubectl get svc -n ingress-nginx ingress-nginx-controller --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}") - if [ -z "$external_ip" ]; then + TF_VAR_ingress_ip="" + while [ -z $TF_VAR_ingress_ip ]; do + echo "Waiting for Ingress IP..." + TF_VAR_ingress_ip=`kubectl get service -n ingress-nginx ingress-nginx-controller -o jsonpath="{.status.loadBalancer.ingress[0].ip}"` + if [ -z "$TF_VAR_ingress_ip" ]; then sleep 10 fi done @@ -29,28 +35,32 @@ if [ ! -f $KUBECONFIG ]; then date kubectl get all -n ingress-nginx sleep 5 - echo "Ingress ready: $external_ip" + echo "Ingress ready: $TF_VAR_ingress_ip" # Create secrets kubectl create secret docker-registry ocirsecret --docker-server=$TF_VAR_ocir --docker-username="$TF_VAR_namespace/$TF_VAR_username" --docker-password="$TF_VAR_auth_token" --docker-email="$TF_VAR_email" # XXXX - This should be by date - kubectl delete secret ${TF_VAR_prefix}-db-secret + kubectl delete secret ${TF_VAR_prefix}-db-secret --ignore-not-found=true kubectl create secret generic ${TF_VAR_prefix}-db-secret --from-literal=db_user=$TF_VAR_db_user --from-literal=db_password=$TF_VAR_db_password --from-literal=db_url=$DB_URL --from-literal=jdbc_url=$JDBC_URL --from-literal=spring_application_json='{ "db.info": "Java - SpringBoot" }' fi # Using & as separator sed "s&##DOCKER_PREFIX##&${DOCKER_PREFIX}&" src/app/app.yaml > $TARGET_DIR/app.yaml sed "s&##DOCKER_PREFIX##&${DOCKER_PREFIX}&" src/ui/ui.yaml > $TARGET_DIR/ui.yaml +cp src/oke/ingress-app.yaml $TARGET_DIR/ingress-app.yaml # If present, replace the ORDS URL -ORDS_HOST=`basename $(dirname $ORDS_URL)` -sed -i "s&##ORDS_HOST##&$ORDS_HOST&" $TARGET_DIR/app.yaml -sed "s&##ORDS_HOST##&$ORDS_HOST&" src/oke/ingress-app.yaml > $TARGET_DIR/ingress-app.yaml +if [ "$ORDS_URL" != "" ]; then + ORDS_HOST=`basename $(dirname $ORDS_URL)` + sed -i "s&##ORDS_HOST##&$ORDS_HOST&" $TARGET_DIR/app.yaml + sed -i "s&##ORDS_HOST##&$ORDS_HOST&" $TARGET_DIR/ingress-app.yaml +fi # delete the old pod, just to be sure a new image is pulled -kubectl delete pod ${TF_VAR_prefix}-app ${TF_VAR_prefix}-ui -# Wait to be sure that the pod is deleted before to recreate -kubectl wait --for=delete pod/${TF_VAR_prefix}-app --timeout=30s +kubectl delete pod ${TF_VAR_prefix}-ui --ignore-not-found=true +kubectl delete deployment ${TF_VAR_prefix}-dep --ignore-not-found=true +# Wait to be sure that the deployment is deleted before to recreate +kubectl wait --for=delete deployment/${TF_VAR_prefix}-dep --timeout=30s # Create objects in Kubernetes kubectl apply -f $TARGET_DIR/app.yaml diff --git a/option/oke/oke_destroy.sh b/option/oke/oke_destroy.sh index cf7a7815..a419148e 100755 --- a/option/oke/oke_destroy.sh +++ b/option/oke/oke_destroy.sh @@ -13,14 +13,20 @@ fi echo "OKE DESTROY" if [ "$1" != "--auto-approve" ]; then - echo "Error: Please call this script via destroy.sh" - exit + error_exit "Please call this script via destroy.sh" fi if [ ! -f $KUBECONFIG ]; then create_kubeconfig fi +# Check if OKE is still in the terraform state file +get_id_from_tfstate "OKE_OCID" "starter_oke" +if [ "$OKE_OCID" == "" ]; then + echo "OKE_DESTROY skipped. OKE not detected in $STATE_FILE" + exit 0 +fi + # The goal is to destroy all LoadBalancers created by OKE in OCI before to delete OKE. # # Delete all ingress, services diff --git a/option/src/app/apex/app.yaml b/option/src/app/apex/app.j2.yaml similarity index 68% rename from option/src/app/apex/app.yaml rename to option/src/app/apex/app.j2.yaml index b8850a27..67127216 100644 --- a/option/src/app/apex/app.yaml +++ b/option/src/app/apex/app.j2.yaml @@ -1,7 +1,7 @@ kind: Service apiVersion: v1 metadata: - name: ##PREFIX##-app-service + name: {{ prefix }}-app-service spec: type: ExternalName externalName: ##ORDS_HOST## diff --git a/option/src/app/apex/ingress-app.yaml b/option/src/app/apex/ingress-app.yaml index a6e84364..7bc85339 100644 --- a/option/src/app/apex/ingress-app.yaml +++ b/option/src/app/apex/ingress-app.yaml @@ -3,16 +3,16 @@ kind: Ingress metadata: name: ##PREFIX##-app-ingress annotations: - kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/rewrite-target: /ords/r/apex_app/apex_app/$2 nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" nginx.ingress.kubernetes.io/upstream-vhost: "##ORDS_HOST##" spec: + ingressClassName: nginx rules: - http: paths: - path: /##PREFIX##/app(/|$)(.*) - pathType: Prefix + pathType: ImplementationSpecific backend: service: name: ##PREFIX##-app-service diff --git a/option/src/app/java_helidon/app.yaml b/option/src/app/java_helidon/app.yaml.orig similarity index 100% rename from option/src/app/java_helidon/app.yaml rename to option/src/app/java_helidon/app.yaml.orig diff --git a/option/src/app/java_helidon4/app.yaml b/option/src/app/java_helidon4/app.yaml.orig similarity index 100% rename from option/src/app/java_helidon4/app.yaml rename to option/src/app/java_helidon4/app.yaml.orig diff --git a/option/src/app/java_micronaut/app.yaml.orig b/option/src/app/java_micronaut/app.yaml.orig new file mode 100644 index 00000000..55353f4e --- /dev/null +++ b/option/src/app/java_micronaut/app.yaml.orig @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ##PREFIX##-dep + labels: + app: ##PREFIX##-app +spec: + replicas: 1 + selector: + matchLabels: + app: ##PREFIX##-app + template: + metadata: + labels: + app: ##PREFIX##-app + spec: + containers: + - name: ##PREFIX##-app + image: ##DOCKER_PREFIX##/##PREFIX##-app + ports: + - containerPort: 8080 + name: app-port + env: + - name: JDBC_URL + valueFrom: + secretKeyRef: + name: ##PREFIX##-db-secret + key: jdbc_url + - name: DB_USER + valueFrom: + secretKeyRef: + name: ##PREFIX##-db-secret + key: db_user + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: ##PREFIX##-db-secret + key: db_password + imagePullSecrets: + - name: ocirsecret +--- +apiVersion: v1 +kind: Service +metadata: + name: ##PREFIX##-app-service +spec: + selector: + app: ##PREFIX##-app + ports: + - name: http-service-port + protocol: TCP + port: 80 + targetPort: app-port +--- \ No newline at end of file diff --git a/option/src/app/java_springboot/app.yaml b/option/src/app/java_springboot/app.yaml.orig similarity index 100% rename from option/src/app/java_springboot/app.yaml rename to option/src/app/java_springboot/app.yaml.orig diff --git a/option/src/app/java_springboot/src/main/java/com/example/demo/DemoController.java b/option/src/app/java_springboot/src/main/java/com/example/demo/DemoController.java index 92bc5aa4..409ae9cd 100644 --- a/option/src/app/java_springboot/src/main/java/com/example/demo/DemoController.java +++ b/option/src/app/java_springboot/src/main/java/com/example/demo/DemoController.java @@ -2,10 +2,10 @@ import org.springframework.web.bind.annotation.*; import org.springframework.beans.factory.annotation.Autowired; -import java.sql.*; -import java.util.ArrayList; -import java.util.List; +import java.net.Inet4Address; +import java.sql.*; +import java.util.*; import oracle.ucp.jdbc.PoolDataSourceFactory; import oracle.ucp.jdbc.PoolDataSource; @@ -13,7 +13,6 @@ public class DemoController { static PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); - public record Dept( int deptno, String dname, String loc ) {}; @Autowired @@ -58,7 +57,8 @@ public List query() { } @RequestMapping(value = "/info", method = RequestMethod.GET, produces = { "text/plain" }) - public String info() { - return "Java - SpringBoot"; + public String info() throws Exception { + String IP = (System.getenv("POD_IP")==null)?Inet4Address.getLocalHost().getHostAddress():System.getenv("POD_IP"); + return "Java - SpringBoot - IP " + IP; } -} \ No newline at end of file +} diff --git a/option/src/app/java_springboot_mysql/src/main/java/com/example/demo/DemoController.java b/option/src/app/java_springboot_mysql/src/main/java/com/example/demo/DemoController.java index 3f789d8f..a9f1a1bb 100644 --- a/option/src/app/java_springboot_mysql/src/main/java/com/example/demo/DemoController.java +++ b/option/src/app/java_springboot_mysql/src/main/java/com/example/demo/DemoController.java @@ -2,10 +2,9 @@ import org.springframework.web.bind.annotation.*; import org.springframework.beans.factory.annotation.Autowired; +import java.net.Inet4Address; import java.sql.*; - -import java.util.ArrayList; -import java.util.List; +import java.util.*; @RestController @@ -45,7 +44,8 @@ public List query() { } @RequestMapping(value = "/info", method = RequestMethod.GET, produces ={ "text/plain" }) - public String info() { - return "Java - SpringBoot"; + public String info() throws Exception { + String IP = (System.getenv("POD_IP")==null)?Inet4Address.getLocalHost().getHostAddress():System.getenv("POD_IP"); + return "Java - SpringBoot - IP " + IP; } } diff --git a/option/src/app/java_springboot_none/src/main/java/com/example/demo/DemoController.java b/option/src/app/java_springboot_none/src/main/java/com/example/demo/DemoController.java index 498085cc..2b4122f0 100644 --- a/option/src/app/java_springboot_none/src/main/java/com/example/demo/DemoController.java +++ b/option/src/app/java_springboot_none/src/main/java/com/example/demo/DemoController.java @@ -3,9 +3,8 @@ import org.springframework.web.bind.annotation.*; import org.springframework.beans.factory.annotation.Autowired; import java.sql.*; - -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.net.Inet4Address; @RestController @@ -33,7 +32,8 @@ public List query() { } @RequestMapping(value = "/info", method = RequestMethod.GET, produces ={ "text/plain" }) - public String info() { - return "Java - SpringBoot / No Database"; + public String info() throws Exception { + String IP = (System.getenv("POD_IP")==null)?Inet4Address.getLocalHost().getHostAddress():System.getenv("POD_IP"); + return "Java - SpringBoot / No Database - IP " + IP; } } diff --git a/option/src/app/java_springboot_psql/src/main/java/com/example/demo/DemoController.java b/option/src/app/java_springboot_psql/src/main/java/com/example/demo/DemoController.java index 3f789d8f..d9e8f1ee 100644 --- a/option/src/app/java_springboot_psql/src/main/java/com/example/demo/DemoController.java +++ b/option/src/app/java_springboot_psql/src/main/java/com/example/demo/DemoController.java @@ -2,10 +2,9 @@ import org.springframework.web.bind.annotation.*; import org.springframework.beans.factory.annotation.Autowired; +import java.net.Inet4Address; import java.sql.*; - -import java.util.ArrayList; -import java.util.List; +import java.util.*; @RestController @@ -45,7 +44,8 @@ public List query() { } @RequestMapping(value = "/info", method = RequestMethod.GET, produces ={ "text/plain" }) - public String info() { - return "Java - SpringBoot"; + public String info() throws Exception { + String IP = (System.getenv("POD_IP")==null)?Inet4Address.getLocalHost().getHostAddress():System.getenv("POD_IP"); + return "Java - SpringBoot - IP " + IP; } } diff --git a/option/src/app/java_tomcat/app.yaml b/option/src/app/java_tomcat/app.yaml deleted file mode 100644 index 2350d3c3..00000000 --- a/option/src/app/java_tomcat/app.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: ##PREFIX##-app - labels: - app: ##PREFIX##-app -spec: - containers: - - name: ##PREFIX##-app - image: ##DOCKER_PREFIX##/##PREFIX##-app - ports: - - containerPort: 8080 - name: app-port - env: - - name: JDBC_URL - valueFrom: - secretKeyRef: - name: ##PREFIX##-db-secret - key: jdbc_url - - name: DB_USER - valueFrom: - secretKeyRef: - name: ##PREFIX##-db-secret - key: db_user - - name: DB_PASSWORD - valueFrom: - secretKeyRef: - name: ##PREFIX##-db-secret - key: db_password - imagePullSecrets: - - name: ocirsecret ---- -apiVersion: v1 -kind: Service -metadata: - name: ##PREFIX##-app-service -spec: - selector: - app: ##PREFIX##-app - ports: - - name: http-service-port - protocol: TCP - port: 80 - targetPort: app-port ---- \ No newline at end of file diff --git a/option/src/app/java_micronaut/app.yaml b/option/src/app/java_tomcat/app.yaml.orig similarity index 100% rename from option/src/app/java_micronaut/app.yaml rename to option/src/app/java_tomcat/app.yaml.orig diff --git a/option/src/app/java_tomcat/ingress-app.yaml b/option/src/app/java_tomcat/ingress-app.yaml index 3158112b..1b7e2e54 100644 --- a/option/src/app/java_tomcat/ingress-app.yaml +++ b/option/src/app/java_tomcat/ingress-app.yaml @@ -4,14 +4,14 @@ kind: Ingress metadata: name: ##PREFIX##-app-ingress annotations: - kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/rewrite-target: /starter-1.0/$2 spec: + ingressClassName: nginx rules: - http: paths: - path: /##PREFIX##/app(/|$)(.*) - pathType: Prefix + pathType: ImplementationSpecific backend: service: name: ##PREFIX##-app-service diff --git a/option/src/app/ords/app.yaml b/option/src/app/ords/app.j2.yaml similarity index 68% rename from option/src/app/ords/app.yaml rename to option/src/app/ords/app.j2.yaml index b8850a27..67127216 100644 --- a/option/src/app/ords/app.yaml +++ b/option/src/app/ords/app.j2.yaml @@ -1,7 +1,7 @@ kind: Service apiVersion: v1 metadata: - name: ##PREFIX##-app-service + name: {{ prefix }}-app-service spec: type: ExternalName externalName: ##ORDS_HOST## diff --git a/option/src/app/ords/ingress-app.yaml b/option/src/app/ords/ingress-app.yaml index 4cabfd68..10ca683c 100644 --- a/option/src/app/ords/ingress-app.yaml +++ b/option/src/app/ords/ingress-app.yaml @@ -3,16 +3,16 @@ kind: Ingress metadata: name: ##PREFIX##-app-ingress annotations: - kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/rewrite-target: /ords/starter/module/$2 nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" nginx.ingress.kubernetes.io/upstream-vhost: "##ORDS_HOST##" spec: + ingressClassName: nginx rules: - http: paths: - path: /##PREFIX##/app(/|$)(.*) - pathType: Prefix + pathType: ImplementationSpecific backend: service: name: ##PREFIX##-app-service diff --git a/option/terraform/apigw.tf b/option/terraform/apigw.j2.tf similarity index 70% rename from option/terraform/apigw.tf rename to option/terraform/apigw.j2.tf index bb1b5a1d..3ec639c7 100644 --- a/option/terraform/apigw.tf +++ b/option/terraform/apigw.j2.tf @@ -8,15 +8,20 @@ resource oci_apigateway_gateway starter_apigw { endpoint_type = "PUBLIC" subnet_id = data.oci_core_subnet.starter_public_subnet.id freeform_tags = local.freeform_tags + +{%- if tls is defined %} + certificate_id = var.certificate_ocid +{%- endif %} } resource "oci_apigateway_api" "starter_api" { compartment_id = local.lz_appdev_cmp_ocid content = var.openapi_spec display_name = "${var.prefix}-api" - freeform_tags = local.freeform_tags + freeform_tags = local.freeform_tags } locals { - apigw_ocid = oci_apigateway_gateway.starter_apigw.id + apigw_ocid = try(oci_apigateway_gateway.starter_apigw.id, "") + apigw_ip = try(oci_apigateway_gateway.starter_apigw.ip_addresses[0].ip_address,"") } diff --git a/option/terraform/apigw_ci_append.tf b/option/terraform/apigw_ci_append.tf index 792058e8..464222d4 100644 --- a/option/terraform/apigw_ci_append.tf +++ b/option/terraform/apigw_ci_append.tf @@ -3,7 +3,11 @@ locals { } resource "oci_apigateway_deployment" "starter_apigw_deployment" { - count = var.docker_image_ui == "" ? 0 : 1 +{%- if tls is defined %} + count = (var.docker_image_ui == "" || var.certificate_ocid == "") ? 0 : 1 +{%- else %} + count = var.docker_image_ui == "" ? 0 : 1 +{%- endif %} compartment_id = local.lz_appdev_cmp_ocid display_name = "${var.prefix}-apigw-deployment" gateway_id = local.apigw_ocid diff --git a/option/terraform/apigw_compute_append.tf b/option/terraform/apigw_compute_append.tf index 60bf610f..b58e0d63 100644 --- a/option/terraform/apigw_compute_append.tf +++ b/option/terraform/apigw_compute_append.tf @@ -15,7 +15,15 @@ resource "oci_apigateway_deployment" "starter_apigw_deployment" { type = "HTTP_BACKEND" url = "##APP_URL##" } - } + } + routes { + path = "/{pathname*}" + methods = [ "ANY" ] + backend { + type = "HTTP_BACKEND" + url = "http://${local.apigw_dest_private_ip}/$${request.path[pathname]}" + } + } } freeform_tags = local.api_tags } diff --git a/option/terraform/apigw_existing.tf b/option/terraform/apigw_existing.j2.tf similarity index 63% rename from option/terraform/apigw_existing.tf rename to option/terraform/apigw_existing.j2.tf index fd9e38f0..0e41bf81 100644 --- a/option/terraform/apigw_existing.tf +++ b/option/terraform/apigw_existing.j2.tf @@ -7,5 +7,6 @@ data "oci_apigateway_gateway" "starter_apigw" { locals { apigw_ocid = var.apigw_ocid + apigw_ip = try(data.oci_apigateway_gateway.starter_apigw.ip_addresses[0].ip_address,"") } diff --git a/option/terraform/apigw_fn_append.tf b/option/terraform/apigw_fn_append.tf index 8d1db553..40f862be 100644 --- a/option/terraform/apigw_fn_append.tf +++ b/option/terraform/apigw_fn_append.tf @@ -1,5 +1,9 @@ resource "oci_apigateway_deployment" "starter_apigw_deployment" { +{%- if tls is defined %} + count = (var.fn_image == "" || var.certificate_ocid == "") ? 0 : 1 +{%- else %} count = var.fn_image == "" ? 0 : 1 +{%- endif %} compartment_id = local.lz_appdev_cmp_ocid display_name = "${var.prefix}-apigw-deployment" gateway_id = local.apigw_ocid diff --git a/option/terraform/apigw_kubernetes_tls_append.tf b/option/terraform/apigw_kubernetes_tls_append.tf new file mode 100644 index 00000000..a7748a35 --- /dev/null +++ b/option/terraform/apigw_kubernetes_tls_append.tf @@ -0,0 +1,20 @@ +variable ingress_ip { default="" } + +resource "oci_apigateway_deployment" "starter_apigw_deployment" { + count = var.ingress_ip == "" ? 0 : 1 + compartment_id = local.lz_appdev_cmp_ocid + display_name = "${var.prefix}-apigw-deployment" + gateway_id = local.apigw_ocid + path_prefix = "/" + specification { + routes { + path = "/{pathname*}" + methods = [ "ANY" ] + backend { + type = "HTTP_BACKEND" + url = "http://${var.ingress_ip}/$${request.path[pathname]}" + } + } + } + freeform_tags = local.api_tags +} \ No newline at end of file diff --git a/option/terraform/compute_append.tf b/option/terraform/compute_append.tf index c80770ce..3c30e49b 100644 --- a/option/terraform/compute_append.tf +++ b/option/terraform/compute_append.tf @@ -2,7 +2,3 @@ output "compute_ip" { value = local.compute_public_ip } - -output "ui_url" { - value = format("http://%s", local.compute_public_ip) -} diff --git a/option/terraform/instance_pool.tf b/option/terraform/instance_pool.j2.tf similarity index 93% rename from option/terraform/instance_pool.tf rename to option/terraform/instance_pool.j2.tf index 5ff500ef..5014d2df 100644 --- a/option/terraform/instance_pool.tf +++ b/option/terraform/instance_pool.j2.tf @@ -41,12 +41,16 @@ resource "oci_load_balancer_backend_set" "starter_pool_backend_set" { resource "oci_load_balancer_listener" "starter_pool_lb_listener" { load_balancer_id = oci_load_balancer.starter_pool_lb.id - name = "http" + name = "HTTP-80" default_backend_set_name = oci_load_balancer_backend_set.starter_pool_backend_set.name port = 80 protocol = "HTTP" +{%- if tls == "new" %} + path_route_set_name = oci_load_balancer_path_route_set.starter-bastion-routeset.name +{%- endif %} } + resource "oci_core_instance_configuration" "starter_instance_configuration" { count = var.compute_ready == "" ? 0 : 1 compartment_id = local.lz_appdev_cmp_ocid @@ -153,6 +157,10 @@ output "pooled_instances_hostname_labels" { value = [data.oci_core_instance.starter_instance_pool_instance_singular_datasource.*.hostname_label] } -output "pool_lb_url" { - value = format("http://%s", oci_load_balancer.starter_pool_lb.ip_address_details[0].ip_address) +locals { + instance_pool_lb_ip = oci_load_balancer.starter_pool_lb.ip_address_details[0].ip_address +} + +output "instance_pool_lb_ip" { + value = local.instance_pool_lb_ip } \ No newline at end of file diff --git a/option/terraform/oke.tf b/option/terraform/oke.tf index 8b55d83b..2b53eb7b 100644 --- a/option/terraform/oke.tf +++ b/option/terraform/oke.tf @@ -1,3 +1,6 @@ +#---------------------------------------------------------------------------- +# VARIABLES + variable "oke_shape" { default = "VM.Standard2.1" } @@ -11,6 +14,7 @@ variable "cluster_options_persistent_volume_config_defined_tags_value" { } #---------------------------------------------------------------------------- +# DATA data "oci_containerengine_cluster_option" "starter_cluster_option" { cluster_option_id = "all" @@ -45,6 +49,7 @@ locals { } #---------------------------------------------------------------------------- +# SECURITY LISTS resource "oci_core_security_list" "starter_seclist_lb" { compartment_id = local.lz_network_cmp_ocid @@ -268,6 +273,7 @@ resource oci_core_security_list starter_seclist_api { } #---------------------------------------------------------------------------- +# SUBNETS resource "oci_core_subnet" "starter_nodepool_subnet" { #Required @@ -314,7 +320,23 @@ resource "oci_core_subnet" "starter_api_subnet" { freeform_tags = local.freeform_tags } +/* +resource "oci_core_subnet" "starter_pod_subnet" { + #Required + cidr_block = "10.0.40.0/24" + compartment_id = local.lz_network_cmp_ocid + vcn_id = oci_core_vcn.starter_vcn.id + + # Provider code tries to maintain compatibility with old versions. + security_list_ids = [oci_core_vcn.starter_vcn.default_security_list_id, oci_core_security_list.starter_security_list.id] + display_name = "${var.prefix}-oke-pod-subnet" + route_table_id = oci_core_vcn.starter_vcn.default_route_table_id + freeform_tags = local.freeform_tags +} +*/ + #---------------------------------------------------------------------------- +# CLUSTER resource "oci_containerengine_cluster" "starter_oke" { #Required @@ -332,7 +354,6 @@ resource "oci_containerengine_cluster" "starter_oke" { options { service_lb_subnet_ids = [oci_core_subnet.starter_lb_subnet.id] - #Optional add_ons { #Optional @@ -350,11 +371,18 @@ resource "oci_containerengine_cluster" "starter_oke" { pods_cidr = "10.1.0.0/16" services_cidr = "10.2.0.0/16" } + + # cluster_pod_network_options { + # cni_type = "OCI_VCN_IP_NATIVE" + # } } freeform_tags = local.freeform_tags } +#---------------------------------------------------------------------------- +# NODE POOL + resource "oci_containerengine_node_pool" "starter_node_pool" { #Required cluster_id = oci_containerengine_cluster.starter_oke.id @@ -379,6 +407,11 @@ resource "oci_containerengine_node_pool" "starter_node_pool" { fault_domains = ["FAULT-DOMAIN-1", "FAULT-DOMAIN-3"] } size = var.node_pool_node_config_details_size + + # node_pool_pod_network_option_details { + # cni_type = "OCI_VCN_IP_NATIVE" + # pod_subnet_ids = [ oci_core_subnet.starter_pod_subnet.id ] + # } } ssh_public_key = var.ssh_public_key @@ -386,6 +419,31 @@ resource "oci_containerengine_node_pool" "starter_node_pool" { } #---------------------------------------------------------------------------- +# ADDONS + +# Database Operator +resource oci_containerengine_addon starter_oke_addon_dboperator { + addon_name = "OracleDatabaseOperator" + cluster_id = oci_containerengine_cluster.starter_oke.id + remove_addon_resources_on_delete = "true" +} + +# WebLogic Operator +resource oci_containerengine_addon starter_oke_addon_wlsoperator { + addon_name = "WeblogicKubernetesOperator" + cluster_id = oci_containerengine_cluster.starter_oke.id + remove_addon_resources_on_delete = "true" +} + +# CertManager +resource oci_containerengine_addon starter_oke_addon_certmanager { + addon_name = "CertManager" + cluster_id = oci_containerengine_cluster.starter_oke.id + remove_addon_resources_on_delete = "true" +} + +#---------------------------------------------------------------------------- +# OUTPUTS output "node_pool" { value = { @@ -397,6 +455,7 @@ output "node_pool" { } #---------------------------------------------------------------------------- +# LOCALS locals { oke_ocid = oci_containerengine_cluster.starter_oke.id diff --git a/option/terraform/oke_append.tf b/option/terraform/oke_append.tf index 4b773da3..3b4a82bb 100644 --- a/option/terraform/oke_append.tf +++ b/option/terraform/oke_append.tf @@ -1,11 +1,3 @@ -variable "cluster_kube_config_expiration" { - default = 2592000 -} - -variable "cluster_kube_config_token_version" { - default = "2.0.0" -} - output "oke_ocid" { value = local.oke_ocid } diff --git a/option/terraform/tls.j2.tf b/option/terraform/tls.j2.tf new file mode 100644 index 00000000..b4ead54e --- /dev/null +++ b/option/terraform/tls.j2.tf @@ -0,0 +1,57 @@ +variable "dns_zone_name" { default="" } +variable "dns_name" { default="" } +variable "dns_ip" { default="" } + +locals { +{%- if deploy_type == "compute" and tls != "existing_ocid" %} + dns_ip = local.compute_public_ip +{%- elif deploy_type == "instance_pool" %} + dns_ip = local.instance_pool_lb_ip +{%- else %} + dns_ip = local.apigw_ip +{%- endif %} +} + +resource "oci_dns_rrset" "starter_rrset" { + # XXXX Advanced case with DNS not in OCI XXXX ? + count = var.dns_zone_name=="" ? 0 : 1 + + #Required + zone_name_or_id = var.dns_zone_name + domain = var.dns_name + rtype = "A" + compartment_id = local.lz_appdev_cmp_ocid + items { + #Required + domain = var.dns_name + rdata = var.dns_ip=="" ? local.dns_ip : var.dns_ip + rtype = "A" + ttl = 300 + } +} + +{%- if deploy_type == "instance_pool" %} +resource "oci_load_balancer_listener" "starter_lb_https_listener" { + load_balancer_id = oci_load_balancer.starter_pool_lb.id + name = "HTTP-443" + default_backend_set_name = oci_load_balancer_backend_set.starter_pool_backend_set.name + port = 443 + protocol = "HTTP" + + ssl_configuration { + certificate_ids = [ var.certificate_ocid ] + cipher_suite_name = "oci-wider-compatible-ssl-cipher-suite-v1" + protocols = [ + "TLSv1", + "TLSv1.1", + "TLSv1.2" + ] + server_order_preference = "ENABLED" + verify_depth = 1 + verify_peer_certificate = false + } +} +{%- endif %} + + + diff --git a/option/test_suite.sh b/option/test_suite.sh index a101f238..38dea53d 100755 --- a/option/test_suite.sh +++ b/option/test_suite.sh @@ -62,7 +62,7 @@ build_test_destroy () { echo "destroy_secs=$SECONDS" >> ${TEST_DIR}_time.txt cat ${TEST_DIR}_time.txt else - echo "Error: no output directory" + echo "ERROR: no output directory" fi } diff --git a/option/test_suite_all.sh b/option/test_suite_all.sh index 53aa8699..3f2bb868 100755 --- a/option/test_suite_all.sh +++ b/option/test_suite_all.sh @@ -88,7 +88,7 @@ build_option() { mv output $TEST_DIR build_test_destroy else - echo "Error: no output directory" + echo "ERROR: no output directory" fi } diff --git a/option/test_suite_group_all.sh b/option/test_suite_group_all.sh index 79f8f5e5..b1c77fc0 100755 --- a/option/test_suite_group_all.sh +++ b/option/test_suite_group_all.sh @@ -45,7 +45,6 @@ loop_shape() { } loop_db() { - OPTION_DB_INSTALL=default if [ "$OPTION_DEPLOY" != "instance_pool" ] ; then # OPTION_DB=database # loop_ui @@ -83,8 +82,6 @@ loop_java_framework () { } loop_lang () { - mkdir_deploy - OPTION_LANG=java OPTION_JAVA_VM=jdk if [ "$OPTION_DEPLOY" == "function" ]; then @@ -126,18 +123,53 @@ loop_shared_compute() { OPTION_DB_INSTALL=shared_compute OPTION_UI=html OPTION_DB=db_free - mkdir_deploy build_option OPTION_DB=mysql build_option # Helidon 4 OPTION_DB_INSTALL=default - OPTION_DB=ATP + OPTION_DB=atp OPTION_JAVA_FRAMEWORK=helidon4 build_option } +loop_tls_deploy() { + OPTION_DEPLOY=compute + build_option + OPTION_DEPLOY=kubernetes + build_option + OPTION_DEPLOY=instance_pool + build_option + OPTION_DEPLOY=container_instance + build_option + OPTION_DEPLOY=function + build_option +} + +loop_tls() { + # TLS + OPTION_GROUP_NAME=none + OPTION_LANG=java + OPTION_JAVA_VM=jdk + OPTION_JAVA_FRAMEWORK=springboot + OPTION_UI=html + OPTION_DB=none + OPTION_TLS=existing_dir + loop_tls_deploy + # existing_ocid is part of existing_dir + + OPTION_TLS=new_http_01 + OPTION_DEPLOY=compute + build_option + + OPTION_TLS=new_dns_01 + OPTION_DEPLOY=container_instance + build_option + + OPTION_GROUP_NAME=dummy +} + loop_deploy() { OPTION_DEPLOY=compute loop_shared_compute @@ -145,11 +177,16 @@ loop_deploy() { OPTION_DEPLOY=kubernetes loop_lang OPTION_DEPLOY=instance_pool - loop_lang + OPTION_LANG=java + OPTION_JAVA_FRAMEWORK=springboot + OPTION_DB=atp + loop_shape OPTION_DEPLOY=container_instance loop_lang OPTION_DEPLOY=function loop_lang + + loop_tls } generate_only() { @@ -168,5 +205,6 @@ pre_test_suite # generate_only cd $TEST_HOME . ./group_common_env.sh +# export TEST_ERROR_ONLY=TRUE loop_deploy post_test_suite diff --git a/option/test_suite_shared.sh b/option/test_suite_shared.sh index e6dbf714..5ef91b2e 100755 --- a/option/test_suite_shared.sh +++ b/option/test_suite_shared.sh @@ -7,12 +7,33 @@ export COLOR_RED='\033[0;31m' export COLOR_GREEN='\033[0;32m' export COLOR_NONE='\033[0m' +# Default +OPTION_TLS=none +OPTION_GROUP_NAME=dummy +OPTION_DB_INSTALL=default +OPTION_SHAPE=amd + # No color for terraforms logs export nocolorarg=1 +exit_on_error() { + RESULT=$? + if [ $RESULT -eq 0 ]; then + echo "Success" + else + echo "Failed (RESULT=$RESULT)" + exit $RESULT + fi +} + start_test() { export TEST_NAME=$1 - export TEST_DIR=$TEST_HOME/$OPTION_DEPLOY/$TEST_NAME + if [ "$OPTION_GROUP_NAME" != "none" ]; then + export TEST_DIR=$TEST_HOME/$OPTION_DEPLOY/$TEST_NAME + else + export TEST_DIR=$TEST_HOME/no_group/$OPTION_DEPLOY/$TEST_NAME + mkdir -p $TEST_DIR + fi echo "-- TEST: $OPTION_DEPLOY - $TEST_NAME ---------------------------------------" } @@ -82,6 +103,11 @@ build_test () { fi } +echo_errors_csv() { + echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,$OPTION_JAVA_FRAMEWORK,$OPTION_JAVA_VM,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/errors.csv + echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/error_rerun.sh +} + build_test_destroy () { BUILD_ID=1 build_test @@ -94,6 +120,7 @@ build_test_destroy () { echo "stop_token file dectected" echo "Exiting before destroy.sh" echo "Last directory: $TEST_DIR" + rm $TEST_HOME/stop_token exit fi ./destroy.sh --auto-approve > destroy.log 2>&1 @@ -107,14 +134,16 @@ build_test_destroy () { echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,-,-,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/result.csv fi if [ "$CSV_JSON_OK" != "1" ] || [ "$CSV_HTML_OK" != "1" ]; then - echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,$OPTION_JAVA_FRAMEWORK,$OPTION_JAVA_VM,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/errors.csv - echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/error_rerun.sh + echo_errors_csv fi } build_option() { + mkdir_deploy if [ "$OPTION_DB_INSTALL" == "shared_compute" ]; then NAME=shared-compute-${OPTION_DB} + elif [ "$OPTION_TLS" != "none" ]; then + NAME=tls-${OPTION_TLS}-${OPTION_DEPLOY} elif [ "$OPTION_LANG" == "java" ] && [ "$OPTION_DEPLOY" != "function" ]; then NAME=${OPTION_LANG}-${OPTION_JAVA_FRAMEWORK}-${OPTION_JAVA_VM}-${OPTION_DB}-${OPTION_UI} else @@ -125,8 +154,19 @@ build_option() { fi NAME=${NAME/_/-} start_test $NAME + if [ "$TEST_ERROR_ONLY" != "" ]; then + if grep -Fxq "$TEST_DIR" $TEST_HOME/error_rerun.sh + then + echo "OK - error_rerun.sh contains - $TEST_DIR" + else + echo "SKIP - error_rerun.sh does not contains - $TEST_DIR" + return + fi + fi + cd $TEST_HOME/oci-starter - ./oci_starter.sh \ + if [ "$OPTION_GROUP_NAME" == "dummy" ]; then + ./oci_starter.sh \ -prefix $NAME \ -deploy $OPTION_DEPLOY \ -ui $OPTION_UI \ @@ -136,8 +176,9 @@ build_option() { -database $OPTION_DB \ -db_password $TEST_DB_PASSWORD \ -db_install $OPTION_DB_INSTALL \ - -group_common dummy \ + -group_common $OPTION_GROUP_NAME \ -shape $OPTION_SHAPE \ + -tls $OPTION_TLS \ -compartment_ocid $EX_COMPARTMENT_OCID \ -vcn_ocid $TF_VAR_vcn_ocid \ -public_subnet_ocid $TF_VAR_public_subnet_ocid \ @@ -151,27 +192,48 @@ build_option() { -apigw_ocid $TF_VAR_apigw_ocid \ -bastion_ocid $TF_VAR_bastion_ocid \ -fnapp_ocid $TF_VAR_fnapp_ocid > ${TEST_DIR}.log 2>&1 - + else + ./oci_starter.sh \ + -prefix tsone \ + -deploy $OPTION_DEPLOY \ + -ui $OPTION_UI \ + -language $OPTION_LANG \ + -java_framework $OPTION_JAVA_FRAMEWORK \ + -java_vm $OPTION_JAVA_VM \ + -database $OPTION_DB \ + -db_password $TEST_DB_PASSWORD \ + -db_install $OPTION_DB_INSTALL \ + -group_common $OPTION_GROUP_NAME \ + -shape $OPTION_SHAPE \ + -tls $OPTION_TLS \ + -compartment_ocid $EX_COMPARTMENT_OCID > ${TEST_DIR}.log 2>&1 + fi # -db_compartment_ocid $EX_COMPARTMENT_OCID \ if [ -d output ]; then mkdir output/target cp $TEST_HOME/group_common/target/ssh* output/target/. rm -Rf $TEST_DIR + if [ -f ${TEST_DIR}_time.txt ]; then + rm ${TEST_DIR}_* + fi mv output $TEST_DIR if [ -z $GENERATE_ONLY ]; then build_test_destroy fi else - echo "Error: no output directory" + echo "ERROR: no output directory" + echo_errors_csv fi } # Create the $OPTION_DEPLOY directory mkdir_deploy() { - mkdir $TEST_HOME/$OPTION_DEPLOY - echo '. $PROJECT_DIR/../../group_common_env.sh' > $TEST_HOME/$OPTION_DEPLOY/group_common_env.sh - chmod +x $TEST_HOME/$OPTION_DEPLOY/group_common_env.sh + if [ ! -d $TEST_HOME/$OPTION_DEPLOY ]; then + mkdir $TEST_HOME/$OPTION_DEPLOY + echo '. $PROJECT_DIR/../../group_common_env.sh' > $TEST_HOME/$OPTION_DEPLOY/group_common_env.sh + chmod +x $TEST_HOME/$OPTION_DEPLOY/group_common_env.sh + fi } @@ -189,10 +251,12 @@ pre_test_suite() { git clone https://github.com/mgueury/oci-starter cd $TEST_HOME/oci-starter - ./oci_starter.sh -group_name tsall -group_common atp,mysql,psql,database,fnapp,apigw,oke,db_free -compartment_ocid $EX_COMPARTMENT_OCID -db_password $TEST_DB_PASSWORD -auth_token $OCI_TOKEN + ./oci_starter.sh -group_name tsall -group_common atp,mysql,psql,database,fnapp,apigw,oke -compartment_ocid $EX_COMPARTMENT_OCID -db_password $TEST_DB_PASSWORD -auth_token $OCI_TOKEN + exit_on_error mv output/group_common ../group_common cd $TEST_HOME/group_common ./build.sh + exit_on_error date echo "CSV_DATE,OPTION_DEPLOY,OPTION_LANG,OPTION_JAVA_FRAMEWORK,OPTION_JAVA_VM,OPTION_DB,OPTION_DB_INSTALL,OPTION_UI,OPTION_SHAPE,CSV_NAME,CSV_HTML_OK,CSV_JSON_OK,CSV_BUILD_SECOND,CSV_DESTROY_SECOND,CSV_RUN100_OK,CSV_RUN100_SECOND" > $TEST_HOME/result.csv } diff --git a/option/tls/compute_existing_dir/nginx_tls.conf b/option/tls/compute_existing_dir/nginx_tls.conf new file mode 100644 index 00000000..fa7fd9d4 --- /dev/null +++ b/option/tls/compute_existing_dir/nginx_tls.conf @@ -0,0 +1,43 @@ +server { + server_name ##DNS_NAME##; + root /usr/share/nginx/html; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + location / { + } + + include conf.d/nginx_app.locations; + error_page 404 /404.html; + location = /40x.html { + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + } + listen [::]:443 ssl ipv6only=on; + listen 443 ssl; + ssl_certificate /home/opc/certificate/fullchain.pem; + ssl_certificate_key /home/opc/certificate/privkey.pem; + + ssl_session_cache shared:le_nginx_SSL:10m; + ssl_session_timeout 1440m; + ssl_session_tickets off; + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers off; + + ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"; +} + +server { + if ($host = ##DNS_NAME##) { + return 301 https://$host$request_uri; + } + + + listen 80 ; + listen [::]:80 ; + server_name ##DNS_NAME##; + return 404; +} diff --git a/option/tls/new_http_01/certbot_http_01.sh b/option/tls/new_http_01/certbot_http_01.sh new file mode 100755 index 00000000..4cbc5e43 --- /dev/null +++ b/option/tls/new_http_01/certbot_http_01.sh @@ -0,0 +1,60 @@ +#!/bin/bash +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd $SCRIPT_DIR + +exit_on_error() { + RESULT=$? + if [ $RESULT -eq 0 ]; then + echo "Success" + else + echo "Failed (RESULT=$RESULT)" + exit $RESULT + fi +} + +# Install certbot +sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y +sudo dnf install snapd nginx -y +sudo systemctl enable --now snapd.socket +sudo ln -s /var/lib/snapd/snap /snap +sudo snap install core; sudo snap refresh core +sudo snap install --classic certbot +sudo ln -s /snap/bin/certbot /usr/bin/certbot + +# Install nginx +sudo systemctl enable nginx +sudo systemctl restart nginx +sudo firewall-cmd --zone=public --add-port=80/tcp --permanent +sudo firewall-cmd --zone=public --add-port=443/tcp --permanent +sudo firewall-cmd --reload + +x_max=5 +x=$x_max +while [ $x -gt 0 ] +do + nslookup $TF_VAR_dns_name + sudo certbot --agree-tos --nginx --email $TF_VAR_certificate_email -d $TF_VAR_dns_name + RESULT=$? + if [ $RESULT -eq 0 ]; then + echo "Success - certbot" + x=0 + else + echo + echo "WARNING" + echo "Cerbot failed - Retrying $x/${x_max} - Waiting 120 secs for the DNS entry to propagate to the verification servers" + sleep 120 + x=$(( $x - 1 )) + if [ $x -eq 0 ]; then + echo "ERROR" + exit 1 + fi + fi +done + +# Place the certificate in an OPC directory so that it can be copied via SSH. +mkdir certificate +sudo cp -Lr /etc/letsencrypt/live/$TF_VAR_dns_name /home/opc/tls/certificate +sudo chown -R opc certificate + +# Cron job for Let's Encrypt (Certbot) renewal (each day at 1AM) +echo '0 1 * * * certbot renew --post-hook "systemctl reload nginx"' | sudo bash -c "tee >> /etc/crontab" diff --git a/py_oci_starter.py b/py_oci_starter.py index 6186dfe6..db89948c 100755 --- a/py_oci_starter.py +++ b/py_oci_starter.py @@ -57,8 +57,8 @@ def prog_arg_dict(): MANDATORY_OPTIONS = { - CLI: ['-language', '-deploy', '-db_password'], - GROUP: ['-group_name','-group_common','-db_password'] + CLI: ['-language', '-deploy'], + GROUP: ['-group_name','-group_common'] } def mandatory_options(mode): @@ -75,17 +75,24 @@ def mandatory_options(mode): '-license': 'included', '-mode': CLI, '-infra_as_code': 'terraform_local', - '-output_dir' : 'output' + '-output_dir' : 'output', + '-db_password' : TO_FILL } no_default_options = ['-compartment_ocid', '-oke_ocid', '-vcn_ocid', '-atp_ocid', '-db_ocid', '-db_compartment_ocid', '-pdb_ocid', '-mysql_ocid', '-psql_ocid', - '-db_user', '-fnapp_ocid', '-apigw_ocid', '-bastion_ocid', '-auth_token', + '-db_user', '-fnapp_ocid', '-apigw_ocid', '-bastion_ocid', '-auth_token', '-tls', '-subnet_ocid','-public_subnet_ocid','-private_subnet_ocid','-shape','-db_install'] # hidden_options - allowed but not advertised hidden_options = ['-zip', '-group_common','-group_name'] +rename_params = { + 'database': 'db_type', + 'deploy' : 'deploy_type', + 'ui' : 'ui_type', + 'license' : 'license_model' +} def allowed_options(): return list(default_options.keys()) + hidden_options \ @@ -94,18 +101,19 @@ def allowed_options(): allowed_values = { '-language': {'java', 'node', 'python', 'dotnet', 'go', 'php', 'ords', 'apex', 'forms', 'none'}, - '-deploy': {'compute', 'instance_pool', 'kubernetes', 'function', 'container_instance', 'hpc', 'datascience'}, + '-deploy_type': {'compute', 'instance_pool', 'kubernetes', 'function', 'container_instance', 'hpc', 'datascience'}, '-java_framework': {'springboot', 'helidon', 'helidon4', 'tomcat', 'micronaut'}, '-java_vm': {'jdk', 'graalvm', 'graalvm-native'}, '-java_version': {'8', '11', '17', '21'}, '-kubernetes': {'oke', 'docker'}, - '-ui': {'html', 'jet', 'angular', 'reactjs', 'jsp', 'php', 'api', 'apex', 'none'}, - '-database': {'atp', 'database', 'dbsystem', 'rac', 'db_free', 'pluggable', 'mysql', 'psql', 'none'}, - '-license': {'included', 'LICENSE_INCLUDED', 'byol', 'BRING_YOUR_OWN_LICENSE'}, + '-ui_type': {'html', 'jet', 'angular', 'reactjs', 'jsp', 'php', 'api', 'apex', 'none'}, + '-db_type': {'atp', 'database', 'dbsystem', 'rac', 'db_free', 'pluggable', 'mysql', 'psql', 'none'}, + '-license_model': {'included', 'LICENSE_INCLUDED', 'byol', 'BRING_YOUR_OWN_LICENSE'}, '-infra_as_code': {'terraform_local', 'terraform_object_storage', 'resource_manager'}, '-mode': {CLI, GIT, ZIP}, '-shape': {'amd','freetier_amd','ampere'}, - '-db_install': {'default', 'shared_compute', 'kubernetes'} + '-db_install': {'default', 'shared_compute', 'kubernetes'}, + '-tls': {'none', 'new_http_01', 'new_dns_01', 'existing_ocid', 'existing_dir'} } def check_values(): @@ -119,16 +127,7 @@ def check_values(): def get_tf_var(param): - special_case = { - 'database': 'TF_VAR_db_strategy', - 'deploy': 'TF_VAR_deploy_strategy', - 'license': 'TF_VAR_license_model', - 'ui': 'TF_VAR_ui_strategy' - }.get(param) - if special_case is not None: - return special_case - else: - return 'TF_VAR_' + param + return 'TF_VAR_' + param def longhand(key, abbreviations): @@ -139,30 +138,42 @@ def longhand(key, abbreviations): return current +def pop_param(dict,param): + if param in dict: + dict.pop(param) + + +def save_params(): + p = params.copy() + pop_param(p,"output_dir") + pop_param(p,"zip") + params['params'] = ",".join(p.keys()) + + def db_rules(): - if params.get('database') == 'rac': + if params.get('db_type') == 'rac': params['db_node_count'] = "2" - params['database'] = longhand( - 'database', {'atp': 'autonomous', 'dbsystem': 'database', 'rac': 'database'}) + params['db_type'] = longhand( + 'db_type', {'atp': 'autonomous', 'dbsystem': 'database', 'rac': 'database'}) - if params.get('database') != 'autonomous': + if params.get('db_type') != 'autonomous': if params.get('language') == 'ords': error(f'OCI starter supports ORDS only on ATP (Autonomous)') if params.get('language') == 'apex': error(f'OCI starter supports APEX only on ATP (Autonomous)') - if params.get('database') == 'pluggable': + if params.get('db_type') == 'pluggable': if (params.get('db_ocid') is None and params.get('pdb_ocid') is None): error(f'Pluggable Database needs an existing DB_OCID or PDB_OCID') if params.get('db_user') == None: default_users = {'autonomous': 'admin', 'database': 'system', 'db_free': 'system', 'pluggable': 'system', 'mysql': 'root', 'psql': 'postgres', 'none': ''} - params['db_user'] = default_users[params['database']] - if params.get('database')=='none': + params['db_user'] = default_users[params['db_type']] + if params.get('db_type')=='none': params.pop('db_password') # shared_compute is valid only in compute deployment if params.get('db_install') == "shared_compute": - if params.get('deploy')!='compute': + if params.get('deploy_type')!='compute': params.pop('db_install') @@ -177,8 +188,8 @@ def language_rules(): def kubernetes_rules(): - if 'deploy' in params: - params['deploy'] = longhand('deploy', {'oke': 'kubernetes', 'ci': 'container_instance'}) + if 'deploy_type' in params: + params['deploy_type'] = longhand('deploy_type', {'oke': 'kubernetes', 'ci': 'container_instance'}) def vcn_rules(): @@ -193,17 +204,17 @@ def vcn_rules(): def ui_rules(): - params['ui'] = longhand('ui', {'reactjs': 'ReactJS'}) - if params.get('ui') == 'jsp': + params['ui_type'] = longhand('ui_type', {'reactjs': 'ReactJS'}) + if params.get('ui_type') == 'jsp': params['language'] = 'java' params['java_framework'] = 'tomcat' - elif params.get('ui') == 'php': + elif params.get('ui_type') == 'php': params['language'] = 'php' - elif params.get('ui') == 'ruby': + elif params.get('ui_type') == 'ruby': params['language'] = 'ruby' def auth_token_rules(): - if params.get('deploy') in [ 'kubernetes', 'container_instance', 'function' ] and params.get('auth_token') is None: + if params.get('deploy_type') in [ 'kubernetes', 'container_instance', 'function' ] and params.get('auth_token') is None: warning('-auth_token is not set. Will need to be set in env.sh') params['auth_token'] = TO_FILL @@ -217,9 +228,9 @@ def compartment_rules(): def license_rules(): license_model = os.getenv('LICENSE_MODEL') if license_model is not None: - params['license'] = license_model - params['license'] = longhand( - 'license', {'included': 'LICENSE_INCLUDED', 'byol': 'BRING_YOUR_OWN_LICENSE'}) + params['license_model'] = license_model + params['license_model'] = longhand( + 'license_model', {'included': 'LICENSE_INCLUDED', 'byol': 'BRING_YOUR_OWN_LICENSE'}) def zip_rules(): @@ -233,11 +244,13 @@ def zip_rules(): output_dir = "zip" + os.sep + params['zip'] + os.sep + zip_dir file_output('zip' + os.sep + params['zip'] + '.param', [json.dumps(params)]) - def group_common_rules(): if params.get('group_common'): - global a_group_common - a_group_common=params.get('group_common').split(',') + if params.get('group_common')=='none': + params.pop('group_common') + else: + global a_group_common + a_group_common=params.get('group_common').split(',') def shape_rules(): @@ -250,6 +263,24 @@ def shape_rules(): params['instance_shape_config_memory_in_gbs'] = 8 +def tls_rules(): + if params.get('tls')=='none': + params.pop('tls') + elif params.get('tls'): + params['dns_name'] = TO_FILL + if params.get('tls')=='new_http_01': + params['certificate_email'] = TO_FILL + elif params.get('tls')=='new_dns_01': + params['certificate_email'] = TO_FILL + params['dns_zone_name'] = TO_FILL + elif params.get('tls')=='existing_ocid': + params['dns_zone_name'] = TO_FILL + params['certificate_ocid'] = TO_FILL + elif params.get('tls')=='existing_dir': + params['dns_zone_name'] = TO_FILL + params['certificate_dir'] = TO_FILL + + def apply_rules(): zip_rules() group_common_rules() @@ -262,6 +293,7 @@ def apply_rules(): compartment_rules() license_rules() shape_rules() + tls_rules() def error(msg): @@ -362,7 +394,12 @@ def missing_parameters(supplied_params, expected_params): def get_params(): - return deprefix_keys({**default_options, **prog_arg_dict()}) + params = deprefix_keys({**default_options, **prog_arg_dict()}) + for key, value in rename_params.items(): + if params.get(key): + params[value] = params[key] + params.pop(key) + return params def git_params(): @@ -417,10 +454,10 @@ def readme_contents(): - db : SQL files of the database - terraform : Terraform scripts (Command: plan.sh / apply.sh)''' ] - if params['deploy'] in [ 'compute', 'instance_pool' ]: + if params['deploy_type'] in [ 'compute', 'instance_pool' ]: contents.append( " - compute : Contains the deployment files to Compute") - elif params['deploy'] == 'kubernetes': + elif params['deploy_type'] == 'kubernetes': contents.append( " - oke : Contains the deployment files to Kubernetes") @@ -448,15 +485,21 @@ def readme_contents(): contents.append(" ./build.sh") return contents +def is_param_default_value(name): + return params.get(name) == default_options.get('-'+name) + def env_param_list(): env_params = list(params.keys()) - exclude = ['mode', 'zip', 'prefix', 'shape'] + exclude = ['mode', 'zip', 'prefix', 'shape', 'params', 'output_dir'] if params.get('language') != 'java' or 'group_name' in params: exclude.extend(['java_vm', 'java_framework', 'java_version']) if 'group_name' in params: - exclude.extend(['ui', 'database', 'language', 'deploy', 'db_user', 'group_name']) + exclude.extend(['ui_type', 'db_type', 'language', 'deploy_type', 'db_user', 'group_name']) else: exclude.append('group_common') + if is_param_default_value('infra_as_code'): + exclude.append('infra_as_code') + print(exclude) for x in exclude: if x in env_params: @@ -471,8 +514,6 @@ def env_sh_contents(): contents.append( 'PROJECT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )') contents.append(f'export BIN_DIR=$PROJECT_DIR/bin') - contents.append(f'export OCI_STARTER_CREATION_DATE={timestamp}') - contents.append(f'export OCI_STARTER_VERSION=1.5') contents.append('') contents.append('# Env Variables') if 'group_name' in params: @@ -492,37 +533,38 @@ def env_sh_contents(): tf_var_comment(contents, param) contents.append(f'export {get_tf_var(param)}="{params[param]}"') contents.append('') + if params.get('compartment_ocid') == None: + contents.append('# export TF_VAR_compartment_ocid=ocid1.compartment.xxxxx') + for s in group_common_contents: + contents.append(s) + + contents.append('') contents.append("if [ -f $PROJECT_DIR/../group_common_env.sh ]; then") contents.append(" . $PROJECT_DIR/../group_common_env.sh") contents.append("elif [ -f $PROJECT_DIR/../../group_common_env.sh ]; then") contents.append(" . $PROJECT_DIR/../../group_common_env.sh") contents.append("elif [ -f $HOME/.oci_starter_profile ]; then") contents.append(" . $HOME/.oci_starter_profile") - contents.append("else") - if params.get('compartment_ocid') == None: - contents.append(' # export TF_VAR_compartment_ocid=ocid1.compartment.xxxxx') - - for x in group_common_contents: - contents.append(" " + x) - - contents.append('') - contents.append(' # API Management') - contents.append(' # export APIM_HOST=xxxx-xxx.adb.region.oraclecloudapps.com') - contents.append('') - - if params.get('instance_shape') == None: - contents.append(' # Compute Shape') - contents.append(' # export TF_VAR_instance_shape=VM.Standard.E4.Flex') - contents.append('') - - contents.append(' # Landing Zone') - contents.append(' # export TF_VAR_lz_appdev_cmp_ocid=$TF_VAR_compartment_ocid') - contents.append(' # export TF_VAR_lz_database_cmp_ocid=$TF_VAR_compartment_ocid') - contents.append(' # export TF_VAR_lz_network_cmp_ocid=$TF_VAR_compartment_ocid') - contents.append(' # export TF_VAR_lz_security_cmp_ocid=$TF_VAR_compartment_ocid') - + # contents.append("else") + # contents.append('') + # contents.append(' # API Management') + # contents.append(' # export APIM_HOST=xxxx-xxx.adb.region.oraclecloudapps.com') + # contents.append('') + # if params.get('instance_shape') == None: + # contents.append(' # Compute Shape') + # contents.append(' # export TF_VAR_instance_shape=VM.Standard.E4.Flex') + # contents.append('') + # contents.append(' # Landing Zone') + # contents.append(' # export TF_VAR_lz_appdev_cmp_ocid=$TF_VAR_compartment_ocid') + # contents.append(' # export TF_VAR_lz_database_cmp_ocid=$TF_VAR_compartment_ocid') + # contents.append(' # export TF_VAR_lz_network_cmp_ocid=$TF_VAR_compartment_ocid') + # contents.append(' # export TF_VAR_lz_security_cmp_ocid=$TF_VAR_compartment_ocid') contents.append("fi") - + contents.append('') + contents.append('# Creation Details') + contents.append(f'export OCI_STARTER_CREATION_DATE={timestamp}') + contents.append(f'export OCI_STARTER_VERSION=2.0') + contents.append(f'export OCI_STARTER_PARAMS="{params["params"]}"') contents.append('') contents.append( '# Get other env variables automatically (-silent flag can be passed)') @@ -533,12 +575,18 @@ def env_sh_contents(): def tf_var_comment(contents, param): comments = { 'auth_token': ['See doc: https://docs.oracle.com/en-us/iaas/Content/Registry/Tasks/registrygettingauthtoken.htm'], - 'db_password': ['Requires at least 12 characters, 2 letters in lowercase, 2 in uppercase, 2 numbers, 2 special characters. Ex: LiveLab__12345', 'If not filled, it will be generated randomly during the first build.'], + 'db_password': ['Min length 12 characters, 2 lowercase, 2 uppercase, 2 numbers, 2 special characters. Ex: LiveLab__12345', 'If not filled, it will be generated randomly during the first build.'], 'license': ['BRING_YOUR_OWN_LICENSE or LICENSE_INCLUDED'] }.get(param) if comments is not None: + b=True for comment in comments: - contents.append(f'# {get_tf_var(param)} : {comment}') + if b: + b=False + contents.append(f'# {get_tf_var(param)} : {comment}') + else: + contents.append(f'# {comment}') + def write_env_sh(): @@ -601,7 +649,6 @@ def cp_terraform(file1, file2=None, file3=None): if file3 is not None: append_file( output_dir + "/src/terraform/"+file1, "option/terraform/"+file3 ) - def output_copy_tree(src, target): copy_tree(src, output_dir + os.sep + target) @@ -617,9 +664,9 @@ def output_remove(src): def output_rm_tree(src): shutil.rmtree(output_dir + os.sep + src) -def cp_dir_src_db(db_type): - print("cp_dir_src_db "+db_type) - output_copy_tree("option/src/db/"+db_type, "src/db") +def cp_dir_src_db(db_family): + print("cp_dir_src_db "+db_family) + output_copy_tree("option/src/db/"+db_family, "src/db") def output_replace_db_node_count(): if params.get('db_node_count')!="2": @@ -636,7 +683,7 @@ def output_replace_db_node_count(): output_move("src/db/deploy_db_node.sh", "bin/deploy_db_node.sh") if params['language'] == "java" and params['java_framework'] == "springboot": output_copy_tree("option/src/app/java_springboot_rac", "src/app") - if params['ui'] == "html": + if params['ui_type'] == "html": output_copy_tree("option/src/ui/html_rac", "src/ui" ) # Copy the terraform for APIGW @@ -651,11 +698,11 @@ def cp_terraform_apigw(append_tf): app_url = "http://${local.apigw_dest_private_ip}:8080/$${request.path[pathname]}" if 'apigw_ocid' in params: - cp_terraform("apigw_existing.tf", "apigw_tags.tf", append_tf) - output_replace('##APP_URL##', app_url,"src/terraform/apigw_existing.tf") + cp_terraform("apigw_existing.j2.tf", "apigw_tags.tf", append_tf) + output_replace('##APP_URL##', app_url,"src/terraform/apigw_existing.j2.tf") else: - cp_terraform("apigw.tf", "apigw_tags.tf", append_tf) - output_replace('##APP_URL##', app_url, "src/terraform/apigw.tf") + cp_terraform("apigw.j2.tf", "apigw_tags.tf", append_tf) + output_replace('##APP_URL##', app_url, "src/terraform/apigw.j2.tf") #---------------------------------------------------------------------------- # Create Directory (shared for group_common and output) @@ -690,7 +737,7 @@ def create_dir_shared(): cp_terraform("bastion_shared_compute.tf") elif 'bastion_ocid' in params: cp_terraform("bastion_existing.tf") - elif params.get('database')!='none': + elif params.get('db_type')!='none': cp_terraform("bastion.tf") #---------------------------------------------------------------------------- @@ -702,36 +749,36 @@ def create_output_dir(): if params['language'] == "none": output_rm_tree("src/app") else: - if params.get('deploy') == "function": + if params.get('deploy_type') == "function": app = "fn/fn_"+params['language'] else: app = params['language'] - if params['database'] == "autonomous" or params['database'] == "database" or params['database'] == "pluggable" or params['database'] == "db_free": - app_db = "oracle" - elif params['database'] == "mysql": - app_db = "mysql" - elif params['database'] == "psql": - app_db = "psql" - elif params['database'] == "none": - app_db = "none" - params['db_family'] = app_db + if params['db_type'] == "autonomous" or params['db_type'] == "database" or params['db_type'] == "pluggable" or params['db_type'] == "db_free": + db_family = "oracle" + elif params['db_type'] == "mysql": + db_family = "mysql" + elif params['db_type'] == "psql": + db_family = "psql" + elif params['db_type'] == "none": + db_family = "none" + params['db_family'] = db_family # Function Common - if params.get('deploy') == "function": + if params.get('deploy_type') == "function": output_copy_tree("option/src/app/fn/fn_common", "src/app") # Generic version for Oracle DB if os.path.exists("option/src/app/"+app): output_copy_tree("option/src/app/"+app, "src/app") - if params.get('deploy') != "function" and params['language'] == "java": + if params.get('deploy_type') != "function" and params['language'] == "java": # Java Framework app = "java_" + params['java_framework'] output_copy_tree("option/src/app/"+app, "src/app") # Overwrite the generic version (ex for mysql) - app_dir = app+"_"+app_db + app_dir = app+"_"+db_family print("app_dir="+app_dir) if os.path.exists("option/src/app/"+app_dir): output_copy_tree("option/src/app/"+app_dir, "src/app") @@ -747,20 +794,20 @@ def create_output_dir(): output_replace('##DOCKER_IMAGE##', 'openjdk:21-jdk-slim', "src/app/Dockerfile") # -- User Interface ----------------------------------------------------- - if params.get('ui') == "none": + if params.get('ui_type') == "none": print("No UI") output_rm_tree("src/ui") - elif params.get('ui') == "api": + elif params.get('ui_type') == "api": print("API Only") output_rm_tree("src/ui") - if params.get('deploy') in [ 'compute', 'instance_pool' ]: + if params.get('deploy_type') in [ 'compute', 'instance_pool' ]: cp_terraform_apigw("apigw_compute_append.tf") else: - ui_lower = params.get('ui').lower() + ui_lower = params.get('ui_type').lower() output_copy_tree("option/src/ui/"+ui_lower, "src/ui") # -- Deployment --------------------------------------------------------- - if params.get('deploy') == "hpc": + if params.get('deploy_type') == "hpc": # remove normal shared terraform file output_terraform_dir = output_dir + os.sep + "src/terraform" for fname in os.listdir(output_terraform_dir): @@ -771,10 +818,10 @@ def create_output_dir(): output_remove( "src/terraform/variables.tf" ) # replace with a prefilled one cp_terraform("hpc_variables.tf") - elif params.get('deploy') == "datascience": + elif params.get('deploy_type') == "datascience": cp_terraform("datascience.tf") elif params['language'] != "none": - if params.get('deploy') == "kubernetes": + if params.get('deploy_type') == "kubernetes": if 'oke_ocid' in params: cp_terraform("oke_existing.tf", "oke_append.tf") else: @@ -792,7 +839,7 @@ def create_output_dir(): output_replace('##PREFIX##', params["prefix"], "src/oke/ingress-app.yaml") output_replace('##PREFIX##', params["prefix"], "src/oke/ingress-ui.yaml") - elif params.get('deploy') == "function": + elif params.get('deploy_type') == "function": if 'fnapp_ocid' in params: cp_terraform("function_existing.tf", "function_append.tf") else: @@ -803,11 +850,11 @@ def create_output_dir(): else: apigw_append = "apigw_fn_append.tf" if 'apigw_ocid' in params: - cp_terraform("apigw_existing.tf", "apigw_tags.tf", apigw_append) + cp_terraform("apigw_existing.j2.tf", "apigw_tags.tf", apigw_append) else: - cp_terraform("apigw.tf", "apigw_tags.tf", apigw_append) + cp_terraform("apigw.j2.tf", "apigw_tags.tf", apigw_append) - elif params.get('deploy') in [ 'compute', 'instance_pool' ]: + elif params.get('deploy_type') in [ 'compute', 'instance_pool' ]: if 'compute_ocid' in params: cp_terraform("compute_existing.tf", "compute_append.tf") elif params.get("language") == 'forms': @@ -816,13 +863,19 @@ def create_output_dir(): cp_terraform("compute.tf", "compute_append.tf") output_mkdir("src/compute") output_copy_tree("option/compute", "src/compute") - if params.get('deploy') == 'instance_pool': - cp_terraform("instance_pool.tf") - - elif params.get('deploy') == "container_instance": + if params.get('deploy_type') == 'instance_pool': + cp_terraform("instance_pool.j2.tf") + elif params.get('tls') == 'existing_dir': + output_copy_tree("option/tls/compute_existing_dir", "src/tls") + elif params.get('tls') == 'new_http_01': + output_copy_tree("option/tls/new_http_01", "src/tls") + elif params.get('tls') == 'existing_ocid': + cp_terraform_apigw("apigw_compute_append.tf") + + elif params.get('deploy_type') == "container_instance": if 'group_common' not in params: cp_terraform("container_instance_policy.tf") - if params.get('database') == "none": + if params.get('db_type') == "none": cp_terraform("container_instance_nodb.tf") else: cp_terraform("container_instance.tf") @@ -831,39 +884,41 @@ def create_output_dir(): output_copy_tree("option/container_instance", "bin") cp_terraform_apigw("apigw_ci_append.tf") + if params.get('tls'): + cp_terraform("tls.j2.tf") + if params.get('deploy_type') == 'kubernetes': + cp_terraform_apigw("apigw_kubernetes_tls_append.tf") + if os.path.exists(output_dir + "/src/app/openapi_spec_append.yaml"): append_file( output_dir + "/src/app/openapi_spec.yaml", output_dir + "/src/app/openapi_spec_append.yaml") os.remove( output_dir + "/src/app/openapi_spec_append.yaml" ) # -- Database ---------------------------------------------------------------- - if params.get('database') != "none": + if params.get('db_type') != "none": cp_terraform("output.tf") output_mkdir("src/db") - if params.get('database') == "autonomous": - cp_dir_src_db("oracle") + cp_dir_src_db(db_family) + if params.get('db_type') == "autonomous": if 'atp_ocid' in params: cp_terraform("atp_existing.tf", "atp_append.tf") else: cp_terraform("atp.tf", "atp_append.tf") - if params.get('database') == "database": - cp_dir_src_db("oracle") + if params.get('db_type') == "database": if 'db_ocid' in params: cp_terraform("dbsystem_existing.tf", "dbsystem_append.tf") else: cp_terraform("dbsystem.tf", "dbsystem_append.tf") output_replace_db_node_count() - if params.get('database') == "pluggable": - cp_dir_src_db("oracle") + if params.get('db_type') == "pluggable": if 'pdb_ocid' in params: cp_terraform("dbsystem_pluggable_existing.tf") else: cp_terraform("dbsystem_existing.tf", "dbsystem_pluggable.tf") - if params.get('database') == "db_free": - cp_dir_src_db("oracle") + if params.get('db_type') == "db_free": if params.get('db_install') == "shared_compute": cp_terraform("db_free_shared_compute.tf") else: @@ -871,8 +926,7 @@ def create_output_dir(): output_copy_tree("option/src/db/db_free", "src/db") output_move("src/db/deploy_db_node.sh", "bin/deploy_db_node.sh") - if params.get('database') == "mysql": - cp_dir_src_db("mysql") + if params.get('db_type') == "mysql": if params.get('db_install') == "shared_compute": cp_terraform("mysql_shared_compute.tf") output_copy_tree("option/src/db/mysql_shared_compute", "src/db") @@ -882,8 +936,7 @@ def create_output_dir(): else: cp_terraform("mysql.tf", "mysql_append.tf") - if params.get('database') == "psql": - cp_dir_src_db("psql") + if params.get('db_type') == "psql": if 'psql_ocid' in params: cp_terraform("psql_existing.tf", "psql_append.tf") else: @@ -896,7 +949,8 @@ def create_output_dir(): src_path = os.path.join("src/app/db", f) dst_path = os.path.join("src/db", f) output_move(src_path, dst_path) - os.rmdir(output_dir + "/src/app/db") + os.rmdir(output_dir + "/src/app/db") + #---------------------------------------------------------------------------- # Create group_common Directory @@ -905,7 +959,7 @@ def create_group_common_dir(): # -- APP ---------------------------------------------------------------- output_copy_tree("option/src/app/group_common", "src/app") - os.remove(output_dir + "/src/app/app.yaml") + os.remove(output_dir + "/src/app/app.j2.yaml") # -- User Interface ----------------------------------------------------- output_rm_tree("src/ui") @@ -957,9 +1011,9 @@ def create_group_common_dir(): if 'apigw' in a_group_common: if 'apigw_ocid' in params: - cp_terraform("apigw_existing.tf", "apigw_tags.tf") + cp_terraform("apigw_existing.j2.tf", "apigw_tags.tf") else: - cp_terraform("apigw.tf", "apigw_tags.tf") + cp_terraform("apigw.j2.tf", "apigw_tags.tf") cp_terraform("log_group.tf") if 'jms' in a_group_common: @@ -1016,19 +1070,25 @@ def create_group_common_dir(): def jinja2_replace_template(): db_param = jinja2_db_params.get( params.get('db_family') ) - template_param = {**params, **db_param} + if db_param is None: + template_param = params + else: + template_param = {**params, **db_param} for subdir, dirs, files in os.walk(output_dir): for filename in files: if filename.find('.j2.')>0 or filename.endswith('.j2'): - environment = Environment(loader=FileSystemLoader(subdir)) - template = environment.get_template(filename) - db_param = jinja2_db_params.get( params.get('db_family') ) - content = template.render( template_param ) output_file_path = os.path.join(subdir, filename.replace(".j2", "")) - with open(output_file_path, mode="w", encoding="utf-8") as output_file: - output_file.write(content) - print(f"Wrote {output_file}") + if os.path.isfile(output_file_path): + print(f"J2 - Skipping - destination file already exists: {output_file_path}") + else: + environment = Environment(loader=FileSystemLoader(subdir)) + template = environment.get_template(filename) + db_param = jinja2_db_params.get( params.get('db_family') ) + content = template.render( template_param ) + with open(output_file_path, mode="w", encoding="utf-8") as output_file: + output_file.write(content) + print(f"J2 - Wrote {output_file_path}") os.remove(os.path.join(subdir, filename)) if filename.endswith('_refresh.sh'): os.remove(os.path.join(subdir, filename)) @@ -1056,20 +1116,16 @@ def jinja2_replace_template(): errors = [] if mode == CLI: - apply_rules() - if len(errors) > 0: - mode = ABORT - elif os.path.isdir(output_dir): + if os.path.isdir(output_dir): print("Output dir exists already.") mode = ABORT else: - print_warnings() - -if mode == GIT: - print("GIT mode currently not implemented.") - # git clone $GIT_URL - # cp ../mode/git/* $REPOSITORY_NAME/. - exit() + save_params() + apply_rules() + if len(errors) > 0: + mode = ABORT + else: + print_warnings() if mode == ABORT: print(help()) @@ -1084,6 +1140,7 @@ def jinja2_replace_template(): # Create a group if 'group_name' in params: create_group_common_dir() + jinja2_replace_template() # Add parameters to the creation if the project is to be used with a group if 'group_common' in params: @@ -1097,7 +1154,7 @@ def jinja2_replace_template(): params['public_subnet_ocid'] = TO_FILL params['private_subnet_ocid'] = TO_FILL # Use a bastion only for the database - if params.get('database')!='none': + if params.get('db_type')!='none': params['bastion_ocid'] = TO_FILL to_ocid = { "atp": "atp_ocid", "database": "db_ocid", "mysql": "mysql_ocid", "psql": "psql_ocid", "oke": "oke_ocid", "fnapp": "fnapp_ocid", "apigw": "apigw_ocid", "jms": "jms_ocid", "compute": "compute_ocid"} for x in a_group_common: @@ -1105,7 +1162,7 @@ def jinja2_replace_template(): ocid = to_ocid[x] params[ocid] = TO_FILL -if 'deploy' in params: +if 'deploy_type' in params: create_output_dir() jinja2_replace_template() diff --git a/schema.yaml b/schema.yaml index d5853529..f12fd7d4 100644 --- a/schema.yaml +++ b/schema.yaml @@ -27,7 +27,7 @@ variableGroups: visible: true variables: - language - - deploy_strategy + - deploy_type - java_framework - java_vm - java_version @@ -35,7 +35,7 @@ variableGroups: - title: User Interface visible: true variables: - - ui_strategy + - ui_type - title: Deployment visible: true @@ -54,7 +54,7 @@ variableGroups: - title: "Database" visible: true variables: - - db_strategy + - db_type - db_existing_strategy - atp_ocid - db_ocid @@ -111,7 +111,7 @@ variables: default: "Java" required: true - deploy_strategy: + deploy_type: visible: true type: enum title: Deployment @@ -131,10 +131,10 @@ variables: - "Java" - or: - eq: - - ${deploy_strategy} + - ${deploy_type} - "Kubernetes" - eq: - - ${deploy_strategy} + - ${deploy_type} - "Virtual Machine" type: enum title: Java Framework @@ -154,10 +154,10 @@ variables: - "Java" - or: - eq: - - ${deploy_strategy} + - ${deploy_type} - "Kubernetes" - eq: - - ${deploy_strategy} + - ${deploy_type} - "Virtual Machine" type: enum title: Java Framework @@ -181,10 +181,10 @@ variables: - "Helidon" - or: - eq: - - ${deploy_strategy} + - ${deploy_type} - "Kubernetes" - eq: - - ${deploy_strategy} + - ${deploy_type} - "Virtual Machine" type: enum title: Java Framework @@ -241,7 +241,7 @@ variables: kubernetes_strategy: visible: eq: - - ${deploy_strategy} + - ${deploy_type} - "Kubernetes" type: enum enum: @@ -255,7 +255,7 @@ variables: visible: and: - eq: - - ${deploy_strategy} + - ${deploy_type} - "Kubernetes" - eq: - ${kubernetes_strategy} @@ -273,7 +273,7 @@ variables: visible: and: - eq: - - ${deploy_strategy} + - ${deploy_type} - "Kubernetes" - eq: - ${kubernetes_strategy} @@ -292,7 +292,7 @@ variables: ###################### Database - db_strategy: + db_type: visible: true type: enum title: Database Type @@ -319,7 +319,7 @@ variables: visible: and: - eq: - - ${db_strategy} + - ${db_type} - "Autonomous Transaction Processing Database" - eq: - ${db_existing_strategy} @@ -335,7 +335,7 @@ variables: visible: and: - eq: - - ${db_strategy} + - ${db_type} - "Database System" - eq: - ${db_existing_strategy} @@ -351,7 +351,7 @@ variables: visible: and: - eq: - - ${db_strategy} + - ${db_type} - "MySQL" - eq: - ${db_existing_strategy} @@ -383,7 +383,7 @@ variables: ###################### User Interface - ui_strategy: + ui_type: visible: true type: enum title: User Interface diff --git a/variables.tf b/variables.tf index 270c21df..cd016340 100644 --- a/variables.tf +++ b/variables.tf @@ -33,12 +33,12 @@ variable "java_version" {} variable "vcn_strategy" {} variable "vcn_ocid" {default=""} variable "subnet_ocid" {default=""} -variable "ui_strategy" {} -variable "deploy_strategy" {} +variable "ui_type" {} +variable "deploy_type" {} variable "kubernetes_strategy" {default=""} variable "oke_strategy" {default=""} variable "oke_ocid" {default=""} -variable "db_strategy" {} +variable "db_type" {} variable "db_existing_strategy" {} variable "atp_ocid" {default=""} variable "db_ocid" {default=""}