8000 feat: lock application/pipeline/environment as code (#4053) · ovh/cds@e857bac · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit e857bac

Browse files
sguiheuxfsamin
authored andcommitted
feat: lock application/pipeline/environment as code (#4053)
1 parent c901936 commit e857bac

Some content is hidden

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

46 files changed

+349
-114
lines changed

engine/api/application.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,10 @@ func (api *API) updateApplicationHandler() service.Handler {
402402
return sdk.WrapError(errloadbyname, "updateApplicationHandler> Cannot load application %s", applicationName)
403403
}
404404

405+
if app.FromRepository != "" {
406+
return sdk.WithStack(sdk.ErrForbidden)
407+
}
408+
405409
var appPost sdk.Application
406410
if err := service.UnmarshalBody(r, &appPost); err != nil {
407411
return err
@@ -466,6 +470,9 @@ func (api *API) postApplicationMetadataHandler() service.Handler {
466470
if err != nil {
467471
return sdk.WrapError(err, "postApplicationMetadataHandler")
468472
}
473+
if app.FromRepository != "" {
474+
return sdk.WithStack(sdk.ErrForbidden)
475+
}
469476
oldApp := *app
470477

471478
m := vars["metadata"]

engine/api/application/application_parser.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ import (
1313
"github.com/ovh/cds/sdk/log"
1414
)
1515

16+
// ImportOptions are options to import application
17+
type ImportOptions struct {
18+
Force bool
19+
FromRepository string
20+
}
21+
1622
// ParseAndImport parse an exportentities.Application and insert or update the application in database
17-
func ParseAndImport(db gorp.SqlExecutor, cache cache.Store, proj *sdk.Project, eapp *exportentities.Application, force bool, decryptFunc keys.DecryptFunc, u *sdk.User) (*sdk.Application, []sdk.Message, error) {
18-
log.Info("ParseAndImport>> Import application %s in project %s (force=%v)", eapp.Name, proj.Key, force)
23+
func ParseAndImport(db gorp.SqlExecutor, cache cache.Store, proj *sdk.Project, eapp *exportentities.Application, opts ImportOptions, decryptFunc keys.DecryptFunc, u *sdk.User) (*sdk.Application, []sdk.Message, error) {
24+
log.Info("ParseAndImport>> Import application %s in project %s (force=%v)", eapp.Name, proj.Key, opts.Force)
1925

2026
//Check valid application name
2127
rx := sdk.NamePatternRegex
@@ -34,15 +40,20 @@ func ParseAndImport(db gorp.SqlExecutor, cache cache.Store, proj *sdk.Project, e
3440
}
3541

3642
//If the application exist and we don't want to force, raise an error
37-
if oldApp != nil && !force {
43+
if oldApp != nil && !opts.Force {
3844
return nil, nil, sdk.ErrApplicationExist
3945
}
4046

47+
if oldApp != nil && oldApp.FromRepository != "" && opts.FromRepository != oldApp.FromRepository {
48+
return nil, nil, sdk.WrapError(sdk.ErrForbidden, "unable to update as code application %s/%s.", oldApp.FromRepository, opts.FromRepository)
49+
}
50+
4151
//Craft the application
4252
app := new(sdk.Application)
4353
app.Name = eapp.Name
4454
app.VCSServer = eapp.VCSServer
4555
app.RepositoryFullname = eapp.RepositoryName
56+
app.FromRepository = opts.FromRepository
4657

4758
//Compute variables
4859
for p, v := range eapp.Variables {

engine/api/application/dao.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ application.last_modified,
2424
application.metadata,
2525
application.vcs_server,
2626
application.vcs_strategy,
27-
application.description
27+
application.description,
28+
application.from_repository
2829
`
2930

3031
// LoadOptionFunc is a type for all options in LoadOptions

engine/api/application_deployment.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ func (api *API) postApplicationDeploymentStrategyConfigHandler() service.Handler
7373
if err != nil {
7474
return sdk.WrapError(err, "unable to load application")
7575
}
76+
if app.FromRepository != "" {
77+
return sdk.WithStack(sdk.ErrForbidden)
78+
}
7679

7780
oldPfConfig, has := app.DeploymentStrategies[pfName]
7881
if !has {
@@ -144,6 +147,9 @@ func (api *API) deleteApplicationDeploymentStrategyConfigHandler() service.Handl
144147
if err != nil {
145148
return sdk.WrapError(err, "unable to load application")
146149
}
150+
if app.FromRepository != "" {
151+
return sdk.WithStack(sdk.ErrForbidden)
152+
}
147153

148154
isUsed, err := workflow.IsDeploymentIntegrationUsed(tx, proj.ID, app.ID, pfName)
149155
if err != nil {

engine/api/application_import.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (api *API) postApplicationImportHandler() service.Handler {
6464
}
6565
defer tx.Rollback()
6666

67-
newApp, msgList, globalError := application.ParseAndImport(tx, api.Cache, proj, eapp, force, project.DecryptWithBuiltinKey, deprecatedGetUser(ctx))
67+
newApp, msgList, globalError := application.ParseAndImport(tx, api.Cache, proj, eapp, application.ImportOptions{Force: force}, project.DecryptWithBuiltinKey, deprecatedGetUser(ctx))
6868
msgListString := translate(r, msgList)
6969
if globalError != nil {
7070
globalError = sdk.WrapError(globalError, "Unable to import application %s", eapp.Name)

engine/api/application_key.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ func (api *API) deleteKeyInApplicationHandler() service.Handler {
4848
if errA != nil {
4949
return sdk.WrapError(errA, "deleteKeyInApplicationHandler> Cannot load application")
5050
}
51+
if app.FromRepository != "" {
52+
return sdk.WithStack(sdk.ErrForbidden)
53+
}
5154

5255
tx, errT := api.mustDB().Begin()
5356
if errT != nil {
@@ -101,6 +104,10 @@ func (api *API) addKeyInApplicationHandler() service.Handler {
101104
}
102105
newKey.ApplicationID = app.ID
103106

107+
if app.FromRepository != "" {
108+
return sdk.WithStack(sdk.ErrForbidden)
109+
}
110+
104111
if !strings.HasPrefix(newKey.Name, "app-") {
105112
newKey.Name = "app-" + newKey.Name
106113
}

engine/api/application_variable.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ func (api *API) deleteVariableFromApplicationHandler() service.Handler {
101101
if err != nil {
102102
return sdk.WrapError(err, "Cannot load application: %s", appName)
103103
}
104+
if app.FromRepository != "" {
105+
return sdk.WithStack(sdk.ErrForbidden)
106+
}
104107

105108
tx, err := api.mustDB().Begin()
106109
if err != nil {
@@ -153,6 +156,9 @@ func (api *API) updateVariableInApplicationHandler() service.Handler {
153156
if err != nil {
154157
return sdk.WrapError(err, "Cannot load application: %s", appName)
155158
}
159+
if app.FromRepository != "" {
160+
return sdk.WithStack(sdk.ErrForbidden)
161+
}
156162

157163
variableBefore, err := application.LoadVariableByID(api.mustDB(), app.ID, newVar.ID, application.WithClearPassword())
158164
if err != nil {
@@ -204,6 +210,9 @@ func (api *API) addVariableInApplicationHandler() service.Handler {
204210
if err != nil {
205211
return sdk.WrapError(err, "Cannot load application %s ", appName)
206212
}
213+
if app.FromRepository != "" {
214+
return sdk.WithStack(sdk.ErrForbidden)
215+
}
207216

208217
tx, err := api.mustDB().Begin()
209218
if err != nil {

engine/api/environment.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ func (api *API) updateEnvironmentHandler() service.Handler {
209209
return sdk.WrapError(errEnv, "updateEnvironmentHandler> Cannot load environment %s", environmentName)
210210
}
211211

212+
if env.FromRepository != "" {
213+
return sdk.WithStack(sdk.ErrForbidden)
214+
}
215+
212216
p, errProj := project.Load(api.mustDB(), api.Cache, projectKey, deprecatedGetUser(ctx))
213217
if errProj != nil {
214218
return sdk.WrapError(errProj, "updateEnvironmentHandler> Cannot load project %s", projectKey)

engine/api/environment/environment.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
func LoadEnvironments(db gorp.SqlExecutor, projectKey string, loadDeps bool, u *sdk.User) ([]sdk.Environment, error) {
2020
var envs []sdk.Environment
2121

22-
query := `SELECT environment.id, environment.name, environment.last_modified, 7 as "perm"
22+
query := `SELECT environment.id, environment.name, environment.last_modified, 7 as "perm", environment.from_repository
2323
FROM environment
2424
JOIN project ON project.id = environment.project_id
2525
WHERE project.projectKey = $1
@@ -29,20 +29,19 @@ func LoadEnvironments(db gorp.SqlExecutor, projectKey string, loadDeps bool, u *
2929
if err == sql.ErrNoRows {
3030
return envs, sdk.ErrNoEnvironment
3131
}
32-
return envs, err
32+
return envs, sdk.WithStack(err)
3333
}
3434
defer rows.Close()
3535

3636
for rows.Next() {
3737
var env sdk.Environment
3838
var lastModified time.Time
39-
err = rows.Scan(&env.ID, &env.Name, &lastModified, &env.Permission)
39+
if err := rows.Scan(&env.ID, &env.Name, &lastModified, &env.Permission, &env.FromRepository); err != nil {
40+
return envs, sdk.WithStack(err)
41+
}
4042
env.LastModified = lastModified.Unix()
4143
env.ProjectKey = projectKey
4244
env.Permission = permission.ProjectPermission(projectKey, u)
43-
if err != nil {
44-
return envs, err
45-
}
4645
envs = append(envs, env)
4746
}
4847
rows.Close()
@@ -94,10 +93,10 @@ func LoadEnvironmentByID(db gorp.SqlExecutor, ID int64) (*sdk.Environment, error
9493
return &sdk.DefaultEnv, nil
9594
}
9695
var env sdk.Environment
97-
query := `SELECT environment.id, environment.name, environment.project_id
96+
query := `SELECT environment.id, environment.name, environment.project_id, environment.from_repository
9897
FROM environment
9998
WHERE id = $1`
100-
if err := db.QueryRow(query, ID).Scan(&env.ID, &env.Name, &env.ProjectID); err != nil {
99+
if err := db.QueryRow(query, ID).Scan(&env.ID, &env.Name, &env.ProjectID, &env.FromRepository); err != nil {
101100
if err == sql.ErrNoRows {
102101
return nil, sdk.ErrNoEnvironment
103102
}
@@ -113,11 +112,11 @@ func LoadEnvironmentByName(db gorp.SqlExecutor, projectKey, envName string) (*sd
113112
}
114113

115114
var env sdk.Environment
116-
query := `SELECT environment.id, environment.name, environment.project_id
115+
query := `SELECT environment.id, environment.name, environment.project_id, environment.from_repository
117116
FROM environment
118117
JOIN project ON project.id = environment.project_id
119118
WHERE project.projectKey = $1 AND environment.name = $2`
120-
if err := db.QueryRow(query, projectKey, envName).Scan(&env.ID, &env.Name, &env.ProjectID); err != nil {
119+
if err := db.QueryRow(query, projectKey, envName).Scan(&env.ID, &env.Name, &env.ProjectID, &env.FromRepository); err != nil {
121120
if err == sql.ErrNoRows {
122121
return nil, sdk.ErrNoEnvironment
123122
}
@@ -196,15 +195,15 @@ func loadDependencies(db gorp.SqlExecutor, env *sdk.Environment) error {
196195

197196
// InsertEnvironment Insert new environment
198197
func InsertEnvironment(db gorp.SqlExecutor, env *sdk.Environment) error {
199-
query := `INSERT INTO environment (name, project_id) VALUES($1, $2) RETURNING id, last_modified`
198+
query := `INSERT INTO environment (name, project_id, from_repository) VALUES($1, $2, $3) RETURNING id, last_modified`
200199

201200
rx := sdk.NamePatternRegex
202201
if !rx.MatchString(env.Name) {
203202
return sdk.NewError(sdk.ErrInvalidName, fmt.Errorf("Invalid environment name. It should match %s", sdk.NamePattern))
204203
}
205204

206205
var lastModified time.Time
207-
err := db.QueryRow(query, env.Name, env.ProjectID).Scan(&env.ID, &lastModified)
206+
err := db.QueryRow(query, env.Name, env.ProjectID, env.FromRepository).Scan(&env.ID, &lastModified)
208207
if err != nil {
209208
pqerr, ok := err.(*pq.Error)
210209
if ok {
@@ -225,8 +224,8 @@ func UpdateEnvironment(db gorp.SqlExecutor, environment *sdk.Environment) error
225224
return sdk.NewError(sdk.ErrInvalidName, fmt.Errorf("Invalid environment name. It should match %s", sdk.NamePattern))
226225
}
227226

228-
query := `UPDATE environment SET name=$1 WHERE id=$2`
229-
if _, err := db.Exec(query, environment.Name, environment.ID); err != nil {
227+
query := `UPDATE environment SET name=$1, from_repository=$3 WHERE id=$2`
228+
if _, err := db.Exec(query, environment.Name, environment.ID, environment.FromRepository); err != nil {
230229
return err
231230
}
232231
return nil

engine/api/environment/environment_importer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ func ImportInto(db gorp.SqlExecutor, proj *sdk.Project, env *sdk.Environment, in
108108
}
109109
}
110110

111+
if err := UpdateEnvironment(db, env); err != nil {
112+
return sdk.WrapError(err, "unable to update environment")
113+
}
114+
111115
log.Debug("ImportInto> Done")
112116

113117
return nil

0 commit comments

Comments
 (0)
0