Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: scheduler/appengine/catalog/catalog.go

Issue 2986033003: [scheduler]: ACLs phase 1 - per Job ACL specification and enforcement. (Closed)
Patch Set: pcg Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The LUCI Authors. 1 // Copyright 2015 The LUCI Authors.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 15 matching lines...) Expand all
26 26
27 "github.com/golang/protobuf/proto" 27 "github.com/golang/protobuf/proto"
28 "golang.org/x/net/context" 28 "golang.org/x/net/context"
29 29
30 "github.com/luci/gae/service/info" 30 "github.com/luci/gae/service/info"
31 "github.com/luci/luci-go/common/logging" 31 "github.com/luci/luci-go/common/logging"
32 "github.com/luci/luci-go/luci_config/common/cfgtypes" 32 "github.com/luci/luci-go/luci_config/common/cfgtypes"
33 "github.com/luci/luci-go/luci_config/server/cfgclient" 33 "github.com/luci/luci-go/luci_config/server/cfgclient"
34 "github.com/luci/luci-go/luci_config/server/cfgclient/textproto" 34 "github.com/luci/luci-go/luci_config/server/cfgclient/textproto"
35 35
36 "github.com/luci/luci-go/common/errors"
37 "github.com/luci/luci-go/scheduler/appengine/acl"
36 "github.com/luci/luci-go/scheduler/appengine/messages" 38 "github.com/luci/luci-go/scheduler/appengine/messages"
37 "github.com/luci/luci-go/scheduler/appengine/schedule" 39 "github.com/luci/luci-go/scheduler/appengine/schedule"
38 "github.com/luci/luci-go/scheduler/appengine/task" 40 "github.com/luci/luci-go/scheduler/appengine/task"
39 ) 41 )
40 42
41 var ( 43 var (
42 // jobIDRe is used to validate job ID field. 44 // jobIDRe is used to validate job ID field.
Vadim Sh. 2017/08/01 01:56:19 remove this comment or add a similar one to aclSet
tandrii(chromium) 2017/08/01 22:50:01 Done.
43 » jobIDRe = regexp.MustCompile(`^[0-9A-Za-z_\-\.]{1,100}$`) 45 » jobIDRe = regexp.MustCompile(`^[0-9A-Za-z_\-\.]{1,100}$`)
46 » aclSetIdRe = jobIDRe
Vadim Sh. 2017/08/01 01:56:19 nit: aclSetIDRe
tandrii(chromium) 2017/08/01 22:50:01 This isn't used actually, and name was wrong anywa
44 ) 47 )
45 48
46 const ( 49 const (
47 // defaultJobSchedule is default value of 'schedule' field of Job proto. 50 // defaultJobSchedule is default value of 'schedule' field of Job proto.
48 defaultJobSchedule = "triggered" 51 defaultJobSchedule = "triggered"
49 // defaultTriggerSchedule is default value of 'schedule' field of Trigge r 52 // defaultTriggerSchedule is default value of 'schedule' field of Trigge r
50 // proto. 53 // proto.
51 defaultTriggerSchedule = "with 30s interval" 54 defaultTriggerSchedule = "with 30s interval"
52 ) 55 )
53 56
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 // 108 //
106 // Defined via 'trigger {...}' config stanza. 109 // Defined via 'trigger {...}' config stanza.
107 JobFlavorTrigger 110 JobFlavorTrigger
108 ) 111 )
109 112
110 // Definition wraps definition of a scheduler job fetched from the config. 113 // Definition wraps definition of a scheduler job fetched from the config.
111 type Definition struct { 114 type Definition struct {
112 // JobID is globally unique job identifier: "<ProjectID>/<JobName>". 115 // JobID is globally unique job identifier: "<ProjectID>/<JobName>".
113 JobID string 116 JobID string
114 117
118 // Acls describes who can read and who owns this job.
119 Acls acl.GrantsByRole
120
115 // Flavor describes what category of jobs this is, see the enum. 121 // Flavor describes what category of jobs this is, see the enum.
116 Flavor JobFlavor 122 Flavor JobFlavor
117 123
118 // Revision is config revision this definition was fetched from. 124 // Revision is config revision this definition was fetched from.
119 Revision string 125 Revision string
120 126
121 // RevisionURL is URL to human readable page with config file. 127 // RevisionURL is URL to human readable page with config file.
122 RevisionURL string 128 RevisionURL string
123 129
124 // Schedule is job's schedule in regular cron expression format. 130 // Schedule is job's schedule in regular cron expression format.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 if projectName == "" { 193 if projectName == "" {
188 logging.Warningf(c, "Unexpected ConfigSet: %s", meta.Con figSet) 194 logging.Warningf(c, "Unexpected ConfigSet: %s", meta.Con figSet)
189 } else { 195 } else {
190 out = append(out, string(projectName)) 196 out = append(out, string(projectName))
191 } 197 }
192 } 198 }
193 return out, nil 199 return out, nil
194 } 200 }
195 201
196 func (cat *catalog) GetProjectJobs(c context.Context, projectID string) ([]Defin ition, error) { 202 func (cat *catalog) GetProjectJobs(c context.Context, projectID string) ([]Defin ition, error) {
197 » // TODO(vadimsh): This is a workaround for crbug.com/710619. Remove it o nce 203 » // TODO(vadimsh): This is a workaround for http://crbug.com/710619. Remo ve it
198 » // the bug is fixed. 204 » // once the bug is fixed.
199 projects, err := cat.GetAllProjects(c) 205 projects, err := cat.GetAllProjects(c)
200 if err != nil { 206 if err != nil {
201 return nil, err 207 return nil, err
202 } 208 }
203 found := false 209 found := false
204 for _, p := range projects { 210 for _, p := range projects {
205 if p == projectID { 211 if p == projectID {
206 found = true 212 found = true
207 } 213 }
208 } 214 }
(...skipping 22 matching lines...) Expand all
231 return nil, nil 237 return nil, nil
232 default: 238 default:
233 return nil, err 239 return nil, err
234 } 240 }
235 241
236 revisionURL := getRevisionURL(&configSetURL, meta.Revision, meta.Path) 242 revisionURL := getRevisionURL(&configSetURL, meta.Revision, meta.Path)
237 if revisionURL != "" { 243 if revisionURL != "" {
238 logging.Infof(c, "Importing %s", revisionURL) 244 logging.Infof(c, "Importing %s", revisionURL)
239 } 245 }
240 246
247 knownAclSets, err := acl.ValidateAclSets(cfg.GetAclSets())
248 if err != nil {
249 logging.Errorf(c, "Invalid aclsets definition %s: %s", projectID , err)
250 return nil, errors.Annotate(err, "Invalid aclsets in a project % s", projectID).Err()
Vadim Sh. 2017/08/01 01:56:19 I think we annotate with lower case
tandrii(chromium) 2017/08/01 22:50:01 OK, fixed.
251 }
252
241 out := make([]Definition, 0, len(cfg.Job)+len(cfg.Trigger)) 253 out := make([]Definition, 0, len(cfg.Job)+len(cfg.Trigger))
242 254
243 // Regular jobs, triggered jobs. 255 // Regular jobs, triggered jobs.
244 for _, job := range cfg.Job { 256 for _, job := range cfg.Job {
245 if job.Disabled { 257 if job.Disabled {
246 continue 258 continue
247 } 259 }
248 id := "(empty)" 260 id := "(empty)"
249 if job.Id != "" { 261 if job.Id != "" {
250 id = job.Id 262 id = job.Id
251 } 263 }
252 var task proto.Message 264 var task proto.Message
253 if task, err = cat.validateJobProto(job); err != nil { 265 if task, err = cat.validateJobProto(job); err != nil {
254 logging.Errorf(c, "Invalid job definition %s/%s: %s", pr ojectID, id, err) 266 logging.Errorf(c, "Invalid job definition %s/%s: %s", pr ojectID, id, err)
255 continue 267 continue
256 } 268 }
257 packed, err := cat.marshalTask(task) 269 packed, err := cat.marshalTask(task)
258 if err != nil { 270 if err != nil {
259 logging.Errorf(c, "Failed to marshal the task: %s/%s: %s ", projectID, id, err) 271 logging.Errorf(c, "Failed to marshal the task: %s/%s: %s ", projectID, id, err)
260 continue 272 continue
261 } 273 }
262 schedule := job.Schedule 274 schedule := job.Schedule
263 if schedule == "" { 275 if schedule == "" {
264 schedule = defaultJobSchedule 276 schedule = defaultJobSchedule
265 } 277 }
266 flavor := JobFlavorTriggered 278 flavor := JobFlavorTriggered
267 if schedule != "triggered" { 279 if schedule != "triggered" {
268 flavor = JobFlavorPeriodic 280 flavor = JobFlavorPeriodic
269 } 281 }
282 acls, err := acl.ValidateTaskAcls(knownAclSets, job.GetAclSets() , job.GetAcls())
283 if err != nil {
284 logging.Errorf(c, "Failed to compute task ACLs: %s/%s: % s", projectID, id, err)
285 continue
286 }
270 out = append(out, Definition{ 287 out = append(out, Definition{
271 JobID: fmt.Sprintf("%s/%s", projectID, job.Id), 288 JobID: fmt.Sprintf("%s/%s", projectID, job.Id),
289 Acls: *acls,
272 Flavor: flavor, 290 Flavor: flavor,
273 Revision: meta.Revision, 291 Revision: meta.Revision,
274 RevisionURL: revisionURL, 292 RevisionURL: revisionURL,
275 Schedule: schedule, 293 Schedule: schedule,
276 Task: packed, 294 Task: packed,
277 }) 295 })
278 } 296 }
279 297
280 // Triggering jobs. 298 // Triggering jobs.
281 for _, trigger := range cfg.Trigger { 299 for _, trigger := range cfg.Trigger {
(...skipping 11 matching lines...) Expand all
293 } 311 }
294 packed, err := cat.marshalTask(task) 312 packed, err := cat.marshalTask(task)
295 if err != nil { 313 if err != nil {
296 logging.Errorf(c, "Failed to marshal the task: %s/%s: %s ", projectID, id, err) 314 logging.Errorf(c, "Failed to marshal the task: %s/%s: %s ", projectID, id, err)
297 continue 315 continue
298 } 316 }
299 schedule := trigger.Schedule 317 schedule := trigger.Schedule
300 if schedule == "" { 318 if schedule == "" {
301 schedule = defaultTriggerSchedule 319 schedule = defaultTriggerSchedule
302 } 320 }
321 acls, err := acl.ValidateTaskAcls(knownAclSets, trigger.GetAclSe ts(), trigger.GetAcls())
322 if err != nil {
323 logging.Errorf(c, "Failed to compute task ACLs: %s/%s: % s", projectID, id, err)
324 continue
325 }
303 out = append(out, Definition{ 326 out = append(out, Definition{
304 JobID: fmt.Sprintf("%s/%s", projectID, trigger.Id) , 327 JobID: fmt.Sprintf("%s/%s", projectID, trigger.Id) ,
328 Acls: *acls,
305 Flavor: JobFlavorTrigger, 329 Flavor: JobFlavorTrigger,
306 Revision: meta.Revision, 330 Revision: meta.Revision,
307 RevisionURL: revisionURL, 331 RevisionURL: revisionURL,
308 Schedule: schedule, 332 Schedule: schedule,
309 Task: packed, 333 Task: packed,
310 }) 334 })
311 } 335 }
312 336
313 return out, nil 337 return out, nil
314 } 338 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 field := v.Field(i) 466 field := v.Field(i)
443 if field.Type() == taskType { 467 if field.Type() == taskType {
444 field.Set(reflect.ValueOf(task)) 468 field.Set(reflect.ValueOf(task))
445 return proto.Marshal(&wrapper) 469 return proto.Marshal(&wrapper)
446 } 470 }
447 } 471 }
448 // This can happen only if TaskDefWrapper wasn't updated when a new task type 472 // This can happen only if TaskDefWrapper wasn't updated when a new task type
449 // was added. This is a developer's mistake, not a config mistake. 473 // was added. This is a developer's mistake, not a config mistake.
450 return nil, fmt.Errorf("could not find a field of type %T in TaskDefWrap per", task) 474 return nil, fmt.Errorf("could not find a field of type %T in TaskDefWrap per", task)
451 } 475 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698