From fd42e6681f506b35dbacb72f804ee78102329f7f Mon Sep 17 00:00:00 2001 From: Khramtsov Valentin <42875838+kvvit@users.noreply.github.com> Date: Thu, 5 Oct 2023 17:50:37 +0300 Subject: [PATCH] Metrics and http probes have been added (#3) * Added vendor to gitignore * Added metrics module for deployments * Added concurency for metrics and delete service * Run metrics and cleanup services concurently, modify helm charts * Changed chart and app versions to 0.1.0 * Modyfied README --------- Co-authored-by: Valentin Khramtsov --- .gitignore | 2 +- README.md | 36 +++++++++++++++++++-- charts/Chart.yaml | 4 +-- charts/templates/deployment.yaml | 8 +++++ charts/templates/service.yaml | 18 +++++++++++ charts/values.yaml | 28 ++++++++++++---- go.mod | 13 ++++++-- go.sum | 28 +++++++++++++--- main.go | 51 +++++++++++++++++++++++++----- pkg/deleteobjects/deleteobjects.go | 8 +++++ pkg/metrics/metrics.go | 38 ++++++++++++++++++++++ 11 files changed, 209 insertions(+), 25 deletions(-) create mode 100644 charts/templates/service.yaml create mode 100644 pkg/metrics/metrics.go diff --git a/.gitignore b/.gitignore index 3b735ec..b8c2a57 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ *.out # Dependency directories (remove the comment below to include it) -# vendor/ +vendor/ # Go workspace file go.work diff --git a/README.md b/README.md index f5644b7..f86c0ba 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,6 @@ my learning purposes of Go programming. This application can be used in the development kubernetes cluster, to automatically delete outdated deployments in particular namespace. -This is next version in which you can use environment variable `DRY_RUN`, -to skip deleting actions if it set to `true`. ## Installation @@ -21,3 +19,37 @@ This application can be installed via helm chart.: helm upgrade --install deployments-cleaner ./charts \ -f ./charts/values.yaml -n your-namespace ``` + +Environmet variables used in this application, with default values that +can be changed in `values.yaml`: + +```yaml +WORK_START: 10 +``` + +The time in which deploymets cleaner will stop to work, or begining of workday. + +```yaml +WORK_END: 19 +``` + +The time in which deploymets cleaner will start to work, or end of workday. + +```yaml +TIME_TO_DELETE: 86400 +``` + +Time in seconds that deploymets cleaner will wait before deleting outdated +deployments. Here is 86400 seconds that means 24 hours. + +```yaml +DRY_RUN: true +``` + +Skip deleting actions if it set to `true`. + +## Monitoring + +This application can be monitored via Grafana. It returns deployments +names and timelive of each deployment in seconds in port `8080` in the +`/metrics` path. diff --git a/charts/Chart.yaml b/charts/Chart.yaml index af71f27..70dd942 100644 --- a/charts/Chart.yaml +++ b/charts/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: deployments-cleaner description: A Helm chart for delete old deployments from Kubernetes namespace type: application -version: 0.0.3 -appVersion: "0.0.3" +version: 0.1.0 +appVersion: "0.1.0" diff --git a/charts/templates/deployment.yaml b/charts/templates/deployment.yaml index 07622be..29c16cb 100644 --- a/charts/templates/deployment.yaml +++ b/charts/templates/deployment.yaml @@ -50,6 +50,14 @@ spec: livenessProbe: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.service.port }} + protocol: TCP {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/charts/templates/service.yaml b/charts/templates/service.yaml new file mode 100644 index 0000000..714b2bd --- /dev/null +++ b/charts/templates/service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "charts.labels" . | nindent 4 }} + annotations: + {{- toYaml .Values.service.annotations | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.service.port }} + protocol: TCP + name: "metrics" + selector: + {{- include "charts.selectorLabels" . | nindent 4 }} diff --git a/charts/values.yaml b/charts/values.yaml index 291ab65..195106b 100644 --- a/charts/values.yaml +++ b/charts/values.yaml @@ -26,16 +26,32 @@ serviceAccount: podAnnotations: {} livenessProbe: - exec: - command: - - ls - - /app/main + httpGet: + path: /health + port: 8080 initialDelaySeconds: 5 - periodSeconds: 10 + periodSeconds: 5 timeoutSeconds: 1 - failureThreshold: 3 + failureThreshold: 5 successThreshold: 1 +readinessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + failureThreshold: 10 + successThreshold: 1 + +service: + type: ClusterIP + port: 8080 + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "8080" + podSecurityContext: {} # fsGroup: 2000 diff --git a/go.mod b/go.mod index ca1bd6b..c198362 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,15 @@ module github.com/kvvit/deployment_cleaner go 1.21.1 require ( + github.com/heptiolabs/healthcheck v0.0.0-20211123025425-613501dd5deb + github.com/prometheus/client_golang v1.17.0 k8s.io/apimachinery v0.28.2 k8s.io/client-go v0.28.2 ) require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/go-logr/logr v1.2.4 // indirect @@ -24,18 +28,23 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.11.1 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.13.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sys v0.10.0 // indirect + golang.org/x/sys v0.11.0 // indirect golang.org/x/term v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index fa9e2ef..15ad330 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,7 @@ +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -17,6 +21,7 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -33,6 +38,8 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/heptiolabs/healthcheck v0.0.0-20211123025425-613501dd5deb h1:tsEKRC3PU9rMw18w/uAptoijhgG4EvlA5kfJPtwrMDk= +github.com/heptiolabs/healthcheck v0.0.0-20211123025425-613501dd5deb/go.mod h1:NtmN9h8vrTveVQRLHcX2HQ5wIPBDCsZ351TGbZWgg38= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -50,6 +57,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -63,6 +72,14 @@ github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= +github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -92,14 +109,15 @@ golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -123,8 +141,10 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY= +gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/main.go b/main.go index 2bad413..56ca0a9 100644 --- a/main.go +++ b/main.go @@ -2,30 +2,65 @@ package main import ( "context" + "fmt" "log" + "net/http" "time" "github.com/kvvit/deployment_cleaner/pkg/clientset" "github.com/kvvit/deployment_cleaner/pkg/deleteobjects" "github.com/kvvit/deployment_cleaner/pkg/loadvars" + "github.com/kvvit/deployment_cleaner/pkg/metrics" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +var ( + deploymentMetrics = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "deployment_live_time_seconds", + Help: "Live time of deployments in seconds", + }, + []string{"deployment"}, + ) +) + func main() { ctx := context.Background() envvars := loadvars.LoadVars() clientset := clientset.GetClientset() + port := "8080" log.Println("Cleaning service has been started") - ticker := time.NewTicker(10 * time.Minute) - for ; true; <-ticker.C { - timeNow := metav1.Now() - timeWork := timeNow.Hour() - if timeWork >= envvars.WorkStart && timeWork < envvars.WorkEnd { - log.Println("Now is working time, pass changes") - } else { - deleteobjects.DeleteOldHelmReleases(ctx, clientset, envvars.TimeToDelete, envvars.DeploymentName, envvars.NameSpace, envvars.IsDryRun) + prometheus.MustRegister(deploymentMetrics) + go func() { + http.Handle("/metrics", promhttp.Handler()) + http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "ok") + }) + log.Println("Web server start listening on", port) + err := http.ListenAndServe(":"+port, nil) + if err != nil { + log.Fatal("Error starting HTTP server:", err) + } + }() + + ticker := time.NewTicker(1 * time.Minute) + defer ticker.Stop() + timeNow := metav1.Now() + timeWork := timeNow.Hour() + + for { + select { + case <-ticker.C: + metrics.FetchAndUpdateDeploymentMetrics(ctx, clientset, envvars.NameSpace, deploymentMetrics) + if timeWork >= envvars.WorkStart && timeWork < envvars.WorkEnd { + log.Println("Now is working time, pass changes") + } else { + deleteobjects.DeleteOldHelmReleases(ctx, clientset, envvars.TimeToDelete, envvars.DeploymentName, envvars.NameSpace, envvars.IsDryRun) + } } } } diff --git a/pkg/deleteobjects/deleteobjects.go b/pkg/deleteobjects/deleteobjects.go index 520ffd3..754985c 100644 --- a/pkg/deleteobjects/deleteobjects.go +++ b/pkg/deleteobjects/deleteobjects.go @@ -7,12 +7,17 @@ import ( "context" "log" "strings" + "sync" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) +var ( + mutex = sync.Mutex{} +) + func DeleteOldHelmReleases( ctx context.Context, clientset *kubernetes.Clientset, @@ -25,6 +30,9 @@ func DeleteOldHelmReleases( log.Fatalf("Error listing Secrets: %v\n", err) } + mutex.Lock() + defer mutex.Unlock() + for _, secret := range secrets.Items { if secret.Labels["name"] == deploymentName { continue diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go new file mode 100644 index 0000000..aa7ac66 --- /dev/null +++ b/pkg/metrics/metrics.go @@ -0,0 +1,38 @@ +package metrics + +import ( + "context" + "log" + "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +var ( + mutex = sync.Mutex{} +) + +func FetchAndUpdateDeploymentMetrics( + ctx context.Context, + clientset *kubernetes.Clientset, + namespace string, + deploymentMetrics *prometheus.GaugeVec) { + secrets, err := clientset.CoreV1().Secrets(namespace).List(ctx, metav1.ListOptions{}) + if err != nil { + log.Println("Error fetching secrets:", err) + return + } + + mutex.Lock() + defer mutex.Unlock() + + for _, secret := range secrets.Items { + if secret.Type != "helm.sh/release.v1" || secret.Labels["version"] != "1" { + continue + } + deploymentMetrics.WithLabelValues(secret.Labels["name"]).Set(float64(time.Now().Sub(secret.CreationTimestamp.Time).Seconds())) + } +}