diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 129b55db..6f02f5da 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,3 +43,25 @@ jobs: registry: quay.io - name: build and push manifest with images run: MULTIARCH_TARGETS="${{ env.WF_MULTIARCH_TARGETS }}" IMAGE_ORG=${{ env.WF_ORG }} VERSION=${{ env.tag }} make images + - name: create github release + uses: actions/create-release@v1 + id: create_release + with: + draft: true + prerelease: false + release_name: ${{ env.tag }} + tag_name: ${{ env.tag }} + body_path: ./tmp/release.md + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: build plugin artifact + run: IMAGE_ORG=${{ env.WF_ORG }} VERSION=${{ env.tag }} make release + - name: push plugin artifact + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: netobserv-cli.tar.gz + asset_name: netobserv-cli.tar.gz + asset_content_type: application/gzip \ No newline at end of file diff --git a/.gitignore b/.gitignore index 41d21a8e..9c2e9dc9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ output tmp cover.out kubeconfig +netobserv-cli.tar.gz \ No newline at end of file diff --git a/Makefile b/Makefile index e82c2ca2..1f21f3b4 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -# VERSION defines the project version for the bundle. +# VERSION defines the project version. # Update this value when you upgrade the version of your project. -# To re-generate a bundle for another specific version without changing the standard setup, you can: -# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) +# To re-generate a tar.gz for another specific version without changing the standard setup, you can: +# - use the VERSION as arg of the bundle target (e.g make tar-commands VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) VERSION ?= main BUILD_DATE := $(shell date +%Y-%m-%d\ %H:%M) @@ -48,6 +48,7 @@ OCI_BUILD_OPTS ?= # Image building tool (docker / podman) - docker is preferred in CI OCI_BIN_PATH := $(shell which docker 2>/dev/null || which podman) OCI_BIN ?= $(shell basename ${OCI_BIN_PATH}) +KREW_PLUGIN ?=false GOLANGCI_LINT_VERSION = v1.54.2 @@ -141,6 +142,7 @@ commands: ## Generate either oc or kubectl plugins and add them to build folder K8S_CLI_BIN=$(K8S_CLI_BIN) \ IMAGE=$(IMAGE) \ PULL_POLICY=$(PULL_POLICY) \ + VERSION=$(VERSION) \ ./scripts/inject.sh .PHONY: kubectl-commands @@ -155,6 +157,14 @@ oc-commands: commands ## Generate oc plugins and add them to build folder install-commands: commands ## Generate plugins and add them to /usr/bin/ sudo cp -a ./build/. /usr/bin/ +.PHONY: release +release: clean ## Generate tar.gz containing krew plugin and display krew updated index + $(MAKE) KREW_PLUGIN=true kubectl-commands + tar -czf netobserv-cli.tar.gz LICENSE ./build/netobserv + @echo "### Generating krew index yaml" + VERSION=$(VERSION) \ + ./scripts/krew.sh + .PHONY: create-kind-cluster create-kind-cluster: prereqs ## Create a kind cluster scripts/kind-cluster.sh @@ -169,8 +179,8 @@ destroy-kind-cluster: ## Destroy the kind cluster. .PHONY: $(COMMANDS) $(COMMANDS): commands ## Run command using custom image - @echo "### Running ${K8S_CLI_BIN}-netobserv-$@ using $(IMAGE)" - ./$(DIST_DIR)/${K8S_CLI_BIN}-netobserv-$@ $(COMMAND_ARGS) + @echo "### Running ${K8S_CLI_BIN}-netobserv $@ using $(IMAGE)" + ./$(DIST_DIR)/${K8S_CLI_BIN}-netobserv $@ $(COMMAND_ARGS) ##@ Images diff --git a/README.md b/README.md index f5b37613..eb70be3c 100644 --- a/README.md +++ b/README.md @@ -149,24 +149,28 @@ You can add this plugin to your favorite `oc` or `kubectl` commands using the fo ```bash K8S_CLI_BIN=oc make install-commands ``` +OR +```bash +K8S_CLI_BIN=kubectl make install-commands +``` -For `oc`, this will add `oc netobserv flows` and `oc netobserv packets` commands to your CLI. +This will add `netobserv` commands to your CLI. You can verify the commands are available using: ```bash oc plugin list ``` +OR +```bash +kubectl plugin list +``` It will display as result: -``` +```bash The following compatible plugins are available: ... -/usr/bin/oc-netobserv-cleanup -/usr/bin/oc-netobserv-flows -/usr/bin/oc-netobserv-packets +/usr/bin/-netobserv ``` -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). diff --git a/commands/netobserv b/commands/netobserv new file mode 100755 index 00000000..6f5237b9 --- /dev/null +++ b/commands/netobserv @@ -0,0 +1,85 @@ +#!/bin/bash +source "./scripts/functions.sh" + +# interface filter such as 'br-ex' or pcap filter such as 'tcp,80' +filter="" + +# CLI image to use +img="quay.io/netobserv/network-observability-cli:main" + +# version to display +version="0.0.1" + +# command to run +command="" + +case "$1" in +"help") + # display Help + echo + echo "Netobserv allows you to capture flow and packets from your cluster." + echo "Find more information at: https://github.com/netobserv/network-observability-cli/" + echo + echo "Syntax: netobserv [flows|packets|cleanup] [filters]" + echo + echo "options:" + echo " flows Capture flows information. You can specify an optionnal interface name as filter such as 'netobserv flows br-ex'." + echo " packets Capture packets from a specific protocol/port pair such as 'netobserv packets tcp,80'" + echo " cleanup Remove netobserv components." + echo " version Print software version." + echo + exit 0 ;; +"version") + # display version + echo "Netobserv CLI version $version" + exit 0 ;; +"flows") + if [ -z "${2:-}" ] + then + echo "Filters not set" + else + echo "Filters set as $2" + filter=$2 + fi + # run flows command + command="flows" ;; +"packets") + if [ -z "${2:-}" ]; then + echo "Specify a valid filter as first argument such as 'tcp,80'" + exit 1 + else + echo "Filters set as $2" + filter=$2 + fi + # run packets command + command="packets" ;; +"cleanup") + # run cleanup command + cleanup + exit 0 ;; +*) + echo "Unknown command $1. Use 'netobserv help' to display options" + exit 1 +esac + +trap cleanup EXIT + +setup $command $filter + +echo "Running network-observability-cli get-$command... " +${K8S_CLI_BIN} run \ + -n netobserv-cli \ + collector \ + --image=$img\ + --image-pull-policy='Always' \ + --restart='Never' \ + --command -- sleep infinity + +${K8S_CLI_BIN} wait \ + -n netobserv-cli \ + --for=condition=Ready pod/collector + +${K8S_CLI_BIN} exec -i --tty \ + -n netobserv-cli \ + collector \ + -- /network-observability-cli get-$command ${filter:+"--filter" "$filter"} \ No newline at end of file diff --git a/commands/netobserv-cleanup b/commands/netobserv-cleanup deleted file mode 100755 index 22d3c6d0..00000000 --- a/commands/netobserv-cleanup +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -source "./scripts/functions.sh" - -cleanup diff --git a/commands/netobserv-flows b/commands/netobserv-flows deleted file mode 100755 index ec9ef9f9..00000000 --- a/commands/netobserv-flows +++ /dev/null @@ -1,38 +0,0 @@ -#!/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 - -echo "Running network-observability-cli get-flows... " -${K8S_CLI_BIN} run \ - -n netobserv-cli \ - collector \ - --image=$img\ - --image-pull-policy='Always' \ - --restart='Never' \ - --command -- sleep infinity - -${K8S_CLI_BIN} wait \ - -n netobserv-cli \ - --for=condition=Ready pod/collector - -${K8S_CLI_BIN} exec -i --tty \ - -n netobserv-cli \ - collector \ - -- /network-observability-cli get-flows ${filter:+"--filter" "$filter"} \ No newline at end of file diff --git a/commands/netobserv-packets b/commands/netobserv-packets deleted file mode 100755 index 16b4c9f9..00000000 --- a/commands/netobserv-packets +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -source "./scripts/functions.sh" - -# pcap filter such as 'tcp,80' -filter="" - -if [ -z "${1:-}" ] -then - 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" - filter=$1 -fi - -# CLI image to use -img="quay.io/netobserv/network-observability-cli:main" - -trap cleanup EXIT - -setup packets $filter - -echo "\nRunning network-observability-cli get-packets... " -${K8S_CLI_BIN} run \ - -n netobserv-cli \ - collector \ - --image=$img \ - --image-pull-policy='Always' \ - --restart='Never' \ - --command -- sleep infinity - -${K8S_CLI_BIN} wait \ - -n netobserv-cli \ - --for=condition=Ready pod/collector - -${K8S_CLI_BIN} exec -i --tty \ - -n netobserv-cli \ - collector \ - -- /network-observability-cli get-packets --filter "$filter" \ No newline at end of file diff --git a/scripts/inject.sh b/scripts/inject.sh index edac1e8d..2e7800f4 100755 --- a/scripts/inject.sh +++ b/scripts/inject.sh @@ -3,32 +3,41 @@ cp -a ./commands/. ./tmp cp ./scripts/functions.sh ./tmp/functions.sh if [ -z "$IMAGE" ]; then - echo "image not provided, keeping current ones" + echo "image not provided, keeping current one" 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 + sed -i "/img=/c\img=\"$IMAGE\"" ./tmp/netobserv fi if [ -z "$PULL_POLICY" ]; then - echo "pull policy not provided, keeping current ones" + echo "pull policy not provided, keeping current one" 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 + sed -i "/ --image-pull-policy/c\ --image-pull-policy='$PULL_POLICY' \\\\" ./tmp/netobserv fi -if [ -z "$K8S_CLI_BIN" ]; then - echo "ERROR: K8S CLI not provided" - exit 1 +if [ -z "$VERSION" ]; then + echo "version not provided, keeping current one" else + echo "updating CLI version to $VERSION" + sed -i "/version=/c\version=\"$VERSION\"" ./tmp/netobserv +fi + +prefix= +if [ -z "$KREW_PLUGIN" ] || [ "$KREW_PLUGIN" = "false" ]; then + if [ -z "$K8S_CLI_BIN" ]; then + echo "ERROR: K8S CLI not provided" + exit 1 + fi echo "updating K8S CLI to $K8S_CLI_BIN" + # remove unecessary call 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 + # replace only first match to force default + sed -i "0,/K8S_CLI_BIN=/c\K8S_CLI_BIN=$K8S_CLI_BIN" ./tmp/functions.sh + # prefix with oc / kubectl for local install + prefix="$K8S_CLI_BIN-" + echo "prefixing with $prefix" + mv ./tmp/netobserv ./tmp/"$prefix"netobserv fi # inject YAML files to functions.sh @@ -39,9 +48,7 @@ sed -i -e '/packetAgentYAMLContent/{r ./res/packet-capture.yml' -e 'd}' ./tmp/fu sed -i -e '/collectorServiceYAMLContent/{r ./res/collector-service.yml' -e 'd}' ./tmp/functions.sh # 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 +sed -i -e '/source.*/{r ./tmp/functions.sh' -e 'd}' ./tmp/"$prefix"netobserv rm ./tmp/functions.sh diff --git a/scripts/krew.sh b/scripts/krew.sh new file mode 100755 index 00000000..9348bc55 --- /dev/null +++ b/scripts/krew.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +SHA=$(sha256sum netobserv-cli.tar.gz | awk '{print $1}') + +URL="" +if [[ $VERSION = +([[:digit:]]).+([[:digit:]]).+([[:digit:]]) ]]; then + URL="https://github.com/netobserv/network-observability-cli/releases/download/v${VERSION}/netobserv-cli.tar.gz" +fi + + +indexYaml=' +apiVersion: krew.googlecontainertools.github.com/v1alpha2 +kind: Plugin +metadata: + name: netobserv +spec: + version: "'${VERSION}'" + homepage: https://github.com/netobserv/network-observability-cli + shortDescription: "Lightweight Flow and Packet visualization tool" + description: | + Deploys NetObserv eBPF agent on your k8s cluster to collect flows + or packets from nodes network interfaces and streams data to a local + collector for analysis and visualization. + platforms: + - selector: + matchExpressions: + - key: "os" + operator: "In" + values: + - darwin + - linux + uri: "'${URL}'" + sha256: "'${SHA}'" + files: + - from: "build/netobserv" + to: "netobserv" + - from: "LICENSE" + to: "." + bin: netobserv +' + +echo "Copy the following YAML and submit it to https://github.com/kubernetes-sigs/krew-index for release:" +echo "${indexYaml}" + +# github todo release notes +# check .github/workflows/release.yml for usage +mkdir -p ./tmp +echo "TODO: +- Submit updated index to https://github.com/kubernetes-sigs/krew-index to update plugin: +\`\`\`yaml${indexYaml}\`\`\` +- Click on 'generate release notes' above and publish" > ./tmp/release.md