Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/push_image_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ jobs:

It will expire after two weeks.

To use this build, update your oc commands using:
To use this build, update your commands using:
\`\`\`bash
USER=netobserv VERSION=${{ env.short_sha }} make oc-commands
USER=netobserv VERSION=${{ env.short_sha }} make commands
\`\`\`
`
})
35 changes: 26 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,16 @@ OUTPUT := $(DIST_DIR)/$(NAME)
COMMANDS = flows packets cleanup
COMMAND_ARGS ?=

# Get either oc (favorite) or kubectl paths
K8S_CLI_BIN_PATH = $(shell which oc 2>/dev/null || which kubectl)
K8S_CLI_BIN ?= $(shell basename ${K8S_CLI_BIN_PATH})

# IMAGE_TAG_BASE defines the namespace and part of the image name for remote images.
IMAGE_TAG_BASE ?= quay.io/$(IMAGE_ORG)/$(NAME)

# Image URL to use all building/pushing image targets
IMAGE ?= $(IMAGE_TAG_BASE):$(VERSION)
PULL_POLICY ?=Always
OCI_BUILD_OPTS ?=

# Image building tool (docker / podman) - docker is preferred in CI
Expand Down Expand Up @@ -129,13 +134,25 @@ clean: ## Clean up build directory
@rm -rf $(DIST_DIR)
@rm -rf $(FILES_OUTPUT_DIR)

.PHONY: commands
commands: ## Generate either oc or kubectl plugins and add them to build folder
@echo "### Generating $(K8S_CLI_BIN) commands"
DIST_DIR=$(DIST_DIR) \
K8S_CLI_BIN=$(K8S_CLI_BIN) \
IMAGE=$(IMAGE) \
PULL_POLICY=$(PULL_POLICY) \
./scripts/inject.sh

.PHONY: kubectl-commands
kubectl-commands: K8S_CLI_BIN=kubectl
kubectl-commands: commands ## Generate kubectl plugins and add them to build folder

.PHONY: oc-commands
oc-commands: ## Generate oc plugins and add them to build folder
@echo "### Generating oc-commands"
./scripts/inject.sh $(DIST_DIR) $(IMAGE)
oc-commands: K8S_CLI_BIN=oc
oc-commands: commands ## Generate oc plugins and add them to build folder

.PHONY: install-oc-commands
install-oc-commands: oc-commands ## Generate oc plugins and add them to /usr/bin/
.PHONY: install-commands
install-commands: commands ## Generate plugins and add them to /usr/bin/
sudo cp -a ./build/. /usr/bin/

.PHONY: create-kind-cluster
Expand All @@ -146,14 +163,14 @@ create-kind-cluster: prereqs ## Create a kind cluster
destroy-kind-cluster: KUBECONFIG=./kubeconfig
destroy-kind-cluster: ## Destroy the kind cluster.
test -s ./kubeconfig || { echo "kubeconfig does not exist! Exiting..."; exit 1; }
oc delete -f ./res/namespace.yml --ignore-not-found
$(K8S_CLI_BIN) delete -f ./res/namespace.yml --ignore-not-found
kind delete cluster --name netobserv-cli-cluster
rm ./kubeconfig

.PHONY: $(COMMANDS)
$(COMMANDS): oc-commands ## Run oc command using custom image
@echo "### Running oc-netobserv-$@ using $(IMAGE)"
./$(DIST_DIR)/oc-netobserv-$@ $(COMMAND_ARGS)
$(COMMANDS): commands ## Run command using custom image
@echo "### Running ${K8S_CLI_BIN}-netobserv-$@ using $(IMAGE)"
./$(DIST_DIR)/${K8S_CLI_BIN}-netobserv-$@ $(COMMAND_ARGS)

##@ Images

Expand Down
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ This project is still a WIP. The following list gives an overview of the current
- [X] Dockerfile
- [ ] Advanced filter capabilities
- [ ] Testing
- [ ] Allow switching between `kubectl` / `oc` commands
- [X] Allow switching between `kubectl` / `oc` commands

Feel free to contribute !

## Prerequisites

To run this CLI, you will need:
- A running kubernetes / OpenShift cluster
- `oc` command installed and connected
- either `oc` or `kubectl` command installed and connected to your cluster
- Cluster admin rights

