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

Side by Side Diff: appengine/logdog/coordinator/project.go

Issue 1971493003: LogDog: Project READ access for user endpoints. (Closed) Base URL: https://github.com/luci/luci-go@logdog-project-service-config
Patch Set: Added project archival parametrs, better support. Created 4 years, 7 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
« no previous file with comments | « appengine/logdog/coordinator/hierarchy/project.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package coordinator 5 package coordinator
6 6
7 import ( 7 import (
8 "strings" 8 "strings"
9 9
10 "github.com/luci/gae/service/datastore/meta"
11 "github.com/luci/gae/service/info" 10 "github.com/luci/gae/service/info"
12 » "github.com/luci/luci-go/common/config" 11 » "github.com/luci/luci-go/appengine/logdog/coordinator/config"
12 » luciConfig "github.com/luci/luci-go/common/config"
13 » log "github.com/luci/luci-go/common/logging"
14 » "github.com/luci/luci-go/common/parallel"
13 "github.com/luci/luci-go/common/proto/logdog/svcconfig" 15 "github.com/luci/luci-go/common/proto/logdog/svcconfig"
14 "golang.org/x/net/context" 16 "golang.org/x/net/context"
nodir 2016/05/19 00:38:58 should be in a separate import block
15 ) 17 )
16 18
17 // projectNamespacePrefix is the datastore namespace prefix for project 19 const (
18 // namespaces. 20 » // projectNamespacePrefix is the datastore namespace prefix for project
19 const projectNamespacePrefix = "luci." 21 » // namespaces.
22 » projectNamespacePrefix = "luci."
nodir 2016/05/19 00:38:58 I'd definitely use "project." so namespaces are "p
23
24 » // projectConfigWorkers is the number of workers that will pull project
25 » // configs from the config service.
26 » projectConfigWorkers = 16
27 )
20 28
21 // ProjectNamespace returns the AppEngine namespace for a given luci-config 29 // ProjectNamespace returns the AppEngine namespace for a given luci-config
22 // project name. 30 // project name.
23 func ProjectNamespace(project config.ProjectName) string { 31 func ProjectNamespace(project luciConfig.ProjectName) string {
24 return projectNamespacePrefix + string(project) 32 return projectNamespacePrefix + string(project)
25 } 33 }
26 34
27 // ProjectFromNamespace returns the current project installed in the supplied 35 // ProjectFromNamespace returns the current project installed in the supplied
28 // Context's namespace. 36 // Context's namespace.
29 // 37 //
30 // If the namespace does not have a project namespace prefix, this function 38 // If the namespace does not have a project namespace prefix, this function
31 // will return an empty string. 39 // will return an empty string.
32 func ProjectFromNamespace(ns string) config.ProjectName { 40 func ProjectFromNamespace(ns string) luciConfig.ProjectName {
33 if !strings.HasPrefix(ns, projectNamespacePrefix) { 41 if !strings.HasPrefix(ns, projectNamespacePrefix) {
34 return "" 42 return ""
35 } 43 }
36 » return config.ProjectName(ns[len(projectNamespacePrefix):]) 44 » return luciConfig.ProjectName(ns[len(projectNamespacePrefix):])
37 } 45 }
38 46
39 // CurrentProject returns the current project based on the currently-loaded 47 // CurrentProject returns the current project based on the currently-loaded
40 // namespace. 48 // namespace.
41 // 49 //
42 // If there is no current namespace, or if the current namespace is not a valid 50 // If there is no current namespace, or if the current namespace is not a valid
43 // project namespace, an empty string will be returned. 51 // project namespace, an empty string will be returned.
44 func CurrentProject(c context.Context) config.ProjectName { 52 func CurrentProject(c context.Context) luciConfig.ProjectName {
45 if ns, ok := info.Get(c).GetNamespace(); ok { 53 if ns, ok := info.Get(c).GetNamespace(); ok {
46 return ProjectFromNamespace(ns) 54 return ProjectFromNamespace(ns)
47 } 55 }
48 return "" 56 return ""
49 } 57 }
50 58
51 // CurrentProjectConfig returns the project-specific configuration for the 59 // CurrentProjectConfig returns the project-specific configuration for the
52 // current project. 60 // current project.
53 // 61 //
54 // If there is no current project namespace, or if the current project has no 62 // If there is no current project namespace, or if the current project has no
55 // configuration, config.ErrInvalidConfig will be returned. 63 // configuration, config.ErrInvalidConfig will be returned.
56 func CurrentProjectConfig(c context.Context) (*svcconfig.ProjectConfig, error) { 64 func CurrentProjectConfig(c context.Context) (*svcconfig.ProjectConfig, error) {
57 return GetServices(c).ProjectConfig(c, CurrentProject(c)) 65 return GetServices(c).ProjectConfig(c, CurrentProject(c))
58 } 66 }
59 67
60 // AllProjectsWithNamespaces scans current namespaces and returns those that 68 // ActiveProjects returns a full list of all config service projects with LogDog
61 // belong to LUCI projects. 69 // project configurations.
62 func AllProjectsWithNamespaces(c context.Context) ([]config.ProjectName, error) { 70 //
63 » var projects []config.ProjectName 71 // If userOnly is true, any project not accessible by the current user will not
64 » err := meta.NamespacesWithPrefix(c, projectNamespacePrefix, func(ns stri ng) error { 72 // be returned.
65 » » if proj := ProjectFromNamespace(ns); proj != "" { 73 func ActiveProjects(c context.Context, userOnly bool) ([]luciConfig.ProjectName, error) {
66 » » » projects = append(projects, proj) 74 » projects, err := config.Projects(c)
67 » » }
68 » » return nil
69 » })
70 if err != nil { 75 if err != nil {
71 return nil, err 76 return nil, err
72 } 77 }
78 log.Infof(c, "All projects: %v", projects)
79
80 svcs := GetServices(c)
81 err = parallel.WorkPool(projectConfigWorkers, func(taskC chan<- func() e rror) {
82 for i := range projects {
83 i := i
84 taskC <- func() error {
85 var err error
86 if userOnly {
87 // Verify user access. This includes loa ding the project's config.
88 err = IsProjectReader(c, projects[i])
89 } else {
90 _, err = svcs.ProjectConfig(c, projects[ i])
91 }
92
93 switch {
94 case err == nil:
95 // Project config loaded and (if request ed) user had access.
96 return nil
97
98 case err == luciConfig.ErrNoConfig, err == confi g.ErrInvalidConfig, IsMembershipError(err):
99 // No configuration for this project, th e configuration is invalid, or
100 // the user didn't have access. Remove i t from the list.
101 projects[i] = ""
102 return nil
103
104 default:
105 log.Fields{
106 log.ErrorKey: err,
107 "project": projects[i],
108 "userOnly": userOnly,
109 }.Errorf(c, "Failed to check project.")
110 return err
111 }
112 }
113 }
114 })
115 if err != nil {
116 log.WithError(err).Errorf(c, "Failed to get project list.")
117 return nil, err
118 }
119
120 // Remove any projects that have been blanked out.
121 cidx := 0
122 for _, proj := range projects {
123 if proj != "" {
124 projects[cidx] = proj
125 cidx++
126 }
127 }
128 projects = projects[:cidx]
129 log.Infof(c, "Pruned projects: %v", projects)
73 return projects, nil 130 return projects, nil
74 } 131 }
OLDNEW
« no previous file with comments | « appengine/logdog/coordinator/hierarchy/project.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698