From 708a618343d2363b8b321f7cdee427fd8645ec73 Mon Sep 17 00:00:00 2001 From: YZ775 Date: Wed, 31 May 2023 17:07:07 +0900 Subject: [PATCH] add release ci flow and refactor tests --- .github/workflows/ci.yaml | 2 +- .github/workflows/release.yaml | 39 +++++++++++++++++++++++++++++++ README.md | 27 ++++++++++++++++----- cmd/root.go | 7 ++---- cmd/root_test.go | 13 +++++------ config/cronjob/cronjob.yaml | 4 ++-- config/default/kustomization.yaml | 8 +++++++ config/dev/kustomization.yaml | 3 +-- e2e/manifests/cronjob.yaml | 20 ++++++++++++++++ e2e/manifests/deployment.yaml | 2 +- e2e/manifests/observer_pod.yaml | 2 +- e2e/manifests/pod.yaml | 2 +- e2e/manifests/serviceaccount.yaml | 0 e2e/suite_test.go | 31 ++++++++++++++---------- e2e/zombie-detector_test.go | 6 ++--- 15 files changed, 125 insertions(+), 41 deletions(-) create mode 100644 .github/workflows/release.yaml create mode 100644 config/default/kustomization.yaml create mode 100644 e2e/manifests/cronjob.yaml delete mode 100644 e2e/manifests/serviceaccount.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 76f34cc..7aab07d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -3,7 +3,7 @@ on: pull_request: push: branches: - - 'develop' + - 'main' jobs: build: runs-on: ubuntu-22.04 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..59d82ab --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,39 @@ +name: Release +on: + push: + tags: + - 'v*' +jobs: + image: + name: Push Container image + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - uses: docker/setup-buildx-action@v2 + - run: make docker-build + - name: Login to ghcr.io + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Push to ghcr.io + run: | + IMAGE_TAG=${GITHUB_REF#refs/tags/v} # Remove "v" prefix. + docker tag zombie-detector:dev ghcr.io/cybozu-go/zombie-detector:$IMAGE_TAG + docker push ghcr.io/cybozu-go/zombie-detector:$IMAGE_TAG + release: + name: Release on GitHub + needs: image + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Create release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + VERSION=${GITHUB_REF#refs/tags/} # Don't remove "v" prefix. + if echo ${VERSION} | grep -q -e '-'; then PRERELEASE_FLAG=-p; fi + gh release create $VERSION $PRERELEASE_FLAG \ + -t "Release $VERSION" \ + -n "See [CHANGELOG.md](./CHANGELOG.md) for details." \ No newline at end of file diff --git a/README.md b/README.md index a2970e2..02bcb4b 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,21 @@ Zombie detector Zombie detector is CronJob to detect resources that elapsed for a long time since deletion. ## Features -- detect resources who's elapsed time exceeds the threthord -- informations about detected resources are pushed into Pushgateway +- It detects resources that remain undeleted after a certain period with a ```deletionTimestamp```. +- Information about detected resources are pushed into Pushgateway. +- We can use this both inside and outside cluster. -## CLI usage +## Build +CLI +``` +go build +``` +Docker Image +``` +make docker-build +``` + +## Usage ``` Usage: zombie-detector [flags] @@ -28,14 +39,18 @@ Flags: --pushgateway string URL of Pushgateway's endpoint --threshold string threshold of detection (default "24h") ``` -example usage +### example ``` -zombie-detector --incluster=false --pushgateway= --threshold=24h30m +zombie-detector --incluster=false --pushgateway= --threshold=24h30m ``` [releases]: https://github.com/cybozu-go/zombie-detector/releases -## example manifest +## Example manifest +We can run zombie-detector periodically as CronJob in a Kubernetes Cluster. + +These are example manifests. + conjob.yaml ```yaml apiVersion: batch/v1 diff --git a/cmd/root.go b/cmd/root.go index 60d95da..aec81b6 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -12,7 +12,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/push" "github.com/spf13/cobra" - apiv1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -92,7 +92,7 @@ func getAllResources(ctx context.Context, config *rest.Config) ([]unstructured.U } for _, resource := range resList.APIResources { groupeResourceDef := schema.GroupVersionResource{Group: gv.Group, Version: gv.Version, Resource: resource.Name} - listResponse, err := dynamicClient.Resource(groupeResourceDef).Namespace(apiv1.NamespaceAll).List(ctx, metav1.ListOptions{}) + listResponse, err := dynamicClient.Resource(groupeResourceDef).Namespace(corev1.NamespaceAll).List(ctx, metav1.ListOptions{}) if err != nil { if strings.Contains(err.Error(), errorFaildtoList) || strings.Contains(err.Error(), errorMethodNotAllowed) { continue @@ -217,10 +217,7 @@ func rootMain(cmd *cobra.Command, args []string) error { if err != nil { return err } - printAllResources(allResources) - fmt.Println("---") zombieResources := detectZombieResources(allResources, threshold) - printAllResources(zombieResources) err = postZombieResourcesMetrics(zombieResources, pushgatewayEndpointFlag) if err != nil { return err diff --git a/cmd/root_test.go b/cmd/root_test.go index 7bcfdd4..8cf7b09 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -16,7 +16,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "k8s.io/api/apps/v1" - apiv1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" @@ -33,7 +32,7 @@ func TestDetectZombieResource(t *testing.T) { }{ { name: "No problem Pod", - resouce: &apiv1.Pod{ + resouce: &corev1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", APIVersion: "v1", @@ -50,7 +49,7 @@ func TestDetectZombieResource(t *testing.T) { }, { name: "Zombie below the threshold Pod", - resouce: &apiv1.Pod{ + resouce: &corev1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", APIVersion: "v1", @@ -67,7 +66,7 @@ func TestDetectZombieResource(t *testing.T) { }, { name: "Zombie over the threshold Pod", - resouce: &apiv1.Pod{ + resouce: &corev1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", APIVersion: "v1", @@ -84,7 +83,7 @@ func TestDetectZombieResource(t *testing.T) { }, { name: "Zombie over the threshold Pod with finalizer", - resouce: &apiv1.Pod{ + resouce: &corev1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", APIVersion: "v1", @@ -101,7 +100,7 @@ func TestDetectZombieResource(t *testing.T) { }, { name: "Zombie over the threshold(changed) Pod", - resouce: &apiv1.Pod{ + resouce: &corev1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", APIVersion: "v1", @@ -118,7 +117,7 @@ func TestDetectZombieResource(t *testing.T) { }, { name: "Zombie threshold boundary Pod", - resouce: &apiv1.Pod{ + resouce: &corev1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", APIVersion: "v1", diff --git a/config/cronjob/cronjob.yaml b/config/cronjob/cronjob.yaml index bc1ba21..6e977ff 100644 --- a/config/cronjob/cronjob.yaml +++ b/config/cronjob/cronjob.yaml @@ -15,6 +15,6 @@ spec: image: zombie-detector:dev command: - ./zombie-detector - - --threshold=1s - - --pushgateway=http://pushgateway.monitoring.svc.cluster.local:9091 + - --threshold=24h + - --pushgateway=http://pushgateway.monitoring.svc:9091 restartPolicy: OnFailure \ No newline at end of file diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml new file mode 100644 index 0000000..1179ee1 --- /dev/null +++ b/config/default/kustomization.yaml @@ -0,0 +1,8 @@ +resources: + - ../namespace + - ../rbac + - ../cronjob +images: + - name: zombie-detector:dev + newName: ghcr.io/cybozu-go/zombie-detector + newTag: 0.0.1 \ No newline at end of file diff --git a/config/dev/kustomization.yaml b/config/dev/kustomization.yaml index 0ece2bb..4bb2c04 100644 --- a/config/dev/kustomization.yaml +++ b/config/dev/kustomization.yaml @@ -1,5 +1,4 @@ resources: - ../namespace - ../rbac - - ../cronjob - - ../pushgateway \ No newline at end of file + - ../cronjob \ No newline at end of file diff --git a/e2e/manifests/cronjob.yaml b/e2e/manifests/cronjob.yaml new file mode 100644 index 0000000..637f6a5 --- /dev/null +++ b/e2e/manifests/cronjob.yaml @@ -0,0 +1,20 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: zombie-detector-cronjob + namespace: zombie-detector +spec: + schedule: "0 0 */1 * *" + jobTemplate: + spec: + template: + spec: + serviceAccountName: zombie-detector-sa + containers: + - name: zombie-detector + image: zombie-detector:dev + command: + - ./zombie-detector + - --threshold=1s + - --pushgateway=http://pushgateway.monitoring.svc:9091 + restartPolicy: OnFailure \ No newline at end of file diff --git a/e2e/manifests/deployment.yaml b/e2e/manifests/deployment.yaml index c01f810..54dcecf 100644 --- a/e2e/manifests/deployment.yaml +++ b/e2e/manifests/deployment.yaml @@ -15,6 +15,6 @@ spec: app: test-pod-deployment spec: containers: - - name: foo + - name: test image: quay.io/cybozu/ubuntu:20.04 command: ["pause"] diff --git a/e2e/manifests/observer_pod.yaml b/e2e/manifests/observer_pod.yaml index 0ab25f0..386eaed 100644 --- a/e2e/manifests/observer_pod.yaml +++ b/e2e/manifests/observer_pod.yaml @@ -8,6 +8,6 @@ spec: runAsUser: 10000 runAsGroup: 10000 containers: - - name: foo + - name: test image: quay.io/cybozu/ubuntu:20.04 command: ["pause"] \ No newline at end of file diff --git a/e2e/manifests/pod.yaml b/e2e/manifests/pod.yaml index 36793dd..1ec50c6 100644 --- a/e2e/manifests/pod.yaml +++ b/e2e/manifests/pod.yaml @@ -10,6 +10,6 @@ spec: runAsUser: 10000 runAsGroup: 10000 containers: - - name: foo + - name: test image: quay.io/cybozu/ubuntu:20.04 command: ["pause"] \ No newline at end of file diff --git a/e2e/manifests/serviceaccount.yaml b/e2e/manifests/serviceaccount.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/e2e/suite_test.go b/e2e/suite_test.go index 43303b2..5af0a83 100644 --- a/e2e/suite_test.go +++ b/e2e/suite_test.go @@ -9,6 +9,7 @@ import ( . "github.com/onsi/gomega" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/json" ) @@ -33,8 +34,25 @@ var _ = BeforeSuite(func() { _, err = kubectl(nil, "apply", "-f", "./manifests/observer_pod.yaml") Expect(err).NotTo(HaveOccurred()) + By("waiting for observer pod to be started") + Eventually(func() error { + res, err := kubectl(nil, "get", "pod", "observer-pod", "-n", "monitoring", "-o", "json") + if err != nil { + return err + } + pod := corev1.Pod{} + err = json.Unmarshal(res, &pod) + if err != nil { + return err + } + if pod.Status.Phase == corev1.PodRunning { + return fmt.Errorf("observer-pod is not ready yet") + } + return nil + }).Should(Succeed()) + By("applying cronjob manifest") - _, err = kubectl(nil, "apply", "-f", "../config/cronjob/cronjob.yaml") + _, err = kubectl(nil, "apply", "-f", "./manifests/cronjob.yaml") Expect(err).NotTo(HaveOccurred()) res, err := kubectl(nil, "get", "cronjob", "zombie-detector-cronjob", "-n", "zombie-detector", "-o", "json") @@ -60,15 +78,4 @@ var _ = BeforeSuite(func() { } return nil }).Should(Succeed()) - -}) - -var _ = AfterSuite(func() { - // By("deleting test resources") - // _, err := kubectl(nil, "patch", "deployment", "test-deployment", "--patch-file", "./manifests/patch.yaml") - // Expect(err).NotTo(HaveOccurred()) - // _, err = kubectl(nil, "patch", "pod", "test-pod", "--patch-file", "./manifests/patch.yaml") - // Expect(err).NotTo(HaveOccurred()) - // _, err = kubectl(nil, "patch", "configmap", "test-configmap", "--patch-file", "./manifests/patch.yaml") - // Expect(err).NotTo(HaveOccurred()) }) diff --git a/e2e/zombie-detector_test.go b/e2e/zombie-detector_test.go index 808c6e8..ed1e0a6 100644 --- a/e2e/zombie-detector_test.go +++ b/e2e/zombie-detector_test.go @@ -9,7 +9,7 @@ import ( appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" - apiv1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/json" ) @@ -59,7 +59,7 @@ var _ = Describe("zombie-detector e2e test", func() { if err != nil { return err } - pod := apiv1.Pod{} + pod := corev1.Pod{} err = json.Unmarshal(res, &pod) if err != nil { return err @@ -77,7 +77,7 @@ var _ = Describe("zombie-detector e2e test", func() { if err != nil { return err } - configmap := apiv1.ConfigMap{} + configmap := corev1.ConfigMap{} err = json.Unmarshal(res, &configmap) if err != nil { return err