Merge pull request #10652 from wy65701436/fix-10552

Use controller rather than manager in the API handler and middleware
This commit is contained in:
Wenkai Yin(尹文开) 2020-02-07 19:30:51 +08:00 committed by GitHub
commit 8a74fcb074
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 161 deletions

View File

@ -3,14 +3,9 @@ package immutable
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/goharbor/harbor/src/api/artifact"
common_util "github.com/goharbor/harbor/src/common/utils" common_util "github.com/goharbor/harbor/src/common/utils"
internal_errors "github.com/goharbor/harbor/src/internal/error" internal_errors "github.com/goharbor/harbor/src/internal/error"
"github.com/goharbor/harbor/src/pkg/art"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/immutabletag/match/rule"
"github.com/goharbor/harbor/src/pkg/q"
"github.com/goharbor/harbor/src/pkg/repository"
"github.com/goharbor/harbor/src/pkg/tag"
"github.com/goharbor/harbor/src/server/middleware" "github.com/goharbor/harbor/src/server/middleware"
"net/http" "net/http"
) )
@ -43,56 +38,20 @@ func handleDelete(req *http.Request) error {
return errors.New("cannot get the manifest information from request context") return errors.New("cannot get the manifest information from request context")
} }
_, repoName := common_util.ParseRepository(mf.Repository) af, err := artifact.Ctl.GetByReference(req.Context(), mf.Repository, mf.Digest, &artifact.Option{
total, repos, err := repository.Mgr.List(req.Context(), &q.Query{ WithTag: true,
Keywords: map[string]interface{}{ TagOption: &artifact.TagOption{WithImmutableStatus: true},
"Name": mf.Repository,
},
}) })
if err != nil { if err != nil {
return err if internal_errors.IsErr(err, internal_errors.NotFoundCode) {
} return nil
if total == 0 {
return nil
}
total, afs, err := artifact.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"ProjectID": mf.ProjectID,
"RepositoryID": repos[0].RepositoryID,
"Digest": mf.Digest,
},
})
if err != nil {
return err
}
if total == 0 {
return nil
}
total, tags, err := tag.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"ArtifactID": afs[0].ID,
},
})
if err != nil {
return err
}
if total == 0 {
return nil
}
for _, tag := range tags {
var matched bool
matched, err = rule.NewRuleMatcher().Match(mf.ProjectID, art.Candidate{
Repository: repoName,
Tag: tag.Name,
NamespaceID: mf.ProjectID,
})
if err != nil {
return err
} }
if matched { return err
}
_, repoName := common_util.ParseRepository(mf.Repository)
for _, tag := range af.Tags {
if tag.Immutable {
return NewErrImmutable(repoName, tag.Name) return NewErrImmutable(repoName, tag.Name)
} }
} }

View File