## Build
Expand All @@ -43,7 +43,7 @@ sudo dnf install -y shellcheck
make build
```

This will also copy resources and oc commands to the `build` directory.
This will also copy resources and commands to the `build` directory.

### Images

Expand Down Expand Up @@ -139,18 +139,18 @@ This will write pcap into a single file located in `./output/pcap/<CAPTURE_DATE_
The `cleanup` function will automatically remove the eBPF programs when the CLI exits. However you may need to run it manually if an error occurs.

```bash
./oc/oc-netobserv-cleanup
./commands/netobserv-cleanup
```

## Extending OpenShift CLI with plugin
## Extending OpenShift or Kubernetes CLI with plugins

You can add this plugin to your favorite oc commands using the following steps:
You can add this plugin to your favorite `oc` or `kubectl` commands using the following steps:

```bash
make install-oc-commands
K8S_CLI_BIN=oc make install-commands
```

This will add `oc netobserv flows` and `oc netobserv packets` commands to your CLI.
For `oc`, this will add `oc netobserv flows` and `oc netobserv packets` commands to your CLI.
You can verify the commands are available using:

```bash
Expand All @@ -167,4 +167,6 @@ The following compatible plugins are available:
/usr/bin/oc-netobserv-packets
```

Similar behavior works for `kubectl`.

