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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « appengine/logdog/coordinator/hierarchy/project.go ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/logdog/coordinator/project.go
diff --git a/appengine/logdog/coordinator/project.go b/appengine/logdog/coordinator/project.go
index 0553620a5bfe27caa9a059bcde0c247b9fd94e46..47defc6c9bc77573382e4000a7bc159ccf967146 100644
--- a/appengine/logdog/coordinator/project.go
+++ b/appengine/logdog/coordinator/project.go
@@ -7,20 +7,28 @@ package coordinator
import (
"strings"
- "github.com/luci/gae/service/datastore/meta"
"github.com/luci/gae/service/info"
- "github.com/luci/luci-go/common/config"
+ "github.com/luci/luci-go/appengine/logdog/coordinator/config"
+ luciConfig "github.com/luci/luci-go/common/config"
+ log "github.com/luci/luci-go/common/logging"
+ "github.com/luci/luci-go/common/parallel"
"github.com/luci/luci-go/common/proto/logdog/svcconfig"
"golang.org/x/net/context"
nodir 2016/05/19 00:38:58 should be in a separate import block
)
-// projectNamespacePrefix is the datastore namespace prefix for project
-// namespaces.
-const projectNamespacePrefix = "luci."
+const (
+ // projectNamespacePrefix is the datastore namespace prefix for project
+ // namespaces.
+ projectNamespacePrefix = "luci."
nodir 2016/05/19 00:38:58 I'd definitely use "project." so namespaces are "p
+
+ // projectConfigWorkers is the number of workers that will pull project
+ // configs from the config service.
+ projectConfigWorkers = 16
+)
// ProjectNamespace returns the AppEngine namespace for a given luci-config
// project name.
-func ProjectNamespace(project config.ProjectName) string {
+func ProjectNamespace(project luciConfig.ProjectName) string {
return projectNamespacePrefix + string(project)
}
@@ -29,11 +37,11 @@ func ProjectNamespace(project config.ProjectName) string {
//
// If the namespace does not have a project namespace prefix, this function
// will return an empty string.
-func ProjectFromNamespace(ns string) config.ProjectName {
+func ProjectFromNamespace(ns string) luciConfig.ProjectName {
if !strings.HasPrefix(ns, projectNamespacePrefix) {
return ""
}
- return config.ProjectName(ns[len(projectNamespacePrefix):])
+ return luciConfig.ProjectName(ns[len(projectNamespacePrefix):])
}
// CurrentProject returns the current project based on the currently-loaded
@@ -41,7 +49,7 @@ func ProjectFromNamespace(ns string) config.ProjectName {
//
// If there is no current namespace, or if the current namespace is not a valid
// project namespace, an empty string will be returned.
-func CurrentProject(c context.Context) config.ProjectName {
+func CurrentProject(c context.Context) luciConfig.ProjectName {
if ns, ok := info.Get(c).GetNamespace(); ok {
return ProjectFromNamespace(ns)
}
@@ -57,18 +65,67 @@ func CurrentProjectConfig(c context.Context) (*svcconfig.ProjectConfig, error) {
return GetServices(c).ProjectConfig(c, CurrentProject(c))
}
-// AllProjectsWithNamespaces scans current namespaces and returns those that
-// belong to LUCI projects.
-func AllProjectsWithNamespaces(c context.Context) ([]config.ProjectName, error) {
- var projects []config.ProjectName
- err := meta.NamespacesWithPrefix(c, projectNamespacePrefix, func(ns string) error {
- if proj := ProjectFromNamespace(ns); proj != "" {
- projects = append(projects, proj)
+// ActiveProjects returns a full list of all config service projects with LogDog
+// project configurations.
+//
+// If userOnly is true, any project not accessible by the current user will not
+// be returned.
+func ActiveProjects(c context.Context, userOnly bool) ([]luciConfig.ProjectName, error) {
+ projects, err := config.Projects(c)
+ if err != nil {
+ return nil, err
+ }
+ log.Infof(c, "All projects: %v", projects)
+
+ svcs := GetServices(c)
+ err = parallel.WorkPool(projectConfigWorkers, func(taskC chan<- func() error) {
+ for i := range projects {
+ i := i
+ taskC <- func() error {
+ var err error
+ if userOnly {
+ // Verify user access. This includes loading the project's config.
+ err = IsProjectReader(c, projects[i])
+ } else {
+ _, err = svcs.ProjectConfig(c, projects[i])
+ }
+
+ switch {
+ case err == nil:
+ // Project config loaded and (if requested) user had access.
+ return nil
+
+ case err == luciConfig.ErrNoConfig, err == config.ErrInvalidConfig, IsMembershipError(err):
+ // No configuration for this project, the configuration is invalid, or
+ // the user didn't have access. Remove it from the list.
+ projects[i] = ""
+ return nil
+
+ default:
+ log.Fields{
+ log.ErrorKey: err,
+ "project": projects[i],
+ "userOnly": userOnly,
+ }.Errorf(c, "Failed to check project.")
+ return err
+ }
+ }
}
- return nil
})
if err != nil {
+ log.WithError(err).Errorf(c, "Failed to get project list.")
return nil, err
}
+
+ // Remove any projects that have been blanked out.
+ cidx := 0
+ for _, proj := range projects {
+ if proj != "" {
+ projects[cidx] = proj
+ cidx++
+ }
+ }
+ projects = projects[:cidx]
+ log.Infof(c, "Pruned projects: %v", projects)
return projects, nil
}
« 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