root: migrate docker images to netlify proxy (#1603)
* migrate to netlify proxy Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * relative forward to func Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * custom logic for go paths Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix const Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * missing break Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add default for new repos Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
db79244ba4
commit
5753182e03
|
@ -1,11 +1,18 @@
|
||||||
[[redirects]]
|
[[redirects]]
|
||||||
from = "/v2/"
|
from = "/*"
|
||||||
to = "https://ghcr.registry.beryju.org/v2/"
|
to = "/.netlify/functions/go-get"
|
||||||
|
status = 200
|
||||||
|
force = true
|
||||||
|
query = {go-get = "1"}
|
||||||
|
|
||||||
|
[[redirects]]
|
||||||
|
from = "/v2"
|
||||||
|
to = "/.netlify/functions/oci-proxy"
|
||||||
status = 200
|
status = 200
|
||||||
force = true
|
force = true
|
||||||
|
|
||||||
[[redirects]]
|
[[redirects]]
|
||||||
from = "/v2/*"
|
from = "/v2/*"
|
||||||
to = "https://ghcr.registry.beryju.org/v2/goauthentik/:splat"
|
to = "https://ghcr.io/v2/goauthentik/:splat"
|
||||||
status = 200
|
status = 200
|
||||||
force = true
|
force = true
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
const gitHubNamespace = "goauthentik.io";
|
||||||
|
|
||||||
|
exports.handler = async function (event, context) {
|
||||||
|
let repo = "";
|
||||||
|
switch (event.path) {
|
||||||
|
case "/":
|
||||||
|
repo = "/authentik.git";
|
||||||
|
break;
|
||||||
|
case "/api":
|
||||||
|
repo = "/client-go.git";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
repo = `${event.path}.git`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {
|
||||||
|
"content-type": "text/html",
|
||||||
|
},
|
||||||
|
body: `<meta name="go-import" content="${event.headers.host}${event.path} git https://github.com/${gitHubNamespace}${repo}">`
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
const config = {
|
||||||
|
namespace: "goauthentik/",
|
||||||
|
// Settings for GHCR
|
||||||
|
registryTokenEndpoint: "https://ghcr.io/token",
|
||||||
|
registryService: "ghcr.io",
|
||||||
|
// Settings for Harbor
|
||||||
|
// registryTokenEndpoint: "https://docker.beryju.org/service/token",
|
||||||
|
// registryService: "harbor-registry",
|
||||||
|
};
|
||||||
|
|
||||||
|
async function getToken(event) {
|
||||||
|
const fetch = await import('node-fetch');
|
||||||
|
const querystring = await import('querystring');
|
||||||
|
let scope = event.queryStringParameters["scope"];
|
||||||
|
let tokenParams = {
|
||||||
|
service: config.registryService,
|
||||||
|
};
|
||||||
|
delete event.headers.host;
|
||||||
|
let forwardHeaders = event.headers;
|
||||||
|
if (scope && scope.includes(":")) {
|
||||||
|
const repo = scope.split(":")[1];
|
||||||
|
console.debug(`oci-proxy[token]: original scope: ${scope}`);
|
||||||
|
scope = `repository:${config.namespace}${repo}:pull`;
|
||||||
|
console.debug(`oci-proxy[token]: rewritten scope: ${scope}`);
|
||||||
|
tokenParams["scope"] = scope;
|
||||||
|
// We only need to forward headers for authentication requests
|
||||||
|
forwardHeaders = {};
|
||||||
|
} else {
|
||||||
|
console.debug(`oci-proxy[token]: no scope`);
|
||||||
|
// For non-scoped requests, we need to forward some URL parameters
|
||||||
|
["account", "client_id", "offline_token", "token"].forEach(param => {
|
||||||
|
tokenParams[param] = event.queryStringParameters[param]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const tokenUrl = `${config.registryTokenEndpoint}?${querystring.stringify(tokenParams)}`
|
||||||
|
console.debug(`oci-proxy[token]: final URL to fetch: ${tokenUrl}`)
|
||||||
|
const tokenRes = await fetch.default(tokenUrl, {
|
||||||
|
headers: forwardHeaders,
|
||||||
|
});
|
||||||
|
const tokenResult = await tokenRes.text();
|
||||||
|
console.debug(`oci-proxy[token]: Status ${tokenRes.status} body '${tokenResult}'`)
|
||||||
|
return {
|
||||||
|
statusCode: tokenRes.status,
|
||||||
|
body: tokenResult,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.handler = async function (event, context) {
|
||||||
|
console.debug(`oci-proxy: URL ${event.httpMethod} ${event.rawUrl}`);
|
||||||
|
if (event.queryStringParameters.hasOwnProperty("token")) {
|
||||||
|
console.debug("oci-proxy: handler=token proxy");
|
||||||
|
return await getToken(event);
|
||||||
|
}
|
||||||
|
if (event.headers.authorization && event.headers.authorization.startsWith("Bearer ")) {
|
||||||
|
console.debug("oci-proxy: authenticated root handler, returning 200");
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {
|
||||||
|
"Docker-Distribution-API-Version": "registry/2.0",
|
||||||
|
"content-type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.debug("oci-proxy: root handler, returning 401 with www-authenticate");
|
||||||
|
return {
|
||||||
|
statusCode: 401,
|
||||||
|
headers: {
|
||||||
|
"www-authenticate": `Bearer realm="https://${event.headers.host}/v2?token",service="${event.headers.host}",scope="repository:user/image:pull"`,
|
||||||
|
"Docker-Distribution-API-Version": "registry/2.0",
|
||||||
|
"content-type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({}),
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue