Skip to content

Commit 65b33aa

Browse files
authored
Merge pull request #5 from devtron-labs/webhook_integration
feat: Webhook integration in CI
2 parents 5d52733 + 8fc0bb1 commit 65b33aa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+6425
-51
lines changed

App.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ package main
1818

1919
import (
2020
"context"
21+
"fmt"
2122
"github.com/devtron-labs/git-sensor/api"
2223
"github.com/devtron-labs/git-sensor/internal/middleware"
2324
"github.com/devtron-labs/git-sensor/pkg/git"
24-
"fmt"
2525
"github.com/go-pg/pg"
2626
"github.com/gorilla/handlers"
2727
"github.com/nats-io/stan"

Gopkg.lock

+25
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,7 @@
7474

7575
[[constraint]]
7676
name = "github.com/prometheus/client_golang"
77-
version = "1.1.0"
77+
version = "1.1.0"
78+
[[constraint]]
79+
name = "github.com/tidwall/gjson"
80+
version = "1.8.0"

api/RestHandler.go

+70-3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
package api
1818

1919
import (
20+
"encoding/json"
2021
"github.com/devtron-labs/git-sensor/internal/sql"
2122
"github.com/devtron-labs/git-sensor/pkg"
2223
"github.com/devtron-labs/git-sensor/pkg/git"
23-
"encoding/json"
2424
"github.com/gorilla/mux"
2525
"go.uber.org/zap"
2626
"net/http"
@@ -40,16 +40,20 @@ type RestHandler interface {
4040
GetChangesInRelease(w http.ResponseWriter, r *http.Request)
4141
GetCommitInfoForTag(w http.ResponseWriter, r *http.Request)
4242
RefreshGitMaterial(w http.ResponseWriter, r *http.Request)
43+
GetWebhookData(w http.ResponseWriter, r *http.Request)
44+
GetAllWebhookEventConfigForHost(w http.ResponseWriter, r *http.Request)
45+
GetWebhookEventConfig(w http.ResponseWriter, r *http.Request)
4346
}
4447

4548
func NewRestHandlerImpl(repositoryManager pkg.RepoManager, logger *zap.SugaredLogger) *RestHandlerImpl {
4649
return &RestHandlerImpl{repositoryManager: repositoryManager, logger: logger}
4750
}
4851

4952
type RestHandlerImpl struct {
50-
repositoryManager pkg.RepoManager
51-
logger *zap.SugaredLogger
53+
repositoryManager pkg.RepoManager
54+
logger *zap.SugaredLogger
5255
}
56+
5357
type Response struct {
5458
Code int `json:"code,omitempty"`
5559
Status string `json:"status,omitempty"`
@@ -235,6 +239,8 @@ func (handler RestHandlerImpl) GetCommitMetadata(w http.ResponseWriter, r *http.
235239
var commits *git.GitCommit
236240
if len(material.GitTag) > 0 {
237241
commits, err = handler.repositoryManager.GetCommitInfoForTag(material)
242+
} else if len(material.BranchName) > 0 {
243+
commits, err = handler.repositoryManager.GetLatestCommitForBranch(material.PipelineMaterialId, material.BranchName)
238244
} else {
239245
commits, err = handler.repositoryManager.GetCommitMetadata(material.PipelineMaterialId, material.GitHash)
240246
}
@@ -299,3 +305,64 @@ func (handler RestHandlerImpl) RefreshGitMaterial(w http.ResponseWriter, r *http
299305
handler.writeJsonResp(w, err, resp, http.StatusOK)
300306
}
301307
}
308+
309+
func (handler RestHandlerImpl) GetWebhookData(w http.ResponseWriter, r *http.Request) {
310+
handler.logger.Debug("GetWebhookData API call")
311+
decoder := json.NewDecoder(r.Body)
312+
request := &git.WebhookDataRequest{}
313+
err := decoder.Decode(request)
314+
if err != nil {
315+
handler.logger.Errorw("error in decoding request of GetWebhookData ", "err", err)
316+
handler.writeJsonResp(w, err, nil, http.StatusBadRequest)
317+
return
318+
}
319+
handler.logger.Debugw("webhook data request ", "req", request)
320+
webhookData, err := handler.repositoryManager.GetWebhookDataById(request.Id)
321+
322+
if err != nil {
323+
handler.writeJsonResp(w, err, nil, http.StatusInternalServerError)
324+
} else {
325+
handler.writeJsonResp(w, err, webhookData, http.StatusOK)
326+
}
327+
}
328+
329+
func (handler RestHandlerImpl) GetAllWebhookEventConfigForHost(w http.ResponseWriter, r *http.Request) {
330+
handler.logger.Debug("GetAllWebhookEventConfigForHost API call")
331+
decoder := json.NewDecoder(r.Body)
332+
request := &git.WebhookEventConfigRequest{}
333+
err := decoder.Decode(request)
334+
if err != nil {
335+
handler.logger.Errorw("error in decoding request of GetAllWebhookEventConfigForHost ", "err", err)
336+
handler.writeJsonResp(w, err, nil, http.StatusBadRequest)
337+
return
338+
}
339+
handler.logger.Infow("webhook event config request ", "req", request)
340+
341+
webhookEventConfigArr, err := handler.repositoryManager.GetAllWebhookEventConfigForHost(request.GitHostId)
342+
if err != nil {
343+
handler.writeJsonResp(w, err, nil, http.StatusInternalServerError)
344+
} else {
345+
handler.writeJsonResp(w, err, webhookEventConfigArr, http.StatusOK)
346+
}
347+
}
348+
349+
func (handler RestHandlerImpl) GetWebhookEventConfig(w http.ResponseWriter, r *http.Request) {
350+
handler.logger.Debug("GetWebhookEventConfig API call")
351+
decoder := json.NewDecoder(r.Body)
352+
request := &git.WebhookEventConfigRequest{}
353+
err := decoder.Decode(request)
354+
if err != nil {
355+
handler.logger.Errorw("error in decoding request of GetWebhookEventConfig ", "err", err)
356+
handler.writeJsonResp(w, err, nil, http.StatusBadRequest)
357+
return
358+
}
359+
handler.logger.Infow("webhook event config request ", "req", request)
360+
361+
webhookEventConfig, err := handler.repositoryManager.GetWebhookEventConfig(request.EventId)
362+
if err != nil {
363+
handler.writeJsonResp(w, err, nil, http.StatusInternalServerError)
364+
} else {
365+
handler.writeJsonResp(w, err, webhookEventConfig, http.StatusOK)
366+
}
367+
368+
}

api/Router.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
package api
1818

1919
import (
20-
"github.com/devtron-labs/git-sensor/util"
2120
"encoding/json"
21+
"github.com/devtron-labs/git-sensor/util"
2222
"github.com/gorilla/mux"
23+
"github.com/prometheus/client_golang/prometheus/promhttp"
2324
"go.uber.org/zap"
2425
"net/http"
25-
"github.com/prometheus/client_golang/prometheus/promhttp"
2626
)
2727

2828
type MuxRouter struct {
@@ -70,4 +70,8 @@ func (r MuxRouter) Init() {
7070
r.Router.Path("/admin/reload/{materialId}").HandlerFunc(r.restHandler.ReloadMaterial).Methods("POST")
7171

7272
r.Router.Path("/release/changes").HandlerFunc(r.restHandler.GetChangesInRelease).Methods("POST")
73+
74+
r.Router.Path("/webhook/data").HandlerFunc(r.restHandler.GetWebhookData).Methods("GET")
75+
r.Router.Path("/webhook/host/events").HandlerFunc(r.restHandler.GetAllWebhookEventConfigForHost).Methods("GET")
76+
r.Router.Path("/webhook/host/event").HandlerFunc(r.restHandler.GetWebhookEventConfig).Methods("GET")
7377
}

internal/NatsClient.go

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
const (
2727
NEW_CI_MATERIAL_TOPIC = "GIT-SENSOR.NEW-CI-MATERIAL" //{publisher-app-name}-{topic-name}
2828
POLL_CI_TOPIC ="GIT-SENSOR.PULL"
29+
WEBHOOK_EVENT_TOPIC = "ORCHESTRATOR.WEBHOOK_EVENT"
2930
)
3031

3132
type PubSubConfig struct {

internal/sql/CiPipelineMaterial.go

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type CiPipelineMaterial struct {
3838
ErrorMsg string `sql:"error_msg,notnull"`
3939
}
4040

41+
4142
type CiPipelineMaterialRepository interface {
4243
FindByGitMaterialId(gitMaterialId int) ([]*CiPipelineMaterial, error)
4344
Update(material []*CiPipelineMaterial) error

internal/sql/GitMaterial.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const (
2828
SOURCE_TYPE_BRANCH_FIXED SourceType = "SOURCE_TYPE_BRANCH_FIXED"
2929
SOURCE_TYPE_BRANCH_REGEX SourceType = "SOURCE_TYPE_BRANCH_REGEX"
3030
SOURCE_TYPE_TAG_ANY SourceType = "SOURCE_TYPE_TAG_ANY"
31-
SOURCE_TYPE_TAG_REGEX SourceType = "SOURCE_TYPE_TAG_REGEX"
31+
SOURCE_TYPE_WEBHOOK SourceType = "WEBHOOK"
3232
)
3333

3434
//TODO: add support for submodule
@@ -57,6 +57,7 @@ type MaterialRepository interface {
5757
Save(material *GitMaterial) error
5858
FindActive() ([]*GitMaterial, error)
5959
FindAll() ([]*GitMaterial, error)
60+
FindAllActiveByUrls(urls []string) ([]*GitMaterial, error)
6061
}
6162
type MaterialRepositoryImpl struct {
6263
dbConnection *pg.DB
@@ -108,3 +109,15 @@ func (repo MaterialRepositoryImpl) FindById(id int) (*GitMaterial, error) {
108109
Select()
109110
return &material, err
110111
}
112+
113+
func (repo MaterialRepositoryImpl) FindAllActiveByUrls(urls[] string) ([]*GitMaterial, error) {
114+
var materials []*GitMaterial
115+
err := repo.dbConnection.Model(&materials).
116+
Relation("CiPipelineMaterials", func(q *orm.Query) (*orm.Query, error) {
117+
return q.Where("active IS TRUE"), nil
118+
}).
119+
Where("deleted =? ", false).
120+
Where("url in (?) ", pg.In(urls)).
121+
Select()
122+
return materials, err
123+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) 2020 Devtron Labs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package sql
18+
19+
import (
20+
"github.com/devtron-labs/git-sensor/util"
21+
"github.com/go-pg/pg"
22+
)
23+
24+
type CiPipelineMaterialWebhookDataMapping struct {
25+
tableName struct{} `sql:"ci_pipeline_material_webhook_data_mapping"`
26+
Id int `sql:"id,pk"`
27+
CiPipelineMaterialId int `sql:"ci_pipeline_material_id"`
28+
WebhookDataId int `sql:"webhook_data_id"`
29+
ConditionMatched bool `sql:"condition_matched,notnull"`
30+
}
31+
32+
type WebhookEventDataMappingRepository interface {
33+
GetCiPipelineMaterialWebhookDataMapping(ciPipelineMaterialId int, webhookParsedDataId int) (*CiPipelineMaterialWebhookDataMapping, error)
34+
SaveCiPipelineMaterialWebhookDataMapping(ciPipelineMaterialWebhookDataMapping *CiPipelineMaterialWebhookDataMapping) error
35+
UpdateCiPipelineMaterialWebhookDataMapping(ciPipelineMaterialWebhookDataMapping *CiPipelineMaterialWebhookDataMapping) error
36+
GetCiPipelineMaterialWebhookDataMappingForPipelineMaterial(ciPipelineMaterialId int) ([]*CiPipelineMaterialWebhookDataMapping, error)
37+
}
38+
39+
type WebhookEventDataMappingRepositoryImpl struct {
40+
dbConnection *pg.DB
41+
}
42+
43+
func NewWebhookEventDataMappingRepositoryImpl(dbConnection *pg.DB) *WebhookEventDataMappingRepositoryImpl {
44+
return &WebhookEventDataMappingRepositoryImpl{dbConnection: dbConnection}
45+
}
46+
47+
func (impl WebhookEventDataMappingRepositoryImpl) GetCiPipelineMaterialWebhookDataMapping(ciPipelineMaterialId int, webhookParsedDataId int) (*CiPipelineMaterialWebhookDataMapping, error) {
48+
var mapping CiPipelineMaterialWebhookDataMapping
49+
err := impl.dbConnection.Model(&mapping).
50+
Where("ci_pipeline_material_id =? ", ciPipelineMaterialId).
51+
Where("webhook_data_id =? ", webhookParsedDataId).
52+
Select()
53+
54+
if err != nil {
55+
if util.IsErrNoRows(err) {
56+
return nil, nil
57+
}
58+
return nil, err
59+
}
60+
61+
return &mapping, nil
62+
}
63+
64+
func (impl WebhookEventDataMappingRepositoryImpl) SaveCiPipelineMaterialWebhookDataMapping(ciPipelineMaterialWebhookDataMapping *CiPipelineMaterialWebhookDataMapping) error {
65+
_, err := impl.dbConnection.Model(ciPipelineMaterialWebhookDataMapping).Insert()
66+
return err
67+
}
68+
69+
func (impl WebhookEventDataMappingRepositoryImpl) UpdateCiPipelineMaterialWebhookDataMapping(ciPipelineMaterialWebhookDataMapping *CiPipelineMaterialWebhookDataMapping) error {
70+
_, err := impl.dbConnection.Model(ciPipelineMaterialWebhookDataMapping).WherePK().Update()
71+
return err
72+
}
73+
74+
func (impl WebhookEventDataMappingRepositoryImpl) GetCiPipelineMaterialWebhookDataMappingForPipelineMaterial(ciPipelineMaterialId int) ([]*CiPipelineMaterialWebhookDataMapping, error) {
75+
var pipelineMaterials []*CiPipelineMaterialWebhookDataMapping
76+
err := impl.dbConnection.Model(&pipelineMaterials).
77+
Where("ci_pipeline_material_id =? ", ciPipelineMaterialId).
78+
Select()
79+
80+
if err != nil {
81+
if util.IsErrNoRows(err) {
82+
return nil, nil
83+
}
84+
return nil, err
85+
}
86+
87+
return pipelineMaterials, nil
88+
}

0 commit comments

Comments
 (0)