Skip to content

Commit 2dafe78

Browse files
Ash-expayu-devtronashokdevtronkartik-579
authored
feat: gitops async with timeline (#5286)
* feat: replace user_deployment_request.status with pipeline_status_timelines * updated schema migration script * fix: migration script * update readme to include multi arch flag (#4998) * updated trigger event func and timeline names * review comment incorporation * fix: GetAllInCompleteRequests query * fix: GetAllInCompleteRequests query * fixed: UpdatePreviousQueuedRunnerStatus error * fix: loogers * doc: Added enhancements to security doc (#5203) * Rough Draft Initiated * Created Security Enhancement Docs + Other Adhoc Fixes * Incorporated PM Feedback * Modified Portforward Section to Kubectl Section (#5236) * feat: cd pipeline deployment history refactoring (#5200) * searchableKey service move * migrated cd deployment history code * idempotency of triggerPipeline func and minor fixes * timeline fixes * updated: NewTriggerEvent func * updated ErrorDeploymentSuperseded err handling * updated: GetArgoPipelinesHavingLatestTriggerStuckInNonTerminalStatuses statuses * fix: timeline status * refactored: UpdatePreviousQueuedRunnerStatus * fix: GetPreviousQueuedRunners query * fix: UpdateRunnerStatusToFailedForIds query * fix: buildTriggerEventForOverrideRequest func * fix: UpdateRunnerStatusToFailedForIds query * fix: UpdateRunnerStatusToFailedForIds query * updated: handleAsyncTriggerReleaseError func * fix: concurrent case handlings * updated folder name * updated GetLastStatusPublishedTimeForWfrId func * feat: removed audit timeline and error handlings * fix: FetchTimelinesForWfrIdExcludingStatuses query * fix: deleted pipeline flow * timeline handling * timeline handling fixed * removed unused const * chore: updated go-bitbucket version * removed unnecessary alais --------- Co-authored-by: ayu-devtron <167413063+ayu-devtron@users.noreply.github.com> Co-authored-by: ashokdevtron <141001279+ashokdevtron@users.noreply.github.com> Co-authored-by: kartik-579 <84493919+kartik-579@users.noreply.github.com>
1 parent afee443 commit 2dafe78

File tree

112 files changed

+1846
-1273
lines changed

Some content is hidden

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

112 files changed

+1846
-1273
lines changed

.gitbook.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,4 @@ redirects:
7777
global-configurations/api-token: user-guide/global-configurations/authorization/api-tokens.md
7878
user-guide/creating-application/workflow/ci-pipeline2: user-guide/creating-application/workflow/ci-pipeline.md
7979
user-guide/clusters: user-guide/resource-browser.md
80+
usage/clusters: user-guide/resource-browser.md

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ helm install devtron devtron/devtron-operator --create-namespace --namespace dev
160160

161161
```
162162

163+
### Install Multi-Architecture Nodes (ARM and AMD)
164+
165+
To install Devtron on clusters with the multi-architecture nodes (ARM and AMD), append the Devtron installation command with ```--set installer.arch=multi-arch```
166+
163167
## :blue_heart: Technology
164168

165169
Devtron is built on some of the most trusted and loved technologies:

Wire.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//go:build wireinject
2+
// +build wireinject
3+
14
/*
25
* Copyright (c) 2024. Devtron Inc.
36
*
@@ -14,9 +17,6 @@
1417
* limitations under the License.
1518
*/
1619

17-
//go:build wireinject
18-
// +build wireinject
19-
2020
package main
2121

2222
import (
@@ -39,6 +39,7 @@ import (
3939
"github.com/devtron-labs/devtron/api/connector"
4040
"github.com/devtron-labs/devtron/api/dashboardEvent"
4141
"github.com/devtron-labs/devtron/api/deployment"
42+
"github.com/devtron-labs/devtron/api/devtronResource"
4243
"github.com/devtron-labs/devtron/api/externalLink"
4344
client "github.com/devtron-labs/devtron/api/helm-app"
4445
"github.com/devtron-labs/devtron/api/infraConfig"
@@ -121,9 +122,8 @@ import (
121122
delete2 "github.com/devtron-labs/devtron/pkg/delete"
122123
deployment2 "github.com/devtron-labs/devtron/pkg/deployment"
123124
git2 "github.com/devtron-labs/devtron/pkg/deployment/gitOps/git"
125+
"github.com/devtron-labs/devtron/pkg/deployment/manifest/publish"
124126
"github.com/devtron-labs/devtron/pkg/deploymentGroup"
125-
"github.com/devtron-labs/devtron/pkg/devtronResource"
126-
repository9 "github.com/devtron-labs/devtron/pkg/devtronResource/repository"
127127
"github.com/devtron-labs/devtron/pkg/dockerRegistry"
128128
"github.com/devtron-labs/devtron/pkg/eventProcessor"
129129
"github.com/devtron-labs/devtron/pkg/generateManifest"
@@ -196,6 +196,9 @@ func InitializeApp() (*App, error) {
196196

197197
eventProcessor.EventProcessorWireSet,
198198
workflow3.WorkflowWireSet,
199+
200+
devtronResource.DevtronResourceWireSet,
201+
199202
// -------wireset end ----------
200203
// -------
201204
gitSensor.GetConfig,
@@ -924,8 +927,8 @@ func InitializeApp() (*App, error) {
924927
wire.Bind(new(executors.SystemWorkflowExecutor), new(*executors.SystemWorkflowExecutorImpl)),
925928
repository5.NewManifestPushConfigRepository,
926929
wire.Bind(new(repository5.ManifestPushConfigRepository), new(*repository5.ManifestPushConfigRepositoryImpl)),
927-
app.NewGitOpsManifestPushServiceImpl,
928-
wire.Bind(new(app.GitOpsPushService), new(*app.GitOpsManifestPushServiceImpl)),
930+
publish.NewGitOpsManifestPushServiceImpl,
931+
wire.Bind(new(publish.GitOpsPushService), new(*publish.GitOpsManifestPushServiceImpl)),
929932

930933
// start: docker registry wire set injection
931934
router.NewDockerRegRouterImpl,
@@ -951,12 +954,6 @@ func InitializeApp() (*App, error) {
951954
resourceQualifiers.NewQualifierMappingServiceImpl,
952955
wire.Bind(new(resourceQualifiers.QualifierMappingService), new(*resourceQualifiers.QualifierMappingServiceImpl)),
953956

954-
repository9.NewDevtronResourceSearchableKeyRepositoryImpl,
955-
wire.Bind(new(repository9.DevtronResourceSearchableKeyRepository), new(*repository9.DevtronResourceSearchableKeyRepositoryImpl)),
956-
957-
devtronResource.NewDevtronResourceSearchableKeyServiceImpl,
958-
wire.Bind(new(devtronResource.DevtronResourceSearchableKeyService), new(*devtronResource.DevtronResourceSearchableKeyServiceImpl)),
959-
960957
argocdServer.NewArgoClientWrapperServiceImpl,
961958
wire.Bind(new(argocdServer.ArgoClientWrapperService), new(*argocdServer.ArgoClientWrapperServiceImpl)),
962959

api/bean/ValuesOverrideRequest.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ func (workflowType WorkflowType) WorkflowTypeToStageType() repository.PipelineSt
4949
}
5050
}
5151

52+
func (workflowType WorkflowType) IsStageTypeDeploy() bool {
53+
switch workflowType {
54+
case CD_WORKFLOW_TYPE_DEPLOY:
55+
return true
56+
}
57+
return false
58+
}
59+
5260
type ValuesOverrideRequest struct {
5361
PipelineId int `json:"pipelineId" validate:"required"`
5462
AppId int `json:"appId" validate:"required"`
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package devtronResource
2+
3+
import (
4+
"fmt"
5+
apiBean "github.com/devtron-labs/devtron/api/devtronResource/bean"
6+
"github.com/devtron-labs/devtron/api/restHandler/common"
7+
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
8+
"github.com/devtron-labs/devtron/pkg/devtronResource"
9+
"github.com/devtron-labs/devtron/pkg/devtronResource/adapter"
10+
"github.com/devtron-labs/devtron/pkg/devtronResource/bean"
11+
"github.com/devtron-labs/devtron/pkg/devtronResource/history/deployment/cdPipeline"
12+
"github.com/devtron-labs/devtron/util/rbac"
13+
"github.com/gorilla/schema"
14+
"go.uber.org/zap"
15+
"net/http"
16+
)
17+
18+
type HistoryRestHandler interface {
19+
GetDeploymentHistory(w http.ResponseWriter, r *http.Request)
20+
GetDeploymentHistoryConfigList(w http.ResponseWriter, r *http.Request)
21+
}
22+
23+
type HistoryRestHandlerImpl struct {
24+
logger *zap.SugaredLogger
25+
enforcer casbin.Enforcer
26+
deploymentHistoryService cdPipeline.DeploymentHistoryService
27+
apiReqDecoderService devtronResource.APIReqDecoderService
28+
enforcerUtil rbac.EnforcerUtil
29+
}
30+
31+
func NewHistoryRestHandlerImpl(logger *zap.SugaredLogger,
32+
enforcer casbin.Enforcer,
33+
deploymentHistoryService cdPipeline.DeploymentHistoryService,
34+
apiReqDecoderService devtronResource.APIReqDecoderService,
35+
enforcerUtil rbac.EnforcerUtil) *HistoryRestHandlerImpl {
36+
return &HistoryRestHandlerImpl{
37+
logger: logger,
38+
enforcer: enforcer,
39+
deploymentHistoryService: deploymentHistoryService,
40+
apiReqDecoderService: apiReqDecoderService,
41+
enforcerUtil: enforcerUtil,
42+
}
43+
}
44+
45+
func (handler *HistoryRestHandlerImpl) GetDeploymentHistory(w http.ResponseWriter, r *http.Request) {
46+
kind, _, _, caughtError := getKindSubKindVersion(w, r)
47+
if caughtError || kind != bean.DevtronResourceCdPipeline.ToString() {
48+
common.WriteJsonResp(w, fmt.Errorf(apiBean.RequestInvalidKindVersionErrMessage), nil, http.StatusBadRequest)
49+
return
50+
}
51+
v := r.URL.Query()
52+
var decoder = schema.NewDecoder()
53+
decoder.IgnoreUnknownKeys(true)
54+
queryParams := apiBean.GetHistoryQueryParams{}
55+
err := decoder.Decode(&queryParams, v)
56+
if err != nil {
57+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
58+
return
59+
}
60+
decodedReqBean, err := handler.apiReqDecoderService.GetFilterCriteriaParamsForDeploymentHistory(queryParams.FilterCriteria)
61+
if err != nil {
62+
handler.logger.Errorw("error in getting filter criteria params", "err", err, "filterCriteria", queryParams.FilterCriteria)
63+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
64+
return
65+
}
66+
67+
// RBAC START
68+
token := r.Header.Get("token")
69+
resourceName := handler.enforcerUtil.GetAppRBACNameByAppId(decodedReqBean.AppId)
70+
if ok := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionGet, resourceName); !ok {
71+
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden)
72+
return
73+
}
74+
// RBAC END
75+
76+
resp, err := handler.deploymentHistoryService.
77+
GetCdPipelineDeploymentHistory(adapter.GetCDDeploymentHistoryListReq(&queryParams, decodedReqBean))
78+
if err != nil {
79+
handler.logger.Errorw("service error, GetCdPipelineDeploymentHistory", "err", err)
80+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
81+
return
82+
}
83+
common.WriteJsonResp(w, err, resp, http.StatusOK)
84+
return
85+
}
86+
87+
func (handler *HistoryRestHandlerImpl) GetDeploymentHistoryConfigList(w http.ResponseWriter, r *http.Request) {
88+
kind, _, _, caughtError := getKindSubKindVersion(w, r)
89+
if caughtError || kind != bean.DevtronResourceCdPipeline.ToString() {
90+
common.WriteJsonResp(w, fmt.Errorf(apiBean.RequestInvalidKindVersionErrMessage), nil, http.StatusBadRequest)
91+
return
92+
}
93+
v := r.URL.Query()
94+
var decoder = schema.NewDecoder()
95+
decoder.IgnoreUnknownKeys(true)
96+
queryParams := apiBean.GetHistoryConfigQueryParams{}
97+
err := decoder.Decode(&queryParams, v)
98+
if err != nil {
99+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
100+
return
101+
}
102+
decodedReqBean, err := handler.apiReqDecoderService.GetFilterCriteriaParamsForDeploymentHistory(queryParams.FilterCriteria)
103+
if err != nil {
104+
handler.logger.Errorw("error in getting filter criteria params", "err", err, "filterCriteria", queryParams.FilterCriteria)
105+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
106+
return
107+
}
108+
//RBAC START
109+
token := r.Header.Get("token")
110+
resourceName := handler.enforcerUtil.GetAppRBACNameByAppId(decodedReqBean.AppId)
111+
if isValidated := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionGet, resourceName); !isValidated {
112+
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden)
113+
return
114+
}
115+
//RBAC END
116+
resp, err := handler.deploymentHistoryService.
117+
GetCdPipelineDeploymentHistoryConfigList(adapter.GetCDDeploymentHistoryConfigListReq(&queryParams, decodedReqBean))
118+
if err != nil {
119+
handler.logger.Errorw("service error, GetCdPipelineDeploymentHistoryConfigList", "err", err)
120+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
121+
return
122+
}
123+
common.WriteJsonResp(w, err, resp, http.StatusOK)
124+
return
125+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package devtronResource
2+
3+
import "github.com/gorilla/mux"
4+
5+
type HistoryRouter interface {
6+
InitDtResourceHistoryRouter(devtronResourceRouter *mux.Router)
7+
}
8+
9+
type HistoryRouterImpl struct {
10+
dtResourceHistoryRestHandler HistoryRestHandler
11+
}
12+
13+
func NewHistoryRouterImpl(dtResourceHistoryRestHandler HistoryRestHandler) *HistoryRouterImpl {
14+
return &HistoryRouterImpl{dtResourceHistoryRestHandler: dtResourceHistoryRestHandler}
15+
}
16+
17+
func (router *HistoryRouterImpl) InitDtResourceHistoryRouter(historyRouter *mux.Router) {
18+
historyRouter.Path("/deployment/config/{kind:[a-zA-Z0-9/-]+}/{version:[a-zA-Z0-9]+}").
19+
HandlerFunc(router.dtResourceHistoryRestHandler.GetDeploymentHistoryConfigList).Methods("GET")
20+
21+
historyRouter.Path("/deployment/{kind:[a-zA-Z0-9/-]+}/{version:[a-zA-Z0-9]+}").
22+
HandlerFunc(router.dtResourceHistoryRestHandler.GetDeploymentHistory).Methods("GET")
23+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package devtronResource
2+
3+
import (
4+
"fmt"
5+
apiBean "github.com/devtron-labs/devtron/api/devtronResource/bean"
6+
"github.com/devtron-labs/devtron/api/restHandler/common"
7+
"github.com/devtron-labs/devtron/pkg/devtronResource/helper"
8+
"github.com/gorilla/mux"
9+
"net/http"
10+
)
11+
12+
func getKindSubKindVersion(w http.ResponseWriter, r *http.Request) (kind string, subKind string, version string, caughtError bool) {
13+
vars := mux.Vars(r)
14+
kindVar := vars[apiBean.PathParamKind]
15+
versionVar := vars[apiBean.PathParamVersion]
16+
kind, subKind, statusCode, err := resolveKindSubKindValues(kindVar)
17+
if err != nil {
18+
common.WriteJsonResp(w, err, nil, statusCode)
19+
caughtError = true
20+
}
21+
return kind, subKind, versionVar, caughtError
22+
}
23+
24+
func resolveKindSubKindValues(kindVar string) (kind, subKind string, statusCode int, err error) {
25+
kind, subKind, err = helper.GetKindAndSubKindFrom(kindVar)
26+
if err != nil {
27+
err = fmt.Errorf("invalid parameter: kind")
28+
statusCode = http.StatusBadRequest
29+
}
30+
return kind, subKind, statusCode, err
31+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package devtronResource
2+
3+
import "github.com/gorilla/mux"
4+
5+
type DevtronResourceRouter interface {
6+
InitDevtronResourceRouter(devtronResourceRouter *mux.Router)
7+
}
8+
9+
type DevtronResourceRouterImpl struct {
10+
historyRouter HistoryRouter
11+
}
12+
13+
func NewDevtronResourceRouterImpl(historyRouter HistoryRouter) *DevtronResourceRouterImpl {
14+
return &DevtronResourceRouterImpl{
15+
historyRouter: historyRouter,
16+
}
17+
}
18+
19+
func (router *DevtronResourceRouterImpl) InitDevtronResourceRouter(devtronResourceRouter *mux.Router) {
20+
historyRouter := devtronResourceRouter.PathPrefix("/history").Subrouter()
21+
router.historyRouter.InitDtResourceHistoryRouter(historyRouter)
22+
}

api/devtronResource/bean/bean.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package bean
2+
3+
type GetHistoryQueryParams struct {
4+
FilterCriteria []string `schema:"filterCriteria"`
5+
OffSet int `schema:"offSet"`
6+
Limit int `schema:"limit"`
7+
}
8+
9+
type GetHistoryConfigQueryParams struct {
10+
BaseConfigurationId int `schema:"baseConfigurationId"`
11+
HistoryComponent string `schema:"historyComponent"`
12+
HistoryComponentName string `schema:"historyComponentName"`
13+
FilterCriteria []string `schema:"filterCriteria"`
14+
}
15+
16+
const (
17+
RequestInvalidKindVersionErrMessage = "Invalid kind and version! Implementation not supported."
18+
PathParamKind = "kind"
19+
PathParamVersion = "version"
20+
)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package devtronResource
2+
3+
import (
4+
"github.com/devtron-labs/devtron/pkg/devtronResource"
5+
"github.com/devtron-labs/devtron/pkg/devtronResource/history/deployment/cdPipeline"
6+
"github.com/devtron-labs/devtron/pkg/devtronResource/read"
7+
"github.com/devtron-labs/devtron/pkg/devtronResource/repository"
8+
"github.com/google/wire"
9+
)
10+
11+
var DevtronResourceWireSet = wire.NewSet(
12+
//old bindings, migrated from wire.go
13+
read.NewDevtronResourceSearchableKeyServiceImpl,
14+
wire.Bind(new(read.DevtronResourceSearchableKeyService), new(*read.DevtronResourceSearchableKeyServiceImpl)),
15+
repository.NewDevtronResourceSearchableKeyRepositoryImpl,
16+
wire.Bind(new(repository.DevtronResourceSearchableKeyRepository), new(*repository.DevtronResourceSearchableKeyRepositoryImpl)),
17+
18+
NewDevtronResourceRouterImpl,
19+
wire.Bind(new(DevtronResourceRouter), new(*DevtronResourceRouterImpl)),
20+
21+
NewHistoryRouterImpl,
22+
wire.Bind(new(HistoryRouter), new(*HistoryRouterImpl)),
23+
NewHistoryRestHandlerImpl,
24+
wire.Bind(new(HistoryRestHandler), new(*HistoryRestHandlerImpl)),
25+
cdPipeline.NewDeploymentHistoryServiceImpl,
26+
wire.Bind(new(cdPipeline.DeploymentHistoryService), new(*cdPipeline.DeploymentHistoryServiceImpl)),
27+
28+
devtronResource.NewAPIReqDecoderServiceImpl,
29+
wire.Bind(new(devtronResource.APIReqDecoderService), new(*devtronResource.APIReqDecoderServiceImpl)),
30+
)

0 commit comments

Comments
 (0)