mirror of
https://github.com/goharbor/harbor
synced 2025-04-15 10:47:07 +00:00

bump golang 1.21.5 update golangci-lint && fix revive error fix white space lint Signed-off-by: yminer <yminer@vmware.com>
281 lines
8.6 KiB
Go
281 lines
8.6 KiB
Go
// 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 reg
|
|
|
|
import (
|
|
"context"
|
|
|
|
commonthttp "github.com/goharbor/harbor/src/common/http"
|
|
"github.com/goharbor/harbor/src/common/utils"
|
|
"github.com/goharbor/harbor/src/lib/config"
|
|
"github.com/goharbor/harbor/src/lib/q"
|
|
"github.com/goharbor/harbor/src/pkg/reg/adapter"
|
|
|
|
// register the AliACR adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/aliacr"
|
|
// register the AwsEcr adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/awsecr"
|
|
// register the AzureAcr adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/azurecr"
|
|
// register the DockerHub adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/dockerhub"
|
|
// register the DTR adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/dtr"
|
|
// register the Github Container Registry adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/githubcr"
|
|
// register the GitLab adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/gitlab"
|
|
// register the Google Gcr adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/googlegcr"
|
|
// register the Harbor adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/harbor"
|
|
// register the huawei adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/huawei"
|
|
// register the Jfrog Artifactory adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/jfrog"
|
|
// register the Native adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/native"
|
|
// register the Quay.io adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/quay"
|
|
// register the TencentCloud TCR adapter
|
|
_ "github.com/goharbor/harbor/src/pkg/reg/adapter/tencentcr"
|
|
"github.com/goharbor/harbor/src/pkg/reg/dao"
|
|
"github.com/goharbor/harbor/src/pkg/reg/model"
|
|
)
|
|
|
|
var (
|
|
// Mgr is the global registry manager instance
|
|
Mgr = NewManager()
|
|
)
|
|
|
|
// Manager defines the registry related operations
|
|
type Manager interface {
|
|
// Create the registry
|
|
Create(ctx context.Context, registry *model.Registry) (id int64, err error)
|
|
// Count returns the count of registries according to the query
|
|
Count(ctx context.Context, query *q.Query) (count int64, err error)
|
|
// List registries according to the query
|
|
List(ctx context.Context, query *q.Query) (registries []*model.Registry, err error)
|
|
// Get the registry specified by ID
|
|
Get(ctx context.Context, id int64) (registry *model.Registry, err error)
|
|
// Update the specified registry
|
|
Update(ctx context.Context, registry *model.Registry, props ...string) (err error)
|
|
// Delete the registry specified by ID
|
|
Delete(ctx context.Context, id int64) (err error)
|
|
// CreateAdapter for the provided registry
|
|
CreateAdapter(ctx context.Context, registry *model.Registry) (adapter adapter.Adapter, err error)
|
|
// ListRegistryProviderTypes returns all the registered registry provider type
|
|
ListRegistryProviderTypes(ctx context.Context) (types []string, err error)
|
|
// ListRegistryProviderInfos returns all the registered registry provider information
|
|
ListRegistryProviderInfos(ctx context.Context) (infos map[string]*model.AdapterPattern, err error)
|
|
}
|
|
|
|
// NewManager creates an instance of registry manager
|
|
func NewManager() Manager {
|
|
return &manager{
|
|
dao: dao.NewDAO(),
|
|
}
|
|
}
|
|
|
|
type manager struct {
|
|
dao dao.DAO
|
|
}
|
|
|
|
func (m *manager) Create(ctx context.Context, registry *model.Registry) (int64, error) {
|
|
reg, err := toDaoModel(registry)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return m.dao.Create(ctx, reg)
|
|
}
|
|
|
|
func (m *manager) Count(ctx context.Context, query *q.Query) (int64, error) {
|
|
return m.dao.Count(ctx, query)
|
|
}
|
|
|
|
func (m *manager) List(ctx context.Context, query *q.Query) ([]*model.Registry, error) {
|
|
registries, err := m.dao.List(ctx, query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var regs []*model.Registry
|
|
for _, registry := range registries {
|
|
r, err := fromDaoModel(registry)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
regs = append(regs, r)
|
|
}
|
|
return regs, nil
|
|
}
|
|
|
|
func (m *manager) Get(ctx context.Context, id int64) (*model.Registry, error) {
|
|
if id == 0 {
|
|
return getLocalRegistry(), nil
|
|
}
|
|
registry, err := m.dao.Get(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return fromDaoModel(registry)
|
|
}
|
|
|
|
func (m *manager) Update(ctx context.Context, registry *model.Registry, props ...string) error {
|
|
reg, err := toDaoModel(registry)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return m.dao.Update(ctx, reg, props...)
|
|
}
|
|
|
|
func (m *manager) Delete(ctx context.Context, id int64) error {
|
|
return m.dao.Delete(ctx, id)
|
|
}
|
|
|
|
func (m *manager) CreateAdapter(_ context.Context, registry *model.Registry) (adapter.Adapter, error) {
|
|
factory, err := adapter.GetFactory(registry.Type)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return factory.Create(registry)
|
|
}
|
|
|
|
func (m *manager) ListRegistryProviderTypes(_ context.Context) ([]string, error) {
|
|
return adapter.ListRegisteredAdapterTypes(), nil
|
|
}
|
|
|
|
func (m *manager) ListRegistryProviderInfos(_ context.Context) (infos map[string]*model.AdapterPattern, err error) {
|
|
return adapter.ListRegisteredAdapterInfos(), nil
|
|
}
|
|
|
|
// getLocalRegistry returns the info of the local Harbor registry
|
|
func getLocalRegistry() *model.Registry {
|
|
return &model.Registry{
|
|
Type: model.RegistryTypeHarbor,
|
|
Name: "Local",
|
|
URL: config.InternalCoreURL(),
|
|
TokenServiceURL: config.InternalTokenServiceEndpoint(),
|
|
Status: "healthy",
|
|
Credential: &model.Credential{
|
|
Type: model.CredentialTypeSecret,
|
|
// use secret to do the auth for the local Harbor
|
|
AccessSecret: config.JobserviceSecret(),
|
|
},
|
|
Insecure: !commonthttp.InternalTLSEnabled(),
|
|
}
|
|
}
|
|
|
|
// decrypt checks whether access secret is set in the registry, if so, decrypt it.
|
|
func decrypt(secret string) (string, error) {
|
|
if len(secret) == 0 {
|
|
return "", nil
|
|
}
|
|
secretKey, err := config.SecretKey()
|
|
if err != nil {
|
|
return "", nil
|
|
}
|
|
decrypted, err := utils.ReversibleDecrypt(secret, secretKey)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return decrypted, nil
|
|
}
|
|
|
|
// encrypt checks whether access secret is set in the registry, if so, encrypt it.
|
|
func encrypt(secret string) (string, error) {
|
|
if len(secret) == 0 {
|
|
return secret, nil
|
|
}
|
|
secretKey, err := config.SecretKey()
|
|
if err != nil {
|
|
return "", nil
|
|
}
|
|
encrypted, err := utils.ReversibleEncrypt(secret, secretKey)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return encrypted, nil
|
|
}
|
|
|
|
// FromDaoModel converts DAO layer registry model to replication model.
|
|
// Also, if access secret is provided, decrypt it.
|
|
func fromDaoModel(registry *dao.Registry) (*model.Registry, error) {
|
|
r := &model.Registry{
|
|
ID: registry.ID,
|
|
Name: registry.Name,
|
|
Description: registry.Description,
|
|
Type: registry.Type,
|
|
Credential: &model.Credential{},
|
|
URL: registry.URL,
|
|
Insecure: registry.Insecure,
|
|
Status: registry.Status,
|
|
CreationTime: registry.CreationTime,
|
|
UpdateTime: registry.UpdateTime,
|
|
}
|
|
|
|
if len(registry.AccessKey) != 0 {
|
|
credentialType := registry.CredentialType
|
|
if len(credentialType) == 0 {
|
|
credentialType = model.CredentialTypeBasic
|
|
}
|
|
decrypted, err := decrypt(registry.AccessSecret)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
r.Credential = &model.Credential{
|
|
Type: credentialType,
|
|
AccessKey: registry.AccessKey,
|
|
AccessSecret: decrypted,
|
|
}
|
|
}
|
|
|
|
return r, nil
|
|
}
|
|
|
|
// ToDaoModel converts registry model from replication to DAO layer model.
|
|
// Also, if access secret is provided, encrypt it.
|
|
func toDaoModel(registry *model.Registry) (*dao.Registry, error) {
|
|
m := &dao.Registry{
|
|
ID: registry.ID,
|
|
URL: registry.URL,
|
|
Name: registry.Name,
|
|
Type: string(registry.Type),
|
|
Insecure: registry.Insecure,
|
|
Description: registry.Description,
|
|
Status: registry.Status,
|
|
CreationTime: registry.CreationTime,
|
|
UpdateTime: registry.UpdateTime,
|
|
}
|
|
|
|
if registry.Credential != nil && len(registry.Credential.AccessKey) != 0 {
|
|
credentialType := registry.Credential.Type
|
|
if len(credentialType) == 0 {
|
|
credentialType = model.CredentialTypeBasic
|
|
}
|
|
encrypted, err := encrypt(registry.Credential.AccessSecret)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
m.CredentialType = string(credentialType)
|
|
m.AccessKey = registry.Credential.AccessKey
|
|
m.AccessSecret = encrypted
|
|
}
|
|
|
|
return m, nil
|
|
}
|