Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 55 additions & 78 deletions commands/netobserv
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,27 @@ maxTime="5m"
maxBytes=50000000

# skip dependencies check for help or version
if [[ ! "$*" =~ ^(.*)help|version(.*) ]]; then
if [[ ! "$*" =~ (help|version) ]]; then
check_dependencies "$required_yq_version" "$supported_archs" "$required_bash_version"
fi

# detect output yaml option before running the script to avoid any apply
if [[ "$*" =~ ^(.*)yaml=true|(yaml$)|(yaml )(.*) ]]; then
if [[ "$*" =~ (yaml=true|yaml$|yaml[[:space:]]) ]]; then
echo "Output YAMLs without applying..."
outputYAML="true"
fi

contains_help() {
for arg in "$@"; do
case "$arg" in
*help) return 0 ;;
esac
done
return 1
}

case "$1" in
*help)
""|*help)
help
exit 0
;;
Expand All @@ -78,100 +87,68 @@ case "$1" in
exit 0
;;
*flows)
case "$2" in
*help)
flows_usage
shift
if contains_help "$@"; then
flows_usage | highlight_keywords flows $(get_help_keywords "$@")
exit 0
;;
*)
shift # remove first argument
options=("$@")
# run flows command
command="flows"
;;
esac
fi
options=("$@")
command="flows"
;;
*packets)
case "$2" in
*help)
packets_usage
shift
if contains_help "$@"; then
packets_usage | highlight_keywords packets $(get_help_keywords "$@")
exit 0
;;
*)
shift # remove first argument
options=("$@")
# run packets command
command="packets"
;;
esac
fi
options=("$@")
command="packets"
;;
*metrics)
case "$2" in
*help)
metrics_usage
shift
if contains_help "$@"; then
metrics_usage | highlight_keywords metrics $(get_help_keywords "$@")
exit 0
;;
*)
shift # remove first argument
options=("$@")
# run metrics command
command="metrics"
# override maxTime default to 1h for metrics only
maxTime="1h"
;;
esac
fi
options=("$@")
command="metrics"
maxTime="1h"
;;
*follow)
case "$2" in
*help)
follow_usage
exit 0
;;
*)
# run follow command
follow
shift
if contains_help "$@"; then
follow_usage | highlight_keywords follow $(get_help_keywords "$@")
exit 0
;;
esac
fi
follow
exit 0
;;
*stop)
case "$2" in
*help)
stop_usage
exit 0
;;
*)
# run deleteDaemonset command
deleteDaemonset
shift
if contains_help "$@"; then
stop_usage | highlight_keywords stop $(get_help_keywords "$@")
exit 0
;;
esac
fi
deleteDaemonset
exit 0
;;
*copy)
case "$2" in
*help)
copy_usage
exit 0
;;
*)
# run copy output command
copyOutput
shift
if contains_help "$@"; then
copy_usage | highlight_keywords copy $(get_help_keywords "$@")
exit 0
;;
esac
fi
copyOutput
exit 0
;;
*cleanup)
case "$2" in
*help)
cleanup_usage
shift
if contains_help "$@"; then
cleanup_usage | highlight_keywords cleanup $(get_help_keywords "$@")
exit 0
;;
*)
# run cleanup command
cleanup
exit 0
;;
esac
fi
cleanup
exit 0
;;
*)
echo "Unknown command $1. Use 'netobserv help' to display options"
Expand Down
51 changes: 51 additions & 0 deletions e2e/script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ package e2e
import (
"os"
"path"
"regexp"
"testing"

"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)

var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;]*m`)

var (
slog = logrus.WithField("component", "script_test")
)
Expand Down Expand Up @@ -40,6 +43,8 @@ func TestHelpCommand(t *testing.T) {
assert.Contains(t, output, "follow Follow collector logs when running in background.")
assert.Contains(t, output, "stop Stop collection by removing agent daemonset.")
assert.Contains(t, output, "version Print software version.")
// ensure help to display --help hint
assert.Contains(t, output, "Use --help with any command for more details")
// ensure help to display examples
assert.Contains(t, output, "Flow capture examples:")
assert.Contains(t, output, "netobserv flows --drops")
Expand All @@ -49,6 +54,52 @@ func TestHelpCommand(t *testing.T) {
assert.Contains(t, output, "Capture flows in the background")
assert.Contains(t, output, "Capture metrics in the background")
})

t.Run("no argument shows help", func(t *testing.T) {
output, err := RunCommand(slog, "commands/oc-netobserv")
assert.Nil(t, err)
assert.NotEmpty(t, output)
assert.Contains(t, output, "Main commands:")
})
}

func TestSubcommandHelp(t *testing.T) {
t.Run("flows --help", func(t *testing.T) {
output, err := RunCommand(slog, "commands/oc-netobserv", "flows", "--help")
assert.Nil(t, err)
assert.NotEmpty(t, output)
plain := ansiRegex.ReplaceAllString(output, "")
assert.Contains(t, plain, "Syntax: netobserv flows [options]")
assert.Contains(t, plain, "Features:")
assert.Contains(t, plain, "Filters:")
assert.Contains(t, plain, "Options:")
assert.Contains(t, plain, "Examples:")
})

t.Run("flows --help at any position", func(t *testing.T) {
output, err := RunCommand(slog, "commands/oc-netobserv", "flows", "--port=8080", "--help")
assert.Nil(t, err)
assert.NotEmpty(t, output)
plain := ansiRegex.ReplaceAllString(output, "")
assert.Contains(t, plain, "Syntax: netobserv flows [options]")
assert.Contains(t, plain, "Filters:")
})

t.Run("packets --help", func(t *testing.T) {
output, err := RunCommand(slog, "commands/oc-netobserv", "packets", "--help")
assert.Nil(t, err)
assert.NotEmpty(t, output)
plain := ansiRegex.ReplaceAllString(output, "")
assert.Contains(t, plain, "Syntax: netobserv packets [options]")
})

t.Run("metrics --help", func(t *testing.T) {
output, err := RunCommand(slog, "commands/oc-netobserv", "metrics", "--help")
assert.Nil(t, err)
assert.NotEmpty(t, output)
plain := ansiRegex.ReplaceAllString(output, "")
assert.Contains(t, plain, "Syntax: netobserv metrics [options]")
})
}

func TestVersionCommand(t *testing.T) {
Expand Down
7 changes: 6 additions & 1 deletion scripts/functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,12 @@ function check_args_and_apply() {
fi
;;
*interfaces) # Interfaces
edit_manifest "interfaces" "$value"
if [[ "$command" == "flows" || "$command" == "metrics" ]]; then
edit_manifest "interfaces" "$value"
else
echo "--interfaces is invalid option for packets"
exit 1
fi
;;
*enable_pkt_drop) # Enable packet drop
if [[ "$command" == "flows" || "$command" == "metrics" ]]; then
Expand Down
40 changes: 37 additions & 3 deletions scripts/help.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,38 @@
# metrics includeList
includeList="namespace_flows_total,node_ingress_bytes_total,node_egress_bytes_total,workload_ingress_bytes_total"

_BOLD_CYAN=$(printf '\033[1;36m')
_RESET=$(printf '\033[0m')

# Extract keywords from args for help highlighting
# e.g. "--port=8080 --drops --help" → "--port" "--drops"
get_help_keywords() {
for arg in "$@"; do
case "$arg" in
*help|or) ;;
--*=*) printf '%s\n' "${arg%%=*}" ;;
*) printf '%s\n' "$arg" ;;
esac
done
}

# Pipe help text through this to highlight keywords
# Usage: some_usage_fn | highlight_keywords --port --drops
highlight_keywords() {
if [ $# -eq 0 ]; then
cat
return
fi

local sed_args=()
for keyword in "$@"; do
keyword="${keyword#--}"
sed_args+=(-e "s|${keyword}|${_BOLD_CYAN}&${_RESET}|g")
done

sed "${sed_args[@]}"
}

# display main help
function help {
echo
Expand All @@ -23,6 +55,8 @@ function help {
echo " stop Stop collection by removing agent daemonset."
echo " version Print software version."
echo
echo "Use --help with any command for more details (e.g. netobserv flows --help)"
echo
echo "Flow capture examples:"
flows_examples
echo
Expand Down Expand Up @@ -210,7 +244,7 @@ function metrics_usage {

function follow_usage {
echo
echo "NetObserv allows you to capture flows and packets asyncronously using the --background option."
echo "NetObserv allows you to capture flows and packets asynchronously using the --background option."
echo "While the capture is running in background, you can connect to the collector pod to see the progression using the follow command."
echo "Find more information at: https://github.com/netobserv/network-observability-cli/"
echo
Expand All @@ -220,7 +254,7 @@ function follow_usage {

function stop_usage {
echo
echo "NetObserv allows you stop the collection and keep collector or dashboard for post analysis."
echo "NetObserv allows you to stop the collection and keep collector or dashboard for post analysis."
echo "While the capture is running, use the stop command to remove the eBPF agents."
echo "Find more information at: https://github.com/netobserv/network-observability-cli/"
echo
Expand All @@ -230,7 +264,7 @@ function stop_usage {

function copy_usage {
echo
echo "NetObserv allows you copy locally the captured flows or packets from the collector pod."
echo "NetObserv allows you to copy locally the captured flows or packets from the collector pod."
echo "While the collector is running, use the copy command to copy the output file(s)."
echo "To avoid modifications during the copy, it's recommended to stop the capture"
echo "Find more information at: https://github.com/netobserv/network-observability-cli/"
Expand Down
Loading