drone/registry/app/remote/adapter/native/adapter.go

118 lines
3.6 KiB
Go

// Source: https://github.com/goharbor/harbor
// Copyright 2016 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 native
import (
"context"
"github.com/harness/gitness/app/store"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/common/lib/errors"
adp "github.com/harness/gitness/registry/app/remote/adapter"
"github.com/harness/gitness/registry/app/remote/clients/registry"
"github.com/harness/gitness/registry/types"
"github.com/harness/gitness/secret"
"github.com/rs/zerolog/log"
)
var _ adp.Adapter = &Adapter{}
var (
_ adp.Adapter = (*Adapter)(nil)
_ adp.ArtifactRegistry = (*Adapter)(nil)
)
// Adapter implements an adapter for Docker proxy. It can be used to all registries
// that implement the proxy V2 API.
type Adapter struct {
proxy types.UpstreamProxy
registry.Client
}
// NewAdapter returns an instance of the Adapter.
func NewAdapter(
ctx context.Context, spacePathStore store.SpacePathStore, service secret.Service, reg types.UpstreamProxy,
) *Adapter {
adapter := &Adapter{
proxy: reg,
}
// Get the password: lookup secrets.secret_data using secret_identifier & secret_space_id.
password := getPwd(ctx, spacePathStore, service, reg)
username, password, url := reg.UserName, password, reg.RepoURL
adapter.Client = registry.NewClient(url, username, password, false)
return adapter
}
// getPwd: lookup secrets.secret_data using secret_identifier & secret_space_id.
func getPwd(
ctx context.Context, spacePathStore store.SpacePathStore, secretService secret.Service, reg types.UpstreamProxy,
) string {
if api.AuthType(reg.RepoAuthType) == api.AuthTypeUserPassword {
secretSpaceID := int64(0)
if reg.SecretSpaceID.Valid {
secretSpaceID = int64(reg.SecretSpaceID.Int32)
}
secretIdentifier := ""
if reg.SecretIdentifier.Valid {
secretIdentifier = reg.SecretIdentifier.String
}
spacePath, err := spacePathStore.FindPrimaryBySpaceID(ctx, secretSpaceID)
if err != nil {
log.Error().Msgf("failed to find space path: %v", err)
return ""
}
decryptSecret, err := secretService.DecryptSecret(ctx, spacePath.Value, secretIdentifier)
if err != nil {
log.Error().Msgf("failed to decrypt secret: %v", err)
return ""
}
return decryptSecret
}
return ""
}
// HealthCheck checks health status of a proxy.
func (a *Adapter) HealthCheck() (string, error) {
return "Not implemented", nil
}
// PingSimple checks whether the proxy is available. It checks the connectivity and certificate (if TLS enabled)
// only, regardless of 401/403 error.
func (a *Adapter) PingSimple() error {
err := a.Ping()
if err == nil {
return nil
}
if errors.IsErr(err, errors.UnAuthorizedCode) || errors.IsErr(err, errors.ForbiddenCode) {
return nil
}
return err
}
// DeleteTag isn't supported for docker proxy.
func (a *Adapter) DeleteTag(_, _ string) error {
return errors.New("the tag deletion isn't supported")
}
// CanBeMount isn't supported for docker proxy.
func (a *Adapter) CanBeMount(_ string) (mount bool, repository string, err error) {
return false, "", nil
}