[AH-310]: temp push; need to check (#2607)

* [AH-310]: Updated secret flows
* [AH-310]: Fixed build issues
* [AH-310]: temp push; need to check
pull/3545/head
Arvind Choudhary 2024-08-29 19:42:22 +00:00 committed by Harness
parent 57368eba55
commit 77e93d587c
12 changed files with 181 additions and 80 deletions

View File

@ -0,0 +1,62 @@
// Copyright 2023 Harness, Inc.
//
// 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 secret
import (
"context"
secretCtrl "github.com/harness/gitness/app/api/controller/secret"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/encrypt"
"github.com/harness/gitness/secret"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
type service struct {
secretStore store.SecretStore
encrypter encrypt.Encrypter
spacePathStore store.SpacePathStore
}
func NewService(
secretStore store.SecretStore, encrypter encrypt.Encrypter, spacePathStore store.SpacePathStore,
) secret.Service {
return &service{
secretStore: secretStore,
encrypter: encrypter,
spacePathStore: spacePathStore,
}
}
func (s *service) DecryptSecret(ctx context.Context, spacePath string, secretIdentifier string) (string, error) {
path, err := s.spacePathStore.FindByPath(ctx, spacePath)
if err != nil {
log.Error().Msgf("failed to find space path: %v", err)
return "", errors.Wrap(err, "failed to find space path")
}
sec, err := s.secretStore.FindByIdentifier(ctx, path.SpaceID, secretIdentifier)
if err != nil {
log.Error().Msgf("failed to find secret: %v", err)
return "", errors.Wrap(err, "failed to find secret")
}
sec, err = secretCtrl.Dec(s.encrypter, sec)
if err != nil {
log.Error().Msgf("could not decrypt secret: %v", err)
return "", errors.Wrap(err, "failed to decrypt secret")
}
return sec.Data, nil
}

View File

@ -0,0 +1,33 @@
// Copyright 2023 Harness, Inc.
//
// 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 secret
import (
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/encrypt"
"github.com/harness/gitness/secret"
"github.com/google/wire"
)
var WireSet = wire.NewSet(
ProvideSecretService,
)
func ProvideSecretService(
secretStore store.SecretStore, encrypter encrypt.Encrypter, spacePathStore store.SpacePathStore,
) secret.Service {
return NewService(secretStore, encrypter, spacePathStore)
}

View File

@ -100,6 +100,7 @@ import (
"github.com/harness/gitness/app/services/publickey"
pullreqservice "github.com/harness/gitness/app/services/pullreq"
reposervice "github.com/harness/gitness/app/services/repo"
secretservice "github.com/harness/gitness/app/services/secret"
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/app/services/trigger"
usergroupservice "github.com/harness/gitness/app/services/usergroup"
@ -262,6 +263,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
aiagent.WireSet,
capabilities.WireSet,
capabilitiesservice.WireSet,
secretservice.WireSet,
)
return &cliserver.System{}, nil
}

View File

@ -91,6 +91,7 @@ import (
"github.com/harness/gitness/app/services/publickey"
"github.com/harness/gitness/app/services/pullreq"
repo2 "github.com/harness/gitness/app/services/repo"
secret3 "github.com/harness/gitness/app/services/secret"
"github.com/harness/gitness/app/services/settings"
trigger2 "github.com/harness/gitness/app/services/trigger"
"github.com/harness/gitness/app/services/usergroup"
@ -429,7 +430,8 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
registryBlobRepository := database2.ProvideRegistryBlobDao(db)
localRegistry := docker.LocalRegistryProvider(app, manifestService, blobRepository, registryRepository, manifestRepository, registryBlobRepository, mediaTypesRepository, tagRepository, artifactRepository, artifactStatRepository, gcService, transactor)
upstreamProxyConfigRepository := database2.ProvideUpstreamDao(db, registryRepository)
remoteRegistry := docker.RemoteRegistryProvider(localRegistry, app, upstreamProxyConfigRepository, secretStore, encrypter)
secretService := secret3.ProvideSecretService(secretStore, encrypter, spacePathStore)
remoteRegistry := docker.RemoteRegistryProvider(localRegistry, app, upstreamProxyConfigRepository, spacePathStore, secretService)
coreController := pkg.CoreControllerProvider(registryRepository)
dockerController := docker.ControllerProvider(localRegistry, remoteRegistry, coreController, spaceStore, authorizer)
handler := api2.NewHandlerProvider(dockerController, spaceStore, tokenStore, controller, authenticator, provider, authorizer)

View File

@ -25,7 +25,6 @@ import (
"github.com/harness/gitness/app/api/request"
store2 "github.com/harness/gitness/app/store"
"github.com/harness/gitness/encrypt"
"github.com/harness/gitness/registry/app/common/lib/errors"
"github.com/harness/gitness/registry/app/manifest"
"github.com/harness/gitness/registry/app/pkg"
@ -33,6 +32,7 @@ import (
proxy2 "github.com/harness/gitness/registry/app/remote/controller/proxy"
"github.com/harness/gitness/registry/app/storage"
"github.com/harness/gitness/registry/app/store"
"github.com/harness/gitness/secret"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/rs/zerolog/log"
@ -48,18 +48,15 @@ const (
)
func NewRemoteRegistry(
local *LocalRegistry,
app *App,
upstreamProxyConfigRepo store.UpstreamProxyConfigRepository,
secretStore store2.SecretStore,
encrypter encrypt.Encrypter,
local *LocalRegistry, app *App, upstreamProxyConfigRepo store.UpstreamProxyConfigRepository,
spacePathStore store2.SpacePathStore, secretService secret.Service,
) Registry {
return &RemoteRegistry{
local: local,
App: app,
upstreamProxyConfigRepo: upstreamProxyConfigRepo,
secretStore: secretStore,
encrypter: encrypter,
spacePathStore: spacePathStore,
secretService: secretService,
}
}
@ -71,8 +68,8 @@ type RemoteRegistry struct {
local *LocalRegistry
App *App
upstreamProxyConfigRepo store.UpstreamProxyConfigRepository
secretStore store2.SecretStore
encrypter encrypt.Encrypter
spacePathStore store2.SpacePathStore
secretService secret.Service
}
func (r *RemoteRegistry) Base() error {
@ -150,7 +147,7 @@ func (r *RemoteRegistry) ManifestExist(
responseHeaders *commons.ResponseHeaders, descriptor manifest.Descriptor, manifestResult manifest.Manifest,
errs []error,
) {
proxyCtl := proxy2.ControllerInstance(r.local, r.local.ms)
proxyCtl := proxy2.ControllerInstance(r.local, r.local.ms, r.secretService, r.spacePathStore)
responseHeaders = &commons.ResponseHeaders{
Headers: make(map[string]string),
}
@ -180,7 +177,8 @@ func (r *RemoteRegistry) ManifestExist(
errs = append(errs, err)
return responseHeaders, descriptor, manifestResult, errs
}
remoteHelper, err := proxy2.NewRemoteHelper(ctx, r.secretStore, r.encrypter, artInfo.RegIdentifier, *upstreamProxy)
remoteHelper, err := proxy2.NewRemoteHelper(ctx, r.spacePathStore, r.secretService, artInfo.RegIdentifier,
*upstreamProxy)
if err != nil {
errs = append(errs, errors.New("Proxy is down"))
return responseHeaders, descriptor, manifestResult, errs
@ -239,7 +237,7 @@ func (r *RemoteRegistry) PullManifest(
responseHeaders *commons.ResponseHeaders, descriptor manifest.Descriptor, manifestResult manifest.Manifest,
errs []error,
) {
proxyCtl := proxy2.ControllerInstance(r.local, r.local.ms)
proxyCtl := proxy2.ControllerInstance(r.local, r.local.ms, r.secretService, r.spacePathStore)
responseHeaders = &commons.ResponseHeaders{
Headers: make(map[string]string),
}
@ -268,7 +266,8 @@ func (r *RemoteRegistry) PullManifest(
errs = append(errs, err)
return responseHeaders, descriptor, manifestResult, errs
}
remoteHelper, err := proxy2.NewRemoteHelper(ctx, r.secretStore, r.encrypter, artInfo.RegIdentifier, *upstreamProxy)
remoteHelper, err := proxy2.NewRemoteHelper(ctx, r.spacePathStore, r.secretService, artInfo.RegIdentifier,
*upstreamProxy)
if err != nil {
errs = append(errs, errors.New("Proxy is down"))
return responseHeaders, descriptor, manifestResult, errs
@ -353,7 +352,7 @@ func (r *RemoteRegistry) fetchBlobInternal(
responseHeaders *commons.ResponseHeaders, fr *storage.FileReader, size int64, readCloser io.ReadCloser,
redirectURL string, errs []error,
) {
proxyCtl := proxy2.ControllerInstance(r.local, r.local.ms)
proxyCtl := proxy2.ControllerInstance(r.local, r.local.ms, r.secretService, r.spacePathStore)
responseHeaders = &commons.ResponseHeaders{
Headers: make(map[string]string),
}
@ -399,7 +398,7 @@ func (r *RemoteRegistry) fetchBlobInternal(
}
// This is start of proxy Code.
size, readCloser, err = proxyCtl.ProxyBlob(ctx, r.secretStore, r.encrypter, registryInfo, repoKey, *upstreamProxy)
size, readCloser, err = proxyCtl.ProxyBlob(ctx, registryInfo, repoKey, *upstreamProxy)
if err != nil {
errs = append(errs, err)
return responseHeaders, fr, size, readCloser, redirectURL, errs

View File

@ -17,12 +17,12 @@ package docker
import (
"github.com/harness/gitness/app/auth/authz"
corestore "github.com/harness/gitness/app/store"
"github.com/harness/gitness/encrypt"
storagedriver "github.com/harness/gitness/registry/app/driver"
"github.com/harness/gitness/registry/app/pkg"
"github.com/harness/gitness/registry/app/storage"
"github.com/harness/gitness/registry/app/store"
"github.com/harness/gitness/registry/gc"
"github.com/harness/gitness/secret"
"github.com/harness/gitness/store/database/dbtx"
"github.com/harness/gitness/types"
@ -58,9 +58,9 @@ func ManifestServiceProvider(
func RemoteRegistryProvider(
local *LocalRegistry, app *App, upstreamProxyConfigRepo store.UpstreamProxyConfigRepository,
secretStore corestore.SecretStore, encrypter encrypt.Encrypter,
spacePathStore corestore.SpacePathStore, secretService secret.Service,
) *RemoteRegistry {
return NewRemoteRegistry(local, app, upstreamProxyConfigRepo, secretStore, encrypter).(*RemoteRegistry)
return NewRemoteRegistry(local, app, upstreamProxyConfigRepo, spacePathStore, secretService).(*RemoteRegistry)
}
func ControllerProvider(

View File

@ -23,9 +23,9 @@ import (
"io"
store2 "github.com/harness/gitness/app/store"
"github.com/harness/gitness/encrypt"
"github.com/harness/gitness/registry/app/manifest"
"github.com/harness/gitness/registry/types"
"github.com/harness/gitness/secret"
)
// const definition.
@ -39,8 +39,7 @@ var registryKeys = []string{}
// Factory creates a specific Adapter according to the params.
type Factory interface {
Create(
ctx context.Context, secretStore store2.SecretStore, encrypter encrypt.Encrypter,
record types.UpstreamProxy,
ctx context.Context, spacePathStore store2.SpacePathStore, record types.UpstreamProxy, service secret.Service,
) (Adapter, error)
}

View File

@ -20,10 +20,10 @@ import (
"context"
store2 "github.com/harness/gitness/app/store"
"github.com/harness/gitness/encrypt"
adp "github.com/harness/gitness/registry/app/remote/adapter"
"github.com/harness/gitness/registry/app/remote/adapter/native"
"github.com/harness/gitness/registry/types"
"github.com/harness/gitness/secret"
"github.com/rs/zerolog/log"
)
@ -38,10 +38,7 @@ func init() {
}
func newAdapter(
ctx context.Context,
secretStore store2.SecretStore,
encrypter encrypt.Encrypter,
registry types.UpstreamProxy,
ctx context.Context, spacePathStore store2.SpacePathStore, service secret.Service, registry types.UpstreamProxy,
) (adp.Adapter, error) {
client, err := NewClient(registry)
if err != nil {
@ -51,7 +48,7 @@ func newAdapter(
// TODO: get Upstream Credentials
return &adapter{
client: client,
Adapter: native.NewAdapter(ctx, secretStore, encrypter, registry),
Adapter: native.NewAdapter(ctx, spacePathStore, service, registry),
}, nil
}
@ -60,12 +57,9 @@ type factory struct {
// Create ...
func (f *factory) Create(
ctx context.Context,
secretStore store2.SecretStore,
encrypter encrypt.Encrypter,
record types.UpstreamProxy,
ctx context.Context, spacePathStore store2.SpacePathStore, record types.UpstreamProxy, service secret.Service,
) (adp.Adapter, error) {
return newAdapter(ctx, secretStore, encrypter, record)
return newAdapter(ctx, spacePathStore, service, record)
}
var (

View File

@ -19,14 +19,13 @@ package native
import (
"context"
s "github.com/harness/gitness/app/api/controller/secret"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/encrypt"
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"
)
@ -47,16 +46,13 @@ type Adapter struct {
// NewAdapter returns an instance of the Adapter.
func NewAdapter(
ctx context.Context,
secretStore store.SecretStore,
encrypter encrypt.Encrypter,
reg types.UpstreamProxy,
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, secretStore, encrypter, reg)
password := getPwd(ctx, spacePathStore, service, reg)
username, password, url := reg.UserName, password, reg.RepoURL
adapter.Client = registry.NewClient(url, username, password, false)
return adapter
@ -64,12 +60,8 @@ func NewAdapter(
// getPwd: lookup secrets.secret_data using secret_identifier & secret_space_id.
func getPwd(
ctx context.Context,
secretStore store.SecretStore,
encrypter encrypt.Encrypter,
reg types.UpstreamProxy,
ctx context.Context, spacePathStore store.SpacePathStore, secretService secret.Service, reg types.UpstreamProxy,
) string {
password := ""
if api.AuthType(reg.RepoAuthType) == api.AuthTypeUserPassword {
secretSpaceID := int64(0)
if reg.SecretSpaceID.Valid {
@ -80,17 +72,20 @@ func getPwd(
if reg.SecretIdentifier.Valid {
secretIdentifier = reg.SecretIdentifier.String
}
secret, err := secretStore.FindByIdentifier(ctx, secretSpaceID, secretIdentifier)
spacePath, err := spacePathStore.FindPrimaryBySpaceID(ctx, secretSpaceID)
if err != nil {
log.Error().Msgf("failed to find secret: %v", err)
log.Error().Msgf("failed to find space path: %v", err)
return ""
}
secret, err = s.Dec(encrypter, secret)
decryptSecret, err := secretService.DecryptSecret(ctx, spacePath.Value, secretIdentifier)
if err != nil {
log.Error().Msgf("could not decrypt secret: %v", err)
log.Error().Msgf("failed to decrypt secret: %v", err)
return ""
}
password = secret.Data
return decryptSecret
}
return password
return ""
}
// HealthCheck checks health status of a proxy.

View File

@ -26,13 +26,13 @@ import (
"time"
"github.com/harness/gitness/app/api/request"
store2 "github.com/harness/gitness/app/store"
"github.com/harness/gitness/encrypt"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/registry/app/common/lib/errors"
"github.com/harness/gitness/registry/app/manifest"
"github.com/harness/gitness/registry/app/pkg"
"github.com/harness/gitness/registry/app/pkg/commons"
"github.com/harness/gitness/registry/types"
"github.com/harness/gitness/secret"
"github.com/distribution/distribution/v3/registry/api/errcode"
"github.com/opencontainers/go-digest"
@ -68,12 +68,7 @@ type Controller interface {
// ProxyBlob proxy the blob request to the remote server, p is the proxy project
// art is the RegistryInfo which includes the digest of the blob
ProxyBlob(
ctx context.Context,
secretStore store2.SecretStore,
encrypter encrypt.Encrypter,
art pkg.RegistryInfo,
repoKey string,
proxy types.UpstreamProxy,
ctx context.Context, art pkg.RegistryInfo, repoKey string, proxy types.UpstreamProxy,
) (int64, io.ReadCloser, error)
// ProxyManifest proxy the manifest request to the remote server, p is the proxy project,
// art is the RegistryInfo which includes the tag or digest of the manifest
@ -99,21 +94,24 @@ type Controller interface {
}
type controller struct {
// blobCtl blob.Controller
// artifactCtl artifact.Controller.
localRegistry registryInterface
localManifestRegistry registryManifestInterface
// cache cache.Cache
// handlerRegistry map[string]ManifestCacheHandler.
secretService secret.Service
spacePathStore store.SpacePathStore
}
// ControllerInstance -- get the proxy controller instance.
func ControllerInstance(l registryInterface, lm registryManifestInterface) Controller {
func ControllerInstance(
l registryInterface, lm registryManifestInterface, secretService secret.Service,
spacePathStore store.SpacePathStore,
) Controller {
once.Do(
func() {
ctl = &controller{
localRegistry: l,
localManifestRegistry: lm,
secretService: secretService,
spacePathStore: spacePathStore,
}
},
)
@ -294,17 +292,12 @@ func (c *controller) HeadManifest(
}
func (c *controller) ProxyBlob(
ctx context.Context,
secretStore store2.SecretStore,
encrypter encrypt.Encrypter,
art pkg.RegistryInfo,
repoKey string,
proxy types.UpstreamProxy,
ctx context.Context, art pkg.RegistryInfo, repoKey string, proxy types.UpstreamProxy,
) (int64, io.ReadCloser, error) {
remoteImage := getRemoteRepo(art)
log.Debug().Msgf("The blob doesn't exist, proxy the request to the target server, url:%v", remoteImage)
rHelper, err := NewRemoteHelper(ctx, secretStore, encrypter, repoKey, proxy)
rHelper, err := NewRemoteHelper(ctx, c.spacePathStore, c.secretService, repoKey, proxy)
if err != nil {
return 0, nil, err
}

View File

@ -20,11 +20,11 @@ import (
"io"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/encrypt"
api "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/manifest"
"github.com/harness/gitness/registry/app/remote/adapter"
"github.com/harness/gitness/registry/types"
"github.com/harness/gitness/secret"
"github.com/rs/zerolog/log"
"golang.org/x/net/context"
@ -52,14 +52,12 @@ type remoteHelper struct {
registry adapter.ArtifactRegistry
upstreamProxy types.UpstreamProxy
URL string
secretService secret.Service
}
// NewRemoteHelper create a remote interface.
func NewRemoteHelper(
ctx context.Context,
secretStore store.SecretStore,
encrypter encrypt.Encrypter,
repoKey string,
ctx context.Context, spacePathStore store.SpacePathStore, secretService secret.Service, repoKey string,
proxy types.UpstreamProxy,
) (RemoteInterface, error) {
if proxy.Source == string(api.UpstreamConfigSourceDockerhub) {
@ -68,14 +66,15 @@ func NewRemoteHelper(
r := &remoteHelper{
repoKey: repoKey,
upstreamProxy: proxy,
secretService: secretService,
}
if err := r.init(ctx, secretStore, encrypter); err != nil {
if err := r.init(ctx, spacePathStore); err != nil {
return nil, err
}
return r, nil
}
func (r *remoteHelper) init(ctx context.Context, secretStore store.SecretStore, encrypter encrypt.Encrypter) error {
func (r *remoteHelper) init(ctx context.Context, spacePathStore store.SpacePathStore) error {
if r.registry != nil {
return nil
}
@ -85,7 +84,7 @@ func (r *remoteHelper) init(ctx context.Context, secretStore store.SecretStore,
if err != nil {
return err
}
adp, err := factory.Create(ctx, secretStore, encrypter, r.upstreamProxy)
adp, err := factory.Create(ctx, spacePathStore, r.upstreamProxy, r.secretService)
if err != nil {
return err
}

23
secret/interface.go Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2023 Harness, Inc.
//
// 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 secret
import (
"context"
)
type Service interface {
DecryptSecret(ctx context.Context, spacePath, secretIdentifier string) (string, error)
}