From 41ed464ef85720544ff7c6cc103cb81bd8afaae4 Mon Sep 17 00:00:00 2001 From: Mohamed Mahmoud Date: Mon, 16 Dec 2024 15:52:09 -0500 Subject: [PATCH] Make sure the required yq version is installed Signed-off-by: Mohamed Mahmoud --- commands/netobserv | 50 ++++++++++++++++++++++++-- scripts/functions.sh | 84 ++++++++++++++++++++++---------------------- 2 files changed, 90 insertions(+), 44 deletions(-) diff --git a/commands/netobserv b/commands/netobserv index 246df7e3..ffb4c160 100755 --- a/commands/netobserv +++ b/commands/netobserv @@ -2,7 +2,6 @@ source "./scripts/functions.sh" set +u - # e2e skips inputs if [ -z "${isE2E+x}" ]; then isE2E=false; fi # keep capture state @@ -72,7 +71,54 @@ function packets() { esac } -case "$1" in +function compare_versions() { + IFS="." read -r -a ver1 <<< "$1" + IFS="." read -r -a ver2 <<< "$2" + + for ((i = 0; i < ${#ver1[@]} || i < ${#ver2[@]}; i++)); do + v1=${ver1[i]:-0} # Default to 0 if unset + v2=${ver2[i]:-0} + if ((v1 < v2)); then + result=0 # less than + elif ((v1 > v2)); then + result=1 # greater than + fi + done + result=2 # equal +} + +# Required version of yq +REQUIRED_YQ_VERSION="v4.43.1" +YQ_BIN=$(which yq) +# Get the current version of yq +CURRENT_YQ_VERSION=$("$YQ_BIN" --version | awk '{print $NF}') +compare_versions "${CURRENT_YQ_VERSION#v}" "${REQUIRED_YQ_VERSION#v}" +# Check if the version matches and install it if needed +if [ "$result" -eq 0 ]; then + echo "Installing yq version $REQUIRED_YQ_VERSION is required. Found $CURRENT_YQ_VERSION." + OS=$(uname | tr '[:upper:]' '[:lower:]') # linux or darwin + ARCH=$(uname -m) + if [ "$ARCH" == "x86_64" ]; then + ARCH="amd64" + elif [[ "$ARCH" == aarch64* ]]; then + ARCH="arm64" + elif [[ "$ARCH" == ppc64* ]]; then + ARCH="ppc64le" + elif [[ "$ARCH" == s390* ]]; then + ARCH="s390x" + fi + + curl -Lo "$YQ_BIN" "https://github.com/mikefarah/yq/releases/download/$REQUIRED_YQ_VERSION/yq_${OS}_${ARCH}" && chmod +x $YQ_BIN + + if [ $? -eq 0 ]; then + echo "Successfully downloaded yq version $REQUIRED_YQ_VERSION." + else + echo "Error: Failed to download yq version $REQUIRED_YQ_VERSION." + exit 1 + fi +fi + +case "$1" in "help") # display Help echo diff --git a/scripts/functions.sh b/scripts/functions.sh index f104fac8..c8202d05 100755 --- a/scripts/functions.sh +++ b/scripts/functions.sh @@ -123,7 +123,7 @@ function getSubnets() { yaml="${MANIFEST_OUTPUT_PATH}/${CLUSTER_CONFIG}" echo "$installConfig" >${yaml} - machines=$(yq e -oj '.networking.machineNetwork[] | select(has("cidr")).cidr' "$yaml") + machines=$("$YQ_BIN" e -oj '.networking.machineNetwork[] | select(has("cidr")).cidr' "$yaml") if [ "${#machines}" -gt 0 ]; then sn["Machines"]=$machines fi @@ -133,12 +133,12 @@ function getSubnets() { yaml="${MANIFEST_OUTPUT_PATH}/${NETWORK_CONFIG}" echo "$networkConfig" >${yaml} - pods=$(yq e -oj '.spec.clusterNetwork[] | select(has("cidr")).cidr' "$yaml") + pods=$("$YQ_BIN" 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") + services=$("$YQ_BIN" e -oj '.spec.serviceNetwork[] | select(.)' "$yaml") if [ "${#services}" -gt 0 ]; then sn["Services"]=$services fi @@ -326,7 +326,7 @@ function packets_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") + jsonContent=$("$YQ_BIN" 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} @@ -339,7 +339,7 @@ function updateFLPConfig { jsonContent=${jsonContent//\"/\\\"} # update FLP_CONFIG env - yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLP_CONFIG\").value|=\"$jsonContent\"" "$2" + "$YQ_BIN" e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLP_CONFIG\").value|=\"$jsonContent\"" "$2" } function edit_manifest() { @@ -347,19 +347,19 @@ function edit_manifest() { echo "opt: $1, evalue: $2" case "$1" in "interfaces") - yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"INTERFACES\").value|=\"$2\"" "$3" + "$YQ_BIN" e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"INTERFACES\").value|=\"$2\"" "$3" ;; "pktdrop_enable") - yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_PKT_DROPS\").value|=\"$2\"" "$3" + "$YQ_BIN" e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_PKT_DROPS\").value|=\"$2\"" "$3" ;; "dns_enable") - yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_DNS_TRACKING\").value|=\"$2\"" "$3" + "$YQ_BIN" e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_DNS_TRACKING\").value|=\"$2\"" "$3" ;; "rtt_enable") - yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_RTT\").value|=\"$2\"" "$3" + "$YQ_BIN" e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_RTT\").value|=\"$2\"" "$3" ;; "network_events_enable") - yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_NETWORK_EVENTS_MONITORING\").value|=\"$2\"" "$3" + "$YQ_BIN" e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_NETWORK_EVENTS_MONITORING\").value|=\"$2\"" "$3" ;; "get_subnets") if [[ "$2" == "true" ]]; then @@ -370,91 +370,91 @@ function edit_manifest() { copyFLPConfig "$3" # get network enrich stage - enrichIndex=$(yq e -oj ".parameters[] | select(.name==\"enrich\") | document_index" "$json") - enrichContent=$(yq e -oj ".parameters[$enrichIndex]" "$json") + enrichIndex=$("$YQ_BIN" e -oj ".parameters[] | select(.name==\"enrich\") | document_index" "$json") + enrichContent=$("$YQ_BIN" 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" + "$YQ_BIN" e -oj --inplace ".transform.network.rules +={\"type\":\"add_subnet_label\",\"add_subnet_label\":{\"input\":\"SrcAddr\",\"output\":\"SrcSubnetLabel\"}}" "$enrichJson" + "$YQ_BIN" 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" + "$YQ_BIN" 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" + "$YQ_BIN" 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" + "$YQ_BIN" 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" + "$YQ_BIN" e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_FLOW_FILTER\").value|=\"$2\"" "$3" ;; "filter_direction") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.direction = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.direction = \"$2\")| tostring)" "$3" ;; "filter_cidr") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.ip_cidr = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.ip_cidr = \"$2\")| tostring)" "$3" ;; "filter_protocol") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.protocol = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.protocol = \"$2\")| tostring)" "$3" ;; "filter_sport") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.source_port = $2)| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.source_port = $2)| tostring)" "$3" ;; "filter_dport") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.destination_port = $2)| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.destination_port = $2)| tostring)" "$3" ;; "filter_port") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.port = $2)| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.port = $2)| tostring)" "$3" ;; "filter_sport_range") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.source_port_range = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.source_port_range = \"$2\")| tostring)" "$3" ;; "filter_dport_range") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.destination_port_range = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.destination_port_range = \"$2\")| tostring)" "$3" ;; "filter_port_range") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.port_range = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.port_range = \"$2\")| tostring)" "$3" ;; "filter_sports") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.source_ports = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.source_ports = \"$2\")| tostring)" "$3" ;; "filter_dports") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.destination_ports = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.destination_ports = \"$2\")| tostring)" "$3" ;; "filter_ports") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.ports = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.ports = \"$2\")| tostring)" "$3" ;; "filter_icmp_type") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.icmp_type = $2)| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.icmp_type = $2)| tostring)" "$3" ;; "filter_icmp_code") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.icmp_code = $2)| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.icmp_code = $2)| tostring)" "$3" ;; "filter_peer_ip") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.peer_ip = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.peer_ip = \"$2\")| tostring)" "$3" ;; "filter_action") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.action = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.action = \"$2\")| tostring)" "$3" ;; "filter_tcp_flags") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.tcp_flags = \"$2\")| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.tcp_flags = \"$2\")| tostring)" "$3" ;; "filter_pkt_drops") - yq e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.drops = $2)| tostring)" "$3" + "$YQ_BIN" e --inplace " .spec.template.spec.containers[0].env[] |= select(.name == \"FLOW_FILTER_RULES\").value |=(fromjson | map(.drops = $2)| tostring)" "$3" ;; "filter_regexes") copyFLPConfig "$3" # remove send step - yq e -oj --inplace "del(.pipeline[] | select(.name==\"send\"))" "$json" + "$YQ_BIN" e -oj --inplace "del(.pipeline[] | select(.name==\"send\"))" "$json" # define rules from arg IFS=',' read -ra regexes <<<"$2" @@ -472,21 +472,21 @@ function edit_manifest() { ) # add filter param & pipeline - yq e -oj --inplace ".parameters += {\"name\":\"filter\",\"transform\":{\"type\":\"filter\",\"filter\":{\"rules\":[{\"type\":\"keep_entry_all_satisfied\",\"keepEntryAllSatisfied\":[$rulesStr]}]}}}" "$json" - yq e -oj --inplace ".pipeline += {\"name\":\"filter\",\"follows\":\"enrich\"}" "$json" + "$YQ_BIN" e -oj --inplace ".parameters += {\"name\":\"filter\",\"transform\":{\"type\":\"filter\",\"filter\":{\"rules\":[{\"type\":\"keep_entry_all_satisfied\",\"keepEntryAllSatisfied\":[$rulesStr]}]}}}" "$json" + "$YQ_BIN" e -oj --inplace ".pipeline += {\"name\":\"filter\",\"follows\":\"enrich\"}" "$json" # add send step back - yq e -oj --inplace ".pipeline += {\"name\":\"send\",\"follows\":\"filter\"}" "$json" + "$YQ_BIN" e -oj --inplace ".pipeline += {\"name\":\"send\",\"follows\":\"filter\"}" "$json" updateFLPConfig "$json" "$3" ;; "log_level") - yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"LOG_LEVEL\").value|=\"$2\"" "$3" + "$YQ_BIN" e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"LOG_LEVEL\").value|=\"$2\"" "$3" ;; "node_selector") key=${2%:*} val=${2#*:} - yq e --inplace ".spec.template.spec.nodeSelector.\"$key\" |= \"$val\"" "$3" + "$YQ_BIN" e --inplace ".spec.template.spec.nodeSelector.\"$key\" |= \"$val\"" "$3" ;; esac }