Skip to content

Commit 38f42b2

Browse files
chore: panic middleware and proxy handler (#4546)
* initial commit * removed from hyperion * changes * added trace * pr comments * pg timeouts * panic message constant * cleaning up * common lib version * argo assets revert * adding image scanner proxy route * common-lib-update
1 parent 7b71af7 commit 38f42b2

Some content is hidden

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

48 files changed

+435
-242
lines changed

App.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"context"
2222
"crypto/tls"
2323
"fmt"
24+
"github.com/devtron-labs/common-lib/middlewares"
2425
"log"
2526
"net/http"
2627
"os"
@@ -101,6 +102,8 @@ func (app *App) Start() {
101102
server := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: authMiddleware.Authorizer(app.sessionManager2, user.WhitelistChecker)(app.MuxRouter.Router)}
102103
app.MuxRouter.Router.Use(app.loggingMiddleware.LoggingMiddleware)
103104
app.MuxRouter.Router.Use(middleware.PrometheusMiddleware)
105+
app.MuxRouter.Router.Use(middlewares.Recovery)
106+
104107
if tracerProvider != nil {
105108
app.MuxRouter.Router.Use(otelmux.Middleware(otel.OTEL_ORCHESTRASTOR_SERVICE_NAME))
106109
}

Wire.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import (
6565
"github.com/devtron-labs/devtron/client/grafana"
6666
jClient "github.com/devtron-labs/devtron/client/jira"
6767
"github.com/devtron-labs/devtron/client/lens"
68+
"github.com/devtron-labs/devtron/client/proxy"
6869
"github.com/devtron-labs/devtron/client/telemetry"
6970
"github.com/devtron-labs/devtron/internal/sql/repository"
7071
app2 "github.com/devtron-labs/devtron/internal/sql/repository/app"
@@ -145,6 +146,7 @@ func InitializeApp() (*App, error) {
145146
sso.SsoConfigWireSet,
146147
cluster.ClusterWireSet,
147148
dashboard.DashboardWireSet,
149+
proxy.ProxyWireSet,
148150
client.HelmAppWireSet,
149151
k8s.K8sApplicationWireSet,
150152
chartRepo.ChartRepositoryWireSet,

api/cluster/EnvironmentRestHandler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ type EnvironmentRestHandlerImpl struct {
6666
validator *validator.Validate
6767
enforcer casbin.Enforcer
6868
deleteService delete2.DeleteService
69-
k8sUtil *k8s2.K8sUtil
69+
k8sUtil *k8s2.K8sServiceImpl
7070
cfg *bean.Config
7171
}
7272

@@ -75,7 +75,7 @@ type ClusterReachableResponse struct {
7575
ClusterName string `json:"clusterName"`
7676
}
7777

78-
func NewEnvironmentRestHandlerImpl(svc request.EnvironmentService, logger *zap.SugaredLogger, userService user.UserService, validator *validator.Validate, enforcer casbin.Enforcer, deleteService delete2.DeleteService, k8sUtil *k8s2.K8sUtil, k8sCommonService k8s.K8sCommonService) *EnvironmentRestHandlerImpl {
78+
func NewEnvironmentRestHandlerImpl(svc request.EnvironmentService, logger *zap.SugaredLogger, userService user.UserService, validator *validator.Validate, enforcer casbin.Enforcer, deleteService delete2.DeleteService, k8sUtil *k8s2.K8sServiceImpl, k8sCommonService k8s.K8sCommonService) *EnvironmentRestHandlerImpl {
7979
cfg := &bean.Config{}
8080
err := env.Parse(cfg)
8181
if err != nil {

api/helm-app/HelmAppService.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ type HelmAppServiceImpl struct {
8484
installedAppRepository repository.InstalledAppRepository
8585
appRepository app.AppRepository
8686
clusterRepository clusterRepository.ClusterRepository
87-
K8sUtil *k8s.K8sUtil
87+
K8sUtil *k8s.K8sServiceImpl
8888
helmReleaseConfig *HelmReleaseConfig
8989
}
9090

@@ -94,7 +94,7 @@ func NewHelmAppServiceImpl(Logger *zap.SugaredLogger, clusterService cluster.Clu
9494
appStoreApplicationVersionRepository appStoreDiscoverRepository.AppStoreApplicationVersionRepository,
9595
environmentService cluster.EnvironmentService, pipelineRepository pipelineConfig.PipelineRepository,
9696
installedAppRepository repository.InstalledAppRepository, appRepository app.AppRepository,
97-
clusterRepository clusterRepository.ClusterRepository, K8sUtil *k8s.K8sUtil,
97+
clusterRepository clusterRepository.ClusterRepository, K8sUtil *k8s.K8sServiceImpl,
9898
helmReleaseConfig *HelmReleaseConfig) *HelmAppServiceImpl {
9999
return &HelmAppServiceImpl{
100100
logger: Logger,

api/router/router.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
webhookHelm "github.com/devtron-labs/devtron/api/webhook/helm"
4343
"github.com/devtron-labs/devtron/client/cron"
4444
"github.com/devtron-labs/devtron/client/dashboard"
45+
"github.com/devtron-labs/devtron/client/proxy"
4546
"github.com/devtron-labs/devtron/client/telemetry"
4647
"github.com/devtron-labs/devtron/pkg/terminal"
4748
"github.com/devtron-labs/devtron/util"
@@ -90,6 +91,7 @@ type MuxRouter struct {
9091
policyRouter PolicyRouter
9192
gitOpsConfigRouter GitOpsConfigRouter
9293
dashboardRouter dashboard.DashboardRouter
94+
proxyRouter proxy.ProxyRouter
9395
attributesRouter AttributesRouter
9496
userAttributesRouter UserAttributesRouter
9597
commonRouter CommonRouter
@@ -153,7 +155,8 @@ func NewMuxRouter(logger *zap.SugaredLogger, HelmRouter PipelineTriggerRouter, P
153155
jobRouter JobRouter, ciStatusUpdateCron cron.CiStatusUpdateCron, resourceGroupingRouter ResourceGroupingRouter,
154156
rbacRoleRouter user.RbacRoleRouter,
155157
scopedVariableRouter ScopedVariableRouter,
156-
ciTriggerCron cron.CiTriggerCron) *MuxRouter {
158+
ciTriggerCron cron.CiTriggerCron,
159+
proxyRouter proxy.ProxyRouter) *MuxRouter {
157160
r := &MuxRouter{
158161
Router: mux.NewRouter(),
159162
HelmRouter: HelmRouter,
@@ -194,6 +197,7 @@ func NewMuxRouter(logger *zap.SugaredLogger, HelmRouter PipelineTriggerRouter, P
194197
attributesRouter: attributesRouter,
195198
userAttributesRouter: userAttributesRouter,
196199
dashboardRouter: dashboardRouter,
200+
proxyRouter: proxyRouter,
197201
commonRouter: commonRouter,
198202
grafanaRouter: grafanaRouter,
199203
ssoLoginRouter: ssoLoginRouter,
@@ -357,6 +361,9 @@ func (r MuxRouter) Init() {
357361
dashboardRouter := r.Router.PathPrefix("/dashboard").Subrouter()
358362
r.dashboardRouter.InitDashboardRouter(dashboardRouter)
359363

364+
proxyRouter := r.Router.PathPrefix("/proxy").Subrouter()
365+
r.proxyRouter.InitProxyRouter(proxyRouter)
366+
360367
grafanaRouter := r.Router.PathPrefix("/grafana").Subrouter()
361368
r.grafanaRouter.initGrafanaRouter(grafanaRouter)
362369

client/dashboard/Config.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package dashboard
22

3-
import "github.com/caarlos0/env"
3+
import (
4+
"github.com/caarlos0/env"
5+
)
46

57
type Config struct {
68
Host string `env:"DASHBOARD_HOST" envDefault:"localhost"`

client/dashboard/DashboardRouter.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package dashboard
22

33
import (
44
"fmt"
5+
"github.com/devtron-labs/devtron/client/proxy"
56
"github.com/google/wire"
67
"github.com/gorilla/mux"
78
"go.uber.org/zap"
@@ -31,7 +32,7 @@ func NewDashboardRouterImpl(logger *zap.SugaredLogger, dashboardCfg *Config) *Da
3132
ExpectContinueTimeout: 1 * time.Second,
3233
},
3334
}
34-
dashboardProxy := NewDashboardHTTPReverseProxy(fmt.Sprintf("http://%s:%s", dashboardCfg.Host, dashboardCfg.Port), client.Transport)
35+
dashboardProxy := proxy.NewDashboardHTTPReverseProxy(fmt.Sprintf("http://%s:%s", dashboardCfg.Host, dashboardCfg.Port), client.Transport)
3536
router := &DashboardRouterImpl{
3637
dashboardProxy: dashboardProxy,
3738
logger: logger,

client/dashboard/proxy.go

Lines changed: 0 additions & 73 deletions
This file was deleted.

client/proxy/Proxy.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package proxy
2+
3+
import (
4+
"fmt"
5+
"github.com/devtron-labs/devtron/api/restHandler/common"
6+
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
7+
"log"
8+
"net/http"
9+
"net/http/httputil"
10+
"net/url"
11+
"strings"
12+
)
13+
14+
const Dashboard = "dashboard"
15+
const Proxy = "proxy"
16+
17+
func NewDashboardHTTPReverseProxy(serverAddr string, transport http.RoundTripper) func(writer http.ResponseWriter, request *http.Request) {
18+
proxy := GetProxyServer(serverAddr, transport, Dashboard)
19+
return func(w http.ResponseWriter, r *http.Request) {
20+
proxy.ServeHTTP(w, r)
21+
}
22+
}
23+
24+
func GetProxyServer(serverAddr string, transport http.RoundTripper, pathToExclude string) *httputil.ReverseProxy {
25+
target, err := url.Parse(serverAddr)
26+
if err != nil {
27+
log.Fatal(err)
28+
}
29+
proxy := httputil.NewSingleHostReverseProxy(target)
30+
proxy.Transport = transport
31+
proxy.Director = func(request *http.Request) {
32+
path := request.URL.Path
33+
request.URL.Host = target.Host
34+
request.URL.Scheme = target.Scheme
35+
request.URL.Path = rewriteRequestUrl(path, pathToExclude)
36+
fmt.Printf("%s\n", request.URL.Path)
37+
}
38+
return proxy
39+
}
40+
41+
func rewriteRequestUrl(path string, pathToExclude string) string {
42+
parts := strings.Split(path, "/")
43+
var finalParts []string
44+
for _, part := range parts {
45+
if part == pathToExclude {
46+
continue
47+
}
48+
finalParts = append(finalParts, part)
49+
}
50+
return strings.Join(finalParts, "/")
51+
}
52+
53+
func NewHTTPReverseProxy(serverAddr string, transport http.RoundTripper, enforcer casbin.Enforcer) func(writer http.ResponseWriter, request *http.Request) {
54+
proxy := GetProxyServer(serverAddr, transport, Proxy)
55+
return func(w http.ResponseWriter, r *http.Request) {
56+
57+
token := r.Header.Get("token")
58+
if ok := enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
59+
common.WriteJsonResp(w, nil, "Unauthorized User", http.StatusForbidden)
60+
return
61+
}
62+
proxy.ServeHTTP(w, r)
63+
}
64+
}

client/proxy/ProxyRouter.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package proxy
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"github.com/caarlos0/env"
7+
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
8+
"github.com/gorilla/mux"
9+
"go.uber.org/zap"
10+
"net"
11+
"net/http"
12+
"time"
13+
)
14+
15+
type ProxyRouter interface {
16+
InitProxyRouter(router *mux.Router)
17+
}
18+
19+
type ProxyConnection struct {
20+
Host string `json:"host"`
21+
Port string `json:"port"`
22+
}
23+
24+
type Config struct {
25+
ProxyServiceConfig string `env:"PROXY_SERVICE_CONFIG" envDefault:""`
26+
}
27+
28+
func GetProxyConfig() (*Config, error) {
29+
cfg := &Config{}
30+
err := env.Parse(cfg)
31+
return cfg, err
32+
}
33+
34+
type ProxyRouterImpl struct {
35+
logger *zap.SugaredLogger
36+
proxy map[string]func(writer http.ResponseWriter, request *http.Request)
37+
}
38+
39+
func NewProxyRouterImpl(logger *zap.SugaredLogger, proxyCfg *Config, enforcer casbin.Enforcer) *ProxyRouterImpl {
40+
client := &http.Client{
41+
Transport: &http.Transport{
42+
Proxy: http.ProxyFromEnvironment,
43+
Dial: (&net.Dialer{
44+
Timeout: 120 * time.Second,
45+
KeepAlive: 120 * time.Second,
46+
}).Dial,
47+
TLSHandshakeTimeout: 10 * time.Second,
48+
ExpectContinueTimeout: 1 * time.Second,
49+
},
50+
}
51+
proxyConnection := make(map[string]ProxyConnection)
52+
err := json.Unmarshal([]byte(proxyCfg.ProxyServiceConfig), &proxyConnection)
53+
if err != nil {
54+
logger.Warnw("bad env value for PROXY_SERVICE_CONFIG", "err", err)
55+
}
56+
57+
proxy := make(map[string]func(writer http.ResponseWriter, request *http.Request))
58+
for s, connection := range proxyConnection {
59+
proxy[s] = NewHTTPReverseProxy(fmt.Sprintf("http://%s:%s", connection.Host, connection.Port), client.Transport, enforcer)
60+
}
61+
62+
router := &ProxyRouterImpl{
63+
proxy: proxy,
64+
logger: logger,
65+
}
66+
return router
67+
}
68+
69+
func (router ProxyRouterImpl) InitProxyRouter(ProxyRouter *mux.Router) {
70+
71+
ProxyRouter.PathPrefix("/kubelink").HandlerFunc(router.proxy["kubelink"])
72+
ProxyRouter.PathPrefix("/gitsensor").HandlerFunc(router.proxy["gitsensor"])
73+
ProxyRouter.PathPrefix("/kubewatch").HandlerFunc(router.proxy["kubewatch"])
74+
ProxyRouter.PathPrefix("/image-scanner").HandlerFunc(router.proxy["image-scanner"])
75+
}

client/proxy/wireset.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package proxy
2+
3+
import "github.com/google/wire"
4+
5+
var ProxyWireSet = wire.NewSet(
6+
GetProxyConfig,
7+
NewProxyRouterImpl,
8+
wire.Bind(new(ProxyRouter), new(*ProxyRouterImpl)),
9+
)

client/telemetry/TelemetryEventClient.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type TelemetryEventClientImpl struct {
4444
logger *zap.SugaredLogger
4545
client *http.Client
4646
clusterService cluster.ClusterService
47-
K8sUtil *k8s.K8sUtil
47+
K8sUtil *k8s.K8sServiceImpl
4848
aCDAuthConfig *util3.ACDAuthConfig
4949
userService user2.UserService
5050
attributeRepo repository.AttributesRepository
@@ -68,7 +68,7 @@ type TelemetryEventClient interface {
6868
}
6969

7070
func NewTelemetryEventClientImpl(logger *zap.SugaredLogger, client *http.Client, clusterService cluster.ClusterService,
71-
K8sUtil *k8s.K8sUtil, aCDAuthConfig *util3.ACDAuthConfig, userService user2.UserService,
71+
K8sUtil *k8s.K8sServiceImpl, aCDAuthConfig *util3.ACDAuthConfig, userService user2.UserService,
7272
attributeRepo repository.AttributesRepository, ssoLoginService sso.SSOLoginService,
7373
PosthogClient *PosthogClient, moduleRepository moduleRepo.ModuleRepository, serverDataStore *serverDataStore.ServerDataStore, userAuditService user2.UserAuditService, helmAppClient client.HelmAppClient, InstalledAppRepository repository2.InstalledAppRepository) (*TelemetryEventClientImpl, error) {
7474
cron := cron.New(

client/telemetry/TelemetryEventClientExtended.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ type TelemetryEventClientImplExtended struct {
4848
}
4949

5050
func NewTelemetryEventClientImplExtended(logger *zap.SugaredLogger, client *http.Client, clusterService cluster.ClusterService,
51-
K8sUtil *util2.K8sUtil, aCDAuthConfig *util3.ACDAuthConfig,
51+
K8sUtil *util2.K8sServiceImpl, aCDAuthConfig *util3.ACDAuthConfig,
5252
environmentService cluster.EnvironmentService, userService user2.UserService,
5353
appListingRepository repository.AppListingRepository, PosthogClient *PosthogClient,
5454
ciPipelineRepository pipelineConfig.CiPipelineRepository, pipelineRepository pipelineConfig.PipelineRepository,

0 commit comments

Comments
 (0)