Merge pull request #10541 from ywk253100/200120_default_resolver

Try to parse the type of the artifact based on the media type when no resolver found
This commit is contained in:
Wenkai Yin(尹文开) 2020-01-21 14:41:35 +08:00 committed by GitHub
commit 4dc59c5e39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 16 deletions

View File

@ -26,8 +26,15 @@ import (
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/repository"
"github.com/opencontainers/image-spec/specs-go/v1"
"regexp"
"strings"
)
// ArtifactTypeUnknown defines the type for the unknown artifacts
const ArtifactTypeUnknown = "UNKNOWN"
var artifactTypeRegExp = regexp.MustCompile(`^application/vnd\.[^.]*\.(.*)\.config\.[^.]*\+json$`)
// Abstractor abstracts the specific information for different types of artifacts
type Abstractor interface {
// Abstract the specific information for the specific artifact type into the artifact model,
@ -109,10 +116,22 @@ func (a *abstractor) Abstract(ctx context.Context, artifact *artifact.Artifact)
return fmt.Errorf("unsupported manifest media type: %s", artifact.ManifestMediaType)
}
resolver, err := resolver.Get(artifact.MediaType)
if err != nil {
return err
resolver := resolver.Get(artifact.MediaType)
if resolver != nil {
artifact.Type = resolver.ArtifactType()
return resolver.Resolve(ctx, content, artifact)
}
artifact.Type = resolver.ArtifactType()
return resolver.Resolve(ctx, content, artifact)
// if got no resolver, try to parse the artifact type based on the media type
artifact.Type = parseArtifactType(artifact.MediaType)
return nil
}
func parseArtifactType(mediaType string) string {
strs := artifactTypeRegExp.FindStringSubmatch(mediaType)
if len(strs) == 2 {
return strings.ToUpper(strs[1])
}
// can not get the artifact type from the media type, return unknown
return ArtifactTypeUnknown
}

View File

@ -294,6 +294,28 @@ func (a *abstractorTestSuite) TestAbstractUnsupported() {
a.fetcher.AssertExpectations(a.T())
}
func (a *abstractorTestSuite) TestParseArtifactType() {
mediaType := ""
typee := parseArtifactType(mediaType)
a.Equal(ArtifactTypeUnknown, typee)
mediaType = "unknown"
typee = parseArtifactType(mediaType)
a.Equal(ArtifactTypeUnknown, typee)
mediaType = "application/vnd.oci.image.config.v1+json"
typee = parseArtifactType(mediaType)
a.Equal("IMAGE", typee)
mediaType = "application/vnd.cncf.helm.chart.config.v1+json"
typee = parseArtifactType(mediaType)
a.Equal("HELM.CHART", typee)
mediaType = "application/vnd.sylabs.sif.config.v1+json"
typee = parseArtifactType(mediaType)
a.Equal("SIF", typee)
}
func TestAbstractorTestSuite(t *testing.T) {
suite.Run(t, &abstractorTestSuite{})
}

View File

@ -49,10 +49,6 @@ func Register(resolver Resolver, mediaTypes ...string) error {
}
// Get the resolver according to the media type
func Get(mediaType string) (Resolver, error) {
resolver, exist := registry[mediaType]
if !exist {
return nil, fmt.Errorf("resolver resolves %s not found", mediaType)
}
return resolver, nil
func Get(mediaType string) Resolver {
return registry[mediaType]
}

View File

@ -11,10 +11,22 @@
package resolver
import (
"context"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/stretchr/testify/suite"
"testing"
)
type fakeResolver struct{}
func (f *fakeResolver) ArtifactType() string {
return ""
}
func (f *fakeResolver) Resolve(ctx context.Context, manifest []byte, artifact *artifact.Artifact) error {
return nil
}
type resolverTestSuite struct {
suite.Suite
}
@ -37,16 +49,16 @@ func (r *resolverTestSuite) TestRegister() {
func (r *resolverTestSuite) TestGet() {
// registry a resolver
mediaType := "fake_media_type"
err := Register(nil, mediaType)
err := Register(&fakeResolver{}, mediaType)
r.Assert().Nil(err)
// get the resolver
_, err = Get(mediaType)
r.Assert().Nil(err)
resolver := Get(mediaType)
r.Assert().NotNil(resolver)
// get the not exist resolver
_, err = Get("not_existing_media_type")
r.Assert().NotNil(err)
resolver = Get("not_existing_media_type")
r.Assert().Nil(resolver)
}
func TestResolverTestSuite(t *testing.T) {