diff --git a/Deploy/config/registry/root.crt b/Deploy/config/registry/root.crt index 326d8080a..71ef6787f 100644 --- a/Deploy/config/registry/root.crt +++ b/Deploy/config/registry/root.crt @@ -1,15 +1,35 @@ -----BEGIN CERTIFICATE----- -MIICWDCCAcGgAwIBAgIJAN1nLuloDeHNMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTYwMTI3MDQyMDM1WhcNNDMwNjE0MDQyMDM1WjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB -gQClak/4HO7EeLU0w/BhtVENPLOqU0AP2QjVUdg1qhNiDWVrbWx9KYHqz5Kn0n2+ -fxdZo3o7ZY5/2+hhgkKh1z6Kge9XGgune6z4fx2J/X2Se8WsGeQUTiND8ngSnsCA -NtYFwW50SbUZPtyf5XjAfKRofZem51OxbxzN3217L/ubKwIDAQABo1AwTjAdBgNV -HQ4EFgQU5EG2VrB3I6G/TudUpz+kBgQXSvYwHwYDVR0jBBgwFoAU5EG2VrB3I6G/ -TudUpz+kBgQXSvYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAx+2eo -oOm0YNy9KQ81+7GQkKVWoPQXjAGGgZuZj8WCFepYqUSJ4q5qbuVCY8WbGcHVk2Rx -Jg1XDCmMjBgYP6S0ikezBRqSmNA3G6oFiydTKBfPs6RNalsB0C78Xk5l5+PIyd2R -jFKOKoMpkjwfeJv2j64WNGoBgqj7XRBoJ11a4g== +MIIGBzCCA++gAwIBAgIJANjBN67MD5SgMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD +VQQGEwJDTjEOMAwGA1UECAwFU3RhdGUxCzAJBgNVBAcMAkNOMRUwEwYDVQQKDAxv +cmdhbml6YXRpb24xHDAaBgNVBAsME29yZ2FuaXphdGlvbmFsIHVuaXQxFDASBgNV +BAMMC2V4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu +Y29tMB4XDTE2MDUxMDA0MTMxM1oXDTI2MDUwODA0MTMxM1owgZkxCzAJBgNVBAYT +AkNOMQ4wDAYDVQQIDAVTdGF0ZTELMAkGA1UEBwwCQ04xFTATBgNVBAoMDG9yZ2Fu +aXphdGlvbjEcMBoGA1UECwwTb3JnYW5pemF0aW9uYWwgdW5pdDEUMBIGA1UEAwwL +ZXhhbXBsZS5jb20xIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20w +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVSMUP/IR3iGdM4WrvuWno +Jy+mjOV/Qcte8gK92ClKd5zObAlo6/hn8ZMTeub76A9i39QN8GlQDFMtfv29EpLn +XXoVvLIwH4olycSdrye0ustOke/KT2RHAl3cVi5Zau0rfnb6h5kPQFFgjHsFdsLi +KIOBru976pJh3qxXq2xHIbmHvqLLEGuvt2WKXiRyz9ex6zbc/RTQhesJIA/N73Xo +9m5TfKOimuTedHYuGwS9XAHdr0W+EZl39keaPemrJz5QcebwwZPApuGwe0We8koL +0W1b2Z1a/gUdjcE++RVDOpHCupB/MltB+FSBJKd6LIbkjV1AC+T3NB3CzDPUP/Ep +bjk4wJqGOmMS+/mZbVu9lybrem7V0Wc03DEQyjZztpBcQ6MFbVw3pIbp3fAWhyDJ +N1y+i0O1Llcybpje5P3fQ0ioYc3hF61Wj3bAAx7ddPmrmtVGgisfvcTIRjNLGylM +qObhRjPPvky03x2jtwTnPX74gowuqq70sZHjfqpmXrjpJi9RMEJz30dxW6gy9Mn+ +MOTzwJ7iu3sm6XidaogMvMFrVlLfgIVLl+WfZJIv+i2by6TXfZ6/5OTvU4fzc1NZ +VeWBUSznmM/V72sWc/3AFgNibysv95OwDohqy91N9U73P6Q8H96hkDVHHhktHSL6 +s1OQau9XDgKS6xhZZsRxlwIDAQABo1AwTjAdBgNVHQ4EFgQUQl1pgU1b+rJMvLsQ +W1YednSAsDUwHwYDVR0jBBgwFoAUQl1pgU1b+rJMvLsQW1YednSAsDUwDAYDVR0T +BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAxCMLH/BhxzAGI2k8oBUXOaFXB+uo +2hrteE4glQw0nY959y7FEgKYBKKktWRqNBB/FlNSsrritfhWNK04tIHDQtUhP09m +2TD/0bxY++i+cyhqflHnyROkhAtcg1SBDhwkDMyEKnjzEe7t80Vq6d2sEBbq4PcA +Owl9Xj8elTt1g6aKP4Wt1V7ktZG+zAct+VPQtCnXCH2GAbkN8zqYKpCmzW0IBy0D +NFWKjsebXawOjUwMFu9MTDIwU3DvcCcrNj8k1palLPNNuyXqbsmencFjDRe2mZDU +lA2l4bpZ4G4HPSUJmhZHQ7eq9CYr5goS+kI36n5Uvg2TDDQQxXtfugRkI1qqxGlU +w+qc5BeQqkBior/dI/70+z0ith8/qZZ4U+y7eYY2lzIaNAOn2YLIdxkjF4YxIbSu +kV+Flxa4pFookeLvucZP1v3yW9VdHwClRGD4S4yiGC4j5uG8kcyRssH+iwdTm4Bl +0PSYiseeb0xlDaZMMq4K1IRvPLZ4PBKe+I6db8TIsTQjLIx8cUKaMdJlBUVLnmVG +uKKxdNz0OBUykEMAltHSagp/QqmVCED/q+Y1dsR2c2jy48dKl0mNRSTxMyaO1DTA +Fuzq0uQJetQdgwEdnoU0nabDk56vP686g4rJR8N6r822JxIfpE6ZLasgBX9P4jJS +rbSyDwCgpBd5p2g= -----END CERTIFICATE----- diff --git a/Deploy/config/ui/private_key.pem b/Deploy/config/ui/private_key.pem index 6c68cacb3..fb3d973fe 100644 --- a/Deploy/config/ui/private_key.pem +++ b/Deploy/config/ui/private_key.pem @@ -1,15 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/Deploy/harbor.cfg b/Deploy/harbor.cfg index bd949cea5..1a59f9578 100644 --- a/Deploy/harbor.cfg +++ b/Deploy/harbor.cfg @@ -2,7 +2,7 @@ #The IP address or hostname to access admin UI and registry service. #DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients. -hostname = reg.mydomain.com +hostname = localhost #The protocol for accessing the UI and token/notification service, by default it is http. #It can be set to https if ssl is enabled on nginx. diff --git a/api/statistic.go b/api/statistic.go new file mode 100644 index 000000000..5612fcd93 --- /dev/null +++ b/api/statistic.go @@ -0,0 +1,146 @@ +/* + Copyright (c) 2016 VMware, Inc. All Rights Reserved. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package api + +import ( + "net/http" + "os" + + "github.com/vmware/harbor/dao" + "github.com/vmware/harbor/models" + svc_utils "github.com/vmware/harbor/service/utils" + "github.com/vmware/harbor/utils/log" + "github.com/vmware/harbor/utils/registry" + "github.com/vmware/harbor/utils/registry/auth" +) + +type StatisticAPI struct { + BaseAPI + userID int + username string + registry *registry.Registry +} + +//Prepare validates the URL and the user +func (s *StatisticAPI) Prepare() { + userID, ok := s.GetSession("userId").(int) + if !ok { + s.userID = dao.NonExistUserID + } else { + s.userID = userID + log.Debug("userID is xxx", userID) + } + username, ok := s.GetSession("username").(string) + if !ok { + log.Warning("failed to get username from session") + s.username = "" + } else { + s.username = username + log.Debug("username is xxx", username) + } + + var client *http.Client + + //no session, initialize a standard auth handler + if s.userID == dao.NonExistUserID && len(s.username) == 0 { + username, password, _ := s.Ctx.Request.BasicAuth() + + credential := auth.NewBasicAuthCredential(username, password) + client = registry.NewClientStandardAuthHandlerEmbeded(credential) + log.Debug("initializing standard auth handler") + + } else { + // session works, initialize a username auth handler + username := s.username + if len(username) == 0 { + user, err := dao.GetUser(models.User{ + UserID: s.userID, + }) + if err != nil { + log.Errorf("error occurred whiling geting user for initializing a username auth handler: %v", err) + return + } + + username = user.Username + } + + client = registry.NewClientUsernameAuthHandlerEmbeded(username) + log.Debug("initializing username auth handler: %s", username) + } + + endpoint := os.Getenv("REGISTRY_URL") + r, err := registry.New(endpoint, client) + if err != nil { + log.Fatalf("error occurred while initializing auth handler for repository API: %v", err) + } + + s.registry = r +} + +// Get total projects and repos of the user +func (s *StatisticAPI) Get() { + queryProject := models.Project{UserID: s.userID} + projectList, err := dao.QueryProject(queryProject) + var projectArr [6]int + if err != nil { + log.Errorf("Error occured in QueryProject, error: %v", err) + s.CustomAbort(http.StatusInternalServerError, "Internal error.") + } + log.Debug("projectList xxx ", projectList) + isAdmin, _ := dao.IsAdminRole(s.userID) + for i := 0; i < len(projectList); i++ { + if isProjectAdmin(s.userID, projectList[i].ProjectID) { + projectArr[0] += 1 + projectArr[1] += s.GetRepos(projectList[i].ProjectID) + } + if projectList[i].Public == 1 { + projectArr[2] += 1 + projectArr[3] += s.GetRepos(projectList[i].ProjectID) + } + if isAdmin { + projectArr[5] += s.GetRepos(projectList[i].ProjectID) + } + } + if isAdmin { + projectArr[4] = len(projectList) + } + s.Data["json"] = projectArr + s.ServeJSON() +} + +func (s *StatisticAPI) GetRepos(projectID int64) int { + p, err := dao.GetProjectByID(projectID) + if err != nil { + log.Errorf("Error occurred in GetProjectById, error: %v", err) + s.CustomAbort(http.StatusInternalServerError, "Internal error.") + } + if p == nil { + log.Warningf("Project with Id: %d does not exist", projectID) + s.RenderError(http.StatusNotFound, "") + return 0 + } + if p.Public == 0 && !checkProjectPermission(s.userID, projectID) { + s.RenderError(http.StatusForbidden, "") + return 0 + } + + repoList, err := svc_utils.GetRepoFromCache() + if err != nil { + log.Errorf("Failed to get repo from cache, error: %v", err) + s.RenderError(http.StatusInternalServerError, "internal sever error") + } + return len(repoList) +} diff --git a/ui/router.go b/ui/router.go index 401745410..1218424c2 100644 --- a/ui/router.go +++ b/ui/router.go @@ -54,6 +54,7 @@ func initRouters() { beego.Router("/api/search", &api.SearchAPI{}) beego.Router("/api/projects/:pid/members/?:mid", &api.ProjectMemberAPI{}) beego.Router("/api/projects/?:id", &api.ProjectAPI{}) + beego.Router("/api/statistics", &api.StatisticAPI{}) beego.Router("/api/projects/:id/logs/filter", &api.ProjectAPI{}, "post:FilterAccessLog") beego.Router("/api/users", &api.UserAPI{}) beego.Router("/api/users/?:id", &api.UserAPI{})