fix: [AH-717]: Added fix to return 404 in case manifest or blobs are not available (#3107)

* [AH-717]: updated lint issues
* Merge branch 'main' of https://git0.harness.io/l7B_kbSEQD2wjrM7PShm5w/PROD/Harness_Commons/gitness into AH-717-404-fix-registry
* [AH-717]: Added fix to return 404 in case manifest or blobs are not available
pull/3597/head
Arvind Choudhary 2024-12-06 03:33:51 +00:00 committed by Harness
parent 3496df5316
commit cfa4e351c4
3 changed files with 65 additions and 17 deletions

View File

@ -112,10 +112,16 @@ func isEmpty(slice interface{}) bool {
return reflect.ValueOf(slice).Len() == 0
}
const (
ResourceTypeBlob = "blob"
ResourceTypeManifest = "manifest"
)
func (c *Controller) ProxyWrapper(
ctx context.Context,
f func(registry registrytypes.Registry, imageName string, artInfo pkg.Artifact) Response,
info pkg.RegistryInfo,
resourceType string,
) Response {
none := pkg.RegistryInfo{}
if info == none {
@ -139,9 +145,21 @@ func (c *Controller) ProxyWrapper(
if isEmpty(response.GetErrors()) {
return response
}
log.Ctx(ctx).Warn().Msgf("Repository: %s, Type: %s, errors: %v", registry.Name, registry.Type,
response.GetErrors())
}
}
}
if response != nil && !isEmpty(response.GetErrors()) {
switch resourceType {
case ResourceTypeManifest:
response.SetError(errcode.ErrCodeManifestUnknown)
case ResourceTypeBlob:
response.SetError(errcode.ErrCodeBlobUnknown)
default:
// do nothing
}
}
return response
}
@ -152,7 +170,8 @@ func (c *Controller) HeadManifest(
ifNoneMatchHeader []string,
) Response {
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, art.RegIdentifier, art.ParentID, enum.PermissionArtifactsDownload,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, art.RegIdentifier, art.ParentID,
enum.PermissionArtifactsDownload,
)
if err != nil {
return &GetManifestResponse{
@ -167,7 +186,7 @@ func (c *Controller) HeadManifest(
return response
}
result := c.ProxyWrapper(ctx, f, art)
result := c.ProxyWrapper(ctx, f, art, ResourceTypeManifest)
return result
}
@ -178,7 +197,8 @@ func (c *Controller) PullManifest(
ifNoneMatchHeader []string,
) Response {
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, art.RegIdentifier, art.ParentID, enum.PermissionArtifactsDownload,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, art.RegIdentifier, art.ParentID,
enum.PermissionArtifactsDownload,
)
if err != nil {
return &GetManifestResponse{
@ -192,7 +212,7 @@ func (c *Controller) PullManifest(
return response
}
result := c.ProxyWrapper(ctx, f, art)
result := c.ProxyWrapper(ctx, f, art, ResourceTypeManifest)
return result
}
@ -235,7 +255,8 @@ func (c *Controller) HeadBlob(
redirectURL string, errs []error,
) {
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, enum.PermissionArtifactsDownload,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDownload,
)
if err != nil {
return nil, nil, 0, nil, "", []error{errcode.ErrCodeDenied}
@ -245,7 +266,8 @@ func (c *Controller) HeadBlob(
func (c *Controller) GetBlob(ctx context.Context, info pkg.RegistryInfo) Response {
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, enum.PermissionArtifactsDownload,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDownload,
)
if err != nil {
return &GetBlobResponse{
@ -258,7 +280,7 @@ func (c *Controller) GetBlob(ctx context.Context, info pkg.RegistryInfo) Respons
return &GetBlobResponse{errs, headers, body, size, readCloser, redirectURL}
}
return c.ProxyWrapper(ctx, f, info)
return c.ProxyWrapper(ctx, f, info, ResourceTypeBlob)
}
func (c *Controller) InitiateUploadBlob(
@ -268,7 +290,8 @@ func (c *Controller) InitiateUploadBlob(
mountDigest string,
) (*commons.ResponseHeaders, []error) {
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, enum.PermissionArtifactsUpload,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsUpload,
enum.PermissionArtifactsDownload,
)
if err != nil {
@ -283,7 +306,8 @@ func (c *Controller) GetUploadBlobStatus(
token string,
) (responseHeaders *commons.ResponseHeaders, errs []error) {
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, enum.PermissionArtifactsDownload,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDownload,
)
if err != nil {
return nil, []error{errcode.ErrCodeDenied}
@ -304,7 +328,8 @@ func (c *Controller) PatchBlobUpload(
) (responseHeaders *commons.ResponseHeaders, errors []error) {
blobCtx := c.local.App.GetBlobsContext(ctx, info)
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, enum.PermissionArtifactsDownload,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDownload,
enum.PermissionArtifactsUpload,
)
if err != nil {
@ -334,7 +359,8 @@ func (c *Controller) CompleteBlobUpload(
stateToken string,
) (responseHeaders *commons.ResponseHeaders, errs []error) {
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, enum.PermissionArtifactsUpload,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsUpload,
enum.PermissionArtifactsDownload,
)
if err != nil {
@ -349,7 +375,8 @@ func (c *Controller) CancelBlobUpload(
stateToken string,
) (responseHeaders *commons.ResponseHeaders, errors []error) {
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, enum.PermissionArtifactsDelete,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDelete,
)
if err != nil {
return nil, []error{errcode.ErrCodeDenied}
@ -389,7 +416,8 @@ func (c *Controller) DeleteBlob(
info pkg.RegistryInfo,
) (responseHeaders *commons.ResponseHeaders, errs []error) {
err := GetRegistryCheckAccess(
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID, enum.PermissionArtifactsDelete,
ctx, c.RegistryDao, c.authorizer, c.spaceStore, info.RegIdentifier, info.ParentID,
enum.PermissionArtifactsDelete,
)
if err != nil {
return nil, []error{errcode.ErrCodeDenied}

View File

@ -213,7 +213,8 @@ func (r *RemoteRegistry) ManifestExist(
localRegistryIdentifier := ExtractRegistryIdentifierFromPath(artInfo.Path)
responseHeaders.Code = http.StatusMovedPermanently
responseHeaders.Headers = map[string]string{
"Location": defaultManifestURL(artInfo.RootIdentifier, localRegistryIdentifier, artInfo.Image, registryInfo),
"Location": defaultManifestURL(artInfo.RootIdentifier, localRegistryIdentifier, artInfo.Image,
registryInfo),
}
return responseHeaders, descriptor, manifestResult, errs
}
@ -274,7 +275,7 @@ func (r *RemoteRegistry) ManifestExist(
if err != nil {
errs = append(errs, err)
log.Ctx(ctx).Warn().Msgf(
"Proxy to remote failed, fallback to local registry: %s",
"Proxy to remote failed, fallback to next registry: %s",
err.Error(),
)
}
@ -303,7 +304,8 @@ func (r *RemoteRegistry) PullManifest(
localRegistryIdentifier := ExtractRegistryIdentifierFromPath(artInfo.Path)
responseHeaders.Code = http.StatusMovedPermanently
responseHeaders.Headers = map[string]string{
"Location": defaultManifestURL(artInfo.RootIdentifier, localRegistryIdentifier, artInfo.Image, registryInfo),
"Location": defaultManifestURL(artInfo.RootIdentifier, localRegistryIdentifier, artInfo.Image,
registryInfo),
}
return responseHeaders, descriptor, manifestResult, errs
}
@ -367,7 +369,7 @@ func (r *RemoteRegistry) PullManifest(
)
if err != nil {
errs = append(errs, err)
log.Ctx(ctx).Warn().Msgf("Proxy to remote failed, fallback to local registry: %s", err.Error())
log.Ctx(ctx).Warn().Msgf("Proxy to remote failed, fallback to next registry: %s", err.Error())
}
return responseHeaders, descriptor, manifestResult, errs
}

View File

@ -24,6 +24,7 @@ import (
type Response interface {
GetErrors() []error
SetError(error)
}
var _ Response = (*GetManifestResponse)(nil)
@ -40,6 +41,10 @@ type GetManifestResponse struct {
func (r *GetManifestResponse) GetErrors() []error {
return r.Errors
}
func (r *GetManifestResponse) SetError(err error) {
r.Errors = make([]error, 1)
r.Errors[0] = err
}
type PutManifestResponse struct {
Errors []error
@ -48,6 +53,10 @@ type PutManifestResponse struct {
func (r *PutManifestResponse) GetErrors() []error {
return r.Errors
}
func (r *PutManifestResponse) SetError(err error) {
r.Errors = make([]error, 1)
r.Errors[0] = err
}
type DeleteManifestResponse struct {
Errors []error
@ -56,6 +65,10 @@ type DeleteManifestResponse struct {
func (r *DeleteManifestResponse) GetErrors() []error {
return r.Errors
}
func (r *DeleteManifestResponse) SetError(err error) {
r.Errors = make([]error, 1)
r.Errors[0] = err
}
type GetBlobResponse struct {
Errors []error
@ -69,3 +82,8 @@ type GetBlobResponse struct {
func (r *GetBlobResponse) GetErrors() []error {
return r.Errors
}
func (r *GetBlobResponse) SetError(err error) {
r.Errors = make([]error, 1)
r.Errors[0] = err
}