@ -3,14 +3,9 @@ package immutable
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/goharbor/harbor/src/api/artifact"
common_util "github.com/goharbor/harbor/src/common/utils" common_util "github.com/goharbor/harbor/src/common/utils"
internal_errors "github.com/goharbor/harbor/src/internal/error" internal_errors "github.com/goharbor/harbor/src/internal/error"
"github.com/goharbor/harbor/src/pkg/art"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/immutabletag/match/rule"
"github.com/goharbor/harbor/src/pkg/q"
"github.com/goharbor/harbor/src/pkg/repository"
"github.com/goharbor/harbor/src/pkg/tag"
"github.com/goharbor/harbor/src/server/middleware" "github.com/goharbor/harbor/src/server/middleware"
"net/http" "net/http"
) )
@ -45,65 +40,22 @@ func handlePush(req *http.Request) error {
return errors.New("cannot get the manifest information from request context") return errors.New("cannot get the manifest information from request context")
} }
af, err := artifact.Ctl.GetByReference(req.Context(), mf.Repository, mf.Tag, &artifact.Option{
WithTag: true,
TagOption: &artifact.TagOption{WithImmutableStatus: true},
})
if err != nil {
if internal_errors.IsErr(err, internal_errors.NotFoundCode) {
return nil
}
return err
}
_, repoName := common_util.ParseRepository(mf.Repository) _, repoName := common_util.ParseRepository(mf.Repository)
var matched bool for _, tag := range af.Tags {
matched, err := rule.NewRuleMatcher().Match(mf.ProjectID, art.Candidate{ // push a existing immutable tag, reject th e request
Repository: repoName, if tag.Name == mf.Tag && tag.Immutable {
Tag: mf.Tag, return NewErrImmutable(repoName, mf.Tag)
NamespaceID: mf.ProjectID,
})
if err != nil {
return err
}
if !matched {
return nil
}
// match repository ...
total, repos, err := repository.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"Name": mf.Repository,
},
})
if err != nil {
return err
}
if total == 0 {
return nil
}
// match artifacts ...
total, afs, err := artifact.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"ProjectID": mf.ProjectID,
"RepositoryID": repos[0].RepositoryID,
},
})
if err != nil {
return err
}
if total == 0 {
return nil
}
// match tags ...
for _, af := range afs {
total, tags, err := tag.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"ArtifactID": af.ID,
},
})
if err != nil {
return err
}
if total == 0 {
continue
}
for _, tag := range tags {
// push a existing immutable tag, reject the request
if tag.Name == mf.Tag {
return NewErrImmutable(repoName, mf.Tag)
}
} }
} }

View File

@ -4,16 +4,13 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/goharbor/harbor/src/api/artifact"
"github.com/goharbor/harbor/src/common/models" "github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/common/utils/log"
"github.com/goharbor/harbor/src/core/config" "github.com/goharbor/harbor/src/core/config"
"github.com/goharbor/harbor/src/core/promgr" "github.com/goharbor/harbor/src/core/promgr"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/q"
"github.com/goharbor/harbor/src/pkg/repository"
"github.com/goharbor/harbor/src/pkg/scan/vuln" "github.com/goharbor/harbor/src/pkg/scan/vuln"
"github.com/goharbor/harbor/src/pkg/scan/whitelist" "github.com/goharbor/harbor/src/pkg/scan/whitelist"
"github.com/goharbor/harbor/src/pkg/tag"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
"github.com/pkg/errors" "github.com/pkg/errors"
"net/http" "net/http"
@ -70,50 +67,13 @@ type ManifestInfo struct {
// ManifestExists ... // ManifestExists ...
func (info *ManifestInfo) ManifestExists(ctx context.Context) (bool, error) { func (info *ManifestInfo) ManifestExists(ctx context.Context) (bool, error) {
info.manifestExistOnce.Do(func() { info.manifestExistOnce.Do(func() {
af, err := artifact.Ctl.GetByReference(ctx, info.Repository, info.Tag, nil)
// ToDo: use the artifact controller method
total, repos, err := repository.Mgr.List(ctx, &q.Query{
Keywords: map[string]interface{}{
"Name": info.Repository,
},
})
if err != nil { if err != nil {
info.manifestExistErr = err info.manifestExistErr = err
return return
} }
if total == 0 { info.manifestExist = true
return info.Digest = af.Digest
}
total, tags, err := tag.Mgr.List(ctx, &q.Query{
Keywords: map[string]interface{}{
"Name": info.Tag,
"RepositoryID": repos[0].RepositoryID,
},
})
if err != nil {
info.manifestExistErr = err
return
}
if total == 0 {
return
}
total, afs, err := artifact.Mgr.List(ctx, &q.Query{
Keywords: map[string]interface{}{
"ID": tags[0].ArtifactID,
},
})
if err != nil {
info.manifestExistErr = err
return
}
if total == 0 {
return
}
info.Digest = afs[0].Digest
info.manifestExist = total > 0
}) })
return info.manifestExist, info.manifestExistErr return info.manifestExist, info.manifestExistErr