perf: image tag list (#1862)

* perf: image tag list

Signed-off-by: 逆流而上 <1666888816@qq.com>

* perf: image tag list

Signed-off-by: 逆流而上 <1666888816@qq.com>

* perf: image tag list

Signed-off-by: 逆流而上 <1666888816@qq.com>

* perf: image tag list

Signed-off-by: 逆流而上 <1666888816@qq.com>

* perf: image tag list

Signed-off-by: 逆流而上 <1666888816@qq.com>

* fix: registry context deadline exceeded

Signed-off-by: 逆流而上 <1666888816@qq.com>

---------

Signed-off-by: 逆流而上 <1666888816@qq.com>
This commit is contained in:
逆流而上 2024-01-25 19:07:55 +08:00 committed by GitHub
parent 1c96c66361
commit 4a425b1b44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 94 additions and 8 deletions

View File

@ -292,4 +292,5 @@ type RegistryAuthSecretInterface interface {
type RegistryInterface interface {
GetAllRepo(w http.ResponseWriter, r *http.Request)
GetTagsByRepoName(w http.ResponseWriter, r *http.Request)
CheckRegistry(w http.ResponseWriter, r *http.Request)
}

View File

@ -72,6 +72,7 @@ func (v2 *V2) proxyRoute() chi.Router {
r := chi.NewRouter()
r.Post("/registry/repos", controller.GetManager().GetAllRepo)
r.Post("/registry/tags", controller.GetManager().GetTagsByRepoName)
r.Post("/registry/check", controller.GetManager().CheckRegistry)
return r
}

View File

@ -1,21 +1,87 @@
package controller
import (
api_model "github.com/goodrain/rainbond/api/model"
"context"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
"strings"
"time"
"crypto/tls"
apimodel "github.com/goodrain/rainbond/api/model"
"github.com/goodrain/rainbond/api/util/bcode"
"github.com/goodrain/rainbond/builder/sources/registry"
httputil "github.com/goodrain/rainbond/util/http"
"github.com/sirupsen/logrus"
"net/http"
"net/url"
)
// Registry -
type Registry struct {
}
// RepositoryTags -
type RepositoryTags struct {
Registry string `json:"registry"`
Repository string `json:"repository"`
Tags []string `json:"tags"`
Total int `json:"total"`
}
// CheckRegistry 根据镜像仓库账号密码 检查镜像仓库是否可用
func (r2 *Registry) CheckRegistry(w http.ResponseWriter, r *http.Request) {
var req apimodel.SearchByDomainRequest
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &req, nil)
if !ok {
return
}
if !strings.Contains(req.Domain, "://") {
req.Domain = "//" + req.Domain
}
parse, err := url.Parse(req.Domain)
if err != nil {
logrus.Errorf("parse url error %s", err.Error())
httputil.ReturnBcodeError(r, w, bcode.NewBadRequest(err.Error()))
return
}
options := make([]name.Option, 0)
if parse.Scheme == "http" {
options = append(options, name.Insecure)
}
tr := http.DefaultTransport.(*http.Transport).Clone()
tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
registryCfg, err := name.NewRegistry(parse.Host, options...)
if err != nil {
logrus.Errorf("parse registry error %s", err.Error())
httputil.ReturnBcodeError(r, w, bcode.NewBadRequest(err.Error()))
return
}
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
_, err = transport.NewWithContext(ctx, registryCfg, &authn.Basic{
Username: req.UserName,
Password: req.Password,
}, tr, []string{})
if err != nil {
logrus.Errorf("check registry error %s", err.Error())
httputil.ReturnBcodeError(r, w, bcode.NewBadRequest(err.Error()))
return
}
httputil.ReturnSuccess(r, w, true)
}
// GetAllRepo 根据镜像仓库账号密码 获取所有的镜像仓库
func (r2 *Registry) GetAllRepo(w http.ResponseWriter, r *http.Request) {
var req api_model.SearchByDomainRequest
var req apimodel.SearchByDomainRequest
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &req, nil)
if !ok {
return
@ -37,23 +103,39 @@ func (r2 *Registry) GetAllRepo(w http.ResponseWriter, r *http.Request) {
// GetTagsByRepoName 根据镜像仓库账号密码 获取镜像tags
func (r2 *Registry) GetTagsByRepoName(w http.ResponseWriter, r *http.Request) {
var req api_model.SearchByDomainRequest
var req apimodel.SearchByDomainRequest
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &req, nil)
if !ok {
return
}
c, err := registry.NewInsecure(req.Domain, req.UserName, req.Password)
var regURL string
if strings.HasSuffix(req.Domain, "/") {
regURL = req.Domain + r.URL.Query().Get("repo")
} else {
regURL = req.Domain + "/" + r.URL.Query().Get("repo")
}
repo, err := name.NewRepository(regURL)
if err != nil {
logrus.Errorf("parse registry error %s", err.Error())
httputil.ReturnBcodeError(r, w, bcode.NewBadRequest(err.Error()))
logrus.Errorf("get tags error %s", err.Error())
return
}
tags, err := c.Tags(r.URL.Query().Get("repo"))
authenticator := authn.FromConfig(authn.AuthConfig{
Username: req.UserName,
Password: req.Password,
})
tags, err := remote.List(repo, remote.WithAuth(authenticator))
if err != nil {
httputil.ReturnBcodeError(r, w, bcode.NewBadRequest(err.Error()))
logrus.Errorf("get tags error %s", err.Error())
httputil.ReturnBcodeError(r, w, bcode.NewBadRequest(err.Error()))
return
}
httputil.ReturnSuccess(r, w, tags)
httputil.ReturnSuccess(r, w, &RepositoryTags{
Registry: repo.RegistryStr(),
Repository: repo.RepositoryStr(),
Tags: tags,
Total: len(tags),
})
}

1
go.mod
View File

@ -111,6 +111,7 @@ require (
github.com/coreos/etcd v3.3.13+incompatible
github.com/dustin/go-humanize v1.0.0
github.com/go-playground/assert/v2 v2.0.1
github.com/google/go-containerregistry v0.5.1
github.com/helm/helm v2.17.0+incompatible
golang.org/x/sync v0.2.0
k8s.io/apimachinery v0.28.3

1
go.sum
View File

@ -933,6 +933,7 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.5.1 h1:/+mFTs4AlwsJ/mJe8NDtKb7BxLtbZFpcn8vDsneEkwQ=
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=