feat:[AH-1231]: changes for switching routes for generic artifacts (#3703)

* feat:[AH-1231]: fix checks
* feat:[AH-1231]: review changes
* feat:[AH-1231]: changes for switching routes for generic artifacts
* Merge branch 'main' of https://git0.harness.io/l7B_kbSEQD2wjrM7PShm5w/PROD/Harness_Commons/gitness
* Merge branch 'main' of https://git0.harness.io/l7B_kbSEQD2wjrM7PShm5w/PROD/Harness_Commons/gitness
* Merge branch 'release/registry-api_1.18.0' of https://git0.harness.io/l7B_kbSEQD2wjrM7PShm5w/PROD/Harness_Commons/gitness
* feat:[AH-1083]: url fix (#3669)

* feat:[AH-1083]: url fix
This commit is contained in:
Sourabh Awashti 2025-04-28 05:10:07 +00:00 committed by Harness
parent 38e2ec8308
commit 3e07a681a1
10 changed files with 77 additions and 19 deletions

View File

@ -537,9 +537,9 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
handler2 := router.MavenHandlerProvider(mavenHandler)
genericDBStore := generic.DBStoreProvider(imageRepository, artifactRepository, bandwidthStatRepository, downloadStatRepository, registryRepository)
genericController := generic.ControllerProvider(spaceStore, authorizer, fileManager, genericDBStore, transactor)
genericHandler := api2.NewGenericHandlerProvider(spaceStore, genericController, tokenStore, controller, authenticator, provider, authorizer)
handler3 := router.GenericHandlerProvider(genericHandler)
packagesHandler := api2.NewPackageHandlerProvider(registryRepository, downloadStatRepository, spaceStore, tokenStore, controller, authenticator, provider, authorizer)
genericHandler := api2.NewGenericHandlerProvider(spaceStore, genericController, tokenStore, controller, authenticator, provider, authorizer, packagesHandler)
handler3 := router.GenericHandlerProvider(genericHandler)
packageTagRepository := database2.ProvidePackageTagDao(db)
localBase := base.LocalBaseProvider(registryRepository, fileManager, transactor, imageRepository, artifactRepository, nodesRepository, packageTagRepository)
pythonLocalRegistry := python.LocalRegistryProvider(localBase, fileManager, upstreamProxyConfigRepository, transactor, registryRepository, imageRepository, artifactRepository, provider)

View File

@ -278,7 +278,7 @@ func (c *APIController) generateGenericClientSetupDetail(
header2 := "Upload Artifact"
section2step1Header := "Run this curl command in your terminal to push the artifact."
//nolint:lll
pushValue := "curl --location --request PUT '<HOSTNAME>/<REGISTRY_NAME>/<ARTIFACT_NAME>/<VERSION>' \\\n--form 'filename=\"<FILENAME>\"' \\\n--form 'file=@\"<FILE_PATH>\"' \\\n--form 'description=\"<DESC>\"' \\\n--header 'x-api-key: <API_KEY>'"
pushValue := "curl --location --request PUT '<HOSTNAME>/<ARTIFACT_NAME>/<VERSION>' \\\n--form 'filename=\"<FILENAME>\"' \\\n--form 'file=@\"<FILE_PATH>\"' \\\n--form 'description=\"<DESC>\"' \\\n--header 'x-api-key: <API_KEY>'"
section2step1Commands := []artifact.ClientSetupStepCommand{
{Label: &blankString, Value: &pushValue},
}
@ -299,8 +299,8 @@ func (c *APIController) generateGenericClientSetupDetail(
header3 := "Download Artifact"
section3step1Header := "Run this command in your terminal to download the artifact."
//nolint:lll
pullValue := "curl --location '<HOSTNAME>/<REGISTRY_NAME>/<ARTIFACT_NAME>:<VERSION>:<FILENAME>' --header 'x-api-key: <API_KEY>' " +
"-J -O"
pullValue := "curl --location '<HOSTNAME>/<ARTIFACT_NAME>/<VERSION>' \\\n--form 'filename=\"<FILENAME>\"' --header 'x-api-key: <API_KEY>' " +
"-o <FILENAME>"
section3step1Commands := []artifact.ClientSetupStepCommand{
{Label: &blankString, Value: &pullValue},
}
@ -1250,7 +1250,7 @@ func (c *APIController) replacePlaceholdersInSection(
_, registryName, _ := paths.DisectLeaf(regRef)
var hostname string
if pkgType == string(artifact.PackageTypeGENERIC) {
hostname = c.URLProvider.RegistryURL(ctx, rootSpace, "generic")
hostname = c.URLProvider.PackageURL(ctx, regRef, "generic")
} else {
hostname = common.TrimURLScheme(c.URLProvider.RegistryURL(ctx, rootSpace))
}

View File

@ -27,12 +27,15 @@ import (
corestore "github.com/harness/gitness/app/store"
urlprovider "github.com/harness/gitness/app/url"
"github.com/harness/gitness/registry/app/api/controller/metadata"
"github.com/harness/gitness/registry/app/api/handler/packages"
"github.com/harness/gitness/registry/app/api/handler/utils"
artifact2 "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/dist_temp/errcode"
"github.com/harness/gitness/registry/app/pkg"
"github.com/harness/gitness/registry/app/pkg/commons"
"github.com/harness/gitness/registry/app/pkg/generic"
"github.com/harness/gitness/registry/app/pkg/types/npm"
"github.com/harness/gitness/registry/request"
"github.com/rs/zerolog/log"
)
@ -47,9 +50,10 @@ const (
func NewGenericArtifactHandler(
spaceStore corestore.SpaceStore, controller *generic.Controller, tokenStore corestore.TokenStore,
userCtrl *usercontroller.Controller, authenticator authn.Authenticator, urlProvider urlprovider.Provider,
authorizer authz.Authorizer,
authorizer authz.Authorizer, packageHandler packages.Handler,
) *Handler {
return &Handler{
Handler: packageHandler,
Controller: controller,
SpaceStore: spaceStore,
TokenStore: tokenStore,
@ -61,6 +65,7 @@ func NewGenericArtifactHandler(
}
type Handler struct {
packages.Handler
Controller *generic.Controller
SpaceStore corestore.SpaceStore
TokenStore corestore.TokenStore
@ -70,8 +75,12 @@ type Handler struct {
Authorizer authz.Authorizer
}
func (h *Handler) GetArtifactInfo(r *http.Request) (pkg.GenericArtifactInfo, errcode.Error) {
func (h *Handler) GetGenericArtifactInfo(r *http.Request) (pkg.GenericArtifactInfo, errcode.Error) {
ctx := r.Context()
info, ok := request.ArtifactInfoFrom(ctx).(pkg.GenericArtifactInfo)
if ok {
return info, errcode.Error{}
}
path := r.URL.Path
rootIdentifier, registryIdentifier, artifact, tag, fileName, description, err := ExtractPathVars(r)
@ -115,7 +124,7 @@ func (h *Handler) GetArtifactInfo(r *http.Request) (pkg.GenericArtifactInfo, err
return pkg.GenericArtifactInfo{}, errcode.ErrCodeParentNotFound.WithDetail(err)
}
info := &pkg.GenericArtifactInfo{
info = pkg.GenericArtifactInfo{
ArtifactInfo: &pkg.ArtifactInfo{
BaseInfo: &pkg.BaseInfo{
RootIdentifier: rootIdentifier,
@ -150,7 +159,7 @@ func (h *Handler) GetArtifactInfo(r *http.Request) (pkg.GenericArtifactInfo, err
}
}
return *info, errcode.Error{}
return info, errcode.Error{}
}
// ExtractPathVars extracts registry,image, reference, digest and tag from the path
@ -242,3 +251,29 @@ func validatePackageVersionAndFileName(packageName, version, filename string) er
return nil
}
func (h *Handler) GetPackageArtifactInfo(r *http.Request) (pkg.PackageArtifactInfo, error) {
info, e := h.GetArtifactInfo(r)
if !commons.IsEmpty(e) {
return npm.ArtifactInfo{}, e
}
info.Image = r.PathValue("package")
version := r.PathValue("version")
fileName := r.FormValue("filename")
description := r.FormValue("description")
if err := validatePackageVersionAndFileName(info.Image, version, fileName); err != nil {
log.Error().Msgf("Invalid image name/version/fileName: %s/%s/%s", info.Image, version, fileName)
return nil, err
}
return pkg.GenericArtifactInfo{
ArtifactInfo: &info,
Version: version,
FileName: fileName,
Description: description,
RegistryID: info.RegistryID,
}, nil
}

View File

@ -25,7 +25,7 @@ import (
func (h *Handler) PullArtifact(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
info, err := h.GetArtifactInfo(r)
info, err := h.GetGenericArtifactInfo(r)
if !commons.IsEmptyError(err) {
handleErrors(r.Context(), err, w)
return

View File

@ -23,7 +23,7 @@ import (
)
func (h *Handler) PushArtifact(w http.ResponseWriter, r *http.Request) {
info, err := h.GetArtifactInfo(r)
info, err := h.GetGenericArtifactInfo(r)
if !commons.IsEmptyError(err) {
handleErrors(r.Context(), err, w)
return

View File

@ -135,7 +135,7 @@ func TrackBandwidthStatForGenericArtifacts(h *generic.Handler) func(http.Handler
}
ctx := r.Context()
info, err := h.GetArtifactInfo(r)
info, err := h.GetGenericArtifactInfo(r)
if !commons.IsEmptyError(err) {
log.Ctx(ctx).Error().Stack().Str("middleware",
"TrackBandwidthStat").Err(err).Msgf("error while putting bandwidth stat for artifact, %v",

View File

@ -138,7 +138,7 @@ func TrackDownloadStatForGenericArtifact(h *generic.Handler) func(http.Handler)
return
}
info, err := h.GetArtifactInfo(r)
info, err := h.GetGenericArtifactInfo(r)
if !commons.IsEmptyError(err) {
log.Ctx(ctx).Error().Stack().Str("middleware",
"TrackDownloadStat").Err(err).Msgf("error while putting download stat of artifact, %v",

View File

@ -70,11 +70,17 @@ func NewRouter(
r.Route("/generic", func(r chi.Router) {
r.Use(middlewareauthn.Attempt(packageHandler.GetAuthenticator()))
r.Use(middleware.CheckAuth())
r.Use(middleware.TrackDownloadStatForGenericArtifact(genericHandler))
r.Use(middleware.TrackBandwidthStatForGenericArtifacts(genericHandler))
r.Route("/{package}/{version}", func(r chi.Router) {
r.Use(middleware.StoreArtifactInfo(genericHandler))
r.Use(middleware.TrackDownloadStatForGenericArtifact(genericHandler))
r.Use(middleware.TrackBandwidthStatForGenericArtifacts(genericHandler))
r.Get("/*", genericHandler.PullArtifact)
r.Put("/*", genericHandler.PushArtifact)
r.With(middleware.RequestPackageAccess(packageHandler, enum.PermissionArtifactsDownload)).
Get("/", genericHandler.PullArtifact)
r.With(middleware.RequestPackageAccess(packageHandler, enum.PermissionArtifactsUpload)).
Put("/", genericHandler.PushArtifact)
})
})
r.Route("/python", func(r chi.Router) {

View File

@ -168,7 +168,7 @@ func NewRpmHandlerProvider(
func NewGenericHandlerProvider(
spaceStore corestore.SpaceStore, controller *generic2.Controller, tokenStore corestore.TokenStore,
userCtrl *usercontroller.Controller, authenticator authn.Authenticator, urlProvider urlprovider.Provider,
authorizer authz.Authorizer,
authorizer authz.Authorizer, packageHandler packages.Handler,
) *generic.Handler {
return generic.NewGenericArtifactHandler(
spaceStore,
@ -178,6 +178,7 @@ func NewGenericHandlerProvider(
authenticator,
urlProvider,
authorizer,
packageHandler,
)
}

View File

@ -79,3 +79,19 @@ type GenericArtifactInfo struct {
func (a *MavenArtifactInfo) SetMavenRepoKey(key string) {
a.RegIdentifier = key
}
// BaseArtifactInfo implements pkg.PackageArtifactInfo interface.
func (a GenericArtifactInfo) BaseArtifactInfo() ArtifactInfo {
return *a.ArtifactInfo
}
func (a GenericArtifactInfo) GetImageVersion() (exists bool, imageVersion string) {
if a.Image != "" && a.Version != "" {
return true, JoinWithSeparator(":", a.Image, a.Version)
}
return false, ""
}
func (a GenericArtifactInfo) GetVersion() string {
return a.Version
}