github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/rollout-service/pkg/service/service.go (about) 1 /*This file is part of kuberpult. 2 3 Kuberpult is free software: you can redistribute it and/or modify 4 it under the terms of the Expat(MIT) License as published by 5 the Free Software Foundation. 6 7 Kuberpult is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 MIT License for more details. 11 12 You should have received a copy of the MIT License 13 along with kuberpult. If not, see <https://directory.fsf.org/wiki/License:Expat>. 14 15 Copyright 2023 freiheit.com*/ 16 17 package service 18 19 import ( 20 "context" 21 "fmt" 22 23 "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" 24 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" 25 "github.com/argoproj/gitops-engine/pkg/health" 26 "github.com/freiheit-com/kuberpult/pkg/logger" 27 "github.com/freiheit-com/kuberpult/pkg/setup" 28 "github.com/freiheit-com/kuberpult/services/rollout-service/pkg/versions" 29 "go.uber.org/zap" 30 "google.golang.org/grpc" 31 "google.golang.org/grpc/codes" 32 "google.golang.org/grpc/status" 33 ) 34 35 // this is a simpler version of ApplicationServiceClient from the application package 36 type SimplifiedApplicationServiceClient interface { 37 Watch(ctx context.Context, qry *application.ApplicationQuery, opts ...grpc.CallOption) (application.ApplicationService_WatchClient, error) 38 } 39 40 // type assertion 41 var ( 42 _ SimplifiedApplicationServiceClient = (application.ApplicationServiceClient)(nil) 43 ) 44 45 type ArgoEventProcessor interface { 46 ProcessArgoEvent(ctx context.Context, ev ArgoEvent) 47 } 48 49 func ConsumeEvents(ctx context.Context, appClient SimplifiedApplicationServiceClient, dispatcher *Dispatcher, hlth *setup.HealthReporter) error { 50 return hlth.Retry(ctx, func() error { 51 //exhaustruct:ignore 52 watch, err := appClient.Watch(ctx, &application.ApplicationQuery{}) 53 if err != nil { 54 if status.Code(err) == codes.Canceled { 55 // context is cancelled -> we are shutting down 56 return setup.Permanent(nil) 57 } 58 return fmt.Errorf("watching applications: %w", err) 59 } 60 hlth.ReportReady("consuming events") 61 for { 62 ev, err := watch.Recv() 63 if err != nil { 64 if status.Code(err) == codes.Canceled { 65 // context is cancelled -> we are shutting down 66 return setup.Permanent(nil) 67 } 68 return err 69 } 70 environment, application := getEnvironmentAndName(ev.Application.Annotations) 71 if application == "" { 72 continue 73 } 74 k := Key{Application: application, Environment: environment} 75 switch ev.Type { 76 case "ADDED", "MODIFIED", "DELETED": 77 dispatcher.Dispatch(ctx, k, ev) 78 case "BOOKMARK": 79 // ignore this event 80 default: 81 logger.FromContext(ctx).Warn("argocd.application.unknown_type", zap.String("event.type", string(ev.Type))) 82 } 83 } 84 }) 85 } 86 87 func getEnvironmentAndName(annotations map[string]string) (string, string) { 88 return annotations["com.freiheit.kuberpult/environment"], annotations["com.freiheit.kuberpult/application"] 89 } 90 91 type ArgoEvent struct { 92 Environment string 93 Application string 94 SyncStatusCode v1alpha1.SyncStatusCode 95 HealthStatusCode health.HealthStatusCode 96 OperationState *v1alpha1.OperationState 97 Version *versions.VersionInfo 98 }