Skip to content

Commit 47bc404

Browse files
committed
Merge branch 'main' into fix-argocd-rbac-kubelink
2 parents c457551 + 2c6ed70 commit 47bc404

File tree

91 files changed

+2540
-726
lines changed

Some content is hidden

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

91 files changed

+2540
-726
lines changed

CHANGELOG/release-notes-v0.6.17.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## v0.6.17
2+
3+
## Bugs
4+
- fix: app metrics dynamically enabled based on support (#3369)
5+
- fix: 404 not found in devtron without cicd app list page (#3439)
6+
- fix: Build context backward compatability (#3408)
7+
- fix: updated audit info for cd pipeline delete req (#3404)
8+
## Enhancements
9+
- feat: Rotate pods feature (#3420)
10+
## Documentation
11+
- docs: how to refresh the argocd certificate (#3364)
12+
13+
14+

Wire.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ func InitializeApp() (*App, error) {
585585
wire.Bind(new(security2.CveStoreRepository), new(*security2.CveStoreRepositoryImpl)),
586586
security2.NewImageScanDeployInfoRepositoryImpl,
587587
wire.Bind(new(security2.ImageScanDeployInfoRepository), new(*security2.ImageScanDeployInfoRepositoryImpl)),
588+
security2.NewScanToolMetadataRepositoryImpl,
589+
wire.Bind(new(security2.ScanToolMetadataRepository), new(*security2.ScanToolMetadataRepositoryImpl)),
588590
router.NewPolicyRouterImpl,
589591
wire.Bind(new(router.PolicyRouter), new(*router.PolicyRouterImpl)),
590592
restHandler.NewPolicyRestHandlerImpl,
@@ -593,6 +595,8 @@ func InitializeApp() (*App, error) {
593595
wire.Bind(new(security.PolicyService), new(*security.PolicyServiceImpl)),
594596
security2.NewPolicyRepositoryImpl,
595597
wire.Bind(new(security2.CvePolicyRepository), new(*security2.CvePolicyRepositoryImpl)),
598+
security2.NewScanToolExecutionHistoryMappingRepositoryImpl,
599+
wire.Bind(new(security2.ScanToolExecutionHistoryMappingRepository), new(*security2.ScanToolExecutionHistoryMappingRepositoryImpl)),
596600

597601
argocdServer.NewArgoK8sClientImpl,
598602
wire.Bind(new(argocdServer.ArgoK8sClient), new(*argocdServer.ArgoK8sClientImpl)),

api/bean/ClusterInfo.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package bean
22

33
type ClusterInfo struct {
4-
ClusterId int `json:"clusterId"`
5-
ClusterName string `json:"clusterName"`
6-
BearerToken string `json:"bearerToken"`
7-
ServerUrl string `json:"serverUrl"`
4+
ClusterId int `json:"clusterId"`
5+
ClusterName string `json:"clusterName"`
6+
BearerToken string `json:"bearerToken"`
7+
ServerUrl string `json:"serverUrl"`
8+
InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify"`
9+
KeyData string `json:"keyData"`
10+
CertData string `json:"certData"`
11+
CAData string `json:"CAData"`
812
}

api/cluster/ClusterRestHandler.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const CLUSTER_DELETE_SUCCESS_RESP = "Cluster deleted successfully."
4343

4444
type ClusterRestHandler interface {
4545
Save(w http.ResponseWriter, r *http.Request)
46+
SaveClusters(w http.ResponseWriter, r *http.Request)
47+
ValidateKubeconfig(w http.ResponseWriter, r *http.Request)
4648
FindAll(w http.ResponseWriter, r *http.Request)
4749
FindById(w http.ResponseWriter, r *http.Request)
4850
FindNoteByClusterId(w http.ResponseWriter, r *http.Request)
@@ -92,6 +94,81 @@ func NewClusterRestHandlerImpl(clusterService cluster.ClusterService,
9294
}
9395
}
9496

97+
func (impl ClusterRestHandlerImpl) SaveClusters(w http.ResponseWriter, r *http.Request) {
98+
token := r.Header.Get("token")
99+
decoder := json.NewDecoder(r.Body)
100+
userId, err := impl.userService.GetLoggedInUser(r)
101+
if userId == 0 || err != nil {
102+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
103+
return
104+
}
105+
beans := []*cluster.ClusterBean{}
106+
err = decoder.Decode(&beans)
107+
if err != nil {
108+
impl.logger.Errorw("request err, Save", "error", err, "payload", beans)
109+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
110+
return
111+
}
112+
// not logging bean object as it contains sensitive data
113+
impl.logger.Infow("request payload received for save clusters")
114+
115+
// RBAC enforcer applying
116+
isSuperAdmin, err := impl.userService.IsSuperAdmin(int(userId))
117+
if !isSuperAdmin || err != nil {
118+
if err != nil {
119+
impl.logger.Errorw("request err, CheckSuperAdmin", "err", err, "isSuperAdmin", isSuperAdmin)
120+
}
121+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
122+
return
123+
}
124+
//RBAC enforcer Ends
125+
ctx, cancel := context.WithCancel(r.Context())
126+
if cn, ok := w.(http.CloseNotifier); ok {
127+
go func(done <-chan struct{}, closed <-chan bool) {
128+
select {
129+
case <-done:
130+
case <-closed:
131+
cancel()
132+
}
133+
}(ctx.Done(), cn.CloseNotify())
134+
}
135+
if util2.IsBaseStack() {
136+
ctx = context.WithValue(ctx, "token", token)
137+
} else {
138+
acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken()
139+
if err != nil {
140+
impl.logger.Errorw("error in getting acd token", "err", err)
141+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
142+
return
143+
}
144+
ctx = context.WithValue(ctx, "token", acdToken)
145+
}
146+
147+
for _, bean := range beans {
148+
l := len(bean.ServerUrl)
149+
if l > 1 && bean.ServerUrl[l-1:] == "/" {
150+
bean.ServerUrl = bean.ServerUrl[0 : l-1]
151+
}
152+
if bean.Id != 0 {
153+
_, err1 := impl.clusterService.Update(ctx, bean, userId)
154+
if err1 != nil {
155+
bean.ErrorInConnecting = err1.Error()
156+
} else {
157+
bean.ClusterUpdated = true
158+
}
159+
} else {
160+
_, err1 := impl.clusterService.Save(ctx, bean, userId)
161+
if err1 != nil {
162+
bean.ErrorInConnecting = err1.Error()
163+
}
164+
}
165+
}
166+
167+
res := beans
168+
169+
common.WriteJsonResp(w, err, res, http.StatusOK)
170+
}
171+
95172
func (impl ClusterRestHandlerImpl) Save(w http.ResponseWriter, r *http.Request) {
96173
token := r.Header.Get("token")
97174
decoder := json.NewDecoder(r.Body)
@@ -161,6 +238,66 @@ func (impl ClusterRestHandlerImpl) Save(w http.ResponseWriter, r *http.Request)
161238
common.WriteJsonResp(w, err, bean, http.StatusOK)
162239
}
163240

241+
func (impl ClusterRestHandlerImpl) ValidateKubeconfig(w http.ResponseWriter, r *http.Request) {
242+
token := r.Header.Get("token")
243+
decoder := json.NewDecoder(r.Body)
244+
userId, err := impl.userService.GetLoggedInUser(r)
245+
if userId == 0 || err != nil {
246+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
247+
return
248+
}
249+
bean := &cluster.Kubeconfig{}
250+
err = decoder.Decode(bean)
251+
if err != nil {
252+
impl.logger.Errorw("request err, Validate", "error", err, "payload", bean)
253+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
254+
return
255+
}
256+
257+
err = impl.validator.Struct(bean)
258+
if err != nil {
259+
impl.logger.Errorw("validation err, Validate", "err", err, "payload", bean)
260+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
261+
return
262+
}
263+
264+
// RBAC enforcer applying
265+
if ok := impl.enforcer.Enforce(token, casbin.ResourceCluster, casbin.ActionCreate, "*"); !ok {
266+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
267+
return
268+
}
269+
//RBAC enforcer Ends
270+
ctx, cancel := context.WithCancel(r.Context())
271+
if cn, ok := w.(http.CloseNotifier); ok {
272+
go func(done <-chan struct{}, closed <-chan bool) {
273+
select {
274+
case <-done:
275+
case <-closed:
276+
cancel()
277+
}
278+
}(ctx.Done(), cn.CloseNotify())
279+
}
280+
if util2.IsBaseStack() {
281+
ctx = context.WithValue(ctx, "token", token)
282+
} else {
283+
acdToken, err := impl.argoUserService.GetLatestDevtronArgoCdUserToken()
284+
if err != nil {
285+
impl.logger.Errorw("error in getting acd token", "err", err)
286+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
287+
return
288+
}
289+
ctx = context.WithValue(ctx, "token", acdToken)
290+
}
291+
res, err := impl.clusterService.ValidateKubeconfig(bean.Config)
292+
if err != nil {
293+
impl.logger.Errorw("error in validating kubeconfig")
294+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
295+
return
296+
}
297+
298+
common.WriteJsonResp(w, err, res, http.StatusOK)
299+
}
300+
164301
func (impl ClusterRestHandlerImpl) FindAll(w http.ResponseWriter, r *http.Request) {
165302
token := r.Header.Get("token")
166303
clusterList, err := impl.clusterService.FindAllWithoutConfig()

api/cluster/ClusterRouter.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ func (impl ClusterRouterImpl) InitClusterRouter(clusterRouter *mux.Router) {
4040
Methods("POST").
4141
HandlerFunc(impl.clusterRestHandler.Save)
4242

43+
clusterRouter.Path("/saveClusters").
44+
Methods("POST").
45+
HandlerFunc(impl.clusterRestHandler.SaveClusters)
46+
47+
clusterRouter.Path("/validate").
48+
Methods("POST").
49+
HandlerFunc(impl.clusterRestHandler.ValidateKubeconfig)
50+
4351
clusterRouter.Path("").
4452
Methods("GET").
4553
Queries("id", "{id}").

api/helm-app/HelmAppService.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (impl *HelmAppServiceImpl) listApplications(ctx context.Context, clusterIds
140140
for _, clusterDetail := range clusters {
141141
config := &ClusterConfig{
142142
ApiServerUrl: clusterDetail.ServerUrl,
143-
Token: clusterDetail.Config["bearer_token"],
143+
Token: clusterDetail.Config[util.BearerToken],
144144
ClusterId: int32(clusterDetail.Id),
145145
ClusterName: clusterDetail.ClusterName,
146146
}
@@ -265,7 +265,7 @@ func (impl *HelmAppServiceImpl) GetClusterConf(clusterId int) (*ClusterConfig, e
265265
}
266266
config := &ClusterConfig{
267267
ApiServerUrl: cluster.ServerUrl,
268-
Token: cluster.Config["bearer_token"],
268+
Token: cluster.Config[util.BearerToken],
269269
ClusterId: int32(cluster.Id),
270270
ClusterName: cluster.ClusterName,
271271
}

api/module/ModuleRestHandler.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type ModuleRestHandler interface {
3434
GetModuleInfo(w http.ResponseWriter, r *http.Request)
3535
GetModuleConfig(w http.ResponseWriter, r *http.Request)
3636
HandleModuleAction(w http.ResponseWriter, r *http.Request)
37+
EnableModule(w http.ResponseWriter, r *http.Request)
3738
}
3839

3940
type ModuleRestHandlerImpl struct {
@@ -164,3 +165,46 @@ func (impl ModuleRestHandlerImpl) HandleModuleAction(w http.ResponseWriter, r *h
164165
}
165166
common.WriteJsonResp(w, err, res, http.StatusOK)
166167
}
168+
169+
func (impl ModuleRestHandlerImpl) EnableModule(w http.ResponseWriter, r *http.Request) {
170+
// check if user is logged in or not
171+
userId, err := impl.userService.GetLoggedInUser(r)
172+
if userId == 0 || err != nil {
173+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
174+
return
175+
}
176+
177+
// check query param
178+
params := mux.Vars(r)
179+
moduleName := params["name"]
180+
if len(moduleName) == 0 {
181+
impl.logger.Error("module name is not supplied")
182+
common.WriteJsonResp(w, errors.New("module name is not supplied"), nil, http.StatusBadRequest)
183+
return
184+
}
185+
// decode request
186+
decoder := json.NewDecoder(r.Body)
187+
var moduleEnableRequestDto module.ModuleEnableRequestDto
188+
err = decoder.Decode(&moduleEnableRequestDto)
189+
if err != nil {
190+
impl.logger.Errorw("error in decoding request in ModuleEnableRequestDto", "err", err)
191+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
192+
return
193+
}
194+
195+
// handle super-admin RBAC
196+
token := r.Header.Get("token")
197+
if ok := impl.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
198+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
199+
return
200+
}
201+
202+
// service call
203+
res, err := impl.moduleService.EnableModule(moduleName, moduleEnableRequestDto.Version)
204+
if err != nil {
205+
impl.logger.Errorw("service err, Enabling Module", "err", err, "moduleName", moduleName, "toolVersion", moduleEnableRequestDto.Version)
206+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
207+
return
208+
}
209+
common.WriteJsonResp(w, err, res, http.StatusOK)
210+
}

api/module/ModuleRouter.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ func (impl ModuleRouterImpl) Init(configRouter *mux.Router) {
2121
configRouter.Path("").HandlerFunc(impl.moduleRestHandler.GetModuleInfo).Methods("GET")
2222
configRouter.Path("/config").HandlerFunc(impl.moduleRestHandler.GetModuleConfig).Queries("name", "{name}").Methods("GET")
2323
configRouter.Path("").HandlerFunc(impl.moduleRestHandler.HandleModuleAction).Queries("name", "{name}").Methods("POST")
24+
configRouter.Path("/enable").HandlerFunc(impl.moduleRestHandler.EnableModule).Queries("name", "{name}").Methods("POST")
2425
}

api/restHandler/PipelineTriggerRestHandler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ func (handler PipelineTriggerRestHandlerImpl) OverrideConfig(w http.ResponseWrit
128128
}
129129
ctx := context.WithValue(r.Context(), "token", acdToken)
130130
_, span := otel.Tracer("orchestrator").Start(ctx, "workflowDagExecutor.ManualCdTrigger")
131-
mergeResp, _, err := handler.workflowDagExecutor.ManualCdTrigger(&overrideRequest, ctx)
131+
mergeResp, err := handler.workflowDagExecutor.ManualCdTrigger(&overrideRequest, ctx)
132132
span.End()
133133
if err != nil {
134134
handler.logger.Errorw("request err, OverrideConfig", "err", err, "payload", overrideRequest)

charts/devtron/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
apiVersion: v2
22
name: devtron-operator
3-
appVersion: 0.6.16
3+
appVersion: 0.6.18-rc.0
44
description: Chart to configure and install Devtron. Devtron is a Kubernetes Orchestration system.
55
keywords:
66
- Devtron
@@ -11,7 +11,7 @@ keywords:
1111
- argocd
1212
- Hyperion
1313
engine: gotpl
14-
version: 0.22.55
14+
version: 0.22.56
1515
sources:
1616
- https://github.com/devtron-labs/charts
1717
dependencies:

0 commit comments

Comments
 (0)