mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-23 17:17:46 +01:00
Merge pull request #10525 from ywk253100/200117_chart_resolver
Implement the resolver for helm chart
This commit is contained in:
commit
8b3313a1ce
@ -1,3 +1,7 @@
|
|||||||
|
// 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
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
// 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
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
@ -9,3 +13,70 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package chart
|
package chart
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/goharbor/harbor/src/api/artifact/abstractor/blob"
|
||||||
|
resolv "github.com/goharbor/harbor/src/api/artifact/abstractor/resolver"
|
||||||
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/repository"
|
||||||
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ArtifactTypeChart defines the artifact type for helm chart
|
||||||
|
ArtifactTypeChart = "CHART"
|
||||||
|
// TODO import it from helm chart repository
|
||||||
|
mediaType = "application/vnd.cncf.helm.config.v1+json"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
resolver := &resolver{
|
||||||
|
repoMgr: repository.Mgr,
|
||||||
|
blobFetcher: blob.Fcher,
|
||||||
|
}
|
||||||
|
if err := resolv.Register(resolver, mediaType); err != nil {
|
||||||
|
log.Errorf("failed to register resolver for artifact %s: %v", resolver.ArtifactType(), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type resolver struct {
|
||||||
|
repoMgr repository.Manager
|
||||||
|
blobFetcher blob.Fetcher
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *resolver) ArtifactType() string {
|
||||||
|
return ArtifactTypeChart
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *resolver) Resolve(ctx context.Context, manifest []byte, artifact *artifact.Artifact) error {
|
||||||
|
repository, err := r.repoMgr.Get(ctx, artifact.RepositoryID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m := &v1.Manifest{}
|
||||||
|
if err := json.Unmarshal(manifest, m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
digest := m.Config.Digest.String()
|
||||||
|
layer, err := r.blobFetcher.FetchLayer(repository.Name, digest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// TODO should we abstract all values?
|
||||||
|
metadata := map[string]interface{}{}
|
||||||
|
if err := json.Unmarshal(layer, &metadata); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if artifact.ExtraAttrs == nil {
|
||||||
|
artifact.ExtraAttrs = map[string]interface{}{}
|
||||||
|
}
|
||||||
|
for k, v := range metadata {
|
||||||
|
artifact.ExtraAttrs[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
104
src/api/artifact/abstractor/resolver/chart/chart_test.go
Normal file
104
src/api/artifact/abstractor/resolver/chart/chart_test.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// 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 chart
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goharbor/harbor/src/common/models"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||||
|
htesting "github.com/goharbor/harbor/src/testing"
|
||||||
|
"github.com/goharbor/harbor/src/testing/api/artifact/abstractor/blob"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type resolverTestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
resolver *resolver
|
||||||
|
repoMgr *htesting.FakeRepositoryManager
|
||||||
|
blobFetcher *blob.FakeFetcher
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *resolverTestSuite) SetupTest() {
|
||||||
|
r.repoMgr = &htesting.FakeRepositoryManager{}
|
||||||
|
r.blobFetcher = &blob.FakeFetcher{}
|
||||||
|
r.resolver = &resolver{
|
||||||
|
repoMgr: r.repoMgr,
|
||||||
|
blobFetcher: r.blobFetcher,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *resolverTestSuite) TestArtifactType() {
|
||||||
|
r.Assert().Equal(ArtifactTypeChart, r.resolver.ArtifactType())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *resolverTestSuite) TestResolve() {
|
||||||
|
content := `{
|
||||||
|
"schemaVersion": 2,
|
||||||
|
"config": {
|
||||||
|
"mediaType": "application/vnd.cncf.helm.config.v1+json",
|
||||||
|
"digest": "sha256:c87983b066bd08616c6135832363ed42784d66386814694b237f5608213be325",
|
||||||
|
"size": 542
|
||||||
|
},
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.cncf.helm.chart.content.layer.v1+tar",
|
||||||
|
"digest": "sha256:0f8c0650d55f5e00d11d7462381c340454a3b9e517e15a0187011dc305690541",
|
||||||
|
"size": 28776
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
config := `{
|
||||||
|
"name": "harbor",
|
||||||
|
"home": "https://goharbor.io",
|
||||||
|
"sources": [
|
||||||
|
"https://github.com/goharbor/harbor",
|
||||||
|
"https://github.com/goharbor/harbor-helm"
|
||||||
|
],
|
||||||
|
"version": "1.1.2",
|
||||||
|
"description": "An open source trusted cloud native registry that stores, signs, and scans content",
|
||||||
|
"keywords": [
|
||||||
|
"docker",
|
||||||
|
"registry",
|
||||||
|
"harbor"
|
||||||
|
],
|
||||||
|
"maintainers": [
|
||||||
|
{
|
||||||
|
"name": "Jesse Hu",
|
||||||
|
"email": "huh@vmware.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "paulczar",
|
||||||
|
"email": "username.taken@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"icon": "https://raw.githubusercontent.com/goharbor/harbor/master/docs/img/harbor_logo.png",
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"appVersion": "1.8.2"
|
||||||
|
}`
|
||||||
|
artifact := &artifact.Artifact{}
|
||||||
|
r.repoMgr.On("Get").Return(&models.RepoRecord{}, nil)
|
||||||
|
r.blobFetcher.On("FetchLayer").Return([]byte(config), nil)
|
||||||
|
err := r.resolver.Resolve(nil, []byte(content), artifact)
|
||||||
|
r.Require().Nil(err)
|
||||||
|
r.repoMgr.AssertExpectations(r.T())
|
||||||
|
r.blobFetcher.AssertExpectations(r.T())
|
||||||
|
r.Assert().Equal("1.1.2", artifact.ExtraAttrs["version"].(string))
|
||||||
|
r.Assert().Equal("1.8.2", artifact.ExtraAttrs["appVersion"].(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolverTestSuite(t *testing.T) {
|
||||||
|
suite.Run(t, &resolverTestSuite{})
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
// 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
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
// 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
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
// 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
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
// 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
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
// 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
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
// 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
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
// 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
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@ -18,8 +18,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/goharbor/harbor/src/api/artifact/abstractor"
|
"github.com/goharbor/harbor/src/api/artifact/abstractor"
|
||||||
// registry image resolvers
|
// register image resolvers
|
||||||
_ "github.com/goharbor/harbor/src/api/artifact/abstractor/resolver/image"
|
_ "github.com/goharbor/harbor/src/api/artifact/abstractor/resolver/image"
|
||||||
|
// register chart resolver
|
||||||
|
_ "github.com/goharbor/harbor/src/api/artifact/abstractor/resolver/chart"
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
ierror "github.com/goharbor/harbor/src/internal/error"
|
ierror "github.com/goharbor/harbor/src/internal/error"
|
||||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||||
|
Loading…
Reference in New Issue
Block a user