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/artifact"
"github.com/goharbor/harbor/src/pkg/repository" "github.com/goharbor/harbor/src/pkg/repository"
"github.com/opencontainers/image-spec/specs-go/v1" "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 // Abstractor abstracts the specific information for different types of artifacts
type Abstractor interface { type Abstractor interface {
// Abstract the specific information for the specific artifact type into the artifact model, // 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) return fmt.Errorf("unsupported manifest media type: %s", artifact.ManifestMediaType)
} }
resolver, err := resolver.Get(artifact.MediaType) resolver := resolver.Get(artifact.MediaType)
if err != nil { if resolver != nil {
return err 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()) 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) { func TestAbstractorTestSuite(t *testing.T) {
suite.Run(t, &abstractorTestSuite{}) 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 // Get the resolver according to the media type
func Get(mediaType string) (Resolver, error) { func Get(mediaType string) Resolver {
resolver, exist := registry[mediaType] return registry[mediaType]
if !exist {
return nil, fmt.Errorf("resolver resolves %s not found", mediaType)
}
return resolver, nil
} }

View File

@ -11,10 +11,22 @@
package resolver package resolver
import ( import (
"context"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"testing" "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 { type resolverTestSuite struct {
suite.Suite suite.Suite
} }
@ -37,16 +49,16 @@ func (r *resolverTestSuite) TestRegister() {
func (r *resolverTestSuite) TestGet() { func (r *resolverTestSuite) TestGet() {
// registry a resolver // registry a resolver
mediaType := "fake_media_type" mediaType := "fake_media_type"
err := Register(nil, mediaType) err := Register(&fakeResolver{}, mediaType)
r.Assert().Nil(err) r.Assert().Nil(err)
// get the resolver // get the resolver
_, err = Get(mediaType) resolver := Get(mediaType)
r.Assert().Nil(err) r.Assert().NotNil(resolver)
// get the not exist resolver // get the not exist resolver
_, err = Get("not_existing_media_type") resolver = Get("not_existing_media_type")
r.Assert().NotNil(err) r.Assert().Nil(resolver)
} }
func TestResolverTestSuite(t *testing.T) { func TestResolverTestSuite(t *testing.T) {