Wenkai Yin(尹文开) 8984979bd2
Relocate/rename some packages (#11183)
Fixes #11016
1. src/pkg/q->src/internal/q
2. src/internal->src/lib (internal is a reserved package name of golang)
3. src/api->src/controller

Signed-off-by: Wenkai Yin <yinw@vmware.com>
2020-03-24 20:45:45 +08:00

145 lines
3.4 KiB
Go

// Copyright Project Harbor Authors
//
// 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 chartmuseum
import (
"context"
"errors"
"net/http"
"net/url"
"strings"
"sync"
"github.com/goharbor/harbor/src/chartserver"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/config"
commonhttp "github.com/goharbor/harbor/src/common/http"
"github.com/goharbor/harbor/src/controller/project"
)
var (
// Ctl is a global chartmuseum controller instance
Ctl = NewController()
)
// Controller defines the operations related with chartmuseum which only used by quota now
type Controller interface {
// Count returns charts count in the project
Count(ctx context.Context, projectID int64) (int64, error)
// Exist returns true when chart exist in the project
Exist(ctx context.Context, projectID int64, chartName, version string) (bool, error)
}
// NewController creates an instance of the default repository controller
func NewController() Controller {
return &controller{
projectCtl: project.Ctl,
}
}
type controller struct {
projectCtl project.Controller
cc *chartserver.Controller
withChartMuseum bool
initializeError error
initializeOnce sync.Once
}
func (c *controller) initialize() error {
c.initializeOnce.Do(func() {
cfg := config.NewDBCfgManager()
c.withChartMuseum = cfg.Get(common.WithChartMuseum).GetBool()
if !c.withChartMuseum {
return
}
chartEndpoint := strings.TrimSpace(cfg.Get(common.ChartRepoURL).GetString())
if len(chartEndpoint) == 0 {
c.initializeError = errors.New("empty chartmuseum endpoint")
return
}
url, err := url.Parse(strings.TrimSuffix(chartEndpoint, "/"))
if err != nil {
c.initializeError = errors.New("endpoint URL of chart storage server is malformed")
return
}
ctr, err := chartserver.NewController(url)
if err != nil {
c.initializeError = errors.New("failed to initialize chart API controller")
return
}
c.cc = ctr
})
return c.initializeError
}
func (c *controller) Count(ctx context.Context, projectID int64) (int64, error) {
if err := c.initialize(); err != nil {
return 0, err
}
if !c.withChartMuseum {
return 0, nil
}
proj, err := c.projectCtl.Get(ctx, projectID)
if err != nil {
return 0, err
}
count, err := c.cc.GetCountOfCharts([]string{proj.Name})
if err != nil {
return 0, err
}
return int64(count), nil
}
func (c *controller) Exist(ctx context.Context, projectID int64, chartName, version string) (bool, error) {
if err := c.initialize(); err != nil {
return false, err
}
if !c.withChartMuseum {
return false, nil
}
proj, err := c.projectCtl.Get(ctx, projectID)
if err != nil {
return false, err
}
chartVersion, err := c.cc.GetChartVersion(proj.Name, chartName, version)
if err != nil {
var httpErr *commonhttp.Error
if errors.As(err, &httpErr) {
if httpErr.Code == http.StatusNotFound {
return false, nil
}
}
return false, err
}
return !chartVersion.Removed, nil
}