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]]
|
||||
from = "/v2/"
|
||||
to = "https://ghcr.registry.beryju.org/v2/"
|
||||
from = "/*"
|
||||
to = "/.netlify/functions/go-get"
|
||||
status = 200
|
||||
force = true
|
||||
query = {go-get = "1"}
|
||||
|
||||
[[redirects]]
|
||||
from = "/v2"
|
||||
to = "/.netlify/functions/oci-proxy"
|
||||
status = 200
|
||||
force = true
|
||||
|
||||
[[redirects]]
|
||||
from = "/v2/*"
|
||||
to = "https://ghcr.registry.beryju.org/v2/goauthentik/:splat"
|
||||
to = "https://ghcr.io/v2/goauthentik/:splat"
|
||||
status = 200
|
||||
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