diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 0000000..ee1696f --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +type: application + +# version and appVersion values are overrided during build step +version: 0.0.0 +appVersion: 0.0.0 + +name: upgrade-manager-chart +description: Upgrade Manager Helm chart +home: https://github.com/qonto/upgrade-manager +sources: + - https://github.com/qonto/upgrade-manager +annotations: + artifacthub.io/category: integration-delivery +keywords: + - argocd + - upgrade + - auto-discovery diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt new file mode 100644 index 0000000..3b93dde --- /dev/null +++ b/chart/templates/NOTES.txt @@ -0,0 +1 @@ +Upgrade Manager is deployed. diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 0000000..da6ea47 --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,76 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "upgrade-manager.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "upgrade-manager.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "upgrade-manager.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "upgrade-manager.labels" -}} +helm.sh/chart: {{ include "upgrade-manager.chart" . }} +{{ include "upgrade-manager.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- range $key, $value := .Values.additionalLabels }} +{{ $key }}: {{ $value | quote }} +{{- end -}} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "upgrade-manager.selectorLabels" -}} +app.kubernetes.io/name: {{ include "upgrade-manager.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "upgrade-manager.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "upgrade-manager.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the pvct to use +*/}} +{{- define "upgrade-manager.persistentVolumeClaimName" -}} +{{- if .Values.persistentVolumeClaim.create }} +{{- default (include "upgrade-manager.fullname" .) .Values.persistentVolumeClaim.name }} +{{- else }} +{{- default "default" .Values.persistentVolumeClaim.name }} +{{- end }} +{{- end }} diff --git a/chart/templates/config.yaml b/chart/templates/config.yaml new file mode 100644 index 0000000..a95d801 --- /dev/null +++ b/chart/templates/config.yaml @@ -0,0 +1,13 @@ +{{- if .Values.config -}} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "upgrade-manager.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "upgrade-manager.labels" . | nindent 4 }} +data: + config.yaml: | + {{- toYaml .Values.config | nindent 4 }} +{{- end -}} diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml new file mode 100644 index 0000000..8ca6f89 --- /dev/null +++ b/chart/templates/deployment.yaml @@ -0,0 +1,102 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "upgrade-manager.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "upgrade-manager.labels" . | nindent 4 }} +spec: + replicas: 1 + serviceName: "upgrade-manager" + selector: + matchLabels: + {{- include "upgrade-manager.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + checksum/config: {{ include (print .Template.BasePath "/config.yaml") . | sha256sum }} + labels: + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "upgrade-manager.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "upgrade-manager.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + volumes: + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: upgrade-manager-config + configMap: + name: {{ include "upgrade-manager.fullname" . }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + args: + - "server" + - "--config" + - "{{ .Values.configFilePath }}" + - "--log-format" + - "{{ .Values.logFormat }}" + - "--log-level" + - "{{ .Values.logLevel }}" + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.env }} + env: + {{- toYaml . | nindent 12 }} + {{- end -}} + {{- with .Values.envFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + failureThreshold: 6 + readinessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 10 + periodSeconds: 5 + failureThreshold: 3 + volumeMounts: + - mountPath: /config + name: upgrade-manager-config + readOnly: true + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/chart/templates/service.yaml b/chart/templates/service.yaml new file mode 100644 index 0000000..af0aa0c --- /dev/null +++ b/chart/templates/service.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "upgrade-manager.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "upgrade-manager.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "upgrade-manager.selectorLabels" . | nindent 4 }} diff --git a/chart/templates/serviceMonitor.yaml b/chart/templates/serviceMonitor.yaml new file mode 100644 index 0000000..135f525 --- /dev/null +++ b/chart/templates/serviceMonitor.yaml @@ -0,0 +1,25 @@ +{{- if .Values.serviceMonitor.enabled -}} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "upgrade-manager.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "upgrade-manager.labels" . | nindent 4 }} + {{- with .Values.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "upgrade-manager.selectorLabels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + endpoints: + - port: http + path: /metrics + interval: {{ .Values.serviceMonitor.interval }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} +{{- end }} diff --git a/chart/templates/serviceaccount.yaml b/chart/templates/serviceaccount.yaml new file mode 100644 index 0000000..487f133 --- /dev/null +++ b/chart/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "upgrade-manager.serviceAccountName" . }} + labels: + {{- include "upgrade-manager.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 0000000..8d0bdb6 --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,168 @@ +# Default values for upgrade-manager. + +image: + repository: public.ecr.aws/qonto/upgrade-manager + pullPolicy: IfNotPresent + tag: "" # Defined by chart appVersion parameter + +# Define environment variables +env: {} +envFrom: {} + +logLevel: info +logFormat: json +configFilePath: "/app/config/config.yaml" + +# Set additional labels on all resources +additionalLabels: {} + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +volumeMounts: {} +volumes: {} + +persistentVolumeClaim: + create: true + annotations: {} + name: "" + storage: "50Gi" + storageClassName: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} +podLabels: {} + +podSecurityContext: + fsGroup: 10001 + +securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsGroup: 10001 + runAsUser: 10001 + +service: + type: ClusterIP + port: 3000 + +serviceMonitor: + enabled: true + interval: 60s + scrapeTimeout: 10s + additionalLabels: {} + +resources: {} + # limits: + # memory: 1000Mi + # requests: + # cpu: 200m + # memory: 1000Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +config: + global: + interval: 10m + aws: + region: us-east-1 + sources: + deployments: + - label-selector: + upgrade-manager.qonto.com/enabled: "true" + filters: + semver-versions: + remove-pre-release: true + remove-first-major-version: true + + registries: + : + enable-date-retrieval: true + auth: + aws: true + argocdHelm: + - enabled: true + argocd-namespace: argocd # namespace where the argocd application object is deployed + git-credentials-secrets-namespace: argocd # namespace where secrets containing git credentials are deployed + git-credentials-secrets-pattern: ".*-repo-.*" # regex to filter which secrets to fetch + filters: + semver-versions: + remove-pre-release: true + remove-first-major-version: true + recent-versions: + days: 21 # number of days since the version was released + destination-namespace: # namespace where the app resources will be deployed + include: [] + # ["kyverno"] # regular expression, if include is empty, it includes all namespaces + exclude: [] + # ["default", "temporary-*", "feature-*", "kube-system"] # regular expression if exclude is empty, it does not exclude any namespace + filesystemHelm: + - enabled: true + paths: + - "./internal/app/_testdata/test_chart/Chart.yaml" + - "./internal/app/_testdata/test_chart2/Chart.yaml" + - "./internal/app/_testdata/test_chart3/Chart.yaml" + - "./internal/app/_testdata/test_chart4/Chart.yaml" + filters: + semver-versions: + remove-pre-release: true + remove-first-major-version: true + recent-versions: + days: 21 + aws: + eks: + enabled: true + request-timeout: 15s + rds: + enabled: true + request-timeout: 15s + aggregation-level: cluster + msk: + enabled: true + request-timeout: 15s + elasticache: + enabled: true + request-timeout: 15s + lambda: + enabled: true + request-timeout: 15s + deprecated-runtimes-score: 100 # defaults to 100 + deprecated-runtimes: + - "nodejs" + - "nodejs4.3" + - "nodejs4.3-edge" + - "nodejs6.10" + - "nodejs8.10" + - "nodejs10.x" + - "nodejs12.x" + - "java8" + - "java8.al2" + - "python2.7" + - "python3.6" + - "dotnetcore1.0" + - "dotnetcore2.0" + - "dotnet6" + - "ruby2.5" + http: + host: 0.0.0.0 + port: 10000 + write-timeout: 10 + read-timeout: 10 + read-header-timeout: 10 + diff --git a/cmd/root.go b/cmd/root.go index 4806055..2ef7efd 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -10,6 +10,8 @@ import ( var ( debug bool configFilePath string + logLevel string + logFormat string ) func InitAndRunCommand() error { @@ -28,7 +30,8 @@ func InitAndRunCommand() error { }, } rootCmd.AddCommand(startCmd) - startCmd.PersistentFlags().BoolVar(&debug, "debug", false, "set log-level to debug") startCmd.PersistentFlags().StringVar(&configFilePath, "config-file", "config/config.yml", "set log-level to debug") + rootCmd.PersistentFlags().StringVarP(&logLevel, "log-level", "v", "info", "Logger log level (debug, info, warn, error)") + rootCmd.PersistentFlags().StringVar(&logFormat, "log-format", "text", "Logger logs format (text, json)") return rootCmd.Execute() } diff --git a/cmd/daemon.go b/cmd/run.go similarity index 67% rename from cmd/daemon.go rename to cmd/run.go index 52ca1aa..dd29017 100644 --- a/cmd/daemon.go +++ b/cmd/run.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "log/slog" "os" "os/signal" "syscall" @@ -13,7 +14,6 @@ import ( "github.com/qonto/upgrade-manager/internal/build" "github.com/qonto/upgrade-manager/internal/infra/http" "github.com/qonto/upgrade-manager/internal/infra/kubernetes" - "go.uber.org/zap" ) func Run() error { @@ -22,18 +22,9 @@ func Run() error { if err != nil { return err } - zapConfig := zap.NewProductionConfig() - if debug { - zapConfig.Level.SetLevel(zap.DebugLevel) - } + + logger := buildLogger(logLevel, logFormat) - logger, err := zapConfig.Build() - if err != nil { - return err - } - defer func() { - err = logger.Sync() - }() logger.Info(build.VersionMessage()) signals := make(chan os.Signal, 1) @@ -87,3 +78,29 @@ func Run() error { exitErr := <-errChan return exitErr } + +func buildLogger(level string, format string) *slog.Logger { + var programLevel = new(slog.LevelVar) + switch level { + case "debug": + programLevel.Set(slog.LevelDebug) + case "info": + programLevel.Set(slog.LevelInfo) + case "warn": + programLevel.Set(slog.LevelWarn) + case "error": + programLevel.Set(slog.LevelError) + default: + programLevel.Set(slog.LevelInfo) + } + + options := &slog.HandlerOptions{Level: programLevel} + switch format { + case "text": + return slog.New(slog.NewTextHandler(os.Stdout, options)) + case "json": + return slog.New(slog.NewJSONHandler(os.Stdout, options)) + default: + return slog.New(slog.NewTextHandler(os.Stdout, options)) + } +} diff --git a/go.mod b/go.mod index 427ee51..83e71c6 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 - go.uber.org/zap v1.26.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.13.3 @@ -141,7 +140,6 @@ require ( go.opentelemetry.io/otel v1.14.0 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - go.uber.org/multierr v1.10.0 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/crypto v0.16.0 // indirect golang.org/x/mod v0.12.0 // indirect diff --git a/go.sum b/go.sum index b0cf1f9..a8b6e62 100644 --- a/go.sum +++ b/go.sum @@ -428,12 +428,6 @@ go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyK go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= diff --git a/internal/app/app.go b/internal/app/app.go index 7457852..0d2a0b1 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -3,6 +3,8 @@ package app import ( "context" "fmt" + "log/slog" + "os" "sync" "time" @@ -27,11 +29,10 @@ import ( "github.com/qonto/upgrade-manager/internal/app/sources/filesystemhelm" "github.com/qonto/upgrade-manager/internal/infra/aws" "github.com/qonto/upgrade-manager/internal/infra/kubernetes" - "go.uber.org/zap" ) type App struct { - log *zap.Logger + log *slog.Logger sources []soft.Source softwares []*soft.Software Config config.Config @@ -56,7 +57,7 @@ type appMetrics struct { loopExecTime prometheus.Gauge } -func New(l *zap.Logger, registry *prometheus.Registry, k8sClient kubernetes.KubernetesClient, config config.Config) (*App, error) { +func New(l *slog.Logger, registry *prometheus.Registry, k8sClient kubernetes.KubernetesClient, config config.Config) (*App, error) { app := &App{ log: l, registry: registry, @@ -97,7 +98,8 @@ func (a *App) InitSources() error { for _, item := range a.Config.Sources.FsHelm { softSource, err := filesystemhelm.NewSource(item, a.log, a.s3Api) if err != nil { - a.log.Fatal(fmt.Sprint(err)) + a.log.Error(fmt.Sprint(err)) + os.Exit(1) } a.sources = append(a.sources, softSource) } @@ -106,8 +108,8 @@ func (a *App) InitSources() error { for _, item := range a.Config.Sources.ArgocdHelm { softSource, err := argohelm.NewSource(item, a.log, a.k8sClient, true, a.s3Api) if err != nil { - a.log.Fatal(fmt.Sprint(err)) - } + a.log.Error(fmt.Sprint(err)) + os.Exit(1) } a.sources = append(a.sources, softSource) } } @@ -115,44 +117,44 @@ func (a *App) InitSources() error { for _, item := range a.Config.Sources.Deployments { softSource, err := deployments.NewSource(a.log, a.k8sClient, item) if err != nil { - a.log.Fatal(fmt.Sprint(err)) - } + a.log.Error(fmt.Sprint(err)) + os.Exit(1) } a.sources = append(a.sources, softSource) } } if a.Config.Sources.Aws.Elasticache.Enabled { escSource, err := elasticacheSource.NewSource(a.escApi, a.log, &a.Config.Sources.Aws.Elasticache) if err != nil { - a.log.Fatal(fmt.Sprint(err)) - } + a.log.Error(fmt.Sprint(err)) + os.Exit(1) } a.sources = append(a.sources, escSource) } if a.Config.Sources.Aws.Eks.Enabled { eksSource, err := eksSource.NewSource(a.eksApi, a.log, &a.Config.Sources.Aws.Eks) if err != nil { - a.log.Fatal(fmt.Sprint(err)) - } + a.log.Error(fmt.Sprint(err)) + os.Exit(1) } a.sources = append(a.sources, eksSource) } if a.Config.Sources.Aws.Msk.Enabled { mskSource, err := mskSource.NewSource(a.mskApi, a.log, &a.Config.Sources.Aws.Msk) if err != nil { - a.log.Fatal(fmt.Sprint(err)) - } + a.log.Error(fmt.Sprint(err)) + os.Exit(1) } a.sources = append(a.sources, mskSource) } if a.Config.Sources.Aws.Rds.Enabled { rdsSource, err := rdsSource.NewSource(a.rdsApi, a.log, &a.Config.Sources.Aws.Rds) if err != nil { - a.log.Fatal(fmt.Sprint(err)) - } + a.log.Error(fmt.Sprint(err)) + os.Exit(1) } a.sources = append(a.sources, rdsSource) } if a.Config.Sources.Aws.Lambda.Enabled { lambdaSource, err := lambdaSource.NewSource(a.lambdaApi, a.log, &a.Config.Sources.Aws.Lambda) if err != nil { - a.log.Fatal(fmt.Sprint(err)) - } + a.log.Error(fmt.Sprint(err)) + os.Exit(1) } a.sources = append(a.sources, lambdaSource) } return nil @@ -222,7 +224,7 @@ func (a *App) InitPrometheusMetrics() error { func (a *App) Start() { interval, err := time.ParseDuration(a.Config.Global.Interval) if err != nil { - a.log.Error("Failed parsing time interval. Using a default interval of 1h", zap.Error(err)) + a.log.Error(fmt.Sprintf("Failed parsing time interval. Using a default interval of 1h, %v", err)) interval = time.Hour } ticker := time.NewTicker(interval) @@ -262,18 +264,18 @@ func (a *App) mainLoop() { // Load here all apps as softwares a.loadSoftwares() a.metrics.successLoads.Add(float64(len(a.softwares))) - a.log.Sugar().Infof("Found %d software(s) in total", len(a.softwares)) + a.log.Info(fmt.Sprintf("Found %d software(s) in total", len(a.softwares))) a.metrics.foundSoftwares.Set(float64(len(a.softwares))) // Process each software for _, software := range a.softwares { - a.log.Debug("computing obsolescence score", zap.String("software", software.Name)) + a.log.Debug("computing obsolescence score", slog.String("software", software.Name)) if err := a.scoreSoftware(software); err != nil { - a.log.Error("failed to compute obsolescence score", zap.String("software", software.Name), zap.String("software_type", string(software.Type))) + a.log.Error("failed to compute obsolescence score", slog.String("software", software.Name), slog.String("software_type", string(software.Type))) a.metrics.processError.WithLabelValues(software.Name, string(software.Type), "1", software.Name, "compute score").Add(1) continue } a.metrics.successComputeScore.Add(1) - a.log.Debug("obsolescence score computed", zap.String("software", software.Name), zap.String("software_type", string(software.Type)), zap.Int("score", software.CalculatedScore)) + a.log.Debug("obsolescence score computed", slog.String("software", software.Name), slog.String("software_type", string(software.Type)), slog.Int("score", software.CalculatedScore)) } // not in reset function because we want to wait as much as possible to avoid empty metrics @@ -291,11 +293,11 @@ func (a *App) loadSoftwares() { for _, source := range a.sources { found, err := source.Load() if err != nil { - a.log.Error("failed to load softwares", zap.Error(err), zap.String("source", source.Name())) + a.log.Error(fmt.Sprintf("failed to load softwares %v", err), slog.String("source", source.Name())) a.metrics.processError.WithLabelValues("", "", "", "", "load software").Add(1) } a.softwares = append(a.softwares, found...) - a.log.Info(fmt.Sprintf("Found %d software(s)", len(found)), zap.String("source", source.Name())) + a.log.Info(fmt.Sprintf("Found %d software(s)", len(found)), slog.String("source", source.Name())) } } @@ -319,13 +321,13 @@ func (a *App) report() { if software.CalculatedScore > 0 { if len(software.VersionCandidates) > 0 { a.metrics.scores.WithLabelValues(software.Name, string(software.Type), software.Version.Version, software.VersionCandidates[0].Version, "1", software.Name, "update").Set(float64(software.CalculatedScore)) - a.log.Debug("--> update: ", zap.String("software", software.Name), zap.String("software_type", string(software.Type)), zap.String("parent", "self"), zap.String("version", software.Version.Version), zap.String("target_version", software.VersionCandidates[0].Version)) + a.log.Debug("--> update: ", slog.String("software", software.Name), slog.String("software_type", string(software.Type)), slog.String("parent", "self"), slog.String("version", software.Version.Version), slog.String("target_version", software.VersionCandidates[0].Version)) } else { for i, dep := range software.Dependencies { if len(dep.VersionCandidates) > 0 { a.metrics.scores.WithLabelValues(software.Name, string(software.Type), software.Version.Version, "", "1", software.Name, "update_dependencies").Set(float64(software.CalculatedScore)) a.metrics.scores.WithLabelValues(dep.Name, string(dep.Type), dep.Version.Version, dep.VersionCandidates[0].Version, "0", software.Name, "update").Set(float64(dep.CalculatedScore)) - a.log.Debug(fmt.Sprintf("--> update %d: ", i+1), zap.String("software", dep.Name), zap.String("software_type", string(dep.Type)), zap.String("parent", software.Name), zap.String("version", dep.Version.Version), zap.String("target_version", dep.VersionCandidates[0].Version)) + a.log.Debug(fmt.Sprintf("--> update %d: ", i+1), slog.String("software", dep.Name), slog.String("software_type", string(dep.Type)), slog.String("parent", software.Name), slog.String("version", dep.Version.Version), slog.String("target_version", dep.VersionCandidates[0].Version)) } } } diff --git a/internal/app/calculators/candidate_count_test.go b/internal/app/calculators/candidate_count_test.go index 48b4196..2dfeaa6 100644 --- a/internal/app/calculators/candidate_count_test.go +++ b/internal/app/calculators/candidate_count_test.go @@ -1,11 +1,11 @@ package calculators import ( + "log/slog" "testing" "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/stretchr/testify/assert" - "go.uber.org/zap" ) func TestCandidateCountCalculateObsolescence(t *testing.T) { @@ -31,7 +31,7 @@ func TestCandidateCountCalculateObsolescence(t *testing.T) { expectedScore: 0 * DefaultPerCandidateScore, }, } - calc := New(zap.NewExample(), software.CandidateCountCalculator, true) + calc := New(slog.Default(), software.CandidateCountCalculator, true) for _, tc := range testCases { t.Run(tc.description, func(t *testing.T) { err := calc.CalculateObsolescenceScore(tc.soft) diff --git a/internal/app/calculators/date_test.go b/internal/app/calculators/date_test.go index 4ccef00..a7939ba 100644 --- a/internal/app/calculators/date_test.go +++ b/internal/app/calculators/date_test.go @@ -1,11 +1,11 @@ package calculators import ( + "log/slog" "testing" "time" s "github.com/qonto/upgrade-manager/internal/app/core/software" - "go.uber.org/zap" ) func TestDateCalculateObsolescenceScore(t *testing.T) { @@ -60,7 +60,7 @@ func TestDateCalculateObsolescenceScore(t *testing.T) { expectedScore: 10, }, } - calculator := New(zap.NewExample(), s.ReleaseDateCalculator, true) + calculator := New(slog.Default(), s.ReleaseDateCalculator, true) for _, tc := range testCases { err := calculator.CalculateObsolescenceScore(tc.software) if err != nil { diff --git a/internal/app/calculators/default.go b/internal/app/calculators/default.go index f463976..5e81d5d 100644 --- a/internal/app/calculators/default.go +++ b/internal/app/calculators/default.go @@ -2,11 +2,11 @@ package calculators import ( "fmt" + "log/slog" goversion "github.com/hashicorp/go-version" soft "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/app/semver" - "go.uber.org/zap" ) const ( @@ -27,7 +27,7 @@ const ( // // z patch versions late = z * 1 type DefaultCalculator struct { - log *zap.Logger + log *slog.Logger scoreTable segmentScoreTable checkDependencies bool } @@ -39,7 +39,7 @@ type segmentScoreTable []int // // NOTE: Should DefaultCalculator be renamed to SemverCalculator // and MetaCalculator be renamed to DefaultCalculator? -func New(logger *zap.Logger, t soft.CalculatorType, checkDependencies bool) soft.Calculator { +func New(logger *slog.Logger, t soft.CalculatorType, checkDependencies bool) soft.Calculator { switch t { //nolint case soft.ReleaseDateCalculator: return &ReleaseDateCalculator{ diff --git a/internal/app/calculators/default_test.go b/internal/app/calculators/default_test.go index e07272e..14abfcd 100644 --- a/internal/app/calculators/default_test.go +++ b/internal/app/calculators/default_test.go @@ -2,10 +2,10 @@ package calculators import ( "fmt" + "log/slog" "testing" s "github.com/qonto/upgrade-manager/internal/app/core/software" - "go.uber.org/zap" ) func TestCalculateObsolescenceScore(t *testing.T) { @@ -46,7 +46,7 @@ func TestCalculateObsolescenceScore(t *testing.T) { } for _, tc := range testCases { fmt.Println(tc.software.Name) - calculator := New(zap.NewExample(), tc.software.Calculator, true) + calculator := New(slog.Default(), tc.software.Calculator, true) err := calculator.CalculateObsolescenceScore(tc.software) if err != nil { t.Fatal(err) diff --git a/internal/app/calculators/meta.go b/internal/app/calculators/meta.go index dac5b04..39d756d 100644 --- a/internal/app/calculators/meta.go +++ b/internal/app/calculators/meta.go @@ -1,14 +1,15 @@ package calculators import ( + "log/slog" + "github.com/qonto/upgrade-manager/internal/app/core/software" - "go.uber.org/zap" ) var calculatorCache = make(map[software.CalculatorType]software.Calculator) type MetaCalculator struct { - log *zap.Logger + log *slog.Logger checkDependencies bool } diff --git a/internal/app/calculators/meta_test.go b/internal/app/calculators/meta_test.go index 30f612b..ca5da2f 100644 --- a/internal/app/calculators/meta_test.go +++ b/internal/app/calculators/meta_test.go @@ -2,10 +2,10 @@ package calculators import ( "fmt" + "log/slog" "testing" s "github.com/qonto/upgrade-manager/internal/app/core/software" - "go.uber.org/zap" ) func TestMetaCalculateObsolescenceScore(t *testing.T) { @@ -37,7 +37,7 @@ func TestMetaCalculateObsolescenceScore(t *testing.T) { } for _, tc := range testCases { fmt.Println(tc.software.Name) - calculator := New(zap.NewExample(), tc.software.Calculator, true) + calculator := New(slog.Default(), tc.software.Calculator, true) err := calculator.CalculateObsolescenceScore(tc.software) if err != nil { t.Fatal(err) diff --git a/internal/app/sources/argohelm/git_credentials.go b/internal/app/sources/argohelm/git_credentials.go index de7a727..6bc622f 100644 --- a/internal/app/sources/argohelm/git_credentials.go +++ b/internal/app/sources/argohelm/git_credentials.go @@ -3,6 +3,7 @@ package argohelm import ( "context" "fmt" + "log/slog" "regexp" "strconv" "time" @@ -11,7 +12,6 @@ import ( "github.com/go-git/go-git/v5/plumbing/transport/ssh" "github.com/qonto/upgrade-manager/internal/app/sources/utils/gitutils" k8sClient "github.com/qonto/upgrade-manager/internal/infra/kubernetes" - "go.uber.org/zap" ) // Retrieve all git credentials in the namespace which have "repo" in their name @@ -21,7 +21,7 @@ import ( // "url: yyyxxx", "username: zzz" // // ssh secrets have "type: ssh", "sshPrivateKey; xxx", "url: yyyxxx" -func getGitRepoConnections(namespace string, r *regexp.Regexp, client k8sClient.KubernetesClient, log *zap.Logger) ([]*gitutils.RepoConnection, error) { +func getGitRepoConnections(namespace string, r *regexp.Regexp, client k8sClient.KubernetesClient, log *slog.Logger) ([]*gitutils.RepoConnection, error) { var connections []*gitutils.RepoConnection ctx, cancel := context.WithTimeout(context.Background(), time.Second*15) defer cancel() diff --git a/internal/app/sources/argohelm/git_credentials_test.go b/internal/app/sources/argohelm/git_credentials_test.go index d64fe86..36308e3 100644 --- a/internal/app/sources/argohelm/git_credentials_test.go +++ b/internal/app/sources/argohelm/git_credentials_test.go @@ -1,18 +1,18 @@ package argohelm import ( + "log/slog" "os" "regexp" "testing" "github.com/qonto/upgrade-manager/internal/infra/kubernetes" - "go.uber.org/zap" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestGetGitCredentialSecretsFromNamespace(t *testing.T) { - log := zap.NewExample() + log := slog.Default() sampleKeyPath := "../../_testdata/fakeSampleKey" f, err := os.ReadFile(sampleKeyPath) if err != nil { diff --git a/internal/app/sources/argohelm/source.go b/internal/app/sources/argohelm/source.go index 82b9aa8..210b5ba 100644 --- a/internal/app/sources/argohelm/source.go +++ b/internal/app/sources/argohelm/source.go @@ -3,6 +3,7 @@ package argohelm import ( "context" "fmt" + "log/slog" "os" "regexp" "strconv" @@ -17,7 +18,6 @@ import ( "github.com/qonto/upgrade-manager/internal/app/sources/utils/gitutils" "github.com/qonto/upgrade-manager/internal/infra/aws" "github.com/qonto/upgrade-manager/internal/infra/kubernetes" - "go.uber.org/zap" "helm.sh/helm/v3/pkg/chart" ) @@ -25,7 +25,7 @@ const ArgoHelm soft.SoftwareType = "argoHelm" type Source struct { k8sClient kubernetes.KubernetesClient - log *zap.Logger + log *slog.Logger gitRepoConnections []*gitutils.RepoConnection cfg Config s3Api aws.S3Api @@ -33,7 +33,7 @@ type Source struct { } // Returns a new argohelm software source -func NewSource(cfg Config, log *zap.Logger, k8sClient kubernetes.KubernetesClient, loadSecretFromNamespace bool, s3Api aws.S3Api) (*Source, error) { +func NewSource(cfg Config, log *slog.Logger, k8sClient kubernetes.KubernetesClient, loadSecretFromNamespace bool, s3Api aws.S3Api) (*Source, error) { if cfg.Filters.SemverVersions == nil { cfg.Filters.SemverVersions = &filters.SemverVersionsConfig{} } diff --git a/internal/app/sources/argohelm/source_test.go b/internal/app/sources/argohelm/source_test.go index f13ec7a..8e20d67 100644 --- a/internal/app/sources/argohelm/source_test.go +++ b/internal/app/sources/argohelm/source_test.go @@ -1,15 +1,15 @@ package argohelm import ( + "log/slog" "testing" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/qonto/upgrade-manager/internal/app/sources/utils/gitutils" - "go.uber.org/zap" ) func TestMatchGitRepoConnection(t *testing.T) { - s := Source{log: zap.NewExample()} + s := Source{log: slog.Default()} s.gitRepoConnections = []*gitutils.RepoConnection{ { Url: "https://github.foo.com/devops/kubernetes-resources/exactmatch.git", diff --git a/internal/app/sources/aws/eks/source.go b/internal/app/sources/aws/eks/source.go index 02375a7..c1897b9 100644 --- a/internal/app/sources/aws/eks/source.go +++ b/internal/app/sources/aws/eks/source.go @@ -3,6 +3,7 @@ package eks import ( "context" "fmt" + "log/slog" "time" "github.com/aws/aws-sdk-go-v2/service/eks" @@ -10,11 +11,10 @@ import ( "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/app/semver" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" ) type Source struct { - log *zap.Logger + log *slog.Logger api aws.EKSApi cfg *Config filter filters.Filter @@ -31,7 +31,7 @@ func (s *Source) Name() string { return "EKS" } -func NewSource(api aws.EKSApi, log *zap.Logger, cfg *Config) (*Source, error) { +func NewSource(api aws.EKSApi, log *slog.Logger, cfg *Config) (*Source, error) { // Current implementation of filters requires this map to be non-nil to filter old versions // so we set RemovePreRelease to true to filter out old versions anyway. // NOTE: this is slightly confusing and should probably be refactored later on diff --git a/internal/app/sources/aws/eks/source_test.go b/internal/app/sources/aws/eks/source_test.go index 739de10..4d8b5f6 100644 --- a/internal/app/sources/aws/eks/source_test.go +++ b/internal/app/sources/aws/eks/source_test.go @@ -2,6 +2,7 @@ package eks import ( "fmt" + "log/slog" "testing" "github.com/aws/aws-sdk-go-v2/aws" @@ -10,7 +11,6 @@ import ( "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/app/filters" awsInfra "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" ) func TestLoad(t *testing.T) { @@ -104,7 +104,7 @@ func TestLoad(t *testing.T) { }, }, ) - src, err := NewSource(mockApi, zap.NewExample(), &Config{ + src, err := NewSource(mockApi, slog.Default(), &Config{ Enabled: true, Filters: filters.Config{ SemverVersions: &filters.SemverVersionsConfig{ diff --git a/internal/app/sources/aws/elasticache/provider.go b/internal/app/sources/aws/elasticache/provider.go index 287b8e9..c7345f4 100644 --- a/internal/app/sources/aws/elasticache/provider.go +++ b/internal/app/sources/aws/elasticache/provider.go @@ -2,6 +2,7 @@ package elasticache import ( "context" + "log/slog" "time" "github.com/aws/aws-sdk-go-v2/service/elasticache" @@ -9,15 +10,14 @@ import ( "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" ) type VersionProvider struct { api aws.ElasticacheApi - log *zap.Logger + log *slog.Logger } -func NewProvider(log *zap.Logger, api aws.ElasticacheApi) (*VersionProvider, error) { +func NewProvider(log *slog.Logger, api aws.ElasticacheApi) (*VersionProvider, error) { return &VersionProvider{ api: api, log: log, diff --git a/internal/app/sources/aws/elasticache/provider_test.go b/internal/app/sources/aws/elasticache/provider_test.go index 8d6078e..288500f 100644 --- a/internal/app/sources/aws/elasticache/provider_test.go +++ b/internal/app/sources/aws/elasticache/provider_test.go @@ -1,12 +1,12 @@ package elasticache import ( + "log/slog" "testing" "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" ) func TestLoad(t *testing.T) { @@ -85,7 +85,7 @@ func TestLoad(t *testing.T) { }, } for idx, tc := range testCases { - vp, err := NewProvider(zap.NewExample(), mockApi) + vp, err := NewProvider(slog.Default(), mockApi) if err != nil { t.Error(err) } diff --git a/internal/app/sources/aws/elasticache/source.go b/internal/app/sources/aws/elasticache/source.go index e421050..f36d3ea 100644 --- a/internal/app/sources/aws/elasticache/source.go +++ b/internal/app/sources/aws/elasticache/source.go @@ -3,17 +3,17 @@ package elasticache import ( "context" "fmt" + "log/slog" "time" "github.com/aws/aws-sdk-go-v2/service/elasticache" "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" ) type Source struct { - log *zap.Logger + log *slog.Logger api aws.ElasticacheApi cfg *Config vp *VersionProvider @@ -30,7 +30,7 @@ func (s *Source) Name() string { return "elasticache" } -func NewSource(api aws.ElasticacheApi, log *zap.Logger, cfg *Config) (*Source, error) { +func NewSource(api aws.ElasticacheApi, log *slog.Logger, cfg *Config) (*Source, error) { // Current implementation of filters requires this map to be non-nil to filter old versions // so we set RemovePreRelease to true to filter out old versions anyway. // NOTE: this is slightly confusing and should probably be refactored later on diff --git a/internal/app/sources/aws/elasticache/source_test.go b/internal/app/sources/aws/elasticache/source_test.go index e8894f0..961b791 100644 --- a/internal/app/sources/aws/elasticache/source_test.go +++ b/internal/app/sources/aws/elasticache/source_test.go @@ -1,11 +1,11 @@ package elasticache import ( + "log/slog" "testing" "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" ) func TestSourceLoad(t *testing.T) { @@ -28,7 +28,7 @@ func TestSourceLoad(t *testing.T) { }, } for idx, tc := range testCases { - source, err := NewSource(mockApi, zap.NewExample(), tc.cfg) + source, err := NewSource(mockApi, slog.Default(), tc.cfg) if err != nil { t.Error(err) } diff --git a/internal/app/sources/aws/lambda/source.go b/internal/app/sources/aws/lambda/source.go index a45c9b9..a58f192 100644 --- a/internal/app/sources/aws/lambda/source.go +++ b/internal/app/sources/aws/lambda/source.go @@ -2,17 +2,17 @@ package lambda import ( "context" + "log/slog" "time" "github.com/aws/aws-sdk-go-v2/service/lambda" "github.com/aws/aws-sdk-go-v2/service/lambda/types" "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" ) type Source struct { - log *zap.Logger + log *slog.Logger api aws.LambdaApi cfg *Config } @@ -27,7 +27,7 @@ func (s *Source) Name() string { return "lambda" } -func NewSource(api aws.LambdaApi, log *zap.Logger, cfg *Config) (*Source, error) { +func NewSource(api aws.LambdaApi, log *slog.Logger, cfg *Config) (*Source, error) { return &Source{ api: api, log: log, @@ -114,7 +114,7 @@ func (s *Source) Load() ([]*software.Software, error) { soft.VersionCandidates[i], soft.VersionCandidates[j] = soft.VersionCandidates[j], soft.VersionCandidates[i] } - s.log.Info("Tracking software", zap.String("software", soft.Name), zap.String("software_type", string(soft.Type))) + s.log.Info("Tracking software", slog.String("software", soft.Name), slog.String("software_type", string(soft.Type))) softwares = append(softwares, soft) } return softwares, nil diff --git a/internal/app/sources/aws/lambda/source_test.go b/internal/app/sources/aws/lambda/source_test.go index 693adc9..81c34e4 100644 --- a/internal/app/sources/aws/lambda/source_test.go +++ b/internal/app/sources/aws/lambda/source_test.go @@ -2,6 +2,7 @@ package lambda import ( "errors" + "log/slog" "testing" "github.com/aws/aws-sdk-go-v2/service/lambda" @@ -11,7 +12,6 @@ import ( "github.com/qonto/upgrade-manager/internal/infra/aws" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "go.uber.org/zap" ) func TestLoad(t *testing.T) { @@ -107,7 +107,7 @@ func TestLoad(t *testing.T) { testCases[i].BuildMock = defaultBuildMock } testCases[i].BuildMock(mockApi) - source, err := NewSource(mockApi, zap.NewExample(), testCases[i].Config) + source, err := NewSource(mockApi, slog.Default(), testCases[i].Config) assert.NoError(t, err) softwares, err := source.Load() diff --git a/internal/app/sources/aws/msk/source.go b/internal/app/sources/aws/msk/source.go index e759d0e..616941d 100644 --- a/internal/app/sources/aws/msk/source.go +++ b/internal/app/sources/aws/msk/source.go @@ -2,6 +2,7 @@ package msk import ( "context" + "log/slog" "strings" "time" @@ -9,12 +10,11 @@ import ( "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" ) type Source struct { api aws.MSKApi - log *zap.Logger + log *slog.Logger cfg *Config filter filters.Filter } @@ -28,7 +28,7 @@ func (s *Source) Name() string { return "MSK" } -func NewSource(api aws.MSKApi, log *zap.Logger, cfg *Config) (*Source, error) { +func NewSource(api aws.MSKApi, log *slog.Logger, cfg *Config) (*Source, error) { cfg.Filters = filters.Config{ SemverVersions: &filters.SemverVersionsConfig{ RemovePreRelease: true, diff --git a/internal/app/sources/aws/msk/source_test.go b/internal/app/sources/aws/msk/source_test.go index 78b9d99..5c06c06 100644 --- a/internal/app/sources/aws/msk/source_test.go +++ b/internal/app/sources/aws/msk/source_test.go @@ -1,6 +1,7 @@ package msk import ( + "log/slog" "testing" "github.com/aws/aws-sdk-go-v2/service/kafka" @@ -8,7 +9,6 @@ import ( "github.com/qonto/upgrade-manager/internal/app/sources/utils" "github.com/qonto/upgrade-manager/internal/infra/aws" "github.com/stretchr/testify/mock" - "go.uber.org/zap" ) func TestLoad(t *testing.T) { @@ -38,7 +38,7 @@ func TestLoad(t *testing.T) { }, }, }) - source, err := NewSource(api, zap.NewExample(), &Config{}) + source, err := NewSource(api, slog.Default(), &Config{}) if err != nil { t.Error(err) } diff --git a/internal/app/sources/aws/rds/source.go b/internal/app/sources/aws/rds/source.go index 0c7c626..96af5c2 100644 --- a/internal/app/sources/aws/rds/source.go +++ b/internal/app/sources/aws/rds/source.go @@ -3,18 +3,18 @@ package rds import ( "context" "fmt" + "log/slog" "time" "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" ) type Source struct { api aws.RDSApi - log *zap.Logger + log *slog.Logger cfg *Config filter filters.Filter engineToSoftTypeMapping map[string]software.SoftwareType @@ -36,7 +36,7 @@ func (s *Source) Name() string { return "RDS" } -func NewSource(api aws.RDSApi, log *zap.Logger, cfg *Config) (*Source, error) { +func NewSource(api aws.RDSApi, log *slog.Logger, cfg *Config) (*Source, error) { mapping := map[string]software.SoftwareType{ "aurora-mysql": RdsAuroraMySQL, "aurora-postgresql": RdsAuroraPostgreSQL, diff --git a/internal/app/sources/aws/rds/source_test.go b/internal/app/sources/aws/rds/source_test.go index 1f6409f..6fe8656 100644 --- a/internal/app/sources/aws/rds/source_test.go +++ b/internal/app/sources/aws/rds/source_test.go @@ -1,13 +1,13 @@ package rds import ( + "log/slog" "testing" "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/aws/aws-sdk-go-v2/service/rds/types" "github.com/qonto/upgrade-manager/internal/infra/aws" "github.com/stretchr/testify/assert" - "go.uber.org/zap" ) func TestLoad(t *testing.T) { @@ -58,7 +58,7 @@ func TestLoad(t *testing.T) { }, } for _, tc := range tcases { - src, err := NewSource(api, zap.NewExample(), tc.cfg) + src, err := NewSource(api, slog.Default(), tc.cfg) if err != nil { t.Error(err) } diff --git a/internal/app/sources/deployments/source.go b/internal/app/sources/deployments/source.go index 46f1380..ad9eace 100644 --- a/internal/app/sources/deployments/source.go +++ b/internal/app/sources/deployments/source.go @@ -3,6 +3,7 @@ package deployments import ( "context" "fmt" + "log/slog" "strings" "time" @@ -12,7 +13,6 @@ import ( "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/infra/kubernetes" "github.com/qonto/upgrade-manager/internal/infra/registry" - "go.uber.org/zap" ) const ( @@ -25,7 +25,7 @@ type Source struct { k8sClient kubernetes.KubernetesClient defaultRegistryClient *registry.Client registryClients map[string]*registry.Client - log *zap.Logger + log *slog.Logger cfg Config filter filters.Filter } @@ -35,7 +35,7 @@ func (s *Source) Name() string { return "deployments" } -func NewSource(log *zap.Logger, k8sClient kubernetes.KubernetesClient, cfg Config) (*Source, error) { +func NewSource(log *slog.Logger, k8sClient kubernetes.KubernetesClient, cfg Config) (*Source, error) { filter := filters.Build(cfg.Filters) s := &Source{ log: log, diff --git a/internal/app/sources/deployments/source_test.go b/internal/app/sources/deployments/source_test.go index b23db28..1001af0 100644 --- a/internal/app/sources/deployments/source_test.go +++ b/internal/app/sources/deployments/source_test.go @@ -1,13 +1,13 @@ package deployments import ( + "log/slog" "testing" "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/infra/kubernetes" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "go.uber.org/zap" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -47,7 +47,7 @@ func TestLoad(t *testing.T) { }, }, nil) - source, err := NewSource(zap.NewExample(), k8sMock, Config{}) + source, err := NewSource(slog.Default(), k8sMock, Config{}) assert.NoError(t, err) softwares, err := source.Load() assert.NoError(t, err) diff --git a/internal/app/sources/filesystemhelm/source.go b/internal/app/sources/filesystemhelm/source.go index c049a41..f982b83 100644 --- a/internal/app/sources/filesystemhelm/source.go +++ b/internal/app/sources/filesystemhelm/source.go @@ -2,12 +2,12 @@ package filesystemhelm import ( "fmt" + "log/slog" soft "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/app/sources/helm/versions" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" "helm.sh/helm/v3/pkg/chart" ) @@ -15,13 +15,13 @@ const FileSystemHelm soft.SoftwareType = "filesystemHelm" type Source struct { Charts []chart.Chart - log *zap.Logger + log *slog.Logger cfg Config s3Api aws.S3Api filter filters.Filter } -func NewSource(cfg Config, log *zap.Logger, s3Api aws.S3Api) (*Source, error) { +func NewSource(cfg Config, log *slog.Logger, s3Api aws.S3Api) (*Source, error) { if cfg.Filters.SemverVersions == nil { cfg.Filters.SemverVersions = &filters.SemverVersionsConfig{} } diff --git a/internal/app/sources/filesystemhelm/source_test.go b/internal/app/sources/filesystemhelm/source_test.go index c1435fb..0a1907d 100644 --- a/internal/app/sources/filesystemhelm/source_test.go +++ b/internal/app/sources/filesystemhelm/source_test.go @@ -2,12 +2,12 @@ package filesystemhelm import ( "fmt" + "log/slog" "os" "testing" "github.com/qonto/upgrade-manager/internal/infra/aws" "github.com/stretchr/testify/mock" - "go.uber.org/zap" ) func TestLoadSoftware(t *testing.T) { @@ -31,7 +31,7 @@ func TestLoadSoftware(t *testing.T) { s3mock := new(aws.S3Mock) s3mock.On("GetObject", mock.Anything).Return(indexFile, nil) - s, err := NewSource(cfg, zap.NewExample(), s3mock) + s, err := NewSource(cfg, slog.Default(), s3mock) if err != nil { t.Fatalf("Error with NewSource(): %s", err) } diff --git a/internal/app/sources/helm/versions/repo_backend.go b/internal/app/sources/helm/versions/repo_backend.go index 2c2bc49..13ad44c 100644 --- a/internal/app/sources/helm/versions/repo_backend.go +++ b/internal/app/sources/helm/versions/repo_backend.go @@ -4,12 +4,12 @@ import ( "context" "fmt" "io" + "log/slog" "net/url" "regexp" "time" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" "helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/getter" "helm.sh/helm/v3/pkg/repo" @@ -70,7 +70,7 @@ func getRepoBackendType(repoUrl string) (RepoBackendType, error) { return "", fmt.Errorf("could not determine RepoBackendType for url %s", repoUrl) } -func buildRepoBackend(repoURL string, chartName string, log *zap.Logger, s3Api aws.S3Api) (RepoBackend, error) { +func buildRepoBackend(repoURL string, chartName string, log *slog.Logger, s3Api aws.S3Api) (RepoBackend, error) { repoType, err := getRepoBackendType(repoURL) if err != nil { return nil, err diff --git a/internal/app/sources/helm/versions/versions.go b/internal/app/sources/helm/versions/versions.go index 2a78400..7a711bb 100644 --- a/internal/app/sources/helm/versions/versions.go +++ b/internal/app/sources/helm/versions/versions.go @@ -5,6 +5,7 @@ import ( "compress/gzip" "context" "fmt" + "log/slog" "net/url" "strings" "time" @@ -13,12 +14,11 @@ import ( soft "github.com/qonto/upgrade-manager/internal/app/core/software" "github.com/qonto/upgrade-manager/internal/app/filters" "github.com/qonto/upgrade-manager/internal/infra/aws" - "go.uber.org/zap" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/repo" ) -func PopulateTopLevelSoftware(s3Api aws.S3Api, log *zap.Logger, topLevelSoftware *soft.Software, repoURL string, chartName string, filter filters.Filter) error { +func PopulateTopLevelSoftware(s3Api aws.S3Api, log *slog.Logger, topLevelSoftware *soft.Software, repoURL string, chartName string, filter filters.Filter) error { log.Debug(fmt.Sprintf("Populate top level software for chart %s repo backend %s", chartName, repoURL)) repoBackend, err := buildRepoBackend(repoURL, chartName, log, s3Api) if err != nil { @@ -34,7 +34,7 @@ func PopulateTopLevelSoftware(s3Api aws.S3Api, log *zap.Logger, topLevelSoftware return nil } -func PopulateSoftwareDependencies(s3Api aws.S3Api, log *zap.Logger, topLevelSoftware *soft.Software, chart *chart.Chart, st soft.SoftwareType, filter filters.Filter) error { +func PopulateSoftwareDependencies(s3Api aws.S3Api, log *slog.Logger, topLevelSoftware *soft.Software, chart *chart.Chart, st soft.SoftwareType, filter filters.Filter) error { softwareDependencies := []*soft.Software{} for _, dependency := range chart.Metadata.Dependencies { var depName string @@ -71,7 +71,7 @@ func PopulateSoftwareDependencies(s3Api aws.S3Api, log *zap.Logger, topLevelSoft return nil } -func computeSoftwareVersions(repoBackend RepoBackend, chartName string, s *soft.Software, filter filters.Filter, log *zap.Logger) error { +func computeSoftwareVersions(repoBackend RepoBackend, chartName string, s *soft.Software, filter filters.Filter, log *slog.Logger) error { index, err := repoBackend.getIndexFile() if err != nil { return err diff --git a/internal/infra/http/server.go b/internal/infra/http/server.go index 6dbe202..2a104c5 100644 --- a/internal/infra/http/server.go +++ b/internal/infra/http/server.go @@ -3,6 +3,7 @@ package http import ( "context" "fmt" + "log/slog" "net/http" "os" "sync" @@ -11,7 +12,6 @@ import ( "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" - "go.uber.org/zap" ) type Config struct { @@ -25,7 +25,7 @@ type Config struct { type HTTPServer struct { server *http.Server Engine *gin.Engine - logger *zap.Logger + logger *slog.Logger wg sync.WaitGroup registry *prometheus.Registry @@ -37,7 +37,7 @@ func healthz(context *gin.Context) { context.JSON(200, "ok") } -func New(registry *prometheus.Registry, logger *zap.Logger, config Config) (*HTTPServer, error) { +func New(registry *prometheus.Registry, logger *slog.Logger, config Config) (*HTTPServer, error) { var defaultTimeout int = 10 engine := gin.New() address := fmt.Sprintf("%s:%d", config.Host, config.Port) diff --git a/internal/infra/kubernetes/argocd_test.go b/internal/infra/kubernetes/argocd_test.go index cb7264a..f3cdff0 100644 --- a/internal/infra/kubernetes/argocd_test.go +++ b/internal/infra/kubernetes/argocd_test.go @@ -2,9 +2,9 @@ package kubernetes import ( "context" + "log/slog" "testing" - "go.uber.org/zap" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/dynamic/fake" @@ -100,7 +100,7 @@ func TestRawToArgoApplication(t *testing.T) { } func TestListArgoApplications(t *testing.T) { - log := zap.NewExample() + log := slog.Default() testCases := []map[string]any{ { "kind": "Application", diff --git a/internal/infra/kubernetes/client.go b/internal/infra/kubernetes/client.go index 34a6bbd..ab5cf1c 100644 --- a/internal/infra/kubernetes/client.go +++ b/internal/infra/kubernetes/client.go @@ -3,10 +3,10 @@ package kubernetes import ( "context" "fmt" + "log/slog" "os" "path/filepath" - "go.uber.org/zap" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" "k8s.io/client-go/dynamic" @@ -19,7 +19,7 @@ import ( type Client struct { dynamicClient dynamic.Interface kubernetesClient kubernetes.Interface - logger *zap.Logger + logger *slog.Logger } type KubernetesClient interface { @@ -28,7 +28,7 @@ type KubernetesClient interface { ListDeployments(ctx context.Context, request ListRequest) (*appsv1.DeploymentList, error) } -func NewClient(logger *zap.Logger) (*Client, error) { +func NewClient(logger *slog.Logger) (*Client, error) { var config *rest.Config var err error