From 392b156bf7f1c587253d1c4c2cf7f762e5c44491 Mon Sep 17 00:00:00 2001 From: Kiran <155609672+kirandevtn@users.noreply.github.com> Date: Thu, 21 Mar 2024 18:26:36 +0530 Subject: [PATCH] feat: Added Apply job in k8s plugin (#4828) * feat: Added Devtron CI Trigger Plugin v1.0.0 * feat: Added Apply JOB in k8s Plugin * modified structure * Added error handelling * Removed CI trigger plugin * Migration number changed * logo changed --- assets/devtron-logo-plugin.png | Bin 0 -> 10873 bytes scripts/sql/230_apply_job_ink8s.down.sql | 5 + scripts/sql/230_apply_job_ink8s_plugin.up.sql | 228 ++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 assets/devtron-logo-plugin.png create mode 100644 scripts/sql/230_apply_job_ink8s.down.sql create mode 100644 scripts/sql/230_apply_job_ink8s_plugin.up.sql diff --git a/assets/devtron-logo-plugin.png b/assets/devtron-logo-plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..fc17baf72802401d58f7a778de5c79959d03e1ee GIT binary patch literal 10873 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 K)veNgi25J-N0`?D literal 0 HcmV?d00001 diff --git a/scripts/sql/230_apply_job_ink8s.down.sql b/scripts/sql/230_apply_job_ink8s.down.sql new file mode 100644 index 0000000000..23b6390e49 --- /dev/null +++ b/scripts/sql/230_apply_job_ink8s.down.sql @@ -0,0 +1,5 @@ +DELETE FROM plugin_step_variable WHERE plugin_step_id =(SELECT id FROM plugin_metadata WHERE name='Apply JOB in k8s v1.0.0'); +DELETE FROM plugin_step WHERE plugin_id=(SELECT id FROM plugin_metadata WHERE name='Apply JOB in k8s v1.0.0'); +DELETE FROM plugin_pipeline_script WHERE id=(SELECT id FROM plugin_metadata WHERE name='Apply JOB in k8s v1.0.0'); +DELETE FROM plugin_stage_mapping WHERE plugin_id=(SELECT id FROM plugin_metadata WHERE name='Apply JOB in k8s v1.0.0'); +DELETE FROM plugin_metadata WHERE name ='Apply JOB in k8s v1.0.0'; \ No newline at end of file diff --git a/scripts/sql/230_apply_job_ink8s_plugin.up.sql b/scripts/sql/230_apply_job_ink8s_plugin.up.sql new file mode 100644 index 0000000000..7a0954a2da --- /dev/null +++ b/scripts/sql/230_apply_job_ink8s_plugin.up.sql @@ -0,0 +1,228 @@ +INSERT INTO plugin_metadata (id,name,description,type,icon,deleted,created_on,created_by,updated_on,updated_by) +VALUES (nextval('id_seq_plugin_metadata'),'Apply JOB in k8s v1.0.0','Apply custom jobs in k8s cluster.','PRESET','https://raw.githubusercontent.com/devtron-labs/devtron/main/assets/devtron-logo-plugin.png',false,'now()',1,'now()',1); + + +INSERT INTO plugin_stage_mapping (id,plugin_id,stage_type,created_on,created_by,updated_on,updated_by)VALUES (nextval('id_seq_plugin_stage_mapping'), +(SELECT id from plugin_metadata where name='Apply JOB in k8s v1.0.0'), 0,'now()',1,'now()',1); + + +INSERT INTO "plugin_pipeline_script" ("id", "script","type","deleted","created_on", "created_by", "updated_on", "updated_by") +VALUES ( nextval('id_seq_plugin_pipeline_script'), +E'#!/bin/sh +RUN_MIGRATION=$(echo $CI_CD_EVENT | jq -r \'.commonWorkflowRequest.extraEnvironmentVariables.RUN_MIGRATION\') +echo $RUN_MIGRATION +if [ "$RUN_MIGRATION" == "true" ]; then + # Configuration variables + NAMESPACE=$Namespace + NAME=$JobName + RUN_COMMAND=$RunCommand + BUILD_ARC=$BuildArch + SERVICE_ACCOUNT=$ServiceAccount + HEALTH_ENDPOINT=$HealthEndpoint + ENV_PATH=$EnvPath + JOB_TEMPLATE=$JobTemplatePath + MAX_ATTEMPTS=$MaxAttempts + SLEEP_TIME=$SleepTime + + if [ -z "$NAMESPACE" ];then + echo "Exiting due to Namespace not specified". + exit 1 + elif [ -z "$NAME" ];then + echo "Exiting due to JobName not specified". + exit 1 + elif [ -z "$RUN_COMMAND" ];then + echo "Exiting due to RunCommand not specified". + exit 1 + elif [ -z "$BUILD_ARC" ];then + echo "Exiting due to BuildArch not specified". + exit 1 + elif [ -z "$SERVICE_ACCOUNT" ];then + echo "Exiting due to ServiceAccount not specified". + exit 1 + elif [ -z "$HEALTH_ENDPOINT" ];then + echo "Exiting due to HealthEndpoint not specified". + exit 1 + elif [ -z "$ENV_PATH" ];then + echo "Exiting due to EnvPath not specified". + exit 1 + elif [ -z "$KubeConfig" ];then + echo "Exiting due to KubeConfig not specified". + exit 1 + fi + + if [ -z "$MAX_ATTEMPTS" ];then + echo "MaxAttempts not specified using the default one i.e. 20" #Will set these values in SQL + fi + if [ -z "$SLEEP_TIME" ];then + echo "SleepTime not specified using the default one i.e. 15" #Will set these values in SQL + fi + + echo "Running migration job" + + # Devtron Config + cd /devtroncd + touch kubeconfig.yaml + touch kubeconfig.txt + echo $KubeConfig > kubeconfig.txt + cat kubeconfig.txt | base64 -d > kubeconfig.yaml + + # Get the system architecture + architecture=$(uname -m) + + # Check if the architecture is AMD or ARM + if [[ $architecture == "x86_64" || $architecture == "amd64" ]]; then + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + elif [[ $architecture == "aarch64" || $architecture == "arm64" ]]; then + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl" + else + echo "Unknown system architecture: $architecture" + exit 1 + fi + install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl + + # Custom Variables + export tag=$(echo $CI_CD_EVENT | jq --raw-output .commonWorkflowRequest.dockerImageTag) + export repo=$(echo $CI_CD_EVENT | jq --raw-output .commonWorkflowRequest.dockerRepository) + export registry=$(echo $CI_CD_EVENT | jq --raw-output .commonWorkflowRequest.dockerRegistryURL) + + echo $registry/$repo:$tag + IMAGE_TAG=$registry/$repo:$tag + + + if [ $JobTemplateScoped ];then + echo "Using JOB template from scoped variable" + touch job-template.yaml + touch temp.txt + echo $JobTemplateScoped > temp.txt + cat temp.txt | base64 -d > job-template.yaml + else + if [ $JOB_TEMPLATE ];then + echo "Using external job template from repo" + touch job-template.yaml + echo "Path to jobtemplate: $JOB_TEMPLATE" + cat $JOB_TEMPLATE > job-template.yaml + else + echo "Using internal job template" + echo "No job template specified. Using the default" + touch jobtemplate.txt + touch job-template.yaml + default_job_template="YXBpVmVyc2lvbjogYmF0Y2gvdjEKa2luZDogSm9iCm1ldGFkYXRhOgogIG5hbWU6IFZBUi1KT0ItTkFNRS1SQU5ET00tU1RSSU5HCiAgbmFtZXNwYWNlOiBWQVItTkFNRVNQQUNFCnNwZWM6CiAgYmFja29mZkxpbWl0OiAwCiAgYWN0aXZlRGVhZGxpbmVTZWNvbmRzOiAxMDgwMAogIHRlbXBsYXRlOgogICAgc3BlYzoKICAgICAgYWZmaW5pdHk6CiAgICAgICAgbm9kZUFmZmluaXR5OgogICAgICAgICAgcmVxdWlyZWREdXJpbmdTY2hlZHVsaW5nSWdub3JlZER1cmluZ0V4ZWN1dGlvbjoKICAgICAgICAgICAgbm9kZVNlbGVjdG9yVGVybXM6CiAgICAgICAgICAgICAgLSBtYXRjaEV4cHJlc3Npb25zOgogICAgICAgICAgICAgICAgICAtIGtleTogbm9kZXR5cGUKICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcjogSW4KICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgICAtIFZBUi1CVUlMRC1BUkMKICAgICAgY29udGFpbmVyczoKICAgICAgLSBuYW1lOiBWQVItSk9CLU5BTUUKICAgICAgICBpbWFnZTogVkFSLUlNQUdFLVRBRwogICAgICAgIGFyZ3M6CiAgICAgICAgICAtIC9iaW4vc2gKICAgICAgICAgIC0gLWMKICAgICAgICAgIC0gVkFSLU1JR1JBVElPTi1SVU4tQ09NTUFORAogICAgICAgIGVudjoKICAgICAgICAgIC0gbmFtZTogRU5WX1BBVEgKICAgICAgICAgICAgdmFsdWU6IFZBUi1FTlYtUEFUSAogICAgICAgICAgLSBuYW1lOiBWQVVMVF9UT0tFTgogICAgICAgICAgICB2YWx1ZUZyb206CiAgICAgICAgICAgICAgc2VjcmV0S2V5UmVmOgogICAgICAgICAgICAgICAgbmFtZTogdmF1bHQtc2VjcmV0CiAgICAgICAgICAgICAgICBrZXk6IFZBVUxUX1RPS0VOCiAgICAgICAgICAtIG5hbWU6IFZBVUxUX1VSTAogICAgICAgICAgICB2YWx1ZUZyb206CiAgICAgICAgICAgICAgY29uZmlnTWFwS2V5UmVmOgogICAgICAgICAgICAgICAgbmFtZTogdmF1bHQtdXJsCiAgICAgICAgICAgICAgICBrZXk6IFZBVUxUX1VSTAogICAgICAgIHJlc291cmNlczoKICAgICAgICAgIGxpbWl0czoKICAgICAgICAgICAgY3B1OiAiMiIKICAgICAgICAgICAgbWVtb3J5OiA0R2kKICAgICAgICAgIHJlcXVlc3RzOgogICAgICAgICAgICBjcHU6ICIyIgogICAgICAgICAgICBtZW1vcnk6IDRHaQogICAgICByZXN0YXJ0UG9saWN5OiBOZXZlcgogICAgICBzZXJ2aWNlQWNjb3VudE5hbWU6IFZBUi1TRVJWSUNFLUFDQ09VTlQ=" + echo $default_job_template > jobtemplate.txt + cat jobtemplate.txt | base64 -d > job-template.yaml + fi + + fi + + set +o pipefail + RANDOM_STRING=$(openssl rand -base64 6 | tr -dc a-z | fold -w 4 | head -n 1) + set -o pipefail + + JOB_NAME="${NAME}-${RANDOM_STRING}" + + sed -i -e "s|VAR-JOB-NAME-RANDOM-STRING| ${JOB_NAME}|g" \\ + -e "s|VAR-JOB-NAME|${NAME}|g" \\ + -e "s|VAR-NAMESPACE|${NAMESPACE}|g" \\ + -e "s|VAR-BUILD-ARC|${BUILD_ARC}|g" \\ + -e "s|VAR-IMAGE-TAG|${IMAGE_TAG}|g" \\ + -e "s|VAR-ENV-PATH|${ENV_PATH}|g" \\ + -e "s|VAR-SERVICE-ACCOUNT|${SERVICE_ACCOUNT}|g" \\ + -e "s|VAR-MIGRATION-RUN-COMMAND|${RUN_COMMAND}|g" job-template.yaml + + FILE_PATH=job-template.yaml + cat job-template.yaml + + echo "Applying job YAML..." + kubectl apply -f "$FILE_PATH" --kubeconfig /devtroncd/kubeconfig.yaml + + echo "Waiting for the pod to be in the Running state..." + for ATTEMPT in $(seq 1 $MAX_ATTEMPTS); do + echo "Checking pod status, attempt $ATTEMPT of $MAX_ATTEMPTS..." + POD_NAME=$(kubectl get pods --kubeconfig /devtroncd/kubeconfig.yaml -n $NAMESPACE --selector=job-name=$JOB_NAME -o jsonpath=\'{.items[0].metadata.name}\') + if [ -z "$POD_NAME" ]; then + echo "Pod not found yet. Waiting..." + sleep $SLEEP_TIME + continue + fi + + POD_STATUS=$(kubectl get pod --kubeconfig /devtroncd/kubeconfig.yaml $POD_NAME -n $NAMESPACE -o jsonpath=\'{.status.phase}\') + if [ "$POD_STATUS" = "Running" ]; then + echo "Pod $POD_NAME is running." + POD_RUNNING=1 + break + else + echo "Pod $POD_NAME is not ready yet. Status: $POD_STATUS" + sleep $SLEEP_TIME + fi + done + + if [ "$POD_STATUS" != "Running" ]; then + echo "Pod did not reach running state within the allowed attempts." + exit 1 + fi + + # Perform health check + echo "Performing health check..." +# Ensure the loop only starts if the pod is in a Running state + if [ $POD_RUNNING -eq 1 ]; then + POD_IPS=$(kubectl get pods --kubeconfig /devtroncd/kubeconfig.yaml -n $NAMESPACE --selector=job-name=$JOB_NAME -o jsonpath=\'{.items[*].status.podIP}\') + echo "Pod IPs: $POD_IPS" + + HEALTHY=0 + echo "Performing health check..." + for ATTEMPT in $(seq 1 $MAX_ATTEMPTS); do + FULL_URL="http://$POD_IPS$HEALTH_ENDPOINT" + echo "Checking URL: $FULL_URL" + STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$FULL_URL") || true + echo "Attempt $ATTEMPT: Received status $STATUS" + + if [ "$STATUS" = "200" ]; then + echo "Pod health check PASSED" + HEALTHY=1 + break + elif [ "$STATUS" = "000" ]; then + echo "Attempt $ATTEMPT: Unable to connect to the pod. Retrying..." + else + echo "Attempt $ATTEMPT: Waiting for pod to become healthy... Status: $STATUS" + fi + sleep $SLEEP_TIME + done + + if [ $HEALTHY -ne 1 ]; then + echo "Pod health check FAILED after $MAX_ATTEMPTS attempts" + kubectl delete job $JOB_NAME -n $NAMESPACE --kubeconfig /devtroncd/kubeconfig.yaml + exit 1 + fi + else + echo "Pod did not reach healthy state within the allowed attempts." + exit 1 + fi + + + echo "Migration completed successfully." +else + echo "Skipping Migration" +fi +' +, + 'SHELL', + 'f', + 'now()', + 1, + 'now()', + 1 +); +INSERT INTO "plugin_step" ("id", "plugin_id","name","description","index","step_type","script_id","deleted", "created_on", "created_by", "updated_on", "updated_by") VALUES (nextval('id_seq_plugin_step'), (SELECT id FROM plugin_metadata WHERE name='Apply JOB in k8s v1.0.0'),'Step 1','Running the plugin','1','INLINE',(SELECT last_value FROM id_seq_plugin_pipeline_script),'f','now()', 1, 'now()', 1); +INSERT INTO plugin_step_variable (id,plugin_step_id,name,format,description,is_exposed,allow_empty_value,default_value,value,variable_type,value_type,previous_step_index,variable_step_index,variable_step_index_in_plugin,reference_variable_name,deleted,created_on,created_by,updated_on,updated_by) +VALUES +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'Namespace', 'STRING','The namespace where the JOB is to be applied.','t','f',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'JobName', 'STRING','The name of the JOB to run','t','f',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'RunCommand', 'STRING','Run command for the JOB','t','f',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'BuildArch', 'STRING','Build architecture.', 't','f',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'ServiceAccount', 'STRING','Service account.','t','f',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'HealthEndpoint', 'STRING','Health endpoint for health-check.', 't','f',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'EnvPath', 'STRING','Path of env variables.','t','f',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'KubeConfig', 'STRING','base64 encoded kubeconfig thorugh scoped variable', 't','f',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'JobTemplateScoped','STRING','base64 encoded job template through scoped variable. Will use default if not provided.','t','t',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'JobTemplatePath','STRING','Path of the JOB template.Will use default if not provided.','t','t',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'MaxAttempts', 'NUMBER','Maximum attempts to check the JOB status.','t','t',20, null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1), +(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Apply JOB in k8s v1.0.0' and ps."index"=1 and ps.deleted=false),'SleepTime', 'NUMBER','Time interval between each health check.','t','t',15, null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1); \ No newline at end of file