More info [on official OpenShift documentation](https://docs.openshift.com/container-platform/4.14/cli_reference/openshift_cli/extending-cli-plugins.html).
File renamed without changes.
6 changes: 3 additions & 3 deletions oc/oc-netobserv-flows → commands/netobserv-flows
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ trap cleanup EXIT
setup flows $filter

echo "Running network-observability-cli get-flows... "
oc run \
${K8S_CLI_BIN} run \
-n netobserv-cli \
collector \
--image=$img\
--image-pull-policy='Always' \
--restart='Never' \
--command -- sleep infinity

oc wait \
${K8S_CLI_BIN} wait \
-n netobserv-cli \
--for=condition=Ready pod/collector

oc exec -i --tty \
${K8S_CLI_BIN} exec -i --tty \
-n netobserv-cli \
collector \
-- /network-observability-cli get-flows ${filter:+"--filter" "$filter"}
8 changes: 4 additions & 4 deletions oc/oc-netobserv-packets → commands/netobserv-packets
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ filter=""

if [ -z "${1:-}" ]
then
echo "Specify a valid filter as first argument such as 'oc get-packets tcp,80'"
echo "Specify a valid filter as first argument such as '${K8S_CLI_BIN} get-packets tcp,80'"
exit 1
else
echo "Filters set as $1"
Expand All @@ -21,19 +21,19 @@ trap cleanup EXIT
setup packets $filter

echo "\nRunning network-observability-cli get-packets... "
oc run \
${K8S_CLI_BIN} run \
-n netobserv-cli \
collector \
--image=$img \
--image-pull-policy='Always' \
--restart='Never' \
--command -- sleep infinity

oc wait \
${K8S_CLI_BIN} wait \
-n netobserv-cli \
--for=condition=Ready pod/collector

oc exec -i --tty \
${K8S_CLI_BIN} exec -i --tty \
-n netobserv-cli \
collector \
-- /network-observability-cli get-packets --filter "$filter"
7 changes: 4 additions & 3 deletions res/namespace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ kind: Namespace
apiVersion: v1
metadata:
name: netobserv-cli
app: netobserv-cli
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
labels:
app: netobserv
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
Comment on lines +5 to +8
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☝️ kubectl can't manage pod-security at metadata level

31 changes: 21 additions & 10 deletions scripts/functions.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#!/usr/bin/env bash
set -eu

# get either oc (favorite) or kubectl paths
# this is used only when calling commands directly
# else it will be overridden by inject.sh
K8S_CLI_BIN_PATH=$( which oc 2>/dev/null || which kubectl 2>/dev/null )
K8S_CLI_BIN=$( basename "${K8S_CLI_BIN_PATH}" )

function loadYAMLs() {
namespaceYAML='
namespaceYAMLContent
Expand Down Expand Up @@ -39,7 +45,12 @@ function loadYAMLs() {
}

function clusterIsReady() {
if oc whoami 2>&1 || oc cluster-info | grep -q "Kubernetes control plane"; then
# use oc whoami as connectivity check by default and fallback to kubectl get all if needed
K8S_CLI_CONNECTIVITY="${K8S_CLI_BIN} whoami"
if [ "${K8S_CLI_BIN}" = "kubectl" ]; then
K8S_CLI_CONNECTIVITY="${K8S_CLI_BIN} get all"
fi
if ${K8S_CLI_CONNECTIVITY} 2>&1 || ${K8S_CLI_BIN} cluster-info | grep -q "Kubernetes control plane"; then
return 0
else
return 1
Expand All @@ -65,22 +76,22 @@ function setup {

# apply yamls
echo "creating netobserv-cli namespace"
echo "$namespaceYAML" | oc apply -f -
echo "$namespaceYAML" | ${K8S_CLI_BIN} apply -f -

echo "creating service account"
echo "$saYAML" | oc apply -f -
echo "$saYAML" | ${K8S_CLI_BIN} apply -f -

echo "creating collector service"
echo "$collectorServiceYAML" | oc apply -f -
echo "$collectorServiceYAML" | ${K8S_CLI_BIN} apply -f -

if [ "$1" = "flows" ]; then
echo "creating flow-capture agents"
echo "${flowAgentYAML/"{{FLOW_FILTER_VALUE}}"/${2:-}}" | oc apply -f -
oc rollout status daemonset netobserv-cli -n netobserv-cli --timeout 60s
echo "${flowAgentYAML/"{{FLOW_FILTER_VALUE}}"/${2:-}}" | ${K8S_CLI_BIN} apply -f -
${K8S_CLI_BIN} rollout status daemonset netobserv-cli -n netobserv-cli --timeout 60s
elif [ "$1" = "packets" ]; then
echo "creating packet-capture agents"
echo "${packetAgentYAML/"{{PCA_FILTER_VALUE}}"/${2:-}}" | oc apply -f -
oc rollout status daemonset netobserv-cli -n netobserv-cli --timeout 60s
echo "${packetAgentYAML/"{{PCA_FILTER_VALUE}}"/${2:-}}" | ${K8S_CLI_BIN} apply -f -
${K8S_CLI_BIN} rollout status daemonset netobserv-cli -n netobserv-cli --timeout 60s
fi
}

Expand All @@ -89,10 +100,10 @@ function cleanup {
if clusterIsReady; then
echo "Copying collector output files..."
mkdir -p ./output
oc cp -n netobserv-cli collector:output ./output
${K8S_CLI_BIN} cp -n netobserv-cli collector:output ./output

printf "\nCleaning up... "
oc delete namespace netobserv-cli
${K8S_CLI_BIN} delete namespace netobserv-cli
else
echo "Cleanup namespace skipped"
return
Expand Down
53 changes: 37 additions & 16 deletions scripts/inject.sh
Original file line number Diff line number Diff line change
@@ -1,34 +1,55 @@
#!/bin/bash
cp -a ./oc/. ./tmp
cp -a ./commands/. ./tmp
cp ./scripts/functions.sh ./tmp/functions.sh

if [ -z "$IMAGE" ]; then
echo "image not provided, keeping current ones"
else
echo "updating CLI images to $IMAGE"
sed -i "/img=/c\img=\"$IMAGE\"" ./tmp/netobserv-flows
sed -i "/img=/c\img=\"$IMAGE\"" ./tmp/netobserv-packets
fi

if [ -z "$PULL_POLICY" ]; then
echo "pull policy not provided, keeping current ones"
else
echo "updating CLI pull policy to $PULL_POLICY"
sed -i "/ --image-pull-policy/c\ --image-pull-policy='$PULL_POLICY' \\\\" ./tmp/netobserv-flows
sed -i "/ --image-pull-policy/c\ --image-pull-policy='$PULL_POLICY' \\\\" ./tmp/netobserv-packets
fi

if [ -z "$K8S_CLI_BIN" ]; then
echo "ERROR: K8S CLI not provided"
exit 1
else
echo "updating K8S CLI to $K8S_CLI_BIN"
sed -i "/K8S_CLI_BIN_PATH=/d" ./tmp/functions.sh
sed -i "/K8S_CLI_BIN=/c\K8S_CLI_BIN=$K8S_CLI_BIN" ./tmp/functions.sh

mv ./tmp/netobserv-flows ./tmp/"$K8S_CLI_BIN"-netobserv-flows
mv ./tmp/netobserv-packets ./tmp/"$K8S_CLI_BIN"-netobserv-packets
mv ./tmp/netobserv-cleanup ./tmp/"$K8S_CLI_BIN"-netobserv-cleanup
fi

# inject YAML files to functions.sh
sed -i -e '/namespaceYAMLContent/{r ./res/namespace.yml' -e 'd}' ./tmp/functions.sh
sed -i -e '/saYAMLContent/{r ./res/service-account.yml' -e 'd}' ./tmp/functions.sh
sed -i -e '/flowAgentYAMLContent/{r ./res/flow-capture.yml' -e 'd}' ./tmp/functions.sh
sed -i -e '/packetAgentYAMLContent/{r ./res/packet-capture.yml' -e 'd}' ./tmp/functions.sh
sed -i -e '/collectorServiceYAMLContent/{r ./res/collector-service.yml' -e 'd}' ./tmp/functions.sh

# inject updated functions to oc commands
sed -i -e '/source.*/{r ./tmp/functions.sh' -e 'd}' ./tmp/oc-netobserv-flows
sed -i -e '/source.*/{r ./tmp/functions.sh' -e 'd}' ./tmp/oc-netobserv-packets
sed -i -e '/source.*/{r ./tmp/functions.sh' -e 'd}' ./tmp/oc-netobserv-cleanup

if [ -z "$2" ]; then
echo "image not provided, keeping current ones"
else
echo "updating CLI images to $2"
sed -i "/img=/c\img=\"$2\"" ./tmp/oc-netobserv-flows
sed -i "/img=/c\img=\"$2\"" ./tmp/oc-netobserv-packets
fi
# inject updated functions to commands
sed -i -e '/source.*/{r ./tmp/functions.sh' -e 'd}' ./tmp/"$K8S_CLI_BIN"-netobserv-flows
sed -i -e '/source.*/{r ./tmp/functions.sh' -e 'd}' ./tmp/"$K8S_CLI_BIN"-netobserv-packets
sed -i -e '/source.*/{r ./tmp/functions.sh' -e 'd}' ./tmp/"$K8S_CLI_BIN"-netobserv-cleanup

rm ./tmp/functions.sh

if [ -z "$1" ]; then
if [ -z "$DIST_DIR" ]; then
echo "output generated in tmp folder"
else
echo "output generated in $1 folder"
cp -a ./tmp/. ./"$1"
echo "output generated in $DIST_DIR folder"
cp -a ./tmp/. ./"$DIST_DIR"
rm -rf ./tmp
fi

8 changes: 6 additions & 2 deletions scripts/kind-cluster.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#!/usr/bin/env bash
set -eux

# get either oc (favorite) or kubectl paths
K8S_CLI_BIN_PATH=$( which oc 2>/dev/null || which kubectl 2>/dev/null )
K8S_CLI_BIN=$( basename "${K8S_CLI_BIN_PATH}" )

DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && cd ../ && pwd )

KIND_CLUSTER_NAME="netobserv-cli-cluster"
Expand Down Expand Up @@ -52,8 +56,8 @@ SVC_CIDR_IPV6=${SVC_CIDR_IPV6:-fd00:10:96::/112}
# At the minimum, deploy the kind cluster
deploy_kind
export KUBECONFIG=${DIR}/kubeconfig
oc label node ${KIND_CLUSTER_NAME}-worker node-role.kubernetes.io/worker=
oc label node ${KIND_CLUSTER_NAME}-worker2 node-role.kubernetes.io/worker=
${K8S_CLI_BIN} label node ${KIND_CLUSTER_NAME}-worker node-role.kubernetes.io/worker=
${K8S_CLI_BIN} label node ${KIND_CLUSTER_NAME}-worker2 node-role.kubernetes.io/worker=

# Print success at the end of this script
print_success