#!/bin/bash POLICY_CRDS_PATH="/tmp/policy_crds.json" APISERVER=https://kubernetes.default.svc SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount TOKEN=$(cat ${SERVICEACCOUNT}/token) NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace) CACERT=${SERVICEACCOUNT}/ca.crt ra_token= tenant_id= agent_id= profile_id= cluster_id= latest_policy_version=1 if [ -f $POLICY_CRDS_PATH ]; then chmod 644 $POLICY_CRDS_PATH fi load_agent_details() { tenant_id=$(awk -F\" '/Tenant ID/{print $4}' /etc/cp/conf/agent_details.json) agent_id=$(awk -F\" '/Agent ID/{print $4}' /etc/cp/conf/agent_details.json) profile_id=$(awk -F\" '/Profile ID/{print $4}' /etc/cp/conf/agent_details.json) cluster_id=$(echo $(curl -s --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/ ) \ | /etc/cp/bin/yq eval '.items' - \ | /etc/cp/bin/yq eval '.[] | select(.metadata.name | contains("kube-system"))' - \ | /etc/cp/bin/yq eval '.metadata.uid' -) } get_latest_policy_version() { bucket_list=$(curl -s -w "%{http_code}\n" --request GET \ -H "user-agent: Infinity Next (a7030abf93a4c13)" -H "Authorization: Bearer ${ra_token}" \ "$var_fog/agents-core/storage/?list-type=2&prefix=${tenant_id}/${profile_id}") paths_list=$(echo $bucket_list | awk -F'|' '/policy-/ {for (i = 1; i <= NF; i++) if ($i ~ /policy/) print $i}') prefix="${tenant_id}/${profile_id}" paths=$(echo $paths_list | tr " " "\n" | grep / ) for path in $paths; do new_path=$(echo ${path%/*}) version=$(echo ${new_path##*/}) if [[ $version =~ ^-?[0-9]+$ ]] && [ $latest_policy_version -lt $version ]; then latest_policy_version=$version fi done latest_policy_version=$((latest_policy_version+1)) echo "Policy version: $latest_policy_version" } concat_to_policy() { api_version="$1" crd_to_concat="$2" is_first=$3 if [ ! -z $is_first ]; then POLICY="$POLICY \"$crd_to_concat\": " else POLICY="$POLICY, \"$crd_to_concat\": " fi CRD=$(curl -s --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" \ -X GET ${APISERVER}/apis/openappsec.io/$api_version/$crd_to_concat) CRD=$(echo $CRD|tr -d '\n') if [ -z "$CRD" ]; then CRD="{}" fi POLICY="$POLICY $CRD" } get_api_version() { CRD=$(curl -s --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" \ -X GET ${APISERVER}/apis/openappsec.io/v1beta2/policies) CRD=$(echo $CRD|tr -d '\n') # if CRD is not empty and does not contain "page not found" then it is v1beta2 if [ ! -z "$CRD" ] && ! echo "$CRD" | grep -q "page not found"; then echo "v1beta2" else echo "v1beta1" fi } generate_policy() { POLICY="{ \"Policy\": {" api_version=$(get_api_version) concat_to_policy $api_version "policies" true if [ "$api_version" = "v1beta2" ]; then concat_to_policy $api_version "threatpreventionpractices" concat_to_policy $api_version "accesscontrolpractices" else concat_to_policy $api_version "practices" fi concat_to_policy $api_version "logtriggers" concat_to_policy $api_version "customresponses" concat_to_policy $api_version "exceptions" concat_to_policy $api_version "sourcesidentifiers" concat_to_policy $api_version "trustedsources" POLICY="$POLICY, \"assets\": { \"items\":[ " FIRST="1" all_ingresses=$(curl -s --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" \ -X GET ${APISERVER}/apis/networking.k8s.io/v1/ingresses) namespaces=$(echo $all_ingresses | /etc/cp/bin/yq eval '.items[].metadata.namespace' -) for ns in ${namespaces}; do ingress_in_ns=$(curl -s --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" \ -X GET ${APISERVER}/apis/networking.k8s.io/v1/namespaces/${ns}/ingresses) ingress_list=$(echo $ingress_in_ns | /etc/cp/bin/yq eval '.items[].metadata.name' -) for ingress_name in ${ingress_list}; do ingress_crd=$(curl -s --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" \ -X GET ${APISERVER}/apis/networking.k8s.io/v1/namespaces/${ns}/ingresses/${ingress_name}) if echo $ingress_crd | grep -n "openappsec" 1>/dev/null; then ingress_crd=$(echo $ingress_crd | tr -d '\n') fi if [ "$FIRST" = "0" ]; then POLICY="$POLICY ," fi POLICY="$POLICY $ingress_crd" FIRST="0" done done POLICY="$POLICY ] } } }" echo $POLICY > $POLICY_CRDS_PATH } upload_the_crds_to_s3() { echo "Uploading local configuration to cloud..." upload_res="$(curl -o /dev/null -s -w "%{http_code}\n" --progress-bar --request PUT -T "${POLICY_CRDS_PATH}" \ -H "user-agent: Infinity Next (a7030abf93a4c13)" -H "Content-Type: application/json" \ -H "Authorization: Bearer ${ra_token}" \ "$var_fog/agents-core/storage/$tenant_id/$profile_id/$latest_policy_version/policy-$cluster_id.json")" if test "$upload_res" != "200"; then echo "Failed uploading CRDs to cloud: Failed Error code ${upload_res}" return 1 fi check_file_exists="$(curl -o /dev/null -s -w "%{http_code}\n" --request GET -H "user-agent: Infinity Next (a7030abf93a4c13)" \ -H "Authorization: Bearer ${ra_token}" \ "$var_fog/agents-core/storage/$tenant_id/$profile_id/$latest_policy_version/policy-$cluster_id.json")" if test "$check_file_exists" != "200"; then echo "Failed uploading CRD to cloud: Failed on checking the file. Error code ${check_file_exists}" return 1 fi } send_notification_to_the_fog() { correlation_id=$(cat /proc/sys/kernel/random/uuid) DATE=$(date "+%FT%T.000") upload_res=$(curl -o /dev/null -s -w "%{http_code}\n" --request POST "$var_fog/api/v1/agents/events/bulk" \ -H "X-Trace-Id:${correlation_id}" --header "Authorization: Bearer ${ra_token}" \ --header "user-agent: Infinity Next (a7030abf93a4c13)" --header "Content-Type: application/json" \ --data "{\"logs\": [{\"log\": {\"eventTime\": \"$DATE\",\"eventName\": \ \"Agent started onboarding process to cloud management\",\"eventSeverity\": \"Info\",\"eventPriority\": \ \"Urgent\",\"eventLogLevel\": \"info\",\"eventType\": \"Event Driven\",\"eventLevel\": \"Log\",\"eventAudience\": \ \"Internal\",\"eventAudienceTeam\": \"Agent Core\",\"eventFrequency\": 0,\"eventSource\": {\"serviceName\": \ \"Orchestration\",\"agentId\": \"$agent_id\",\"tenantId\": \"$tenant_id\",\"serviceId\": \"1\",\"issuingEngineVersion\": \ \"1.2229.123456\",\"issuingEngine\": \"onboardingInfoProvider\"},\"eventData\": {\"eventObject\": {\"onboardingInfo\": \ {\"policyVersion\": $latest_policy_version,\"clusterId\": \"$cluster_id\",\"profileId\": \"$profile_id\"}}},\ \"eventTags\": [\"Orchestration\"]}, \"tenantId\": \"$tenant_id\", \"id\": 1}]}") if test "$upload_res" != "200"; then sleep 5 upload_res=$(curl -o /dev/null -s -w "%{http_code}\n" --request POST "$var_fog/api/v1/agents/events/bulk" \ -H "X-Trace-Id:${correlation_id}" --header "Authorization: Bearer ${ra_token}" \ --header "user-agent: Infinity Next (a7030abf93a4c13)" --header "Content-Type: application/json" \ --data "{\"logs\": [{\"log\": {\"eventTime\": \"$DATE\",\"eventName\": \ \"Agent started onboarding process to cloud management\",\"eventSeverity\": \"Info\",\"eventPriority\": \ \"Urgent\",\"eventLogLevel\": \"info\",\"eventType\": \"Event Driven\",\"eventLevel\": \"Log\",\ \"eventAudience\": \"Internal\",\"eventAudienceTeam\": \"Agent Core\",\"eventFrequency\": 0,\"eventSource\": \ {\"serviceName\": \"Orchestration\",\"agentId\": \"$agent_id\",\"tenantId\": \"$tenant_id\",\ \"serviceId\": \"1\",\"issuingEngineVersion\": \"1.2229.123456\",\"issuingEngine\": \"onboardingInfoProvider\"},\ \"eventData\": {\"eventObject\": {\"onboardingInfo\": {\"policyVersion\": $latest_policy_version,\ \"clusterId\": \"$cluster_id\",\"profileId\": \"$profile_id\"}}},\"eventTags\": [\"Orchestration\"]}, \ \"tenantId\": \"$tenant_id\", \"id\": 1}]}") if test "$upload_res" != "200"; then echo "Failed to notify the FOG on the new CRDs: Failed Error code ${upload_res}" return 1 fi fi } poll_for_status_file() { correlation_id=$(cat /proc/sys/kernel/random/uuid) attempt_counter=0 max_attempts=18 until [ ${attempt_counter} -eq ${max_attempts} ]; do if [ ${attempt_counter} -eq ${max_attempts} ];then echo "Max attempts reached" exit 1 fi file_exists="$(curl -s -w "%{http_code}\n" --request GET -H "user-agent: Infinity Next (a7030abf93a4c13)" \ -H "Authorization: Bearer ${ra_token}" \ "$var_fog/agents-core/storage/$tenant_id/$profile_id/$latest_policy_version/status-$cluster_id.json")" check_file_exists=$(echo $file_exists | grep 200) if [ ! -z "$check_file_exists" ]; then FAILURE=$(echo $file_exists | grep "false") if [ ! -z "$FAILURE" ]; then echo "Failed creating the Assets: $(echo $file_exists | cut -c27- | cut -d '"' -f 1)" exit 1 else echo "." return 0 fi else echo -n '.' attempt_counter=$(($attempt_counter+1)) sleep 10 fi done echo "Error: Status file was not generated" exit 1 } upload_crds_to_the_cloud() { STATUS="FAILURE" load_agent_details get_latest_policy_version generate_policy upload_the_crds_to_s3 if [ "$?" = "1" ]; then echo "Failed uploading the CRDs to S3" exit 1 fi send_notification_to_the_fog if [ "$?" = "1" ]; then echo "Failed Notifying to FOG" exit 1 fi poll_for_status_file if [ "$?" = "0" ]; then STATUS="SUCCESS" fi if [ "$STATUS" = "FAILURE" ]; then echo "Failed to upload CRDs to the cloud" exit 1 fi } usage() { echo "Usage: $0 --token [options...] ]" echo " --token : Registration token" echo "Options:" echo " --fog : Namespace with the relevant Helm Chart" echo " --upload_policy_only : Upload policy to the fog, withput changing agent mode" echo " --debug : Keep the debuging files" exit 255 } validate_flags() { if [ -z $var_token ]; then usage exit 1 fi } validate_arg_value_exists() { if test "$2" = "1"; then echo "Error: The script is missing value for '$1'" usage exit 1 fi } debug_mode="false" while true; do if [ "$1" = "--token" ]; then validate_arg_value_exists "$1" "$#" shift var_token="$1" elif [ "$1" = "--fog" ]; then validate_arg_value_exists "$1" "$#" shift var_fog="$1" elif [ "$1" = "--access_token" ] || [ "$1" = "-at" ]; then validate_arg_value_exists "$1" "$#" shift ra_token="$1" elif [ "$1" = "--debug" ]; then debug_mode="true" elif [ -z "$1" ]; then break fi shift done if [ -z "$var_fog" ]; then var_fog=$(awk -F\" '/Fog domain/{print $4}' /etc/cp/conf/agent_details.json) var_fog="https://$var_fog" fi upload_crds_to_the_cloud if [ "$?" = "0" ]; then echo "SUCCESS" fi if [ "$debug_mode" = "false" ]; then rm $POLICY_CRDS_PATH fi exit 0