diff --git a/Makefile b/Makefile index e82c2ca2..c8608e20 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,7 @@ OCI_BIN_PATH := $(shell which docker 2>/dev/null || which podman) OCI_BIN ?= $(shell basename ${OCI_BIN_PATH}) GOLANGCI_LINT_VERSION = v1.54.2 +YQ_VERSION = v4.43.1 # build a single arch target provided as argument define build_target @@ -82,6 +83,9 @@ prereqs: ## Test if prerequisites are met, and installing missing dependencies ifeq (, $(shell which golangci-lint)) GOFLAGS="" go install github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION} endif +ifeq (, $(shell which yq)) + GOFLAGS="" go install github.com/mikefarah/yq/v4@${YQ_VERSION} +endif .PHONY: vendors vendors: ## Refresh vendors directory. diff --git a/commands/netobserv-flows b/commands/netobserv-flows index ec9ef9f9..2300c336 100755 --- a/commands/netobserv-flows +++ b/commands/netobserv-flows @@ -1,23 +1,13 @@ #!/bin/bash source "./scripts/functions.sh" -# interface filter such as 'br-ex' -filter="" - -if [ -z "${1:-}" ] -then - echo "Filters not set" -else - echo "Filters set as $1" - filter=$1 -fi - # CLI image to use img="quay.io/netobserv/network-observability-cli:main" trap cleanup EXIT -setup flows $filter + +setup flows "$*" echo "Running network-observability-cli get-flows... " ${K8S_CLI_BIN} run \ @@ -35,4 +25,4 @@ ${K8S_CLI_BIN} wait \ ${K8S_CLI_BIN} exec -i --tty \ -n netobserv-cli \ collector \ - -- /network-observability-cli get-flows ${filter:+"--filter" "$filter"} \ No newline at end of file + -- /network-observability-cli get-flows \ No newline at end of file diff --git a/res/flow-capture.yml b/res/flow-capture.yml index 95677442..c0853b3f 100644 --- a/res/flow-capture.yml +++ b/res/flow-capture.yml @@ -30,7 +30,7 @@ spec: - name: LOG_LEVEL value: trace - name: INTERFACES - value: "{{FLOW_FILTER_VALUE}}" + value: "" - name: EXCLUDE_INTERFACES value: "lo" - name: SAMPLING @@ -41,6 +41,34 @@ spec: value: "true" - name: ENABLE_DNS_TRACKING value: "true" + - name: ENABLE_FLOW_FILTER + value: "" + - name: FLOW_FILTER_DIRECTION + value: "" + - name: FLOW_FILTER_IP_CIDR + value: "" + - name: FLOW_FILTER_PROTOCOL + value: "" + - name: FLOW_FILTER_SOURCE_PORT + value: "" + - name: FLOW_FILTER_DESTINATION_PORT + value: "" + - name: FLOW_FILTER_PORT + value: "" + - name: FLOW_FILTER_SOURCE_PORT_RANGE + value: "" + - name: FLOW_FILTER_DESTINATION_PORT_RANGE + value: "" + - name: FLOW_FILTER_PORT_RANGE + value: "" + - name: FLOW_FILTER_ICMP_TYPE + value: "" + - name: FLOW_FILTER_ICMP_CODE + value: "" + - name: FLOW_FILTER_PEER_IP + value: "" + - name: FLOW_FILTER_ACTION + value: "" - name: EXPORT value: "direct-flp" - name: FLP_CONFIG diff --git a/scripts/functions.sh b/scripts/functions.sh index cb533ace..60a428d9 100755 --- a/scripts/functions.sh +++ b/scripts/functions.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +source ./scripts/update_flowcapture.sh + set -eu # get either oc (favorite) or kubectl paths @@ -22,13 +24,6 @@ function loadYAMLs() { saYAML="$(cat ./res/service-account.yml)" fi - flowAgentYAML=' - flowAgentYAMLContent - ' - if [ -f ./res/flow-capture.yml ]; then - flowAgentYAML="$(cat ./res/flow-capture.yml)" - fi - packetAgentYAML=' packetAgentYAMLContent ' @@ -57,6 +52,9 @@ function clusterIsReady() { fi } +MANIFEST_FILE="flow-capture.yml" +MANIFEST_OUTPUT_PATH="output" + function setup { echo "Setting up... " @@ -85,9 +83,71 @@ function setup { echo "$collectorServiceYAML" | ${K8S_CLI_BIN} apply -f - if [ "$1" = "flows" ]; then - echo "creating flow-capture agents" - echo "${flowAgentYAML/"{{FLOW_FILTER_VALUE}}"/${2:-}}" | ${K8S_CLI_BIN} apply -f - - ${K8S_CLI_BIN} rollout status daemonset netobserv-cli -n netobserv-cli --timeout 60s + shift + echo "creating flow-capture agents:" + options="$*" + # Iterate through the command-line arguments + for option in $options; do + key="${option%%=*}" + value="${option#*=}" + case "$key" in + --interfaces) # Interfaces + edit_manifest "interfaces" "$value" + ;; + --enable) # Enable flow filter + edit_manifest "filter_enable" "$value" + ;; + --direction) # Configure flow filter direction + edit_manifest "filter_direction" "$value" + ;; + --cidr) # Configure flow filter CIDR + edit_manifest "filter_cidr" "$value" + ;; + --protocol) # Configure flow filter protocol + edit_manifest "filter_protocol" "$value" + ;; + --sport) # Configure flow filter source port + edit_manifest "filter_src_port" "$value" + ;; + --dport) # Configure flow filter destination port + edit_manifest "filter_dst_port" "$value" + ;; + --port) # Configure flow filter port + edit_manifest "filter_port" "$value" + ;; + --sport-range) # Configure flow filter source port range + edit_manifest "filter_src_port_range" "$value" + ;; + --dport-range) # Configure flow filter destination port range + edit_manifest "filter_dst_port_range" "$value" + ;; + --port-range) # Configure flow filter port range + edit_manifest "filter_port_range" "$value" + ;; + --icmp-type) # ICMP type + edit_manifest "filter_icmp_type" "$value" + ;; + --icmp-code) # ICMP code + edit_manifest "filter_icmp_code" "$value" + ;; + --peer-ip) # Peer IP + edit_manifest "filter_peer_ip" "$value" + ;; + --action) # Filter action + edit_manifest "filter_action" "$value" + ;; + *) # Invalid option + echo "Invalid option: $key" >&2 + exit 1 + ;; + esac + done + + manifest="$MANIFEST_OUTPUT_PATH"/"$MANIFEST_FILE" + if [[ -f "$manifest" ]]; then + ${K8S_CLI_BIN} apply -f "$manifest" + ${K8S_CLI_BIN} rollout status daemonset netobserv-cli -n netobserv-cli --timeout 60s + fi elif [ "$1" = "packets" ]; then echo "creating packet-capture agents" echo "${packetAgentYAML/"{{PCA_FILTER_VALUE}}"/${2:-}}" | ${K8S_CLI_BIN} apply -f - diff --git a/scripts/update_flowcapture.sh b/scripts/update_flowcapture.sh new file mode 100755 index 00000000..2b9e301b --- /dev/null +++ b/scripts/update_flowcapture.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +MANIFEST_FILE="flow-capture.yml" +MANIFEST_PATH="res" +MANIFEST_OUTPUT_PATH="output" + +function edit_manifest() { + echo "Editing manifest file..." + if [[ ! -d ${MANIFEST_OUTPUT_PATH} ]]; then + mkdir -p ${MANIFEST_OUTPUT_PATH} > /dev/null + cp ${MANIFEST_PATH}/${MANIFEST_FILE} ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + fi + ## replace the env variable in the manifest file + echo "env: $1, env_value: $2" + case "$1" in + "interfaces") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"INTERFACES\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_enable") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"ENABLE_FLOW_FILTER\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_direction") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_DIRECTION\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_cidr") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_IP_CIDR\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_protocol") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_PROTOCOL\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_sport") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_SOURCE_PORT\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_dport") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_DESTINATION_PORT\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_port") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_PORT\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_sport_range") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_SOURCE_PORT_RANGE\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_dport_range") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_DESTINATION_PORT_RANGE\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_port_range") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_PORT_RANGE\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_icmp_type") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_ICMP_TYPE\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_icmp_code") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_ICMP_CODE\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_peer_ip") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_PEER_IP\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + "filter_action") + yq e --inplace ".spec.template.spec.containers[0].env[] |= select(.name==\"FLOW_FILTER_ACTION\").value|=\"$2\"" ${MANIFEST_OUTPUT_PATH}/${MANIFEST_FILE} + ;; + esac +}