[feat]: [AH-147]: added maven integration api handlers (#3269)

* [feat]: [AH-147]: added maven handlers, routers
* [feat]: [AH-147]: added maven handlers, routers
* [feat]: [AH-147]: added maven handlers, routers
* Merge branch 'main' of https://git0.harness.io/l7B_kbSEQD2wjrM7PShm5w/PROD/Harness_Commons/gitness into maven-integration-api-handler
* [feat]: [AH-147]: added maven handlers, routers
* [feat]: [AH-147]: added maven handlers, routers
This commit is contained in:
Pragyesh Mishra 2025-01-15 12:23:21 +00:00 committed by Harness
parent ab2a066bf9
commit af016422cd
25 changed files with 949 additions and 34 deletions

View File

@ -127,6 +127,7 @@ import (
"github.com/harness/gitness/registry/app/api/router" "github.com/harness/gitness/registry/app/api/router"
"github.com/harness/gitness/registry/app/pkg" "github.com/harness/gitness/registry/app/pkg"
"github.com/harness/gitness/registry/app/pkg/docker" "github.com/harness/gitness/registry/app/pkg/docker"
"github.com/harness/gitness/registry/app/pkg/maven"
database2 "github.com/harness/gitness/registry/app/store/database" database2 "github.com/harness/gitness/registry/app/store/database"
"github.com/harness/gitness/registry/gc" "github.com/harness/gitness/registry/gc"
"github.com/harness/gitness/ssh" "github.com/harness/gitness/ssh"
@ -480,7 +481,13 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
registryOCIHandler := router.OCIHandlerProvider(handler) registryOCIHandler := router.OCIHandlerProvider(handler)
cleanupPolicyRepository := database2.ProvideCleanupPolicyDao(db, transactor) cleanupPolicyRepository := database2.ProvideCleanupPolicyDao(db, transactor)
apiHandler := router.APIHandlerProvider(registryRepository, upstreamProxyConfigRepository, tagRepository, manifestRepository, cleanupPolicyRepository, imageRepository, storageDriver, spaceStore, transactor, authenticator, provider, authorizer, auditService, spacePathStore) apiHandler := router.APIHandlerProvider(registryRepository, upstreamProxyConfigRepository, tagRepository, manifestRepository, cleanupPolicyRepository, imageRepository, storageDriver, spaceStore, transactor, authenticator, provider, authorizer, auditService, spacePathStore)
appRouter := router.AppRouterProvider(registryOCIHandler, apiHandler) mavenDBStore := maven.DBStoreProvider(registryRepository, imageRepository, artifactRepository, spaceStore, bandwidthStatRepository, downloadStatRepository)
mavenLocalRegistry := maven.LocalRegistryProvider(mavenDBStore, transactor)
mavenRemoteRegistry := maven.RemoteRegistryProvider(mavenDBStore, transactor)
mavenController := maven.ControllerProvider(mavenLocalRegistry, mavenRemoteRegistry, authorizer, mavenDBStore)
mavenHandler := api2.NewMavenHandlerProvider(mavenController, spaceStore, tokenStore, controller, authenticator, authorizer)
handler2 := router.MavenHandlerProvider(mavenHandler)
appRouter := router.AppRouterProvider(registryOCIHandler, apiHandler, handler2)
sender := usage.ProvideMediator(ctx, config, spaceStore, usageMetricStore) sender := usage.ProvideMediator(ctx, config, spaceStore, usageMetricStore)
routerRouter := router2.ProvideRouter(ctx, config, authenticator, repoController, reposettingsController, executionController, logsController, spaceController, pipelineController, secretController, triggerController, connectorController, templateController, pluginController, pullreqController, webhookController, githookController, gitInterface, serviceaccountController, controller, principalController, usergroupController, checkController, systemController, uploadController, keywordsearchController, infraproviderController, gitspaceController, migrateController, aiagentController, capabilitiesController, provider, openapiService, appRouter, sender) routerRouter := router2.ProvideRouter(ctx, config, authenticator, repoController, reposettingsController, executionController, logsController, spaceController, pipelineController, secretController, triggerController, connectorController, templateController, pluginController, pullreqController, webhookController, githookController, gitInterface, serviceaccountController, controller, principalController, usergroupController, checkController, systemController, uploadController, keywordsearchController, infraproviderController, gitspaceController, migrateController, aiagentController, capabilitiesController, provider, openapiService, appRouter, sender)
serverServer := server2.ProvideServer(config, routerRouter) serverServer := server2.ProvideServer(config, routerRouter)

View File

@ -0,0 +1,218 @@
// 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 maven
import (
"context"
"fmt"
"net/http"
"regexp"
"strings"
usercontroller "github.com/harness/gitness/app/api/controller/user"
"github.com/harness/gitness/app/auth/authn"
"github.com/harness/gitness/app/auth/authz"
corestore "github.com/harness/gitness/app/store"
"github.com/harness/gitness/registry/app/api/controller/metadata"
"github.com/harness/gitness/registry/app/api/handler/utils"
"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/maven"
"github.com/harness/gitness/registry/request"
"github.com/rs/zerolog/log"
)
type Handler struct {
Controller *maven.Controller
SpaceStore corestore.SpaceStore
TokenStore corestore.TokenStore
UserCtrl *usercontroller.Controller
Authenticator authn.Authenticator
Authorizer authz.Authorizer
}
func NewHandler(
controller *maven.Controller, spaceStore corestore.SpaceStore, tokenStore corestore.TokenStore,
userCtrl *usercontroller.Controller, authenticator authn.Authenticator, authorizer authz.Authorizer,
) *Handler {
return &Handler{
Controller: controller,
SpaceStore: spaceStore,
TokenStore: tokenStore,
UserCtrl: userCtrl,
Authenticator: authenticator,
Authorizer: authorizer,
}
}
const (
mavenMetadataFile = "maven-metadata.xml"
extensionMD5 = ".md5"
extensionSHA1 = ".sha1"
extensionSHA256 = ".sha256"
extensionSHA512 = ".sha512"
extensionPom = ".pom"
extensionJar = ".jar"
contentTypeJar = "application/java-archive"
contentTypeXML = "text/xml"
)
var (
illegalCharacters = regexp.MustCompile(`[\\/:"<>|?\*]`)
invalidPathFormat = "invalid path format: %s"
)
func (h *Handler) GetArtifactInfo(r *http.Request, remoteSupport bool) (pkg.MavenArtifactInfo, error) {
ctx := r.Context()
path := r.URL.Path
rootIdentifier, registryIdentifier, groupID, artifactID, version, fileName, err := ExtractPathVars(path)
if err != nil {
return pkg.MavenArtifactInfo{}, err
}
if err = metadata.ValidateIdentifier(rootIdentifier); err != nil {
return pkg.MavenArtifactInfo{}, err
}
rootSpace, err := h.SpaceStore.FindByRefCaseInsensitive(ctx, rootIdentifier)
if err != nil {
log.Ctx(ctx).Error().Msgf("Root space not found: %s", rootIdentifier)
return pkg.MavenArtifactInfo{}, errcode.ErrCodeRootNotFound
}
registry, err := h.Controller.DBStore.RegistryDao.GetByRootParentIDAndName(ctx, rootSpace.ID, registryIdentifier)
if err != nil {
log.Ctx(ctx).Error().Msgf(
"registry %s not found for root: %s. Reason: %s", registryIdentifier, rootSpace.Identifier, err,
)
return pkg.MavenArtifactInfo{}, errcode.ErrCodeRegNotFound
}
_, err = h.SpaceStore.Find(r.Context(), registry.ParentID)
if err != nil {
log.Ctx(ctx).Error().Msgf("Parent space not found: %d", registry.ParentID)
return pkg.MavenArtifactInfo{}, errcode.ErrCodeParentNotFound
}
pathRoot := getPathRoot(r.Context())
info := &pkg.MavenArtifactInfo{
BaseInfo: &pkg.BaseInfo{
PathRoot: pathRoot,
RootIdentifier: rootIdentifier,
RootParentID: rootSpace.ID,
ParentID: registry.ParentID,
},
RegIdentifier: registryIdentifier,
RegistryID: registry.ID,
GroupID: groupID,
ArtifactID: artifactID,
Version: version,
FileName: fileName,
Path: r.URL.Path,
}
log.Ctx(ctx).Info().Msgf("Dispatch: URI: %s", path)
if commons.IsEmpty(rootSpace.Identifier) {
log.Ctx(ctx).Error().Msgf("ParentRef not found in context")
return pkg.MavenArtifactInfo{}, errcode.ErrCodeParentNotFound
}
if commons.IsEmpty(registryIdentifier) {
log.Ctx(ctx).Warn().Msgf("registry not found in context")
return pkg.MavenArtifactInfo{}, errcode.ErrCodeRegNotFound
}
if !commons.IsEmpty(info.GroupID) && !commons.IsEmpty(info.ArtifactID) && !commons.IsEmpty(info.Version) {
flag, err2 := utils.MatchArtifactFilter(registry.AllowedPattern, registry.BlockedPattern,
info.GroupID+":"+info.ArtifactID+":"+info.Version)
if !flag || err2 != nil {
return pkg.MavenArtifactInfo{}, errcode.ErrCodeDenied
}
}
if registry.Type == artifact.RegistryTypeUPSTREAM && !remoteSupport {
log.Ctx(ctx).Warn().Msgf("Remote registryIdentifier %s not supported", registryIdentifier)
return pkg.MavenArtifactInfo{}, errcode.ErrCodeDenied
}
return *info, nil
}
// ExtractPathVars extracts registry, groupId, artifactId, version and tag from the path
// Path format: /maven/:rootSpace/:registry/:groupId/artifactId/:version/:filename (for ex:
// /maven/myRootSpace/reg1/io/example/my-app/1.0/my-app-1.0.jar.
func ExtractPathVars(path string) (rootIdentifier, registry, groupID, artifactID, version, fileName string, err error) {
path = strings.Trim(path, "/")
segments := strings.Split(path, "/")
if len(segments) < 6 {
err = fmt.Errorf(invalidPathFormat, path)
return "", "", "", "", "", "", err
}
rootIdentifier = segments[1]
registry = segments[2]
fileName = segments[len(segments)-1]
segments = segments[:len(segments)-1]
version = segments[len(segments)-1]
if isMetadataFile(fileName) && !strings.HasSuffix(version, "-SNAPSHOT") {
version = ""
} else {
segments = segments[:len(segments)-1]
if len(segments) < 5 {
err = fmt.Errorf(invalidPathFormat, path)
return rootIdentifier, registry, groupID, artifactID, version, fileName, err
}
}
artifactID = segments[len(segments)-1]
groupID = strings.Join(segments[:len(segments)-1], ".")
if illegalCharacters.MatchString(groupID) || illegalCharacters.MatchString(artifactID) ||
illegalCharacters.MatchString(version) {
err = fmt.Errorf(invalidPathFormat, path)
return rootIdentifier, registry, groupID, artifactID, version, fileName, err
}
return rootIdentifier, registry, groupID, artifactID, version, fileName, nil
}
func isMetadataFile(filename string) bool {
return filename == mavenMetadataFile ||
filename == mavenMetadataFile+extensionMD5 ||
filename == mavenMetadataFile+extensionSHA1 ||
filename == mavenMetadataFile+extensionSHA256 ||
filename == mavenMetadataFile+extensionSHA512
}
func getPathRoot(ctx context.Context) string {
originalURL := request.OriginalURLFrom(ctx)
pathRoot := ""
if originalURL != "" {
originalURL = strings.Trim(originalURL, "/")
segments := strings.Split(originalURL, "/")
if len(segments) > 1 {
pathRoot = segments[1]
}
}
return pathRoot
}
func LogError(errList errcode.Errors) {
for _, e1 := range errList {
log.Error().Err(e1).Msgf("error: %v", e1)
}
}

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 maven
import (
"net/http"
)
func (h *Handler) GetArtifact(_ http.ResponseWriter, _ *http.Request) {
// ctx := r.Context()
}

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 maven
import (
"net/http"
)
func (h *Handler) HeadArtifact(_ http.ResponseWriter, _ *http.Request) {
// ctx := r.Context()
}

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 maven
import (
"net/http"
)
func (h *Handler) PutArtifact(_ http.ResponseWriter, _ *http.Request) {
// ctx := r.Context()
}

View File

@ -25,6 +25,7 @@ import (
corestore "github.com/harness/gitness/app/store" corestore "github.com/harness/gitness/app/store"
urlprovider "github.com/harness/gitness/app/url" urlprovider "github.com/harness/gitness/app/url"
"github.com/harness/gitness/registry/app/api/controller/metadata" "github.com/harness/gitness/registry/app/api/controller/metadata"
"github.com/harness/gitness/registry/app/api/handler/utils"
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact" "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
"github.com/harness/gitness/registry/app/common" "github.com/harness/gitness/registry/app/common"
"github.com/harness/gitness/registry/app/dist_temp/dcontext" "github.com/harness/gitness/registry/app/dist_temp/dcontext"
@ -243,7 +244,7 @@ func (h *Handler) GetRegistryInfo(r *http.Request, remoteSupport bool) (pkg.Regi
} }
if !commons.IsEmpty(info.Image) && !commons.IsEmpty(info.Tag) { if !commons.IsEmpty(info.Image) && !commons.IsEmpty(info.Tag) {
flag, err2 := MatchArtifactFilter(registry.AllowedPattern, registry.BlockedPattern, info.Image+":"+info.Tag) flag, err2 := utils.MatchArtifactFilter(registry.AllowedPattern, registry.BlockedPattern, info.Image+":"+info.Tag)
if !flag || err2 != nil { if !flag || err2 != nil {
return pkg.RegistryInfo{}, errcode.ErrCodeDenied return pkg.RegistryInfo{}, errcode.ErrCodeDenied
} }

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package oci package utils
import ( import (
"errors" "errors"

View File

@ -136,7 +136,7 @@ func dbBandwidthStat(
} }
func getImageFromUpstreamProxy(ctx context.Context, c *docker.Controller, info pkg.RegistryInfo) (*types.Image, error) { func getImageFromUpstreamProxy(ctx context.Context, c *docker.Controller, info pkg.RegistryInfo) (*types.Image, error) {
repos, err := c.GetOrderedRepos(ctx, info.RegIdentifier, info) repos, err := c.GetOrderedRepos(ctx, info.RegIdentifier, *info.BaseInfo)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -0,0 +1,65 @@
// 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 maven
import (
"net/http"
middlewareauthn "github.com/harness/gitness/app/api/middleware/authn"
"github.com/harness/gitness/registry/app/api/handler/maven"
"github.com/harness/gitness/registry/app/api/middleware"
"github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log"
)
type Handler interface {
http.Handler
}
func NewMavenHandler(handler *maven.Handler) Handler {
r := chi.NewRouter()
var routeHandlers = map[string]http.HandlerFunc{
http.MethodHead: handler.HeadArtifact,
http.MethodGet: handler.GetArtifact,
http.MethodPut: handler.PutArtifact,
}
r.Route("/maven", func(r chi.Router) {
r.Use(middleware.StoreOriginalURL)
r.Use(middlewareauthn.Attempt(handler.Authenticator))
//todo: r.Use(middleware.TrackDownloadStat(handler))
//todo: r.Use(middleware.TrackBandwidthStat(handler))
r.Handle("/*", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
methodType := req.Method
if h, ok := routeHandlers[methodType]; ok {
h(w, req)
return
}
w.WriteHeader(http.StatusNotFound)
_, err := w.Write([]byte("Invalid route"))
if err != nil {
log.Error().Err(err).Msg("Failed to write response")
return
}
}))
})
return r
}

View File

@ -41,7 +41,7 @@ func (r *RegistryRouter) IsEligibleTraffic(req *http.Request) bool {
if req.URL.RawPath != "" { if req.URL.RawPath != "" {
urlPath = req.URL.RawPath urlPath = req.URL.RawPath
} }
if utils.HasAnyPrefix(urlPath, []string{RegistryMount, "/v2/", "/registry/"}) || if utils.HasAnyPrefix(urlPath, []string{RegistryMount, "/v2/", "/registry/", "/maven/"}) ||
(strings.HasPrefix(urlPath, APIMount+"/v1/spaces/") && (strings.HasPrefix(urlPath, APIMount+"/v1/spaces/") &&
utils.HasAnySuffix(urlPath, []string{"/artifacts", "/registries"})) { utils.HasAnySuffix(urlPath, []string{"/artifacts", "/registries"})) {
return true return true

View File

@ -22,6 +22,7 @@ import (
"github.com/harness/gitness/app/api/middleware/logging" "github.com/harness/gitness/app/api/middleware/logging"
"github.com/harness/gitness/registry/app/api/handler/swagger" "github.com/harness/gitness/registry/app/api/handler/swagger"
"github.com/harness/gitness/registry/app/api/router/harness" "github.com/harness/gitness/registry/app/api/router/harness"
"github.com/harness/gitness/registry/app/api/router/maven"
"github.com/harness/gitness/registry/app/api/router/oci" "github.com/harness/gitness/registry/app/api/router/oci"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
@ -36,6 +37,7 @@ func GetAppRouter(
ociHandler oci.RegistryOCIHandler, ociHandler oci.RegistryOCIHandler,
appHandler harness.APIHandler, appHandler harness.APIHandler,
baseURL string, baseURL string,
mavenHandler maven.Handler,
) AppRouter { ) AppRouter {
r := chi.NewRouter() r := chi.NewRouter()
r.Use(hlog.URLHandler("http.url")) r.Use(hlog.URLHandler("http.url"))
@ -47,6 +49,7 @@ func GetAppRouter(
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {
r.Handle(fmt.Sprintf("%s/*", baseURL), appHandler) r.Handle(fmt.Sprintf("%s/*", baseURL), appHandler)
r.Handle("/v2/*", ociHandler) r.Handle("/v2/*", ociHandler)
r.Handle("/maven/*", mavenHandler)
r.Handle("/registry/swagger*", swagger.GetSwaggerHandler("/registry")) r.Handle("/registry/swagger*", swagger.GetSwaggerHandler("/registry"))
}) })

View File

@ -21,8 +21,10 @@ import (
corestore "github.com/harness/gitness/app/store" corestore "github.com/harness/gitness/app/store"
urlprovider "github.com/harness/gitness/app/url" urlprovider "github.com/harness/gitness/app/url"
"github.com/harness/gitness/audit" "github.com/harness/gitness/audit"
"github.com/harness/gitness/registry/app/api/handler/maven"
hoci "github.com/harness/gitness/registry/app/api/handler/oci" hoci "github.com/harness/gitness/registry/app/api/handler/oci"
"github.com/harness/gitness/registry/app/api/router/harness" "github.com/harness/gitness/registry/app/api/router/harness"
mavenRouter "github.com/harness/gitness/registry/app/api/router/maven"
"github.com/harness/gitness/registry/app/api/router/oci" "github.com/harness/gitness/registry/app/api/router/oci"
storagedriver "github.com/harness/gitness/registry/app/driver" storagedriver "github.com/harness/gitness/registry/app/driver"
"github.com/harness/gitness/registry/app/store" "github.com/harness/gitness/registry/app/store"
@ -34,8 +36,9 @@ import (
func AppRouterProvider( func AppRouterProvider(
ocir oci.RegistryOCIHandler, ocir oci.RegistryOCIHandler,
appHandler harness.APIHandler, appHandler harness.APIHandler,
mavenHandler mavenRouter.Handler,
) AppRouter { ) AppRouter {
return GetAppRouter(ocir, appHandler, config.APIURL) return GetAppRouter(ocir, appHandler, config.APIURL, mavenHandler)
} }
func APIHandlerProvider( func APIHandlerProvider(
@ -77,4 +80,8 @@ func OCIHandlerProvider(handlerV2 *hoci.Handler) oci.RegistryOCIHandler {
return oci.NewOCIHandler(handlerV2) return oci.NewOCIHandler(handlerV2)
} }
var WireSet = wire.NewSet(APIHandlerProvider, OCIHandlerProvider, AppRouterProvider) func MavenHandlerProvider(handler *maven.Handler) mavenRouter.Handler {
return mavenRouter.NewMavenHandler(handler)
}
var WireSet = wire.NewSet(APIHandlerProvider, OCIHandlerProvider, AppRouterProvider, MavenHandlerProvider)

View File

@ -20,6 +20,7 @@ import (
"github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/auth/authz"
corestore "github.com/harness/gitness/app/store" corestore "github.com/harness/gitness/app/store"
urlprovider "github.com/harness/gitness/app/url" urlprovider "github.com/harness/gitness/app/url"
mavenhandler "github.com/harness/gitness/registry/app/api/handler/maven"
ocihandler "github.com/harness/gitness/registry/app/api/handler/oci" ocihandler "github.com/harness/gitness/registry/app/api/handler/oci"
"github.com/harness/gitness/registry/app/api/router" "github.com/harness/gitness/registry/app/api/router"
storagedriver "github.com/harness/gitness/registry/app/driver" storagedriver "github.com/harness/gitness/registry/app/driver"
@ -28,6 +29,7 @@ import (
"github.com/harness/gitness/registry/app/driver/s3-aws" "github.com/harness/gitness/registry/app/driver/s3-aws"
"github.com/harness/gitness/registry/app/pkg" "github.com/harness/gitness/registry/app/pkg"
"github.com/harness/gitness/registry/app/pkg/docker" "github.com/harness/gitness/registry/app/pkg/docker"
"github.com/harness/gitness/registry/app/pkg/maven"
"github.com/harness/gitness/registry/app/store/database" "github.com/harness/gitness/registry/app/store/database"
"github.com/harness/gitness/registry/config" "github.com/harness/gitness/registry/config"
"github.com/harness/gitness/registry/gc" "github.com/harness/gitness/registry/gc"
@ -82,12 +84,29 @@ func NewHandlerProvider(
) )
} }
func NewMavenHandlerProvider(
controller *maven.Controller, spaceStore corestore.SpaceStore,
tokenStore corestore.TokenStore, userCtrl *usercontroller.Controller, authenticator authn.Authenticator,
authorizer authz.Authorizer,
) *mavenhandler.Handler {
return mavenhandler.NewHandler(
controller,
spaceStore,
tokenStore,
userCtrl,
authenticator,
authorizer,
)
}
var WireSet = wire.NewSet( var WireSet = wire.NewSet(
BlobStorageProvider, BlobStorageProvider,
NewHandlerProvider, NewHandlerProvider,
NewMavenHandlerProvider,
database.WireSet, database.WireSet,
pkg.WireSet, pkg.WireSet,
docker.WireSet, docker.WireSet,
maven.WireSet,
router.WireSet, router.WireSet,
gc.WireSet, gc.WireSet,
) )

View File

@ -56,3 +56,18 @@ func (r *RegistryInfo) SetReference(ref string) {
func (a *ArtifactInfo) SetRepoKey(key string) { func (a *ArtifactInfo) SetRepoKey(key string) {
a.RegIdentifier = key a.RegIdentifier = key
} }
type MavenArtifactInfo struct {
*BaseInfo
RegIdentifier string
RegistryID int64
GroupID string
ArtifactID string
Version string
FileName string
Path string
}
func (a *MavenArtifactInfo) SetMavenRepoKey(key string) {
a.RegIdentifier = key
}

View File

@ -65,7 +65,7 @@ func (c *CoreController) GetArtifact(registry types.Registry) Artifact {
func (c *CoreController) GetOrderedRepos( func (c *CoreController) GetOrderedRepos(
ctx context.Context, ctx context.Context,
repoKey string, repoKey string,
artInfo RegistryInfo, artInfo BaseInfo,
) ([]types.Registry, error) { ) ([]types.Registry, error) {
var result []types.Registry var result []types.Registry
if registry, err := c.RegistryDao.GetByParentIDAndName(ctx, artInfo.ParentID, repoKey); err == nil { if registry, err := c.RegistryDao.GetByParentIDAndName(ctx, artInfo.ParentID, repoKey); err == nil {

View File

@ -26,7 +26,6 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"reflect"
"github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/auth/authz"
corestore "github.com/harness/gitness/app/store" corestore "github.com/harness/gitness/app/store"
@ -105,13 +104,6 @@ func NewDBStore(
} }
} }
func isEmpty(slice interface{}) bool {
if slice == nil {
return true
}
return reflect.ValueOf(slice).Len() == 0
}
const ( const (
ResourceTypeBlob = "blob" ResourceTypeBlob = "blob"
ResourceTypeManifest = "manifest" ResourceTypeManifest = "manifest"
@ -132,7 +124,7 @@ func (c *Controller) ProxyWrapper(
var response Response var response Response
requestRepoKey := info.RegIdentifier requestRepoKey := info.RegIdentifier
imageName := info.Image imageName := info.Image
if repos, err := c.GetOrderedRepos(ctx, requestRepoKey, info); err == nil { if repos, err := c.GetOrderedRepos(ctx, requestRepoKey, *info.BaseInfo); err == nil {
for _, registry := range repos { for _, registry := range repos {
log.Ctx(ctx).Info().Msgf("Using Repository: %s, Type: %s", registry.Name, registry.Type) log.Ctx(ctx).Info().Msgf("Using Repository: %s, Type: %s", registry.Name, registry.Type)
artifact, ok := c.GetArtifact(registry).(Registry) artifact, ok := c.GetArtifact(registry).(Registry)
@ -142,7 +134,7 @@ func (c *Controller) ProxyWrapper(
} }
if artifact != nil { if artifact != nil {
response = f(registry, imageName, artifact) response = f(registry, imageName, artifact)
if isEmpty(response.GetErrors()) { if pkg.IsEmpty(response.GetErrors()) {
return response return response
} }
log.Ctx(ctx).Warn().Msgf("Repository: %s, Type: %s, errors: %v", registry.Name, registry.Type, log.Ctx(ctx).Warn().Msgf("Repository: %s, Type: %s, errors: %v", registry.Name, registry.Type,
@ -150,7 +142,7 @@ func (c *Controller) ProxyWrapper(
} }
} }
} }
if response != nil && !isEmpty(response.GetErrors()) { if response != nil && !pkg.IsEmpty(response.GetErrors()) {
switch resourceType { switch resourceType {
case ResourceTypeManifest: case ResourceTypeManifest:
response.SetError(errcode.ErrCodeManifestUnknown) response.SetError(errcode.ErrCodeManifestUnknown)
@ -169,7 +161,7 @@ func (c *Controller) HeadManifest(
acceptHeaders []string, acceptHeaders []string,
ifNoneMatchHeader []string, ifNoneMatchHeader []string,
) Response { ) Response {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, art.RegIdentifier, art.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, art.RegIdentifier, art.ParentID,
enum.PermissionArtifactsDownload, enum.PermissionArtifactsDownload,
) )
@ -196,7 +188,7 @@ func (c *Controller) PullManifest(
acceptHeaders []string, acceptHeaders []string,
ifNoneMatchHeader []string, ifNoneMatchHeader []string,
) Response { ) Response {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, art.RegIdentifier, art.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, art.RegIdentifier, art.ParentID,
enum.PermissionArtifactsDownload, enum.PermissionArtifactsDownload,
) )
@ -223,7 +215,7 @@ func (c *Controller) PutManifest(
body io.ReadCloser, body io.ReadCloser,
length int64, length int64,
) (responseHeaders *commons.ResponseHeaders, errs []error) { ) (responseHeaders *commons.ResponseHeaders, errs []error) {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, artInfo.RegIdentifier, ctx, c.RegistryDao, c.authorizer, c.spaceStore, artInfo.RegIdentifier,
artInfo.ParentID, enum.PermissionArtifactsUpload, enum.PermissionArtifactsDownload, artInfo.ParentID, enum.PermissionArtifactsUpload, enum.PermissionArtifactsDownload,
) )
@ -237,7 +229,7 @@ func (c *Controller) DeleteManifest(
ctx context.Context, ctx context.Context,
artInfo pkg.RegistryInfo, artInfo pkg.RegistryInfo,
) (errs []error, responseHeaders *commons.ResponseHeaders) { ) (errs []error, responseHeaders *commons.ResponseHeaders) {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, artInfo.RegIdentifier, artInfo.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, artInfo.RegIdentifier, artInfo.ParentID,
enum.PermissionArtifactsDelete, enum.PermissionArtifactsDelete,
) )
@ -254,7 +246,7 @@ func (c *Controller) HeadBlob(
responseHeaders *commons.ResponseHeaders, fr *storage.FileReader, size int64, readCloser io.ReadCloser, responseHeaders *commons.ResponseHeaders, fr *storage.FileReader, size int64, readCloser io.ReadCloser,
redirectURL string, errs []error, redirectURL string, errs []error,
) { ) {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDownload, enum.PermissionArtifactsDownload,
) )
@ -265,7 +257,7 @@ func (c *Controller) HeadBlob(
} }
func (c *Controller) GetBlob(ctx context.Context, info pkg.RegistryInfo) Response { func (c *Controller) GetBlob(ctx context.Context, info pkg.RegistryInfo) Response {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDownload, enum.PermissionArtifactsDownload,
) )
@ -289,7 +281,7 @@ func (c *Controller) InitiateUploadBlob(
fromImageRef string, fromImageRef string,
mountDigest string, mountDigest string,
) (*commons.ResponseHeaders, []error) { ) (*commons.ResponseHeaders, []error) {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsUpload, enum.PermissionArtifactsUpload,
enum.PermissionArtifactsDownload, enum.PermissionArtifactsDownload,
@ -305,7 +297,7 @@ func (c *Controller) GetUploadBlobStatus(
info pkg.RegistryInfo, info pkg.RegistryInfo,
token string, token string,
) (responseHeaders *commons.ResponseHeaders, errs []error) { ) (responseHeaders *commons.ResponseHeaders, errs []error) {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDownload, enum.PermissionArtifactsDownload,
) )
@ -327,7 +319,7 @@ func (c *Controller) PatchBlobUpload(
body io.ReadCloser, body io.ReadCloser,
) (responseHeaders *commons.ResponseHeaders, errors []error) { ) (responseHeaders *commons.ResponseHeaders, errors []error) {
blobCtx := c.local.App.GetBlobsContext(ctx, info) blobCtx := c.local.App.GetBlobsContext(ctx, info)
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDownload, enum.PermissionArtifactsDownload,
enum.PermissionArtifactsUpload, enum.PermissionArtifactsUpload,
@ -358,7 +350,7 @@ func (c *Controller) CompleteBlobUpload(
length int64, length int64,
stateToken string, stateToken string,
) (responseHeaders *commons.ResponseHeaders, errs []error) { ) (responseHeaders *commons.ResponseHeaders, errs []error) {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsUpload, enum.PermissionArtifactsUpload,
enum.PermissionArtifactsDownload, enum.PermissionArtifactsDownload,
@ -374,7 +366,7 @@ func (c *Controller) CancelBlobUpload(
info pkg.RegistryInfo, info pkg.RegistryInfo,
stateToken string, stateToken string,
) (responseHeaders *commons.ResponseHeaders, errors []error) { ) (responseHeaders *commons.ResponseHeaders, errors []error) {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDelete, enum.PermissionArtifactsDelete,
) )
@ -415,7 +407,7 @@ func (c *Controller) DeleteBlob(
ctx context.Context, ctx context.Context,
info pkg.RegistryInfo, info pkg.RegistryInfo,
) (responseHeaders *commons.ResponseHeaders, errs []error) { ) (responseHeaders *commons.ResponseHeaders, errs []error) {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDelete, enum.PermissionArtifactsDelete,
) )
@ -433,7 +425,7 @@ func (c *Controller) GetTags(
origURL string, origURL string,
artInfo pkg.RegistryInfo, artInfo pkg.RegistryInfo,
) (*commons.ResponseHeaders, []string, error) { ) (*commons.ResponseHeaders, []string, error) {
err := GetRegistryCheckAccess( err := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, artInfo.RegIdentifier, ctx, c.RegistryDao, c.authorizer, c.spaceStore, artInfo.RegIdentifier,
artInfo.ParentID, enum.PermissionArtifactsDownload, artInfo.ParentID, enum.PermissionArtifactsDownload,
) )
@ -452,7 +444,7 @@ func (c *Controller) GetReferrers(
artInfo pkg.RegistryInfo, artInfo pkg.RegistryInfo,
artifactType string, artifactType string,
) (index *v1.Index, responseHeaders *commons.ResponseHeaders, err error) { ) (index *v1.Index, responseHeaders *commons.ResponseHeaders, err error) {
accessErr := GetRegistryCheckAccess( accessErr := pkg.GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, artInfo.RegIdentifier, ctx, c.RegistryDao, c.authorizer, c.spaceStore, artInfo.RegIdentifier,
artInfo.ParentID, enum.PermissionArtifactsDownload, artInfo.ParentID, enum.PermissionArtifactsDownload,
) )

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package docker package pkg
import ( import (
"context" "context"

View File

@ -0,0 +1,19 @@
// 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 maven
type Artifact interface {
GetMavenArtifactType() string
}

View File

@ -0,0 +1,188 @@
// 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 maven
import (
"context"
"github.com/harness/gitness/app/auth/authz"
corestore "github.com/harness/gitness/app/store"
"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/store"
registrytypes "github.com/harness/gitness/registry/types"
"github.com/harness/gitness/store/database/dbtx"
"github.com/harness/gitness/types/enum"
"github.com/rs/zerolog/log"
)
var _ Artifact = (*LocalRegistry)(nil)
var _ Artifact = (*RemoteRegistry)(nil)
type ArtifactType int
const (
LocalRegistryType ArtifactType = 1 << iota
RemoteRegistryType
)
var TypeRegistry = map[ArtifactType]Artifact{}
type Controller struct {
local *LocalRegistry
remote *RemoteRegistry
authorizer authz.Authorizer
DBStore *DBStore
_ dbtx.Transactor
}
type DBStore struct {
RegistryDao store.RegistryRepository
ImageDao store.ImageRepository
ArtifactDao store.ArtifactRepository
SpaceStore corestore.SpaceStore
BandwidthStatDao store.BandwidthStatRepository
DownloadStatDao store.DownloadStatRepository
}
func NewController(
local *LocalRegistry,
remote *RemoteRegistry,
authorizer authz.Authorizer,
dBStore *DBStore,
) *Controller {
c := &Controller{
local: local,
remote: remote,
authorizer: authorizer,
DBStore: dBStore,
}
TypeRegistry[LocalRegistryType] = local
TypeRegistry[RemoteRegistryType] = remote
return c
}
func NewDBStore(
registryDao store.RegistryRepository,
imageDao store.ImageRepository,
artifactDao store.ArtifactRepository,
spaceStore corestore.SpaceStore,
bandwidthStatDao store.BandwidthStatRepository,
downloadStatDao store.DownloadStatRepository,
) *DBStore {
return &DBStore{
RegistryDao: registryDao,
SpaceStore: spaceStore,
ImageDao: imageDao,
ArtifactDao: artifactDao,
BandwidthStatDao: bandwidthStatDao,
DownloadStatDao: downloadStatDao,
}
}
func (c *Controller) factory(t ArtifactType) Artifact {
switch t {
case LocalRegistryType:
return TypeRegistry[t]
case RemoteRegistryType:
return TypeRegistry[t]
default:
log.Error().Stack().Msgf("Invalid artifact type %v", t)
return nil
}
}
func (c *Controller) GetArtifactRegistry(registry registrytypes.Registry) Artifact {
if string(registry.Type) == string(artifact.RegistryTypeVIRTUAL) {
return c.factory(LocalRegistryType)
}
return c.factory(RemoteRegistryType)
}
func (c *Controller) GetArtifact(ctx context.Context, info pkg.MavenArtifactInfo) Response {
err := pkg.GetRegistryCheckAccess(
ctx, c.DBStore.RegistryDao, c.authorizer, c.DBStore.SpaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDownload,
)
if err != nil {
return &GetArtifactResponse{
Errors: []error{errcode.ErrCodeDenied},
}
}
f := func(registry registrytypes.Registry, a Artifact) Response {
info.SetMavenRepoKey(registry.Name)
headers, body, e := a.(Registry).GetArtifact(ctx, info)
return &GetArtifactResponse{e, headers, body}
}
return c.ProxyWrapper(ctx, f, info)
}
func (c *Controller) ProxyWrapper(
ctx context.Context,
f func(registry registrytypes.Registry, a Artifact) Response,
info pkg.MavenArtifactInfo,
) Response {
none := pkg.MavenArtifactInfo{}
if info == none {
log.Ctx(ctx).Error().Stack().Msg("artifactinfo is not found")
return nil
}
var response Response
requestRepoKey := info.RegIdentifier
if repos, err := c.GetOrderedRepos(ctx, requestRepoKey, *info.BaseInfo); err == nil {
for _, registry := range repos {
log.Ctx(ctx).Info().Msgf("Using Repository: %s, Type: %s", registry.Name, registry.Type)
artifact, ok := c.GetArtifactRegistry(registry).(Registry)
if !ok {
log.Ctx(ctx).Warn().Msgf("artifact %s is not a registry", registry.Name)
continue
}
if artifact != nil {
response = f(registry, artifact)
if pkg.IsEmpty(response.GetErrors()) {
return response
}
log.Ctx(ctx).Warn().Msgf("Repository: %s, Type: %s, errors: %v", registry.Name, registry.Type,
response.GetErrors())
}
}
}
return response
}
func (c *Controller) GetOrderedRepos(
ctx context.Context,
repoKey string,
artInfo pkg.BaseInfo,
) ([]registrytypes.Registry, error) {
var result []registrytypes.Registry
if registry, err := c.DBStore.RegistryDao.GetByParentIDAndName(ctx, artInfo.ParentID, repoKey); err == nil {
result = append(result, *registry)
proxies := registry.UpstreamProxies
if len(proxies) > 0 {
upstreamRepos, _ := c.DBStore.RegistryDao.GetByIDIn(ctx, proxies)
result = append(result, *upstreamRepos...)
}
} else {
return result, err
}
return result, nil
}

View File

@ -0,0 +1,60 @@
// 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 maven
import (
"context"
"github.com/harness/gitness/registry/app/pkg"
"github.com/harness/gitness/registry/app/pkg/commons"
"github.com/harness/gitness/registry/app/storage"
"github.com/harness/gitness/store/database/dbtx"
)
const (
ArtifactTypeLocalRegistry = "Local Registry"
)
func NewLocalRegistry(dBStore *DBStore, tx dbtx.Transactor,
) Registry {
return &LocalRegistry{
DBStore: dBStore,
tx: tx,
}
}
type LocalRegistry struct {
DBStore *DBStore
tx dbtx.Transactor
}
func (r *LocalRegistry) GetMavenArtifactType() string {
return ArtifactTypeLocalRegistry
}
func (r *LocalRegistry) HeadArtifact(_ context.Context, _ pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, errs []error) {
return nil, nil
}
func (r *LocalRegistry) GetArtifact(_ context.Context, _ pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, errs []error) {
return nil, nil, nil
}
func (r *LocalRegistry) PutArtifact(_ context.Context, _ pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, errs []error) {
return nil, nil
}

View File

@ -0,0 +1,36 @@
// 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 maven
import (
"context"
"github.com/harness/gitness/registry/app/pkg"
"github.com/harness/gitness/registry/app/pkg/commons"
"github.com/harness/gitness/registry/app/storage"
)
type Registry interface {
Artifact
HeadArtifact(ctx context.Context, artInfo pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, errs []error)
GetArtifact(ctx context.Context, artInfo pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, errs []error)
PutArtifact(ctx context.Context, artInfo pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, errs []error)
}

View File

@ -0,0 +1,60 @@
// 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 maven
import (
"context"
"github.com/harness/gitness/registry/app/pkg"
"github.com/harness/gitness/registry/app/pkg/commons"
"github.com/harness/gitness/registry/app/storage"
"github.com/harness/gitness/store/database/dbtx"
)
const (
ArtifactTypeRemoteRegistry = "Remote Registry"
)
func NewRemoteRegistry(dBStore *DBStore, tx dbtx.Transactor,
) Registry {
return &RemoteRegistry{
DBStore: dBStore,
tx: tx,
}
}
type RemoteRegistry struct {
DBStore *DBStore
tx dbtx.Transactor
}
func (r *RemoteRegistry) GetMavenArtifactType() string {
return ArtifactTypeRemoteRegistry
}
func (r *RemoteRegistry) HeadArtifact(_ context.Context, _ pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, errs []error) {
return nil, nil
}
func (r *RemoteRegistry) GetArtifact(_ context.Context, _ pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, errs []error) {
return nil, nil, nil
}
func (r *RemoteRegistry) PutArtifact(_ context.Context, _ pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, errs []error) {
return nil, nil
}

View File

@ -0,0 +1,69 @@
// 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 maven
import (
"github.com/harness/gitness/registry/app/pkg/commons"
"github.com/harness/gitness/registry/app/storage"
)
type Response interface {
GetErrors() []error
SetError(error)
}
var _ Response = (*HeadArtifactResponse)(nil)
var _ Response = (*GetArtifactResponse)(nil)
var _ Response = (*PutArtifactResponse)(nil)
type HeadArtifactResponse struct {
Errors []error
ResponseHeaders *commons.ResponseHeaders
}
func (r *HeadArtifactResponse) GetErrors() []error {
return r.Errors
}
func (r *HeadArtifactResponse) SetError(err error) {
r.Errors = make([]error, 1)
r.Errors[0] = err
}
type GetArtifactResponse struct {
Errors []error
ResponseHeaders *commons.ResponseHeaders
body *storage.FileReader
}
func (r *GetArtifactResponse) GetErrors() []error {
return r.Errors
}
func (r *GetArtifactResponse) SetError(err error) {
r.Errors = make([]error, 1)
r.Errors[0] = err
}
type PutArtifactResponse struct {
Errors []error
ResponseHeaders *commons.ResponseHeaders
}
func (r *PutArtifactResponse) GetErrors() []error {
return r.Errors
}
func (r *PutArtifactResponse) SetError(err error) {
r.Errors = make([]error, 1)
r.Errors[0] = err
}

View File

@ -0,0 +1,63 @@
// 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 maven
import (
"github.com/harness/gitness/app/auth/authz"
corestore "github.com/harness/gitness/app/store"
"github.com/harness/gitness/registry/app/store"
"github.com/harness/gitness/store/database/dbtx"
"github.com/google/wire"
)
func LocalRegistryProvider(
dBStore *DBStore,
tx dbtx.Transactor,
) *LocalRegistry {
return NewLocalRegistry(dBStore, tx).(*LocalRegistry)
}
func RemoteRegistryProvider(
dBStore *DBStore,
tx dbtx.Transactor,
) *RemoteRegistry {
return NewRemoteRegistry(dBStore, tx).(*RemoteRegistry)
}
func ControllerProvider(
local *LocalRegistry,
remote *RemoteRegistry,
authorizer authz.Authorizer,
dBStore *DBStore,
) *Controller {
return NewController(local, remote, authorizer, dBStore)
}
func DBStoreProvider(
registryDao store.RegistryRepository,
imageDao store.ImageRepository,
artifactDao store.ArtifactRepository,
spaceStore corestore.SpaceStore,
bandwidthStatDao store.BandwidthStatRepository,
downloadStatDao store.DownloadStatRepository,
) *DBStore {
return NewDBStore(registryDao, imageDao, artifactDao, spaceStore, bandwidthStatDao, downloadStatDao)
}
var ControllerSet = wire.NewSet(ControllerProvider)
var DBStoreSet = wire.NewSet(DBStoreProvider)
var RegistrySet = wire.NewSet(LocalRegistryProvider, RemoteRegistryProvider)
var WireSet = wire.NewSet(ControllerSet, DBStoreSet, RegistrySet)

24
registry/app/pkg/utils.go Normal file
View File

@ -0,0 +1,24 @@
// 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 pkg
import "reflect"
func IsEmpty(slice interface{}) bool {
if slice == nil {
return true
}
return reflect.ValueOf(slice).Len() == 0
}