8000 fix(api): edit as code worker model with a non-admin user (#4097) · ovh/cds@a10545f · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit a10545f

Browse files
bnjjjyesnault
authored andcommitted
fix(api): edit as code worker model with a non-admin user (#4097)
Signed-off-by: Benjamin Coenen <benjamin.coenen@corp.ovh.com>
1 parent 75cf5b6 commit a10545f

File tree

8 files changed

+92
-36
lines changed

8 files changed

+92
-36
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
.vscode
66
.DS_Store
77
dump.rdb
8+
dist
89
cli/cds/cds
910
engine/engine
1011
10000 engine/dist

engine/api/api_routes.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ func (api *API) InitRouter() {
365365
r.Handle("/worker/model/type", r.GET(api.getWorkerModelTypesHandler))
366366
r.Handle("/worker/model/communication", r.GET(api.getWorkerModelCommunicationsHandler))
367367
r.Handle("/worker/model/{permModelID}", r.PUT(api.updateWorkerModelHandler), r.DELETE(api.deleteWorkerModelHandler))
368-
r.Handle("/worker/model/{permModelID}/export", r.GET(api.getWorkerModelExportHandler))
368+
r.Handle("/worker/model/{modelID}/export", r.GET(api.getWorkerModelExportHandler))
369369
r.Handle("/worker/model/{modelID}/usage", r.GET(api.getWorkerModelUsageHandler))
370370
r.Handle("/worker/model/capability/type", r.GET(api.getRequirementTypesHandler))
371371

engine/api/worker/model.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ func updateAllToCheckRegistration(db gorp.SqlExecutor) error {
426426

427427
// UpdateSpawnErrorWorkerModel updates worker model error registration
428428
func UpdateSpawnErrorWorkerModel(db gorp.SqlExecutor, modelID int64, spawnError sdk.SpawnErrorForm) error {
429-
// some times when the docker container fails to start, the docker logs is not empty but only contains utf8 null char
429+
// some times when the docker container fails to start, the docker logs is not empty but only contains utf8 null char
430430
if spawnError.Error == string([]byte{0x00}) {
431431
spawnError.Error = ""
432432
}

engine/api/worker/model_export.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
)
99

1010
// Export convert sdk.Model to an exportentities.WorkerModel, format and write into a io.Writer
11-
func Export(wm sdk.Model, f exportentities.Format, w io.Writer) (int, error) {
12-
eWm := exportentities.NewWorkerModel(wm)
11+
func Export(wm sdk.Model, f exportentities.Format, w io.Writer, opts ...exportentities.WorkerModelOption) (int, error) {
12+
eWm := exportentities.NewWorkerModel(wm, opts...)
1313

1414
// Marshal to the desired format
1515
b, err := exportentities.Marshal(eWm, f)

engine/api/worker/model_import.go

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ import (
1515

1616
// ParseAndImport parse and import an exportentities.WorkerModel
1717
func ParseAndImport(db gorp.SqlExecutor, store cache.Store, eWorkerModel *exportentities.WorkerModel, force bool, u *sdk.User) (*sdk.Model, error) {
18-
sdkWm, err := eWorkerModel.GetWorkerModel()
19-
if err != nil {
20-
return nil, err
21-
}
22-
18+
sdkWm, errInvalidModel := eWorkerModel.GetWorkerModel()
2319
gr, err := group.LoadGroupByName(db, sdkWm.Group.Name)
2420
if err != nil {
2521
return nil, sdk.WrapError(err, "Unable to get group %s", sdkWm.Group.Name)
@@ -55,41 +51,33 @@ currentUGroup:
5551
return nil, sdk.ErrWorkerModelNoAdmin
5652
}
5753

54+
var badRequestError error
55+
asSimpleUser := !u.Admin && !sdkWm.Restricted
5856
switch sdkWm.Type {
5957
case sdk.Docker:
6058
if sdkWm.ModelDocker.Image == "" {
6159
return nil, sdk.NewErrorFrom(sdk.ErrWrongRequest, "Invalid worker image")
6260
}
63-
if !u.Admin && !sdkWm.Restricted {
64-
if modelPattern == nil {
65-
return nil, sdk.ErrWorkerModelNoPattern
66-
}
67-
}
6861
if modelPattern != nil {
6962
sdkWm.ModelDocker.Cmd = modelPattern.Model.Cmd
7063
sdkWm.ModelDocker.Shell = modelPattern.Model.Shell
7164
sdkWm.ModelDocker.Envs = modelPattern.Model.Envs
7265
}
7366
if sdkWm.ModelDocker.Cmd == "" || sdkWm.ModelDocker.Shell == "" {
74-
return nil, sdk.NewErrorFrom(sdk.ErrWrongRequest, "Invalid worker command or invalid shell command")
67+
badRequestError = sdk.NewErrorFrom(sdk.ErrWrongRequest, "Invalid worker command or invalid shell command")
7568
}
7669
default:
7770
if sdkWm.ModelVirtualMachine.Image == "" {
7871
return nil, sdk.NewErrorFrom(sdk.ErrWrongRequest, "Invalid worker image: cannot be empty")
7972
}
80-
if !u.Admin && !sdkWm.Restricted {
81-
if modelPattern == nil {
82-
return nil, sdk.ErrWorkerModelNoPattern
83-
}
84-
}
8573
if modelPattern != nil {
8674
sdkWm.ModelVirtualMachine.PreCmd = modelPattern.Model.PreCmd
8775
sdkWm.ModelVirtualMachine.Cmd = modelPattern.Model.Cmd
8876
sdkWm.ModelVirtualMachine.PostCmd = modelPattern.Model.PostCmd
8977
}
9078

9179
if sdkWm.ModelVirtualMachine.Cmd == "" {
92-
return nil, sdk.NewErrorFrom(sdk.ErrWrongRequest, "Invalid worker command: Cannot be empty")
80+
badRequestError = sdk.NewErrorFrom(sdk.ErrWrongRequest, "Invalid worker command: Cannot be empty")
9381
}
9482
}
9583

@@ -103,13 +91,22 @@ currentUGroup:
10391

10492
// provision is allowed only for CDS Admin
10593
// or by currentUser with a restricted model
106-
if !u.Admin && !sdkWm.Restricted {
94+
if asSimpleUser {
10795
sdkWm.Provision = 0
10896
}
10997

11098
if force {
11199
if existingWm, err := LoadWorkerModelByName(db, sdkWm.Name); err != nil {
112100
if sdk.Cause(err) == sql.ErrNoRows {
101+
if asSimpleUser && modelPattern == nil {
102+
return nil, sdk.ErrWorkerModelNoPattern
103+
}
104+
if errInvalidModel != nil {
105+
return nil, errInvalidModel
106+
}
107+
if badRequestError != nil {
108+
return nil, badRequestError
109+
}
113110
if errAdd := InsertWorkerModel(db, &sdkWm); errAdd != nil {
114111
return nil, sdk.WrapError(errAdd, "cannot add worker model %s", sdkWm.Name)
115112
}
@@ -118,13 +115,48 @@ currentUGroup:
118115
}
119116
} else {
120117
sdkWm.ID = existingWm.ID
118+
if asSimpleUser && modelPattern == nil {
119+
if existingWm.Type != sdk.Docker || existingWm.Restricted != sdkWm.Restricted { // Forbidden because we can't fetch previous user data
120+
return nil, sdk.WrapError(sdk.ErrWorkerModelNoPattern, "we can't fetch previous user data because type or restricted is different")
121+
}
122+
switch sdkWm.Type {
123+
case sdk.Docker:
124+
img := sdkWm.ModelDocker.Image
125+
sdkWm.ModelDocker = existingWm.ModelDocker
126+
sdkWm.ModelDocker.Image = img
127+
default:
128+
img := sdkWm.ModelVirtualMachine.Image
129+
flavor := sdkWm.ModelVirtualMachine.Flavor
130+
sdkWm.ModelVirtualMachine = existingWm.ModelVirtualMachine
131+
sdkWm.ModelVirtualMachine.Image = img
132+
sdkWm.ModelVirtualMachine.Flavor = flavor
133+
}
134+
}
135+
if !asSimpleUser {
136+
if errInvalidModel != nil {
137+
return nil, errInvalidModel
138+
}
139+
if badRequestError != nil {
140+
return nil, badRequestError
141+
}
142+
}
143+
121144
if errU := UpdateWorkerModel(db, &sdkWm); errU != nil {
122145
return nil, sdk.WrapError(errU, "cannot update worker model %s", sdkWm.Name)
123146
}
124147
}
125148
return &sdkWm, nil
126149
}
127150

151+
if asSimpleUser && modelPattern == nil {
152+
return nil, sdk.ErrWorkerModelNoPattern
153+
}
154+
if errInvalidModel != nil {
155+
return nil, errInvalidModel
156+
}
157+
if badRequestError != nil {
158+
return nil, badRequestError
159+
}
128160
if errAdd := InsertWorkerModel(db, &sdkWm); errAdd != nil {
129161
if errPG, ok := sdk.Cause(errAdd).(*pq.Error); ok && errPG.Code == gorpmapping.ViolateUniqueKeyPGCode {
130162
errAdd = sdk.ErrConflict

engine/api/worker_model.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,10 @@ func (api *API) updateWorkerModelHandler() service.Handler {
264264
//User must be admin of the group set in the model
265265
var ok bool
266266
currentUGroup:
267-
for _, g := range deprecatedGetUser(ctx).Groups {
267+
for _, g := range user.Groups {
268268
if g.ID == model.GroupID {
269269
for _, a := range g.Admins {
270-
if a.ID == deprecatedGetUser(ctx).ID {
270+
if a.ID == user.ID {
271271
ok = true
272272
break currentUGroup
273273
}
@@ -276,7 +276,7 @@ func (api *API) updateWorkerModelHandler() service.Handler {
276276
}
277277

278278
//User should have the right permission or be admin
279-
if !deprecatedGetUser(ctx).Admin && !ok {
279+
if !user.Admin && !ok {
280280
return sdk.ErrWorkerModelNoAdmin
281281
}
282282

@@ -287,8 +287,8 @@ func (api *API) updateWorkerModelHandler() service.Handler {
287287
}
288288
if !user.Admin && !model.Restricted {
289289
if modelPattern == nil {
290-
if old.Type != sdk.Docker { // Forbidden because we can't fetch previous user data
291-
return sdk.WrapError(sdk.ErrWorkerModelNoPattern, "we can't fetch previous user data because type is different")
290+
if old.Type != sdk.Docker || old.Restricted != model.Restricted { // Forbidden because we can't fetch previous user data
291+
return sdk.WrapError(sdk.ErrWorkerModelNoPattern, "we can't fetch previous user data because type or restricted is different")
292292
}
293293
model.ModelDocker.Cmd = old.ModelDocker.Cmd
294294
model.ModelDocker.Shell = old.ModelDocker.Shell

engine/api/worker_model_export.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ import (
F438 1212

1313
func (api *API) getWorkerModelExportHandler() service.Handler {
1414
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
15-
workerModelID, errr := requestVarInt(r, "permModelID")
15+
u := deprecatedGetUser(ctx)
16+
workerModelID, errr := requestVarInt(r, "modelID")
1617
if errr != nil {
17-
return sdk.WrapError(errr, "Invalid permModelID")
18+
return sdk.WrapError(errr, "Invalid modelID")
1819
}
1920

2021
format := FormString(r, "format")
@@ -33,7 +34,12 @@ func (api *API) getWorkerModelExportHandler() service.Handler {
3334
return sdk.WrapError(err, "Format invalid")
3435
}
3536

36-
if _, err := worker.Export(*wm, f, w); err != nil {
37+
opts := []exportentities.WorkerModelOption{}
38+
if u != nil && !u.Admin && !wm.Restricted {
39+
opts = append(opts, exportentities.WorkerModelLoadOptions.HideAdminFields)
40+
}
41+
42+
if _, err := worker.Export(*wm, f, w, opts...); err != nil {
3743
return err
3844
}
3945

sdk/exportentities/worker_model.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,25 @@ type WorkerModel struct {
2424
IsDeprecated bool `json:"is_deprecated,omitempty" yaml:"is_deprecated,omitempty"`
2525
}
2626

27+
type WorkerModelOption func(sdk.Model, *WorkerModel) error
28+
29+
var WorkerModelLoadOptions = struct {
30+
HideAdminFields WorkerModelOption
31+
}{
32+
HideAdminFields: loadWorkerModelWithoutAdminFields,
33+
}
34+
35+
func loadWorkerModelWithoutAdminFields(_ sdk.Model, wm *WorkerModel) error {
36+
wm.PreCmd = ""
37+
wm.Shell = ""
38+
wm.Cmd = ""
39+
wm.PostCmd = ""
40+
wm.Envs = nil
41+
return nil
42+
}
43+
2744
// NewWorkerModel creates an exportentities WorkerModel from a struct sdk.Model
28-
func NewWorkerModel(wm sdk.Model) WorkerModel {
45+
func NewWorkerModel(wm sdk.Model, opts ...WorkerModelOption) WorkerModel {
2946
model := WorkerModel{
3047
Type: wm.Type,
3148
Name: wm.Name,
@@ -53,15 +70,15 @@ func NewWorkerModel(wm sdk.Model) WorkerModel {
5370
model.PostCmd = wm.ModelVirtualMachine.PostCmd
5471
}
5572

73+
for _, opt := range opts {
74+
_ = opt(wm, &model)
75+
}
76+
5677
return model
5778
}
5879

5980
// GetWorkerModel convert an exportentities to a real sdk.Model
6081
func (wm WorkerModel) GetWorkerModel() (sdk.Model, error) {
61-
if err := wm.IsValid(); err != nil {
62-
return sdk.Model{}, err
63-
}
64-
6582
model := sdk.Model{
6683
Type: wm.Type,
6784
Name: wm.Name,
@@ -92,7 +109,7 @@ func (wm WorkerModel) GetWorkerModel() (sdk.Model, error) {
92109
}
93110
}
94111

95-
return model, nil
112+
return model, wm.IsValid()
96113
}
97114

98115
// IsValid returns error if worker model is invalid

0 commit comments

Comments
 (0)
0