Skip to content

Commit

Permalink
Add support for Keppel image reagistry (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
defo89 authored Feb 4, 2025
1 parent 99e0d98 commit b7d188e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot
LABEL source_repository="https://github.com/ironcore-dev/boot-operator"
WORKDIR /
COPY --from=builder /workspace/manager .
COPY --from=builder /workspace/templates/ templates/
Expand Down
35 changes: 33 additions & 2 deletions server/imageproxyserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

const (
ghcrIOKey = "ghcr.io/"
keppelKey = "keppel.global.cloud.sap/"
imageKey = "imageName"
layerDigestKey = "layerDigest"
versionKey = "version"
Expand Down Expand Up @@ -45,6 +46,8 @@ func RunImageProxyServer(imageProxyServerAddr string, k8sClient client.Client, l

if strings.HasPrefix(imageDetails.OCIImageName, ghcrIOKey) {
handleGHCR(w, r, &imageDetails, log)
} else if strings.HasPrefix(imageDetails.OCIImageName, keppelKey) {
handleKeppel(w, r, &imageDetails, log)
} else {
http.Error(w, "Bad Request", http.StatusBadRequest)
log.Info("Unsupported registry")
Expand Down Expand Up @@ -84,6 +87,24 @@ func handleGHCR(w http.ResponseWriter, r *http.Request, imageDetails *ImageDetai
proxy.ServeHTTP(w, r)
}

func handleKeppel(w http.ResponseWriter, r *http.Request, imageDetails *ImageDetails, log logr.Logger) {
log.Info("Processing Image Proxy request for Keppel", "method", r.Method, "path", r.URL.Path, "clientIP", r.RemoteAddr)

digest := imageDetails.LayerDigest
targetURL := fmt.Sprintf("https://%sv2/%s/blobs/%s", keppelKey, imageDetails.RepositoryName, digest)
proxyURL, _ := url.Parse(targetURL)

proxy := &httputil.ReverseProxy{
Director: imageDetails.modifyDirector(proxyURL, "", digest),
}

r.URL.Host = proxyURL.Host
r.URL.Scheme = proxyURL.Scheme
r.Host = proxyURL.Host

proxy.ServeHTTP(w, r)
}

func (imageDetails ImageDetails) getBearerToken() (string, error) {
url := fmt.Sprintf("https://ghcr.io/token?scope=repository:%s:pull", imageDetails.RepositoryName)
resp, err := http.Get(url)
Expand Down Expand Up @@ -157,12 +178,20 @@ func parseImageURL(queries url.Values) (imageDetails ImageDetails, err error) {
ociImageName := queries.Get(imageKey)
layerDigest := queries.Get(layerDigestKey)
version := queries.Get(versionKey)
repositoryName := strings.TrimPrefix(ociImageName, ghcrIOKey)

if ociImageName == "" || layerDigest == "" || version == "" {
return ImageDetails{}, fmt.Errorf("missing required query parameters 'image' or 'layer' or 'version'")
}

var repositoryName string
if strings.HasPrefix(ociImageName, ghcrIOKey) {
repositoryName = strings.TrimPrefix(ociImageName, ghcrIOKey)
} else if strings.HasPrefix(ociImageName, keppelKey) {
repositoryName = strings.TrimPrefix(ociImageName, keppelKey)
} else {
return ImageDetails{}, fmt.Errorf("unsupported registry key")
}

return ImageDetails{
OCIImageName: ociImageName,
RepositoryName: repositoryName,
Expand All @@ -176,6 +205,8 @@ func (ImageDetails ImageDetails) modifyDirector(proxyURL *url.URL, bearerToken s
req.URL.Scheme = proxyURL.Scheme
req.URL.Host = proxyURL.Host
req.URL.Path = fmt.Sprintf("/v2/%s/blobs/%s", ImageDetails.RepositoryName, digest)
req.Header.Set("Authorization", "Bearer "+bearerToken)
if bearerToken != "" {
req.Header.Set("Authorization", "Bearer "+bearerToken)
}
}
}

0 comments on commit b7d188e

Please sign in to comment.