From 297c5e6a281a2a5108c3cd0e576985bd0c85d551 Mon Sep 17 00:00:00 2001 From: Christian Nicolai Date: Fri, 21 Aug 2020 14:19:51 +0200 Subject: [PATCH] ci: add e2e tests using kind + k8s --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++++++++++++++-- Makefile | 20 ++++++++++++++++++++ e2e/blacklist-kind-empty.txt | 2 ++ e2e/resources-kind-empty.yml | 0 e2e/resources-kind-one.yml | 19 +++++++++++++++++++ kube-stale-resources.py | 3 +++ 6 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 e2e/blacklist-kind-empty.txt create mode 100644 e2e/resources-kind-empty.yml create mode 100644 e2e/resources-kind-one.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 401fdf0..8e4144a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,9 +9,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Set up Python 3.8 - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install dependencies @@ -21,3 +21,35 @@ jobs: - name: Linting run: | make lint + + e2e-with-kind: + name: e2e with kind + needs: build + runs-on: ubuntu-latest + strategy: + matrix: + k8s-version: + - v1.16.9 + - v1.18.8 + env: + kind-version: v0.8.1 + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install dependencies + run: | + pip install poetry + poetry install + - name: Set up kind with K8s version ${{ matrix.k8s-version }} + uses: engineerd/setup-kind@v0.4.0 + with: + image: kindest/node:${{ matrix.k8s-version }} + version: ${{ env.kind-version }} + - name: E2E test + run: | + kubectl cluster-info + kubectl proxy & + make e2e-with-kind diff --git a/Makefile b/Makefile index ee5f83c..3b09929 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,26 @@ lint: ## Lint all source code poetry run pylint *.py poetry run mypy *.py +.PHONY: e2e-with-kind +e2e-with-kind: ## Run E2E tests against running kind (K8s in Docker) instance + function cleanup { + (kubectl delete namespace e2e || true) + } + trap cleanup EXIT + + # no resources and empty cluster should have no stale resources + poetry run python kube-stale-resources.py --blacklist e2e/blacklist-kind-empty.txt -f e2e/resources-kind-empty.yml + + # some resources in VCS and empty cluster should have no stale resources + kubectl apply -f e2e/resources-kind-one.yml + poetry run python kube-stale-resources.py --blacklist e2e/blacklist-kind-empty.txt -f e2e/resources-kind-one.yml + cleanup + + # some resources NOT in VCS and empty cluster should have stale resources + kubectl apply -f e2e/resources-kind-one.yml + (poetry run python kube-stale-resources.py --blacklist e2e/blacklist-kind-empty.txt -f e2e/resources-kind-empty.yml && exit 1 || exit 0) + cleanup + .PHONY: help help: ## Print this help text @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}' diff --git a/e2e/blacklist-kind-empty.txt b/e2e/blacklist-kind-empty.txt new file mode 100644 index 0000000..e82a74e --- /dev/null +++ b/e2e/blacklist-kind-empty.txt @@ -0,0 +1,2 @@ +^default:events.k8s.io/v1beta1:Event:kind-.*$ +^local-path-storage:.*$ diff --git a/e2e/resources-kind-empty.yml b/e2e/resources-kind-empty.yml new file mode 100644 index 0000000..e69de29 diff --git a/e2e/resources-kind-one.yml b/e2e/resources-kind-one.yml new file mode 100644 index 0000000..fc21c1b --- /dev/null +++ b/e2e/resources-kind-one.yml @@ -0,0 +1,19 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: e2e +--- +apiVersion: v1 +kind: Service +metadata: + name: foo + namespace: e2e +spec: + type: ClusterIP + ports: + - port: 80 + name: http + targetPort: 80 + selector: + app: foo diff --git a/kube-stale-resources.py b/kube-stale-resources.py index e2b23ee..43df9d0 100644 --- a/kube-stale-resources.py +++ b/kube-stale-resources.py @@ -20,6 +20,7 @@ BLACKLIST_REGEXS = [ r'^.*:batch/v1:Job:.*-\d{10,}$', # jobs created by cron jobs with unix timestamp suffix r'^.*:metrics.k8s.io/v1beta1:PodMetrics:.*$', r'^.*:v1:Endpoints:.*$', + r'^.*:.*:EndpointSlice:.*$', r'^.*:v1:Event:.*$', r'^.*:v1:Pod:.*$', r'^.*:v1:Secret:.*-token-\S{5}$', # secrets with token for service accounts @@ -166,6 +167,8 @@ def main(): print(' ' + x) print("..", counter, "entries") + sys.exit(len(list(slive - starget))) + if __name__ == "__main__": main()