From d9eefa61522adc629ab6d66ac2d4da6d2ecdeb4d Mon Sep 17 00:00:00 2001 From: Julien Pinsonneau Date: Tue, 10 Dec 2024 12:23:19 +0100 Subject: [PATCH] Add --get-subnets option --- scripts/functions.sh | 135 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 21 deletions(-) diff --git a/scripts/functions.sh b/scripts/functions.sh index 1d47293f..4c5283f9 100755 --- a/scripts/functions.sh +++ b/scripts/functions.sh @@ -79,8 +79,48 @@ function clusterIsReady() { FLOWS_MANIFEST_FILE="flow-capture.yml" PACKETS_MANIFEST_FILE="packet-capture.yml" CONFIG_JSON_TEMP="config.json" +CLUSTER_CONFIG="cluster-config-v1.yaml" +NETWORK_CONFIG="cluster-network.yaml" MANIFEST_OUTPUT_PATH="tmp" +function getSubnets() { + declare -n sn="$1" + + # get cluster-config-v1 Configmap to retreive machine networks + installConfig=$(${K8S_CLI_BIN} get configmap cluster-config-v1 -n kube-system -o custom-columns=":data.install-config") + yaml="${MANIFEST_OUTPUT_PATH}/${CLUSTER_CONFIG}" + echo "$installConfig" >${yaml} + + machines=$(yq e -oj '.networking.machineNetwork[] | select(has("cidr")).cidr' "$yaml") + if [ "${#machines}" -gt 0 ]; then + sn["Machines"]=$machines + fi + + # get OCP cluster Network to retreive pod / services / external networks + networkConfig=$(${K8S_CLI_BIN} get network cluster -o yaml) + yaml="${MANIFEST_OUTPUT_PATH}/${NETWORK_CONFIG}" + echo "$networkConfig" >${yaml} + + pods=$(yq e -oj '.spec.clusterNetwork[] | select(has("cidr")).cidr' "$yaml") + if [ "${#pods}" -gt 0 ]; then + sn["Pods"]=$pods + fi + + services=$(yq e -oj '.spec.serviceNetwork[] | select(.)' "$yaml") + if [ "${#services}" -gt 0 ]; then + sn["Services"]=$services + fi + + if [ "${#sn[@]}" -gt 0 ]; then + echo "Found subnets:" + for key in "${!sn[@]}"; do + echo " $key: ${sn[$key]}" + done + else + echo "Didn't found subnets" + fi +} + function setup { echo "Setting up... " @@ -175,6 +215,8 @@ function common_usage { echo " --max-time: maximum capture time (default: 5m)" echo " --max-bytes: maximum capture bytes (default: 50000000 = 50MB)" echo " --copy: copy the output files locally (default: prompt)" + # enrichment + echo " --get-subnets: get subnets informations (default: false)" # filters echo " --node-selector: capture on specific nodes (default: n/a)" echo " --direction: filter direction (default: n/a)" @@ -217,9 +259,27 @@ function packets_usage { common_usage } +# get current config and save it to temp file +function copyFLPConfig { + jsonContent=$(yq e '.spec.template.spec.containers[0].env[] | select(.name=="FLP_CONFIG").value' "$1") + # json temp file location is set as soon as this function is called + json="${MANIFEST_OUTPUT_PATH}/${CONFIG_JSON_TEMP}" + echo "$jsonContent" >${json} +} + +# update FLP Config +function updateFLPConfig { + # get json as string with escaped quotes + jsonContent=$(cat "$1") + jsonContent=${jsonContent//\"/\\\"} + + # update FLP_CONFIG env + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLP_CONFIG\").value|=\"$jsonContent\"" "$2" +} + function edit_manifest() { - ## replace the env variable in the manifest file - echo "env: $1, env_value: $2" + ## replace the configuration in the manifest file + echo "opt: $1, evalue: $2" case "$1" in "interfaces") yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"INTERFACES\").value|=\"$2\"" "$3" @@ -236,6 +296,38 @@ function edit_manifest() { "network_events_enable") yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_NETWORK_EVENTS_MONITORING\").value|=\"$2\"" "$3" ;; + "get_subnets") + if [[ "$2" == "true" ]]; then + declare -A subnets + getSubnets subnets + + if [ "${#subnets[@]}" -gt 0 ]; then + copyFLPConfig "$3" + + # get network enrich stage + enrichIndex=$(yq e -oj ".parameters[] | select(.name==\"enrich\") | document_index" "$json") + enrichContent=$(yq e -oj ".parameters[$enrichIndex]" "$json") + enrichJson="${MANIFEST_OUTPUT_PATH}/enrich.json" + echo "$enrichContent" >${enrichJson} + + # add rules to network + yq e -oj --inplace ".transform.network.rules +={\"type\":\"add_subnet_label\",\"add_subnet_label\":{\"input\":\"SrcAddr\",\"output\":\"SrcSubnetLabel\"}}" "$enrichJson" + yq e -oj --inplace ".transform.network.rules +={\"type\":\"add_subnet_label\",\"add_subnet_label\":{\"input\":\"DstAddr\",\"output\":\"DstSubnetLabel\"}}" "$enrichJson" + + # add subnetLabels to network + yq e -oj --inplace ".transform.network.subnetLabels = []" "$enrichJson" + for key in "${!subnets[@]}"; do + yq e -oj --inplace ".transform.network.subnetLabels += {\"name\":\"$key\",\"cidrs\":[${subnets[$key]}]}" "$enrichJson" + done + + # override network + enrichJsonStr=$(cat $enrichJson) + yq e -oj --inplace ".parameters[$enrichIndex] = $enrichJsonStr" "$json" + + updateFLPConfig "$json" "$3" + fi + fi + ;; "filter_enable") yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_FLOW_FILTER\").value|=\"$2\"" "$3" ;; @@ -294,26 +386,25 @@ function edit_manifest() { yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FILTER_DROPS\").value|=\"$2\"" "$3" ;; "filter_regexes") - # get current config and save it to temp file - jsonContent=$(yq e '.spec.template.spec.containers[0].env[] | select(.name=="FLP_CONFIG").value' "$3") - json="${MANIFEST_OUTPUT_PATH}/${CONFIG_JSON_TEMP}" - echo "$jsonContent" >${json} + copyFLPConfig "$3" # remove send step yq e -oj --inplace "del(.pipeline[] | select(.name==\"send\"))" "$json" # define rules from arg - IFS=',' read -ra regexes <<< "$2" + IFS=',' read -ra regexes <<<"$2" rules=() - for regex in "${regexes[@]}" - do - IFS='~' read -ra keyValue <<< "$regex" - key=${keyValue[0]} - value=${keyValue[1]} - echo "key: $key value: $value" - rules+=("{\"type\":\"keep_entry_if_regex_match\",\"keepEntry\":{\"input\":\"$key\",\"value\":\"$value\"}}") + for regex in "${regexes[@]}"; do + IFS='~' read -ra keyValue <<<"$regex" + key=${keyValue[0]} + value=${keyValue[1]} + echo "key: $key value: $value" + rules+=("{\"type\":\"keep_entry_if_regex_match\",\"keepEntry\":{\"input\":\"$key\",\"value\":\"$value\"}}") done - rulesStr=$(IFS=, ; echo "${rules[*]}") + rulesStr=$( + IFS=, + echo "${rules[*]}" + ) # add filter param & pipeline yq e -oj --inplace ".parameters += {\"name\":\"filter\",\"transform\":{\"type\":\"filter\",\"filter\":{\"rules\":[{\"type\":\"keep_entry_all_satisfied\",\"keepEntryAllSatisfied\":[$rulesStr]}]}}}" "$json" @@ -322,12 +413,7 @@ function edit_manifest() { # add send step back yq e -oj --inplace ".pipeline += {\"name\":\"send\",\"follows\":\"filter\"}" "$json" - # get json as string with escaped quotes - jsonContent=$(cat $json) - jsonContent=${jsonContent//\"/\\\"} - - # update FLP_CONFIG env - yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLP_CONFIG\").value|=\"$jsonContent\"" "$3" + updateFLPConfig "$json" "$3" ;; "log_level") yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"LOG_LEVEL\").value|=\"$2\"" "$3" @@ -528,6 +614,13 @@ function check_args_and_apply() { exit 1 fi ;; + --get-subnets) # Get subnets + if [[ "$value" == "true" || "$value" == "false" ]]; then + edit_manifest "get_subnets" "$value" "$2" + else + echo "invalid value for --get-subnets" + fi + ;; *) # Invalid option echo "Invalid option: $key" >&2 exit 1