// 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 acceleration import ( "context" "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/acceleration/adapter" "github.com/goharbor/harbor/src/pkg/acceleration/dao" "github.com/goharbor/harbor/src/pkg/acceleration/model" _ "github.com/goharbor/harbor/src/pkg/acceleration/adapter/nydus" ) 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.AccelerationService) (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.AccelerationService, err error) // Get the registry specified by ID Get(ctx context.Context, id int64) (registry *model.AccelerationService, err error) // Update the specified registry Update(ctx context.Context, registry *model.AccelerationService, 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.AccelerationService) (adapter adapter.Adapter, 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.AccelerationService) (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.AccelerationService, error) { registries, err := m.dao.List(ctx, query) if err != nil { return nil, err } var regs []*model.AccelerationService 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.AccelerationService, error) { 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.AccelerationService, 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(ctx context.Context, registry *model.AccelerationService) (adapter.Adapter, error) { factory, err := adapter.GetFactory(registry.Type) if err != nil { return nil, err } return factory.Create(registry) } // 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.AccelerationService) (*model.AccelerationService, error) { r := &model.AccelerationService{ 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 ... func toDaoModel(registry *model.AccelerationService) (*dao.AccelerationService, error) { m := &dao.AccelerationService{ 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 }