-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
150 lines (128 loc) · 3.79 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package main
import (
"context"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"keptn/git-promotion-service/pkg/handler"
"log"
"os"
"os/signal"
"sync"
"syscall"
cloudevents "github.com/cloudevents/sdk-go/v2"
"github.com/kelseyhightower/envconfig"
logger "github.com/sirupsen/logrus"
api "github.com/keptn/go-utils/pkg/api/utils"
keptnapi "github.com/keptn/go-utils/pkg/api/utils"
keptncommon "github.com/keptn/go-utils/pkg/lib/keptn"
keptnv2 "github.com/keptn/go-utils/pkg/lib/v0_2_0"
)
const envVarLogLevel = "LOG_LEVEL"
type envConfig struct {
// Port on which to listen for cloudevents
Port int `envconfig:"RCV_PORT" default:"8080"`
Path string `envconfig:"RCV_PATH" default:"/"`
}
// Opaque key type used for graceful shutdown context value
type gracefulShutdownKeyType struct{}
var gracefulShutdownKey = gracefulShutdownKeyType{}
func main() {
logger.SetLevel(logger.InfoLevel)
logger.Printf("Starting keptn git promotion service")
if os.Getenv(envVarLogLevel) != "" {
logLevel, err := logger.ParseLevel(os.Getenv(envVarLogLevel))
if err != nil {
logger.WithError(err).Error("could not parse log level provided by 'LOG_LEVEL' env var")
} else {
logger.SetLevel(logLevel)
}
}
var env envConfig
if err := envconfig.Process("", &env); err != nil {
log.Fatalf("Failed to process env var: %s", err)
}
os.Exit(_main(os.Args[1:], env))
}
func _main(args []string, env envConfig) int {
ctx := getGracefulContext()
p, err := cloudevents.NewHTTP(cloudevents.WithPath(env.Path), cloudevents.WithPort(env.Port), cloudevents.WithGetHandlerFunc(keptnapi.HealthEndpointHandler))
if err != nil {
log.Fatalf("failed to create client, %v", err)
}
c, err := cloudevents.NewClient(p)
if err != nil {
log.Fatalf("failed to create client, %v", err)
}
log.Fatal(c.StartReceiver(ctx, gotEvent))
return 0
}
func gotEvent(ctx context.Context, event cloudevents.Event) error {
ctx.Value(gracefulShutdownKey).(*sync.WaitGroup).Add(1)
val := ctx.Value(gracefulShutdownKey)
if val != nil {
if wg, ok := val.(*sync.WaitGroup); ok {
wg.Add(1)
}
}
go switchEvent(ctx, event)
return nil
}
func switchEvent(ctx context.Context, event cloudevents.Event) {
defer func() {
val := ctx.Value(gracefulShutdownKey)
if val == nil {
return
}
if wg, ok := val.(*sync.WaitGroup); ok {
wg.Done()
}
}()
keptnHandlerV2, err := keptnv2.NewKeptn(&event, keptncommon.KeptnOpts{})
if err != nil {
logger.WithError(err).Error("failed to initialize Keptn handler")
return
}
apiSet, err := api.New(os.Getenv("API_BASE_URL"), api.WithAuthToken(os.Getenv("API_AUTH_TOKEN")))
if err != nil {
logger.WithError(err).Error("failed to initialize API Set")
return
}
config, err := rest.InClusterConfig()
if err != nil {
logger.WithError(err).Error("failed to initialize kube client rest")
return
}
kubeAPI, err := kubernetes.NewForConfig(config)
if err != nil {
logger.WithError(err).Error("failed to initialize kube client config")
return
}
handlers := []handler.Handler{
handler.NewGitPromotionTriggeredEventHandler(keptnHandlerV2, apiSet, kubeAPI),
}
unhandled := true
for _, currHandler := range handlers {
if currHandler.IsTypeHandled(event) {
unhandled = false
currHandler.Handle(event, keptnHandlerV2)
}
}
if unhandled {
logger.Debugf("Received unexpected keptn event type %s", event.Type())
}
}
func getGracefulContext() context.Context {
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
wg := &sync.WaitGroup{}
ctx, cancel := context.WithCancel(context.WithValue(context.Background(), gracefulShutdownKey, wg))
ctx = cloudevents.WithEncodingStructured(ctx)
go func() {
<-ch
logger.Fatal("Container termination triggered, starting graceful shutdown")
wg.Wait()
logger.Fatal("cancelling context")
cancel()
}()
return ctx
}